wb_sdram.v

Wed, 18 Aug 2010 14:14:38 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Wed, 18 Aug 2010 14:14:38 +0100
changeset 18
275105a6a36b
parent 17
ac979332d5fd
child 19
d39b0f302ca3
permissions
-rw-r--r--

move all user parameters into top of module

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