wb_sdram.v

Tue, 10 Aug 2010 17:36:00 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Tue, 10 Aug 2010 17:36:00 +0100
changeset 4
96badb38531d
parent 3
6a724779fb48
child 5
dd6f40c05963
permissions
-rw-r--r--

add basic R/W test

     1 /****************************************************************************
     2  *
     3  *
     4  ****************************************************************************/
     6 module wb_sdram (
     7 	// Clocks and resets
     8 	input						wb_clk_i,			// WISHBONE clock
     9 	input						wb_rst_i,			// WISHBONE reset
    11 	// WISHBONE bus
    12 	input			[31:0]	wb_adr_i,			// WISHBONE address
    13 	input			[31:0]	wb_dat_i,			// WISHBONE data in
    14 	output reg	[31:0]	wb_dat_o,			// WISHBONE data out
    15 	input			[3:0]		wb_sel_i,			// WISHBONE byte select
    16 	input						wb_we_i,				// WISHBONE write enable (R/#W)
    17 	input						wb_cyc_i,			// WISHBONE cycle
    18 	input						wb_stb_i,			// WISHBONE strobe
    19 	output					wb_ack_o,			// WISHBONE cycle acknowledge (data available, DTACK)
    20 	output					wb_err_o,			// WISHBONE bus error
    21 	output					wb_rty_o,			// WISHBONE retry-later
    23 	// SDRAM
    24 	output reg				sdram_cke,			// SDRAM clock enable
    25 	output					sdram_cs_n,			// SDRAM chip select (active low)
    26 	output					sdram_ras_n,		// SDRAM row address strobe (active low)
    27 	output					sdram_cas_n,		// SDRAM column address strobe (active low)
    28 	output					sdram_we_n,			// SDRAM write enable (active low)
    29 	output		[11:0]	sdram_a,				// SDRAM address
    30 	output reg	[1:0]		sdram_ba,			// SDRAM bank address
    31 	output reg	[3:0]		sdram_dqm,			// SDRAM data mask (OE#; 0=active, 1=disabled)
    32 	inout			[31:0]	sdram_dq,			// SDRAM data bus
    34 	// Debugging
    35 	output /*reg*/	[2:0]		debug					// debug bits
    36 );
    39 /****
    40  * SDRAM data output buffer
    41  ****/
    42 // OE=1 for output mode, 0 for input
    43 reg sdram_dq_oe;
    44 // SDRAM output register
    45 reg [31:0] sdram_dq_r;
    46 assign sdram_dq = sdram_dq_oe ? sdram_dq_r : 32'hZZZZ;
    50 /****
    51  * State timer
    52  * This is used to ensure that the state machine abides by RAM timing
    53  * restrictions.
    54  ****/
    55 reg [31:0] timer;
    58 /****
    59  * MODE logic
    60  ****/
    61 reg  [5:0]  sdram_mode;
    62 reg  [11:0]	sdram_addr;
    63 assign sdram_cs_n		= sdram_mode[3];
    64 assign sdram_ras_n	= sdram_mode[2];
    65 assign sdram_cas_n	= sdram_mode[1];
    66 assign sdram_we_n		= sdram_mode[0];
    67 assign sdram_a = {sdram_addr[11], (sdram_mode[5] ? sdram_mode[4] : sdram_addr[10]), sdram_addr[9:0]};
    69 // SDRAM chip instructions
    70 // The bit order is as specified in the ISSI datasheet: A10 Override, A10, CS#, RAS#, CAS#, WE#.
    71 // If A10 Override is set, then A10 will be overridden to the value specified in the M_ constant.
    72 localparam M_BankActivate		= 6'b0X0011;
    73 localparam M_PrechargeBank		= 6'b100010;
    74 localparam M_PrechargeAll		= 6'b110010;
    75 localparam M_Write				= 6'b100100;
    76 localparam M_WritePrecharge	= 6'b110100;
    77 localparam M_Read					= 6'b100101;
    78 localparam M_ReadPrecharge		= 6'b110101;
    79 localparam M_LoadModeRegister	= 6'b0X0000;
    80 localparam M_Nop					= 6'b0X0111;
    81 localparam M_BurstStop			= 6'b0X0110;
    82 localparam M_Inhibit				= 6'b0X1XXX;		// maybe X1111?
    83 localparam M_AutoRefresh		= 6'b0X0001;
    86 /****
    87  * Refresh Timer
    88  ****/
    89 parameter REFRESH_INTERVAL = 32'd390 - 32'd1;
    90 reg [31:0] refresh_timer;
    91 reg refresh_req, refresh_ack, refresh_timer_en;
    92 always @(posedge wb_clk_i) begin
    93 	if (wb_rst_i | !refresh_timer_en) begin
    94 		// Reset; clear timer, unset REFRESH REQUEST
    95 		refresh_req <= 1'b0;
    96 		refresh_timer <= REFRESH_INTERVAL;
    97 	end else if (refresh_ack) begin
    98 		// Refresh Ack, clear Refresh Request.
    99 		refresh_req <= 1'b0;
   100 	end else if (refresh_timer == 0) begin
   101 		// Refresh timer timed out, make a Refresh Request and reload the timer
   102 		refresh_req <= 1'b1;
   103 		refresh_timer <= REFRESH_INTERVAL;
   104 	end else begin
   105 		// Otherwise just decrement the timer
   106 		refresh_timer <= refresh_timer - 32'd1;
   107 	end
   108 end
   110 assign debug = { 1'b0, refresh_req, refresh_ack };
   113 /****
   114  * Address decoder
   115  ****/
   116 wire [8:0] column_addr;
   117 wire [11:0] row_addr;
   118 wire [1:0] bank_addr;
   120 // Convert a 22-bit linear address into an SDRAM address
   121 assign column_addr	= wb_adr_i[8:0];
   122 assign bank_addr		= wb_adr_i[10:9];
   123 assign row_addr		= wb_adr_i[21:11];
   126 /****
   127  * Finite State Machine
   128  ****/
   129 localparam	ST_INIT1							= 32'd0;
   130 localparam	ST_INIT2							= 32'd1;
   131 localparam	ST_NOP1							= 32'd2;
   132 localparam	ST_PrechargeAll				= 32'd3;
   133 localparam	ST_PrechargeAll_Wait			= 32'd4;
   134 localparam	ST_AutoRefresh1				= 32'd5;
   135 localparam	ST_AutoRefresh1_Wait			= 32'd6;
   136 localparam	ST_AutoRefresh2				= 32'd7;
   137 localparam	ST_AutoRefresh2_Wait			= 32'd8;
   138 localparam	ST_LoadModeRegister			= 32'd9;
   139 localparam	ST_LoadModeRegister_Wait	= 32'd10;
   140 localparam	ST_Spin							= 32'd11;		// <<== main 'spin' / 'idle' state
   141 localparam	ST_Refresh						= 32'd12;
   142 localparam	ST_Refresh_Wait				= 32'd13;
   143 localparam	ST_Test_Activate				= 32'd500;
   144 localparam	ST_Test_Activate_Wait		= 32'd501;
   145 localparam	ST_Test_Read					= 32'd502;
   146 localparam	ST_Test_Read_Wait				= 32'd503;
   147 localparam	ST_Test_Write					= 32'd504;
   148 localparam	ST_Test_Precharge_All		= 32'd505;
   149 localparam	ST_Test_Precharge_All_Wait	= 32'd506;
   151 reg [31:0] state;
   152 always @(posedge wb_clk_i) begin
   153 	if (wb_rst_i) begin
   154 		// Initialise state machine and timer
   155 		state <= ST_INIT1;
   156 //		debug <= 3'd0;
   157 		timer <= 32'd0;
   159 		// Clear REFRESH ACK flag and disable refresh timer
   160 		refresh_ack <= 1'b0;
   161 		refresh_timer_en <= 1'b0;
   163 		// Initialisation state for SDRAM
   164 		sdram_cke	<= 1'b0;
   165 		sdram_mode	<= M_Inhibit;
   166 		sdram_addr	<= 12'h000;
   167 		sdram_ba		<= 2'b00;
   168 		sdram_dqm	<= 4'b0000;
   169 		sdram_dq_oe	<= 1'b0;			// data output disabled
   170 		sdram_dq_r	<= 32'd0;
   171 	end else begin
   172 		// timer logic
   173 		if (timer > 32'd0) begin
   174 			timer <= timer - 32'd1;
   175 		end
   177 		// state machine logic
   178 		case (state)
   179 			ST_INIT1: begin
   180 					// INIT1: Set up for initial power-up wait
   181 					state <= ST_INIT2;
   182 					timer <= 32'd50_000;		// TODO: dependent on core clock rate. Needs to be >= 100us
   184 					// SDRAM state
   185 					sdram_cke	<= 1'b0;			// clock disabled
   186 					sdram_mode	<= M_Inhibit;
   187 					sdram_addr	<= 12'h000;
   188 					sdram_ba		<= 2'b00;
   189 					sdram_dqm	<= 4'b1111;
   190 					sdram_dq_oe	<= 1'b0;			// data output disabled
   191 					sdram_dq_r	<= 32'd0;
   192 				end
   194 			ST_INIT2: begin
   195 					// INIT2: Power-up wait. Keep CKE low until ~50 cycles before
   196 					// the end of the power-up wait, then bring CKE high.
   197 					if (timer == 32'd0) begin
   198 						// Timer hit zero. Send a NOP.
   199 						state <= ST_NOP1;
   200 					end else if (timer < 32'd50) begin
   201 						// Timer value is more than zero but less than 50; CKE is on, but
   202 						// keep waiting for the timer to actually expire.
   203 						sdram_cke	<= 1'b1;
   204 						state			<= ST_INIT2;
   205 //						debug <= 3'd1;
   206 					end
   207 					sdram_mode <= M_Inhibit;
   208 				end
   210 			ST_NOP1: begin
   211 					// Apply one or more NOP commands to the SDRAM
   212 					sdram_mode <= M_Nop;
   213 					state <= ST_PrechargeAll;
   214 				end
   216 			ST_PrechargeAll: begin
   217 					// Precharge All, then wait T_rp (20ns)
   218 					sdram_mode <= M_PrechargeAll;
   219 					timer <= 32'd0;	// wait 1tcy (40ns)   ---> TIMER HERE
   220 					state <= ST_PrechargeAll_Wait;
   221 				end
   223 			ST_PrechargeAll_Wait: begin
   224 					// Wait for T_rp after Precharge All
   225 					sdram_mode <= M_Nop;
   226 					if (timer == 32'd0) begin
   227 						// Timer hit zero. Continue
   228 						state <= ST_AutoRefresh1;
   229 					end
   230 				end
   232 			ST_AutoRefresh1: begin
   233 					// Auto Refresh 1 of 2, wait T_rfc (70ns) after each
   234 					sdram_mode <= M_AutoRefresh;
   235 					timer <= 32'd1;	// wait 2tcy (80ns)  ---> TIMER HERE
   236 					state <= ST_AutoRefresh1_Wait;
   237 				end
   239 			ST_AutoRefresh1_Wait: begin
   240 					// Wait for T_rfc
   241 					sdram_mode <= M_Nop;
   242 					if (timer == 32'd0) begin
   243 						// Timer hit zero. Continue
   244 						state <= ST_AutoRefresh2;
   245 					end
   246 				end
   248 			ST_AutoRefresh2: begin
   249 					// Auto Refresh 2 of 2, wait T_rfc (70ns) after each
   250 					sdram_mode <= M_AutoRefresh;
   251 					timer <= 32'd1;	// wait 2tcy (80ns)  ---> TIMER HERE
   252 					state <= ST_AutoRefresh2_Wait;
   253 				end
   255 			ST_AutoRefresh2_Wait: begin
   256 					// Wait for T_rfc
   257 					sdram_mode <= M_Nop;
   258 					if (timer == 32'd0) begin
   259 						// Timer hit zero. Continue
   260 						state <= ST_LoadModeRegister;
   261 					end
   262 				end
   264 			ST_LoadModeRegister: begin
   265 					// Load Mode Register
   266 					/**
   267 					 * Mode register:
   268 					 *   - BS0,1  = 00  [RFU]
   269 					 *   - A11,10 = 00  [RFU]
   270 					 *   - A9     = 0   [WBL -- write burst length same as read burst length]
   271 					 *   - A8,7   = 00  [Test Mode off]
   272 					 *   - A6..4  = 010 [CAS Latency = 2 clocks]
   273 					 *   - A3     = 0   [Burst type = sequential]
   274 					 *   - A2..0  = 000 [Burst length = 1 word]
   275 					 */
   276 					sdram_ba <= 2'b00;
   277 					sdram_addr <= 12'b00_0_00_010_000;
   278 					sdram_mode <= M_LoadModeRegister;
   280 					// Wait T_mrd (2 clock cycles)
   281 					timer <= 32'd1;	// (2cy)-1  ---> TIMER HERE
   282 					state <= ST_LoadModeRegister_Wait;
   283 				end
   285 			ST_LoadModeRegister_Wait: begin
   286 					// Wait for LMR to complete
   287 					sdram_mode <= M_Nop;
   288 					sdram_ba <= 2'd0;
   289 					sdram_addr <= 12'd0;
   290 					if (timer == 32'd0) begin
   291 						// Timer hit zero. Continue
   292 						state <= ST_Spin;
   293 					end
   294 				end
   296 			ST_Spin: begin
   297 					// Enable refresh timer
   298 					refresh_timer_en <= 1'b1;
   300 					sdram_mode <= M_Inhibit;
   302 					if (refresh_req) begin
   303 						// Refresh request received. Ack it and do a refresh.
   304 						refresh_ack <= 1'b1;
   305 						state <= ST_Refresh;
   306 					end else begin
   307 						//state <= ST_Spin;		// NOTE: turned off to run a ram test...
   308 						state <= ST_Test_Activate;
   309 					end
   310 				end
   312 			ST_Refresh: begin
   313 					// Refresh timer timed out; do a refresh run
   314 					// Start by clearing the ACK flag (which was set by the Spin state)
   315 					refresh_ack <= 1'b0;
   316 					// Tell the SDRAM to do a Refresh
   317 					sdram_mode <= M_AutoRefresh;
   318 					// Wait for T_rfc
   319 					timer <= 32'd1;	// wait Trfc (70ns ideally, we give 80ns)  ---> TIMER HERE
   320 					state <= ST_Refresh_Wait;
   321 				end
   323 			ST_Refresh_Wait: begin
   324 					// Wait for T_rfc
   325 					sdram_mode <= M_Nop;
   326 					if (timer == 32'd0) begin
   327 						// Timer hit zero. Go back to spin state.
   328 						state <= ST_Spin;
   329 					end
   330 				end
   332 			ST_Test_Activate: begin
   333 					// Activate bank
   334 					sdram_mode <= M_BankActivate;
   335 					sdram_addr <= row_addr;
   336 					sdram_ba <= bank_addr;
   337 					timer <= 32'd0;	// wait Trcd (20ns ideally, this is 40ns)		---> TIMER HERE
   338 					state <= ST_Test_Activate_Wait;
   339 				end
   341 			ST_Test_Activate_Wait: begin
   342 					// Wait for Activate Bank to complete
   343 					sdram_mode <= M_Nop;
   344 					if (timer == 32'd0) begin
   345 						state <= ST_Test_Read;
   346 					end
   347 				end
   349 			ST_Test_Read: begin
   350 					// Do the Read operation
   351 					sdram_mode <= M_Read;
   352 					sdram_addr <= column_addr;
   353 					sdram_dqm <= 4'b0000;		// Allow data through (DQM = OE# = 1 to mask off, 0 to allow)
   354 					timer <= 32'd3 - 32'd1;		// wait CAS# Latency (2 clock cycles)	---> TIMER HERE
   355 					state <= ST_Test_Read_Wait;
   356 				end
   358 			ST_Test_Read_Wait: begin
   359 					// Wait for CAS latency
   360 					sdram_mode <= M_Nop;
   361 					sdram_dqm <= 4'b1111;		// Disable SDRAM output buffers
   362 					if (timer == 32'd0) begin
   363 						state <= ST_Test_Write;
   364 						// TODO: capture data locally
   365 					end
   366 				end
   368 			ST_Test_Write: begin
   369 					// Write to SDRAM
   370 					sdram_mode <= M_Write;
   371 					sdram_addr <= column_addr;
   372 					sdram_dq_r <= 32'h55AA_BCDE;
   373 					sdram_dq_oe <= 1'b1;		// output enable
   374 					sdram_dqm <= 4'b0000;		// Allow data through (DQM = OE# = 1 to mask off, 0 to allow)
   375 					state <= ST_Test_Precharge_All;
   376 				end
   378 			ST_Test_Precharge_All: begin
   379 					// Precharge All
   380 					sdram_mode <= M_PrechargeAll;
   381 					sdram_addr <= 12'd0;
   382 					sdram_dq_oe <= 1'b0;		// output disable
   383 					sdram_dqm <= 4'b1111;		// Disable SDRAM output buffers
   384 					sdram_dq_r <= 32'd0;
   385 					state <= ST_Spin;
   386 					// Wait T_rp (20ns)
   387 					timer <= 32'd0;	// wait 1tcy (40ns)   ---> TIMER HERE
   388 					state <= ST_Test_Precharge_All_Wait;
   389 				end
   391 			ST_Test_Precharge_All_Wait: begin
   392 					// Wait for T_rp after Precharge All
   393 					sdram_mode <= M_Nop;
   394 					if (timer == 32'd0) begin
   395 						// Timer hit zero. Continue
   396 						state <= ST_Spin;
   397 					end
   398 				end
   399 		endcase
   400 	end
   401 end
   403 endmodule