wb_sdram.v

Wed, 18 Aug 2010 14:10:48 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Wed, 18 Aug 2010 14:10:48 +0100
changeset 17
ac979332d5fd
parent 16
49f3a5bd860e
child 18
275105a6a36b
permissions
-rw-r--r--

parameterise data and addr. buses, tidy up

Parameterised the width of the data and address buses, and the number of
COLUMN, ROW and BANK address bits.

Tidied up code to (hopefully!) work when bus widths are changed.

     1 /****************************************************************************
     2  *
     3  *
     4  ****************************************************************************/
     6 module wb_sdram #(
     7 	parameter	DATA_BITS				= 32,				// Width of SDRAM data bus
     8 	parameter	COLADDR_BITS			= 9,				// Number of SDRAM Column Address bits
     9 	parameter	BANKADDR_BITS			= 2,				// Number of SDRAM Bank Address bits
    10 	parameter	ROWADDR_BITS			= 12				// Number of SDRAM Row Address bits
    11 ) (
    12 	// Clocks and resets
    13 	input										wb_clk_i,		// WISHBONE clock
    14 	input										wb_rst_i,		// WISHBONE reset
    16 	// WISHBONE bus
    17 	input			[31:0]					wb_adr_i,		// WISHBONE address
    18 	input			[DATA_BITS-1:0]		wb_dat_i,		// WISHBONE data in
    19 	output reg	[DATA_BITS-1:0]		wb_dat_o,		// WISHBONE data out
    20 	input			[(DATA_BITS/4)-1:0]	wb_sel_i,		// WISHBONE byte select
    21 	input										wb_we_i,			// WISHBONE write enable (R/#W)
    22 	input										wb_cyc_i,		// WISHBONE cycle
    23 	input										wb_stb_i,		// WISHBONE strobe
    24 	output reg								wb_ack_o,		// WISHBONE cycle acknowledge (data available, DTACK)
    25 	output									wb_err_o,		// WISHBONE bus error
    26 	output									wb_rty_o,		// WISHBONE retry-later
    28 	// SDRAM
    29 	output reg								sdram_cke,		// SDRAM clock enable
    30 	output									sdram_cs_n,		// SDRAM chip select (active low)
    31 	output									sdram_ras_n,	// SDRAM row address strobe (active low)
    32 	output									sdram_cas_n,	// SDRAM column address strobe (active low)
    33 	output									sdram_we_n,		// SDRAM write enable (active low)
    34 	output		[ROWADDR_BITS-1:0]	sdram_a,			// SDRAM address
    35 	output reg	[BANKADDR_BITS-1:0]	sdram_ba,		// SDRAM bank address
    36 	output reg	[(DATA_BITS/4)-1:0]	sdram_dqm,		// SDRAM data mask (OE#; 0=active, 1=disabled)
    37 	inout			[DATA_BITS-1:0]		sdram_dq			// SDRAM data bus
    38 );
    41 /****
    42  * Timer values
    43  ****/
    44 // CAS latency -- either 2 or 3   [2010-08-10: tested with CL=3, worked fine]
    45 parameter	CAS_LATENCY		= 3'd2;
    46 // System clock frequency
    47 parameter	CLOCK_RATE		= 25_000_000;
    49 // SDRAM timings in nanoseconds
    50 // Precharge to refresh/row activate command (same bank) -- Trp
    51 parameter	TIME_Trp			= 20;
    52 // RAS# to CAS# delay -- Trcd
    53 parameter	TIME_Trcd		= 20;
    54 // Row cycle time -- Trfc, also known as Trc
    55 parameter	TIME_Trfc		= 70;
    56 // Time between refresh cycles -- refresh interval divided by number of rows to refresh (in this case, 64e-3/4096*1e9 --> 15.625us or 15,625ns)
    57 parameter	TIME_Refresh	= 15_625;
    58 // 2ms power-up init period
    59 parameter	TIME_InitDelay	= 2_000_000;
    60 // 2us before the end of the init period, raise CKE
    61 parameter	TIME_InitFinal	= 2_000;
    63 // Calculate clock period in nanoseconds
    64 localparam	CLOCK_PERIOD = 1_000_000_000 / CLOCK_RATE;
    66 // T_rp  ==> 20ns
    67 localparam	TCY_Trp			= (TIME_Trp+CLOCK_PERIOD-1) / CLOCK_PERIOD - 1;
    68 // T_rcd ==> 20ns
    69 localparam	TCY_Trcd			= (TIME_Trcd+CLOCK_PERIOD-1) / CLOCK_PERIOD - 1;
    70 // T_rfc (a.k.a. T_rc) ==> 70ns
    71 localparam	TCY_Trfc			= (TIME_Trfc+CLOCK_PERIOD-1) / CLOCK_PERIOD - 1;
    72 // T_mrd ==> 2 clock cycles
    73 localparam	TCY_Tmrd			= 32'd2;
    74 // Maximum allowed time between two refresh cycles
    75 localparam	TCY_Refresh		= (TIME_Refresh+CLOCK_PERIOD-1) / CLOCK_PERIOD - 1;
    77 localparam	TCY_InitDelay	= (TIME_InitDelay+CLOCK_PERIOD-1) / CLOCK_PERIOD - 1;
    78 localparam	TCY_InitFinal	= (TIME_InitFinal+CLOCK_PERIOD-1) / CLOCK_PERIOD - 1;
    81 /****
    82  * WISHBONE status pins
    83  ****/
    84 // Can't raise bus errors
    85 assign wb_err_o = 1'b0;
    86 // Can't request retries
    87 assign wb_rty_o = 1'b0;
    90 /****
    91  * SDRAM data output buffer
    92  ****/
    93 // OE=1 for output mode, 0 for input
    94 reg sdram_dq_oe;
    95 // SDRAM output register
    96 reg [DATA_BITS-1:0] sdram_dq_r;
    97 assign sdram_dq = sdram_dq_oe ? sdram_dq_r : {DATA_BITS{1'bZ}};
   100 /****
   101  * State timer
   102  * This is used to ensure that the state machine abides by RAM timing
   103  * restrictions.
   104  ****/
   105 reg [31:0] timer;
   108 /****
   109  * MODE logic
   110  ****/
   111 reg  [5:0]  sdram_mode;
   112 reg  [11:0]	sdram_addr;
   113 assign sdram_cs_n		= sdram_mode[3];
   114 assign sdram_ras_n	= sdram_mode[2];
   115 assign sdram_cas_n	= sdram_mode[1];
   116 assign sdram_we_n		= sdram_mode[0];
   117 assign sdram_a = {sdram_addr[11], (sdram_mode[5] ? sdram_mode[4] : sdram_addr[10]), sdram_addr[9:0]};
   119 // SDRAM chip instructions
   120 // The bit order is as specified in the ISSI datasheet: A10 Override, A10, CS#, RAS#, CAS#, WE#.
   121 // If A10 Override is set, then A10 will be overridden to the value specified in the M_ constant.
   122 localparam M_BankActivate		= 6'b0X0011;
   123 localparam M_PrechargeBank		= 6'b100010;
   124 localparam M_PrechargeAll		= 6'b110010;
   125 localparam M_Write				= 6'b100100;
   126 localparam M_WritePrecharge	= 6'b110100;
   127 localparam M_Read					= 6'b100101;
   128 localparam M_ReadPrecharge		= 6'b110101;
   129 localparam M_LoadModeRegister	= 6'b0X0000;
   130 localparam M_Nop					= 6'b0X0111;
   131 localparam M_BurstStop			= 6'b0X0110;
   132 localparam M_Inhibit				= 6'b0X1XXX;		// maybe X1111?
   133 localparam M_AutoRefresh		= 6'b0X0001;
   136 /****
   137  * Refresh Timer
   138  ****/
   139 reg [31:0] refresh_timer;
   140 reg refresh_req, refresh_ack, refresh_timer_en;
   141 always @(posedge wb_clk_i) begin
   142 	if (wb_rst_i | !refresh_timer_en) begin
   143 		// Reset; clear timer, unset REFRESH REQUEST
   144 		refresh_req <= 1'b0;
   145 		refresh_timer <= TCY_Refresh - 32'd1;
   146 	end else if (refresh_ack) begin
   147 		// Refresh Ack, clear Refresh Request.
   148 		refresh_req <= 1'b0;
   149 	end else if (refresh_timer == 0) begin
   150 		// Refresh timer timed out, make a Refresh Request and reload the timer
   151 		refresh_req <= 1'b1;
   152 		refresh_timer <= TCY_Refresh - 32'd1;
   153 	end else begin
   154 		// Otherwise just decrement the timer
   155 		refresh_timer <= refresh_timer - 32'd1;
   156 	end
   157 end
   160 /****
   161  * Address decoder
   162  ****/
   163 wire [COLADDR_BITS-1:0] column_addr;
   164 wire [ROWADDR_BITS-1:0] row_addr;
   165 wire [BANKADDR_BITS-1:0] bank_addr;
   167 // Convert a 23-bit linear address into an SDRAM address
   168 assign column_addr	= wb_adr_i[COLADDR_BITS-1:0];
   169 assign bank_addr		= wb_adr_i[COLADDR_BITS+BANKADDR_BITS-1:COLADDR_BITS];
   170 assign row_addr		= wb_adr_i[COLADDR_BITS+BANKADDR_BITS+ROWADDR_BITS-1:COLADDR_BITS+BANKADDR_BITS];
   173 /****
   174  * Finite State Machine
   175  ****/
   176 localparam	ST_INIT1							= 32'd0;
   177 localparam	ST_INIT2							= 32'd1;
   178 localparam	ST_NOP1							= 32'd2;
   179 localparam	ST_PrechargeAll				= 32'd3;
   180 localparam	ST_PrechargeAll_Wait			= 32'd4;
   181 localparam	ST_AutoRefresh1				= 32'd5;
   182 localparam	ST_AutoRefresh1_Wait			= 32'd6;
   183 localparam	ST_AutoRefresh2				= 32'd7;
   184 localparam	ST_AutoRefresh2_Wait			= 32'd8;
   185 localparam	ST_LoadModeRegister			= 32'd9;
   186 localparam	ST_LoadModeRegister_Wait	= 32'd10;
   187 localparam	ST_Spin							= 32'd11;		// <<== main 'spin' / 'idle' state
   188 localparam	ST_Refresh						= 32'd12;
   189 localparam	ST_Refresh_Wait				= 32'd13;
   190 localparam	ST_Activate						= 32'd30;
   191 localparam	ST_Activate_Wait				= 32'd31;
   192 localparam	ST_Write							= 32'd32;
   193 localparam	ST_Read							= 32'd33;
   194 localparam	ST_Read_Wait					= 32'd34;
   195 localparam	ST_Wait_Trp						= 32'd35;
   196 localparam	ST_Ack							= 32'd36;
   199 reg [31:0] state;
   200 always @(posedge wb_clk_i) begin
   201 	if (wb_rst_i) begin
   202 		// Initialise state machine and timer
   203 		state <= ST_INIT1;
   204 		timer <= 32'd0;
   206 		// Clear REFRESH ACK flag and disable refresh timer
   207 		refresh_ack <= 1'b0;
   208 		refresh_timer_en <= 1'b0;
   210 		// Initialisation state for SDRAM
   211 		sdram_cke	<= 1'b0;
   212 		sdram_mode	<= M_Inhibit;
   213 		sdram_addr	<= 0;
   214 		sdram_ba		<= 0;
   215 		sdram_dqm	<= 0;
   216 		sdram_dq_oe	<= 0;				// data output disabled
   217 		sdram_dq_r	<= 0;
   218 	end else begin
   219 		// timer logic
   220 		if (timer > 32'd0) begin
   221 			timer <= timer - 32'd1;
   222 		end
   224 		// state machine logic
   225 		case (state)
   226 			ST_INIT1: begin
   227 					// INIT1: Set up for initial power-up wait
   228 					state <= ST_INIT2;
   229 					timer <= TCY_InitDelay;		// Needs to be >= 100us
   231 					// SDRAM state
   232 					sdram_cke	<= 1'b0;			// clock disabled
   233 					sdram_mode	<= M_Inhibit;
   234 					sdram_addr	<= 0;
   235 					sdram_ba		<= 0;
   236 					sdram_dqm	<= {(DATA_BITS/4){1'b1}};
   237 					sdram_dq_oe	<= 0;				// data output disabled
   238 					sdram_dq_r	<= 0;
   239 				end
   241 			ST_INIT2: begin
   242 					// INIT2: Power-up wait. Keep CKE low until ~50 cycles before
   243 					// the end of the power-up wait, then bring CKE high.
   244 					if (timer == 32'd0) begin
   245 						// Timer hit zero. Send a NOP.
   246 						state <= ST_NOP1;
   247 					end else if (timer < TCY_InitFinal) begin
   248 						// Timer value is more than zero but less than 50; CKE is on, but
   249 						// keep waiting for the timer to actually expire.
   250 						sdram_cke	<= 1'b1;
   251 						state			<= ST_INIT2;
   252 					end
   253 					sdram_mode <= M_Inhibit;
   254 				end
   256 			ST_NOP1: begin
   257 					// Apply one or more NOP commands to the SDRAM
   258 					sdram_mode <= M_Nop;
   259 					state <= ST_PrechargeAll;
   260 				end
   262 			ST_PrechargeAll: begin
   263 					// Precharge All, then wait T_rp (20ns)
   264 					sdram_mode <= M_PrechargeAll;
   265 					timer <= TCY_Trp - 32'd1;
   266 					state <= ST_PrechargeAll_Wait;
   267 				end
   269 			ST_PrechargeAll_Wait: begin
   270 					// Wait for T_rp after Precharge All
   271 					sdram_mode <= M_Nop;
   272 					if (timer == 32'd0) begin
   273 						// Timer hit zero. Continue
   274 						state <= ST_AutoRefresh1;
   275 					end
   276 				end
   278 			ST_AutoRefresh1: begin
   279 					// Auto Refresh 1 of 2, wait T_rfc (70ns) after each
   280 					sdram_mode <= M_AutoRefresh;
   281 					timer <= TCY_Trfc - 32'd1;
   282 					state <= ST_AutoRefresh1_Wait;
   283 				end
   285 			ST_AutoRefresh1_Wait: begin
   286 					// Wait for T_rfc
   287 					sdram_mode <= M_Nop;
   288 					if (timer == 32'd0) begin
   289 						// Timer hit zero. Continue
   290 						state <= ST_AutoRefresh2;
   291 					end
   292 				end
   294 			ST_AutoRefresh2: begin
   295 					// Auto Refresh 2 of 2, wait T_rfc (70ns) after each
   296 					sdram_mode <= M_AutoRefresh;
   297 					timer <= TCY_Trfc - 32'd1;
   298 					state <= ST_AutoRefresh2_Wait;
   299 				end
   301 			ST_AutoRefresh2_Wait: begin
   302 					// Wait for T_rfc
   303 					sdram_mode <= M_Nop;
   304 					if (timer == 32'd0) begin
   305 						// Timer hit zero. Continue
   306 						state <= ST_LoadModeRegister;
   307 					end
   308 				end
   310 			ST_LoadModeRegister: begin
   311 					// Load Mode Register
   312 					/**
   313 					 * Mode register:
   314 					 *   - BS0,1  = 00  [RFU]
   315 					 *   - A11,10 = 00  [RFU]
   316 					 *   - A9     = 0   [WBL -- write burst length same as read burst length]
   317 					 *   - A8,7   = 00  [Test Mode off]
   318 					 *   - A6..4  = 010 [CAS Latency = 2 or 3 clocks, set above]
   319 					 *   - A3     = 0   [Burst type = sequential]
   320 					 *   - A2..0  = 000 [Burst length = 1 word]
   321 					 */
   322 					sdram_ba <= 0;
   323 					sdram_addr <= {5'b00_0_00, CAS_LATENCY[2:0], 3'b000};
   324 					sdram_mode <= M_LoadModeRegister;
   326 					// Wait T_mrd (2 clock cycles)
   327 					timer <= TCY_Tmrd - 32'd1;
   328 					state <= ST_LoadModeRegister_Wait;
   329 				end
   331 			ST_LoadModeRegister_Wait: begin
   332 					// Wait for LMR to complete
   333 					sdram_mode <= M_Nop;
   334 					sdram_ba <= 0;
   335 					sdram_addr <= 0;
   336 					if (timer == 32'd0) begin
   337 						// Timer hit zero. Continue
   338 						state <= ST_Spin;
   339 					end
   340 				end
   342 			ST_Spin: begin
   343 					// Enable refresh timer
   344 					refresh_timer_en <= 1'b1;
   346 					// Idle the SDRAM (Inhibit is lower power than NOP on some SDRAMs)
   347 					sdram_mode <= M_Inhibit;
   349 					// Check if a refresh is due (these have highest priority)
   350 					if (refresh_req) begin
   351 						// Refresh request received. Ack it and do a refresh.
   352 						refresh_ack <= 1'b1;
   353 						state <= ST_Refresh;
   354 					end else begin
   355 						if (wb_cyc_i & wb_stb_i) begin
   356 							// CYC and STB high. A Wishbone cycle just started.
   357 							state <= ST_Activate;
   358 						end
   359 					end
   360 				end
   362 /////
   363 // Refresh logic
   364 /////
   366 			ST_Refresh: begin
   367 					// Refresh timer timed out; do a refresh run
   368 					// Start by clearing the ACK flag (which was set by the Spin state)
   369 					refresh_ack <= 1'b0;
   370 					// Tell the SDRAM to do a Refresh
   371 					sdram_mode <= M_AutoRefresh;
   372 					// Wait for T_rfc
   373 					timer <= TCY_Trfc;
   374 					state <= ST_Refresh_Wait;
   375 				end
   377 			ST_Refresh_Wait: begin
   378 					// Wait for T_rfc
   379 					sdram_mode <= M_Nop;
   380 					if (timer == 32'd0) begin
   381 						// Timer hit zero. Go back to spin state.
   382 						state <= ST_Spin;
   383 					end
   384 				end
   386 //////
   387 // R/W logic
   388 //////
   389 			ST_Activate: begin
   390 					// Activate the required bank
   391 					sdram_mode <= M_BankActivate;
   392 					sdram_addr <= row_addr;
   393 					sdram_ba   <= bank_addr;
   394 					timer <= TCY_Trcd - 32'd1;
   395 					state <= ST_Activate_Wait;
   396 				end
   398 			ST_Activate_Wait: begin
   399 					// Wait for T_rcd
   400 					sdram_mode <= M_Nop;
   401 					if (timer == 32'd0) begin
   402 						if (wb_we_i) begin
   403 							// Write cycle.
   404 							state <= ST_Write;
   405 						end else begin
   406 							// Read cycle
   407 							state <= ST_Read;
   408 						end
   409 					end
   410 				end
   412 			ST_Write: begin
   413 					// Write cycle handler
   414 					sdram_mode	<= M_WritePrecharge;
   415 					sdram_addr	<= column_addr;
   416 					sdram_dq_r	<= 0;
   417 					sdram_dq_oe	<= 1;			// FPGA drives the DQ bus
   418 					sdram_dqm	<= ~wb_sel_i;
   420 					// Wait T_rp (20ns)
   421 					timer <= TCY_Trp - 32'd1;
   422 					state <= ST_Wait_Trp;
   423 				end
   425 			ST_Read: begin
   426 					// Read cycle handler
   427 					sdram_mode	<= M_ReadPrecharge;
   428 					sdram_addr	<= column_addr;
   429 					sdram_dq_oe	<= 0;			// SDRAM drives the DQ bus
   430 					sdram_dqm	<= 0;			// Grab all the data (easier than playing with WB_SEL...)
   431 					timer <= CAS_LATENCY - 32'd1;	// CAS# Latency
   432 					state <= ST_Read_Wait;
   433 				end
   435 			ST_Read_Wait: begin
   436 					// Wait for CAS# latency
   437 					sdram_mode	<= M_Nop;
   438 					sdram_dqm	<= {(DATA_BITS/4){1'b1}};	// Make SDRAM DQ bus float
   439 					if (timer == 32'd0) begin
   440 						// Latch data
   441 						wb_dat_o <= sdram_dq;
   442 						// Wait T_rp (20ns)
   443 						timer <= TCY_Trp - 32'd1;
   444 						state <=	ST_Wait_Trp;
   445 					end
   446 				end
   448 			ST_Wait_Trp: begin
   449 					// Wait for T_rp, then ack
   450 					if (timer == 32'd0) begin
   451 						state <= ST_Ack;
   452 					end
   453 				end
   455 			ST_Ack: begin
   456 					// Ack the transfer to the WISHBONE host
   457 					sdram_mode	<= M_Nop;
   458 					sdram_addr	<= 0;
   459 					sdram_dq_r	<= 0;
   460 					sdram_dq_oe	<= 0;			// SDRAM drives the DQ bus
   461 					sdram_dqm	<= {(DATA_BITS/4){1'b1}};	// mask off DQM
   462 					if (wb_cyc_i & wb_stb_i) begin
   463 						// CYC and STB high, ack the transfer
   464 						wb_ack_o		<= 1'b1;
   465 						state			<= ST_Ack;
   466 					end else begin
   467 						// CYC and STB low, go back and wait for another transaction
   468 						wb_ack_o		<= 1'b0;
   469 						state			<= ST_Spin;
   470 					end
   471 				end
   472 		endcase
   473 	end
   474 end
   476 endmodule