⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddr2_32mx32_controller_0.v

📁 Xilinx DDR2存储器接口调试代码
💻 V
📖 第 1 页 / 共 3 页
字号:
   end

//******************************************************************************
// autoref_count - This counter is used to issue AUTO REFRESH command to 
// the memory for every 7.8125us.
// (Auto Refresh Request is raised for every 7.7 us to allow for termination 
// of any ongoing bus transfer).For example at 200MHz frequency
// autoref_count = refresh_time_period/clock_period =  7.7us/5ns = 1540
//******************************************************************************

   always @ (negedge clk) begin
      if (rst180_r == 1'b1)  begin
         rfc_counter_value <= `RFC_COUNT_VALUE;
         ref_freq_cnt      <= `MAX_REF_CNT;
      end
      else begin
         rfc_counter_value <= `RFC_COUNT_VALUE;
         ref_freq_cnt      <= `MAX_REF_CNT;
         autoref_value   <= (autoref_count == ref_freq_cnt);
      end
   end

   always @(negedge clk) begin
      if(rst180_r)
        autoref_count <= `MAX_REF_WIDTH'b0;
      else if(autoref_value)
        autoref_count <= `MAX_REF_WIDTH'b0;
      else
        autoref_count <= autoref_count + 1'b1;
   end
   
   always @ (negedge clk) begin
      if (rst180_r == 1'b1) begin
         auto_ref_detect1   <= 1'b0;
         auto_ref1          <= 1'b0;
      end
      else begin
         auto_ref_detect1   <= autoref_value && init_done;
         auto_ref1          <= auto_ref_detect1;
      end
   end

   assign ar_done_p = (ar_done_reg == 1'b1) ? 1'b1 : 1'b0;

   always @ (negedge clk) begin
      if (rst180_r == 1'b1) begin
         auto_ref_wait <= 1'b0;
         ar_done  <= 1'b0;
         auto_ref_issued <= 1'b0;
      end
      else begin
         if (auto_ref1 && !auto_ref_wait)
           auto_ref_wait <= 1'b1;
         else if (auto_ref_issued_p)
           auto_ref_wait <= 1'b0;
         else
           auto_ref_wait <= auto_ref_wait;

         ar_done         <= ar_done_p;
         auto_ref_issued <= auto_ref_issued_p;
      end
   end

   always @ (negedge clk) begin
      if (rst180_r == 1'b1) begin
         auto_ref_wait1 <= 1'b0;
         auto_ref_wait2 <= 1'b0;
         auto_ref       <= 1'b0;
      end
      else begin
         if (auto_ref_issued_p) begin
            auto_ref_wait1 <= 1'b0;
            auto_ref_wait2 <= 1'b0;
            auto_ref       <= 1'b0;
         end
         else begin
            auto_ref_wait1  <= auto_ref_wait;
            auto_ref_wait2  <= auto_ref_wait1;
            auto_ref        <= auto_ref_wait2;
         end
      end
   end

   assign auto_ref_req = auto_ref_wait;
   assign auto_ref_issued_p = (current_state == AUTO_REFRESH);
   
//******************************************************************************
// Common counter for the Initialization sequence
//******************************************************************************
   always @(negedge clk) begin
      if(rst180_r)
        count6 <= 6'b000000;
      else if(init_current_state == INIT_AUTO_REFRESH || init_current_state ==
              INIT_PRECHARGE || init_current_state == INIT_LOAD_MODE_REG)
        count6 <= CNTNEXT;
      else if(count6 != 6'd0)
        count6 <= count6 - 1'b1;
      else
        count6 <= 6'b000000;
   end

//******************************************************************************
// While doing consecutive READs or WRITEs, the burst_cnt_max value determines
// when the next READ or WRITE command should be issued. burst_cnt_max shows the
// number of clock cycles for each burst. 
// e.g burst_cnt_max = 2 for a burst length of 4
//                   = 4 for a burst length of 8
//******************************************************************************
   assign burst_cnt_max = (burst_length == 3'b010) ? 3'b010 :
                          (burst_length == 3'b011) ? 3'b100 :
                          3'b000;

   always @( negedge clk) begin
      if(rst180_r)
        cas_count <= 3'b000;
      else if(current_state == BURST_READ)
        cas_count <= burst_cnt_max - 1'b1;
      else if(cas_count != 3'b000)
        cas_count <= cas_count - 1'b1;
   end


   always @( negedge clk ) begin
      if(rst180_r)
        wrburst_end_cnt <= 3'b000;
      else if((current_state == FIRST_WRITE) || (current_state == BURST_WRITE))
        wrburst_end_cnt <= burst_cnt_max;
      else if(wrburst_end_cnt != 3'b000)
        wrburst_end_cnt <= wrburst_end_cnt - 1'b1;
   end


   always @ (negedge clk) begin
      if (rst180_r == 1'b1) 
        rdburst_end_1 <= 1'b0;
      else begin
         rdburst_end_2 <= rdburst_end_1;
         if (burst_done == 1'b1) 
           rdburst_end_1 <= 1'b1;
         else
           rdburst_end_1 <= 1'b0;
      end
   end

   assign rdburst_end   = rdburst_end_1 || rdburst_end_2 ;
   
   always @ (negedge clk) begin
      if (rst180_r == 1'b1) 
        wrburst_end_1 <= 1'b0;
      else begin
         wrburst_end_2  <= wrburst_end_1;
         wrburst_end_3  <= wrburst_end_2;
         if  (burst_done == 1'b1)  
           wrburst_end_1 <= 1'b1;
         else
           wrburst_end_1 <= 1'b0;
      end
   end

   assign wrburst_end = wrburst_end_1 || wrburst_end_2 || wrburst_end_3;

//******************************************************************************
// dqs_enable and dqs_reset signals are used to generate DQS signal during write
// data.
//******************************************************************************

   

   assign dqs_enable     = dqs_enable2;
   assign dqs_reset      = dqs_reset2_clk0;

   always @ (negedge clk) begin
      if (rst180_r == 1'b1) begin
         dqs_enable_int <= 1'b0;
         dqs_reset_int  <= 1'b0;
      end
      else begin
         dqs_enable_int <= ((current_state == FIRST_WRITE) ||
                            (current_state == BURST_WRITE) ||
                            (wrburst_end_cnt != 3'b000));
         dqs_reset_int  <= (current_state == FIRST_WRITE);
      end
   end

   always @ (posedge clk) begin
      if (rst0_r == 1'b1) begin
         dqs_enable1     <= 1'b0;
         dqs_enable2     <= 1'b0;
         dqs_enable3     <= 1'b0;
         dqs_reset1_clk0 <= 1'b0;
         dqs_reset2_clk0 <= 1'b0;
         dqs_reset3_clk0 <= 1'b0;
      end
      else begin
         dqs_enable1     <= dqs_enable_int;
         dqs_enable2     <= dqs_enable1;
         dqs_enable3     <= dqs_enable2;
         dqs_reset1_clk0 <= dqs_reset_int;
         dqs_reset2_clk0 <= dqs_reset1_clk0;
         dqs_reset3_clk0 <= dqs_reset2_clk0;
      end
   end

//******************************************************************************
//Write Enable signal to the datapath
//******************************************************************************



   always @ (negedge clk) begin
      if (rst180_r == 1'b1)
         write_enable <= 1'b0;
      else if(wrburst_end_cnt != 3'b000)
         write_enable <= 1'b1; 
      else
         write_enable <= 1'b0;
   end

   assign cmd_ack = ack_reg;

   FD ack_reg_inst1
     (
      .Q (ack_reg),
      .D (ack_o),
      .C (~clk)
      );


   assign ack_o = ((write_cmd_in == 1'b1) || (write_cmd1 == 1'b1) ||
                   (read_cmd == 1'b1) || (read_cmd1 == 1'b1));
   
//******************************************************************************
//  init_done will be asserted when initialization sequence is complete
//******************************************************************************

   always @ (negedge clk) begin
      if (rst180_r == 1'b1) begin
         init_memory <= 1'b0;
         init_done   <= 1'b0;
         init_done_r1   <= 1'b0;
      end
      else begin
         init_memory <= init_mem;
         init_done   <= init_done_value && (init_count == 4'b1011);
         init_done_r1   <= init_done;
      end
   end

   //synthesis translate_off 
   always @ (negedge clk) begin
      if (rst180_r == 1'b0)
        if (init_done == 1'b1 && init_done_r1 == 1'b0)
	  $display ("INITIALIZATION_DONE");
   end 
   //synthesis translate_on

   always @ (negedge clk) begin
      if (initialize_memory) begin
         init_pre_count <= 7'b101_0000;
      end
      else begin
         init_pre_count <= init_pre_count - 7'h1;
      end
   end

   always @( negedge clk ) begin
      if ( rst180_r )
        init_mem <= 1'b0;
      else if ( initialize_memory )
        init_mem <= 1'b1;
      else if ( (init_count == 4'b1011) && (count6 == 6'd1) )
        init_mem <= 1'b0;
      else
        init_mem <= init_mem;
   end

 always @( negedge clk ) begin
      if ( rst180_r )
        init_count  <= 4'b0;
      else if (((init_current_state == INIT_PRECHARGE) || 
		(init_current_state == INIT_LOAD_MODE_REG)
                || (init_current_state == INIT_AUTO_REFRESH))
	       && init_memory == 1'b1)
        init_count    <= init_count + 1'b1;
      else
        init_count    <= init_count;
   end

   assign init_done_value =  (dll_rst_count == 8'b0000_0001) ;


//Counter to count 200 clock cycles When DLL reset is issued during 
//initialization.

   always @( negedge clk ) begin
     if( rst180_r )
       dll_rst_count  <= 8'd0;
     else if(init_count == 4'b0011)
       dll_rst_count  <= 8'd200;
     else if(dll_rst_count != 8'b0000_0001)
       dll_rst_count    <= dll_rst_count - 8'b0000_0001;
     else
       dll_rst_count    <= dll_rst_count;
   end



   assign go_to_active_value =((write_cmd_in == 1'b1) && (write_cmd1 != 1'b1))
          || ((read_cmd == 1'b1) && (read_cmd1 != 1'b1))
          ? 1'b1 : 1'b0;

   always @ (negedge clk) begin
      if (rst180_r == 1'b1) begin
         go_to_active <= 1'b0;
      end
      else begin
         go_to_active <= go_to_active_value;
      end
   end


   always @ (negedge clk) begin
      if (rst180_r == 1'b1) begin
         rp_count       <= 3'b000;
         rfc_count_reg   <= 1'b0;
         ar_done_reg     <= 1'b0;
         rpcnt0 <= 1'b1;
      end
      else begin
         rp_count       <= rp_cnt_value;
         if(rfc_count == 6'b000010 ) 
           ar_done_reg <= 1'b1;
         else
           ar_done_reg <= 1'b0;
         if(ar_done_reg == 1'b1)
           rfc_count_reg <= 1'b1;
         else if(init_done == 1'b1 && init_mem == 1'b0 &&
                 rfc_count == 6'b000000)
           rfc_count_reg <= 1'b1;
         else if (auto_ref_issued  == 1'b1)
           rfc_count_reg <= 1'b0;
         else
           rfc_count_reg <= rfc_count_reg;
           rpcnt0  <= (rp_count[2] == 1'b0 && rp_count[1] == 1'b0
                        && !rp_cnt_value[2]);
      end
   end

  

//******************************************************************************
// Initialization state machine
//******************************************************************************

   always @ (negedge clk) begin
      if (rst180_r == 1'b1) 
         init_current_state    <= INIT_IDLE;
      else 
         init_current_state    <= init_next_state;
   end

   always @ (*) begin
      if (rst180_r == 1'b1)
        init_next_state = INIT_IDLE;
      else begin
         case (init_current_state)
           INIT_IDLE : begin
              if (init_memory == 1'b1) begin
                 case (init_count)
                   4'b0000 : begin
                      if(init_pre_count == 7'b000_0001)
                        init_next_state = INIT_PRECHARGE;
                      else
                        init_next_state = INIT_IDLE;
                   end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -