fully parameterise CLOCK_RATE and SDRAM timing

Wed, 11 Aug 2010 01:15:20 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Wed, 11 Aug 2010 01:15:20 +0100
changeset 15
da71a5efdf98
parent 14
b541478bbb73
child 16
49f3a5bd860e

fully parameterise CLOCK_RATE and SDRAM timing

wb_sdram.v file | annotate | diff | revisions
     1.1 --- a/wb_sdram.v	Tue Aug 10 23:11:10 2010 +0100
     1.2 +++ b/wb_sdram.v	Wed Aug 11 01:15:20 2010 +0100
     1.3 @@ -41,16 +41,33 @@
     1.4   ****/
     1.5  // CAS latency -- either 2 or 3   [2010-08-10: tested with CL=3, worked fine]
     1.6  parameter	CAS_LATENCY		= 3'd2;
     1.7 +// System clock frequency
     1.8 +parameter	CLOCK_RATE		= 25_000_000;
     1.9 +
    1.10 +// SDRAM timings in nanoseconds
    1.11 +parameter	TIME_Trp			= 20;
    1.12 +parameter	TIME_Trcd		= 20;
    1.13 +parameter	TIME_Trfc		= 70;
    1.14 +parameter	TIME_Refresh	= 15_625;
    1.15 +parameter	TIME_InitDelay	= 2_000_000;	// 2ms init period
    1.16 +parameter	TIME_InitFinal	= 2_000;			// 2us before the end of the init period, raise CKE
    1.17 +
    1.18 +// Calculate clock period in nanoseconds
    1.19 +localparam	CLOCK_PERIOD = 1_000_000_000 / CLOCK_RATE;
    1.20 +
    1.21  // T_rp  ==> 20ns
    1.22 -parameter	TIME_Trp			= 32'd1;
    1.23 +localparam	TCY_Trp			= (TIME_Trp+CLOCK_PERIOD-1) / CLOCK_PERIOD - 1;
    1.24  // T_rcd ==> 20ns
    1.25 -parameter	TIME_Trcd		= 32'd1;
    1.26 +localparam	TCY_Trcd			= (TIME_Trcd+CLOCK_PERIOD-1) / CLOCK_PERIOD - 1;
    1.27  // T_rfc (a.k.a. T_rc) ==> 70ns
    1.28 -parameter	TIME_Trfc		= 32'd2;
    1.29 +localparam	TCY_Trfc			= (TIME_Trfc+CLOCK_PERIOD-1) / CLOCK_PERIOD - 1;
    1.30  // T_mrd ==> 2 clock cycles
    1.31 -parameter	TIME_Tmrd		= 32'd2;
    1.32 +localparam	TCY_Tmrd			= 32'd2;
    1.33  // Maximum allowed time between two refresh cycles
    1.34 -parameter	TIME_REFRESH	= 32'd390;
    1.35 +localparam	TCY_Refresh		= (TIME_Refresh+CLOCK_PERIOD-1) / CLOCK_PERIOD - 1;
    1.36 +
    1.37 +localparam	TCY_InitDelay	= (TIME_InitDelay+CLOCK_PERIOD-1) / CLOCK_PERIOD - 1;
    1.38 +localparam	TCY_InitFinal	= (TIME_InitFinal+CLOCK_PERIOD-1) / CLOCK_PERIOD - 1;
    1.39  
    1.40  
    1.41  /****
    1.42 @@ -119,14 +136,14 @@
    1.43  	if (wb_rst_i | !refresh_timer_en) begin
    1.44  		// Reset; clear timer, unset REFRESH REQUEST
    1.45  		refresh_req <= 1'b0;
    1.46 -		refresh_timer <= TIME_REFRESH - 32'd1;
    1.47 +		refresh_timer <= TCY_Refresh - 32'd1;
    1.48  	end else if (refresh_ack) begin
    1.49  		// Refresh Ack, clear Refresh Request.
    1.50  		refresh_req <= 1'b0;
    1.51  	end else if (refresh_timer == 0) begin
    1.52  		// Refresh timer timed out, make a Refresh Request and reload the timer
    1.53  		refresh_req <= 1'b1;
    1.54 -		refresh_timer <= TIME_REFRESH - 32'd1;
    1.55 +		refresh_timer <= TCY_Refresh - 32'd1;
    1.56  	end else begin
    1.57  		// Otherwise just decrement the timer
    1.58  		refresh_timer <= refresh_timer - 32'd1;
    1.59 @@ -203,7 +220,7 @@
    1.60  			ST_INIT1: begin
    1.61  					// INIT1: Set up for initial power-up wait
    1.62  					state <= ST_INIT2;
    1.63 -					timer <= 32'd50_000;		// TODO: dependent on core clock rate. Needs to be >= 100us
    1.64 +					timer <= TCY_InitDelay;		// Needs to be >= 100us
    1.65  					
    1.66  					// SDRAM state
    1.67  					sdram_cke	<= 1'b0;			// clock disabled
    1.68 @@ -221,7 +238,7 @@
    1.69  					if (timer == 32'd0) begin
    1.70  						// Timer hit zero. Send a NOP.
    1.71  						state <= ST_NOP1;
    1.72 -					end else if (timer < 32'd50) begin
    1.73 +					end else if (timer < TCY_InitFinal) begin
    1.74  						// Timer value is more than zero but less than 50; CKE is on, but
    1.75  						// keep waiting for the timer to actually expire.
    1.76  						sdram_cke	<= 1'b1;
    1.77 @@ -239,7 +256,7 @@
    1.78  			ST_PrechargeAll: begin
    1.79  					// Precharge All, then wait T_rp (20ns)
    1.80  					sdram_mode <= M_PrechargeAll;
    1.81 -					timer <= TIME_Trp - 32'd1;
    1.82 +					timer <= TCY_Trp - 32'd1;
    1.83  					state <= ST_PrechargeAll_Wait;
    1.84  				end
    1.85  
    1.86 @@ -255,7 +272,7 @@
    1.87  			ST_AutoRefresh1: begin
    1.88  					// Auto Refresh 1 of 2, wait T_rfc (70ns) after each
    1.89  					sdram_mode <= M_AutoRefresh;
    1.90 -					timer <= TIME_Trfc - 32'd1;
    1.91 +					timer <= TCY_Trfc - 32'd1;
    1.92  					state <= ST_AutoRefresh1_Wait;
    1.93  				end
    1.94  				
    1.95 @@ -271,7 +288,7 @@
    1.96  			ST_AutoRefresh2: begin
    1.97  					// Auto Refresh 2 of 2, wait T_rfc (70ns) after each
    1.98  					sdram_mode <= M_AutoRefresh;
    1.99 -					timer <= TIME_Trfc - 32'd1;
   1.100 +					timer <= TCY_Trfc - 32'd1;
   1.101  					state <= ST_AutoRefresh2_Wait;
   1.102  				end
   1.103  				
   1.104 @@ -301,7 +318,7 @@
   1.105  					sdram_mode <= M_LoadModeRegister;
   1.106  
   1.107  					// Wait T_mrd (2 clock cycles)
   1.108 -					timer <= TIME_Tmrd - 32'd1;
   1.109 +					timer <= TCY_Tmrd - 32'd1;
   1.110  					state <= ST_LoadModeRegister_Wait;
   1.111  				end
   1.112  
   1.113 @@ -347,7 +364,7 @@
   1.114  					// Tell the SDRAM to do a Refresh
   1.115  					sdram_mode <= M_AutoRefresh;
   1.116  					// Wait for T_rfc
   1.117 -					timer <= TIME_Trfc;
   1.118 +					timer <= TCY_Trfc;
   1.119  					state <= ST_Refresh_Wait;
   1.120  				end
   1.121  				
   1.122 @@ -368,7 +385,7 @@
   1.123  					sdram_mode <= M_BankActivate;
   1.124  					sdram_addr <= row_addr;
   1.125  					sdram_ba   <= bank_addr;
   1.126 -					timer <= TIME_Trcd - 32'd1;
   1.127 +					timer <= TCY_Trcd - 32'd1;
   1.128  					state <= ST_Activate_Wait;
   1.129  				end
   1.130  				
   1.131 @@ -395,7 +412,7 @@
   1.132  					sdram_dqm	<= ~wb_sel_i;
   1.133  					
   1.134  					// Wait T_rp (20ns)
   1.135 -					timer <= TIME_Trp - 32'd1;
   1.136 +					timer <= TCY_Trp - 32'd1;
   1.137  					state <= ST_Wait_Trp;
   1.138  				end
   1.139  
   1.140 @@ -417,7 +434,7 @@
   1.141  						// Latch data
   1.142  						wb_dat_o <= sdram_dq;
   1.143  						// Wait T_rp (20ns)
   1.144 -						timer <= TIME_Trp - 32'd1;
   1.145 +						timer <= TCY_Trp - 32'd1;
   1.146  						state <=	ST_Wait_Trp;
   1.147  					end
   1.148  				end