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

📄 ddr_cntl_a_controller_0.v

📁 arm控制FPGA的DDR测试代码
💻 V
📖 第 1 页 / 共 4 页
字号:

assign PRECHARGE_CMD     = (command_register == 3'b001 && accept_cmd_in == 1'b1);
assign initialize_memory = (command_register == 3'b010);
assign write_cmd_in      = (command_register == 3'b100 && accept_cmd_in == 1'b1);
assign ld_mode           = (command_register == 3'b101 && accept_cmd_in == 1'b1);
assign read_cmd          = (command_register == 3'b110 && accept_cmd_in == 1'b1);


//**************************************************************************
// write_cmd is used to determine when there is a new write request
//**************************************************************************

// register write_cmd until WRITE command needs to be issued

  always @ (negedge clk)       //(posedge clk180)
  begin
     if (rst180_r == 1'b1)
      begin
       write_cmd1  <= 1'b0;
       write_cmd2  <= 1'b0;
       write_cmd3  <= 1'b0;
       write_cmd4  <= 1'b0;
       write_cmd5  <= 1'b0;
       write_cmd6  <= 1'b0;
       write_cmd7  <= 1'b0;
       write_cmd8  <= 1'b0;
       write_cmd   <= 1'b0;
      end
     else
      begin
	  if (accept_cmd_in)
           write_cmd1 <= write_cmd_in;
       write_cmd2 <= write_cmd1;
       write_cmd3 <= write_cmd2;
       write_cmd4 <= write_cmd3;
       write_cmd5 <= write_cmd4; 
       write_cmd6 <= write_cmd5; 
       write_cmd7 <= write_cmd6; 
       write_cmd8  <= write_cmd7;   
       write_cmd  <= write_cmd6;
      end               
  end
  
//************************************************************************
// register read cmd until READ command needs to be issued 
//************************************************************************

  always @ (negedge clk)       //(posedge clk180)
  begin
     if (rst180_r == 1'b1)
      begin
       read_cmd1      <= 1'b0;
       read_cmd2      <= 1'b0;
       read_cmd3      <= 1'b0;
       read_cmd4      <= 1'b0;
       read_cmd5      <= 1'b0;
       read_cmd6      <= 1'b0;
       read_cmd7      <= 1'b0;
       read_cmd8      <= 1'b0;
       read_cmd_reg   <= 1'b0;
       read_rcd_end   <= 1'b0;
      end
     else
      begin
	  if (accept_cmd_in)
       read_cmd1       <= read_cmd;
       read_cmd2       <= read_cmd1;
       read_cmd3       <= read_cmd2;
       read_cmd4       <= read_cmd3;
       read_cmd5       <= read_cmd4; 
       read_cmd6       <= read_cmd5;  
       read_cmd7       <= read_cmd6;
       read_cmd_reg    <= read_cmd7; 
       read_cmd8       <= read_cmd7; 
       read_rcd_end    <= read_cmd8;
      end
  end
  
//********************************************************************************************                
// MRD Counter
// an executable command can be issued only after Tmrd(2 cycles) after a LMR command is issued
//********************************************************************************************
assign MRD_COUNT_value = (ldMdReg_flag) ? 2'b11 :
                            (mrdCnt0 != 1'b1) ? (MRD_COUNT - 1'b1) :
                           2'b00;
                          
//********************************************************************************************                
// RFC Counter
// an executable command can be issued only after Trfc(60 ns => 60/5 = 12 cycles) 
//                                after a AUTOREFRESH command is issued
//********************************************************************************************

assign RFC_COUNT_value = (aref_flag) ?  (RFC_COUNTER_value):
			  (RFC_COUNT != 5'b00000) ?  (RFC_COUNT - 1'b1):
			   5'b00000;

//********************************************************************************************                
// RP Counter
// an executable command can be issued only after Trp(20 ns for a -5 device => 4 cycles) 
//                        after a PRECHARGE command is issued
//********************************************************************************************
assign rp_cnt_value = (precharge_flag) ? 3'b100 :                  
					(rpCnt0 != 1'b1) ? (RP_COUNT - 1'b1) :  3'b000;
                       
//********************************************************************************************                
// RRD Counter
// minimum interval between successive ACTIVE commands to different banks - Trrd
// 2 clock cycles
//********************************************************************************************
assign RRD_COUNT_value = (next_state1 == ACTIVE) ? 2'b10 :
                          (RRD_COUNT != 2'b00) ? (RRD_COUNT - 1'b1) :
                           2'b00;
                           
//*********************************************************************************************
// ACTIVE to READ/WRITE counter
// RCDr counter
// ACTIVE to READ delay - (-5) device requires 20 ns of delay => 4 clock cycles
//
// RCDW counter
// ACTIVE to WRITE delay - (-5) device requires 10 ns of delay => 2 clock cycles
//
//*********************************************************************************************


assign RCDR_COUNT_value =  (next_state1 == ACTIVE) ? 3'b100 :
                           (rcdrCnt0 != 1'b1) ? (RCDR_COUNT - 1'b1) :
                            3'b000;

assign RCDW_COUNT_value = (next_state1 == ACTIVE) ? 2'b11 :                        
                          (rcdwCnt0 != 1'b1) ? (RCDW_COUNT - 1'b1) :
                           2'b00;  
                           
//*********************************************************************************************
// ACTIVE to PRECHARGE counter
// RAS counter
// ACTIVE to PRECHARGE delay -
// the memory device require 40 ns (8 clock cycles)after issuing an ACTIVE command before issuing a
// PRECHARGE command
//
//*********************************************************************************************
assign ras_count_value = (next_state1 == ACTIVE) ? 4'b1000 :
                          (RAS_COUNT != 4'b0000) ? (RAS_COUNT - 1'b1) :
                          4'b0000;

//**********************************************************************************************
// RC counter
// an ACTIVE command to a different row can be issued only after the previous row has been 
// precharged & after Trc is met 
// Trc = 60 ns = 12 clock cycles
//**********************************************************************************************
assign RC_COUNT_value = (next_state1 == ACTIVE) ? 4'b1100 :
                         (rcCnt0 != 1'b1) ? (RC_COUNT - 1'b1) :
                         4'b0000;


//********************************************************************************************                
// WR Counter
// a PRECHARGE command can be applied only after 2 cycles after a WRITE command has finished 
// executing
//********************************************************************************************
assign WR_COUNT_value = (next_state1 == PRECHARGE_AFTER_WRITE) ? 2'b11 :
                         (WR_COUNT != 2'b00) ? (WR_COUNT - 1'b1) :
                         2'b00;

//********************************************************************************************************
// Auto refresh counter - the design uses AUTO REFRESH
// 
// the DDR SDRAM requires AUTO REFRESH cycles at an average interval of 7.8 us
// Hence, a counter value to obtain a 7.8.6 us clock for Auto Refresh
// Refresh Request is raised for every 7.7 us
// Hence for 200MHz frequency,The Refresh_count_value = freq * refresh_time_period = 200*7.7 = 1540 
//**********************************************************************************************************


assign AUTOREF_value   = (AUTOREF_COUNT == max_ref_cnt)  ? 1'b1 : 1'b0;               


assign AUTOREF_CNT_val = ((AUTOREF_value) || !INIT_DONE )? 11'b0 : //sarala, 22nd june
                          AUTOREF_COUNT + 1'b1;



always @ (negedge clk)       //(posedge clk180)   
begin
  if (rst180_r == 1'b1)
  begin
     AUTOREF_COUNT     <= 11'b00000000000;
     RFC_COUNTER_value <= `rfc_count_value;
     max_ref_cnt       <=  `max_ref_cnt;
  end 
  else
     begin
     AUTOREF_COUNT     <= AUTOREF_CNT_val;
     RFC_COUNTER_value <= `rfc_count_value;
     max_ref_cnt       <= `max_ref_cnt;
     end 
end

always @ (negedge clk)       //(posedge clk180)
begin
  if (rst180_r == 1'b1)
    begin
      AUTO_REF_pulse_end <= 1'b0;
      AUTO_REF_detect1   <= 1'b0;
      AUTO_REF_detect    <= 1'b0; 
    end
  else
    begin
      AUTO_REF_detect1   <= AUTOREF_value;
      AUTO_REF_detect    <= AUTO_REF_detect1;
      AUTO_REF_pulse_end <= AUTO_REF_detect;
    end
end
    


assign auto_ref1 = ((AUTO_REF_detect == 1'b1) && (AUTO_REF_pulse_end != 1'b1)) ; // Sarala, June 22

assign AR_done_p = (AR_Done_reg == 1'b1); // Sarala June 22 
   
           
always @ (negedge clk)       //(posedge clk180)
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) 
        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)       //(posedge clk180)
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)
     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_issued_p = (next_state1 == AUTO_REFRESH || aref_flag); 

//**********************************************************************************************
// Burst count value counter when there are cosecutive READs or WRITEs
// While doing consecutive READs or WRITEs, the Burst_count value determines when the next 
// READ or WRITE command should be issued. The burst length is determined while loading the 
// Load Mode Register
// burst_cnt_max shows the number of clock cycles for each burst
// burst_cnt_max = 1 for a burst length of 2, since it is ddr
//**********************************************************************************************
assign burst_cnt_max = (burst_length == 3'b001) ? 3'b001 :
                       (burst_length == 3'b010) ? 3'b010 :
                       (burst_length == 3'b011) ? 3'b100 :
                       (burst_length == 3'b111) ? 3'b100 :
                       3'b000;

//********************************************************************************************
// CAS latency counter
// CAS latencies of 2,3,4 can be set using Mode register bits M(6:4)
//
//      M6  M5  M4   CAS latency
//      0    1   0 -    2
//      0    1   1 -    3
//      1    0   0 -    4
//      others     -   reserved
// This design uses a CAS latency of 3 for a clock rate of 200 MHz
//
//********************************************************************************************
  assign cas_count_value = (next_state1 == BURST_READ) ? burst_cnt_max :  //Modified by Abhishake for BL=8
                         (CAS_COUNT != 3'b000) ? (CAS_COUNT - 1'b1) :
                         CAS_COUNT;



assign rdburst_end_cnt_value = (CAS_COUNT == 3'b001) ? burst_cnt_max :  //Modified by Abhishake for BL=8
                               (RDBURST_END_CNT != 3'b000) ? (RDBURST_END_CNT - 1'b1) :
                               3'b000;


assign wrburst_end_cnt_value = ((next_state1 == FIRST_WRITE) || (next_state1 == BURST_WRITE)) ? burst_cnt_max :
                               (wrburst_end_cnt != 3'b000) ? (wrburst_end_cnt - 1'b1) :
                               3'b000;


assign wrburst_chk = ((next_state1 == BURST_WRITE) || (next_state1 == WRITE_WAIT)) ? 1'b1 : 1'b0;
                      
assign rdburst_chk  = ((next_state1 == BURST_READ) || (next_state1 == READ_WAIT)) ? 1'b1 : 1'b0;

always @ (negedge clk)       //(posedge clk180)
begin
  if (rst180_r == 1'b1)
    begin
      rdburst_end_1 <= 1'b0;
      rdburst_end_2 <= 1'b0;
      rdburst_end_3 <= 1'b0;
      rdburst_end_4 <= 1'b0;
      rdburst_end_5 <= 1'b0; 
    end
  else
    begin
      rdburst_end_2 <= rdburst_end_1;
      rdburst_end_3 <= rdburst_end_2;
      rdburst_end_4 <= rdburst_end_3;
      rdburst_end_5 <= rdburst_end_4;
      rdburst_end_6 <= rdburst_end_5;
      rdburst_end_7 <= rdburst_end_6;
      rdburst_end_8 <= rdburst_end_7;
      if (burst_done == 1'b1) //BL=8
        rdburst_end_1 <= 1'b1;
      else
        rdburst_end_1 <= 1'b0;
    end
end

assign rdburst_end_r = rdburst_end_3 || rdburst_end_4 || rdburst_end_5 || rdburst_end_6 || rdburst_end_7 || rdburst_end_8;
assign rdburst_end = rdburst_end_1 || rdburst_end_2 ;

always @ (negedge clk)       //(posedge clk180)
begin
  if (rst180_r == 1'b1)
    begin
     wrburst_end_1 <= 1'b0;
     wrburst_end_2 <= 1'b0;
     wrburst_end_3 <= 1'b0;
     wrburst_end_4 <= 1'b0;
     wrburst_end_5 <= 1'b0;
     wrburst_end_6 <= 1'b0;
     wrburst_end_7 <= 1'b0;
     wrburst_end_8 <= 1'b0;
     wrburst_end_9 <= 1'b0;
    end
  else
    begin
     wrburst_end_2  <= wrburst_end_1;  
     wrburst_end_3  <= wrburst_end_2;
     wrburst_end_4  <= wrburst_end_3; 
     wrburst_end_5  <= wrburst_end_4; 
     wrburst_end_6  <= wrburst_end_5; 
     wrburst_end_7  <= wrburst_end_6; 
     wrburst_end_8  <= wrburst_end_7; 
     if  (burst_done == 1'b1)   //BL =8
         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;



//**********************************************************************************************
// to generate the Data Strobe enable and reset signal
// The DQS signal needs to be generated center aligned with the data. 
// The controller generates the DQS enable signal when the state machine is in the FIRST_WRITE
// state,to take care of the write preamble
//**********************************************************************************************

assign DQS_enable_out = ((next_state1 == FIRST_WRITE) || (next_state1 == BURST_WRITE)  || (wrburst_end_cnt != 3'b000)) ? 1'b1 : 1'b0;

assign DQS_reset_out  = (next_state1 == FIRST_WRITE) ? 1'b1 : 1'b0;


  assign dqs_enable = DQS_enable2;
  assign dqs_reset  = DQS_reset2_clk0; 

  

always @ (negedge clk)       //(posedge clk180)
begin
  if (rst180_r == 1'b1)
    begin
      DQS_enable_int <= 1'b0;
      DQS_reset_int  <= 1'b0;
    end
  else
    begin
      DQS_enable_int <= DQS_enable_out;
      DQS_reset_int  <= DQS_reset_out;
    end
end

always @ (posedge clk)
begin
 if (rst0_r == 1'b1)

⌨️ 快捷键说明

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