wb_sdram.v

changeset 7
001f5282bff0
parent 6
39984d9ff640
child 8
b00018dfe8e5
     1.1 diff -r 39984d9ff640 -r 001f5282bff0 wb_sdram.v
     1.2 --- a/wb_sdram.v	Tue Aug 10 18:04:05 2010 +0100
     1.3 +++ b/wb_sdram.v	Tue Aug 10 18:33:25 2010 +0100
     1.4 @@ -16,7 +16,7 @@
     1.5  	input						wb_we_i,				// WISHBONE write enable (R/#W)
     1.6  	input						wb_cyc_i,			// WISHBONE cycle
     1.7  	input						wb_stb_i,			// WISHBONE strobe
     1.8 -	output					wb_ack_o,			// WISHBONE cycle acknowledge (data available, DTACK)
     1.9 +	output reg				wb_ack_o,			// WISHBONE cycle acknowledge (data available, DTACK)
    1.10  	output					wb_err_o,			// WISHBONE bus error
    1.11  	output					wb_rty_o,			// WISHBONE retry-later
    1.12  	
    1.13 @@ -117,10 +117,10 @@
    1.14  wire [11:0] row_addr;
    1.15  wire [1:0] bank_addr;
    1.16  
    1.17 -// Convert a 22-bit linear address into an SDRAM address
    1.18 +// Convert a 23-bit linear address into an SDRAM address
    1.19  assign column_addr	= wb_adr_i[8:0];
    1.20  assign bank_addr		= wb_adr_i[10:9];
    1.21 -assign row_addr		= wb_adr_i[21:11];
    1.22 +assign row_addr		= wb_adr_i[22:11];
    1.23  
    1.24  
    1.25  /****
    1.26 @@ -140,17 +140,16 @@
    1.27  localparam	ST_Spin							= 32'd11;		// <<== main 'spin' / 'idle' state
    1.28  localparam	ST_Refresh						= 32'd12;
    1.29  localparam	ST_Refresh_Wait				= 32'd13;
    1.30 -localparam	ST_Test_Activate				= 32'd500;
    1.31 -localparam	ST_Test_Activate_Wait		= 32'd501;
    1.32 -localparam	ST_Test_Read					= 32'd502;
    1.33 -localparam	ST_Test_Read_Wait				= 32'd503;
    1.34 -localparam	ST_Test_Read_Finish			= 32'd504;
    1.35 -localparam	ST_Test_Write					= 32'd505;
    1.36 -localparam	ST_Test_Precharge_All		= 32'd506;
    1.37 -localparam	ST_Test_Precharge_All_Wait	= 32'd507;
    1.38 +localparam	ST_Activate						= 32'd30;
    1.39 +localparam	ST_Activate_Wait				= 32'd31;
    1.40 +localparam	ST_Write							= 32'd32;
    1.41 +localparam	ST_Read							= 32'd33;
    1.42 +localparam	ST_Read_Wait					= 32'd34;
    1.43 +localparam	ST_Wait_Trp						= 32'd35;
    1.44 +localparam	ST_Ack							= 32'd36;
    1.45 +
    1.46   
    1.47  reg [31:0] state;
    1.48 -reg [31:0] captured_data;
    1.49  always @(posedge wb_clk_i) begin
    1.50  	if (wb_rst_i) begin
    1.51  		// Initialise state machine and timer
    1.52 @@ -299,7 +298,11 @@
    1.53  					// Enable refresh timer
    1.54  					refresh_timer_en <= 1'b1;
    1.55  
    1.56 +					// Idle the SDRAM (Inhibit is lower power than NOP on some SDRAMs)
    1.57  					sdram_mode <= M_Inhibit;
    1.58 +					
    1.59 +					// Clear the WISHBONE Ack flag -- NOTE: is this required?
    1.60 +					wb_ack_o <= 1'b0;
    1.61  
    1.62  					if (refresh_req) begin
    1.63  						// Refresh request received. Ack it and do a refresh.
    1.64 @@ -307,9 +310,17 @@
    1.65  						state <= ST_Refresh;
    1.66  					end else begin
    1.67  						//state <= ST_Spin;		// NOTE: turned off to run a ram test...
    1.68 -						state <= ST_Test_Activate;
    1.69 +						//state <= ST_Test_Activate;
    1.70 +						if (wb_cyc_i & wb_stb_i) begin
    1.71 +							// CYC and STB high. A Wishbone cycle just started.
    1.72 +							state <= ST_Activate;
    1.73 +						end
    1.74  					end
    1.75  				end
    1.76 +
    1.77 +/////
    1.78 +// Refresh logic
    1.79 +/////
    1.80  				
    1.81  			ST_Refresh: begin
    1.82  					// Refresh timer timed out; do a refresh run
    1.83 @@ -330,79 +341,90 @@
    1.84  						state <= ST_Spin;
    1.85  					end
    1.86  				end
    1.87 -				
    1.88 -			ST_Test_Activate: begin
    1.89 -					// Activate bank
    1.90 +
    1.91 +//////
    1.92 +// R/W logic
    1.93 +//////
    1.94 +			ST_Activate: begin
    1.95 +					// Activate the required bank
    1.96  					sdram_mode <= M_BankActivate;
    1.97  					sdram_addr <= row_addr;
    1.98 -					sdram_ba <= bank_addr;
    1.99 -					timer <= 32'd0;	// wait Trcd (20ns ideally, this is 40ns)		---> TIMER HERE
   1.100 -					state <= ST_Test_Activate_Wait;
   1.101 +					sdram_ba   <= bank_addr;
   1.102 +					timer <= 32'd0;		// Wait T_rcd (20ns ideally, here 40ns)	---> TIMER HERE
   1.103 +					state <= ST_Activate_Wait;
   1.104  				end
   1.105  				
   1.106 -			ST_Test_Activate_Wait: begin
   1.107 -					// Wait for Activate Bank to complete
   1.108 +			ST_Activate_Wait: begin
   1.109 +					// Wait for T_rcd
   1.110  					sdram_mode <= M_Nop;
   1.111  					if (timer == 32'd0) begin
   1.112 -						state <= ST_Test_Read;
   1.113 +						if (wb_we_i) begin
   1.114 +							// Write cycle.
   1.115 +							state <= ST_Write;
   1.116 +						end else begin
   1.117 +							// Read cycle
   1.118 +							state <= ST_Read;
   1.119 +						end
   1.120  					end
   1.121  				end
   1.122  				
   1.123 -			ST_Test_Read: begin
   1.124 -					// Do the Read operation
   1.125 -					sdram_mode <= M_Read;
   1.126 -					sdram_addr <= column_addr;
   1.127 -					sdram_dqm <= 4'b0000;		// Allow data through (DQM = OE# = 1 to mask off, 0 to allow)
   1.128 -					timer <= 32'd2 - 32'd1;		// wait CAS# Latency (2 clock cycles)	---> TIMER HERE
   1.129 -					state <= ST_Test_Read_Wait;
   1.130 +			ST_Write: begin
   1.131 +					// Write cycle handler
   1.132 +					sdram_mode	<= M_WritePrecharge;
   1.133 +					sdram_addr	<= column_addr;
   1.134 +					sdram_dq_r	<= wb_dat_i;
   1.135 +					sdram_dq_oe	<= 1'b1;		// FPGA drives the DQ bus
   1.136 +					sdram_dqm	<= 4'b0000;	// TODO: use WB_SEL_I to set these
   1.137 +					
   1.138 +					// Wait T_rp (20ns)
   1.139 +					timer <= 32'd0;	// wait 1tcy (40ns)   ---> TIMER HERE
   1.140 +					state <= ST_Wait_Trp;
   1.141 +				end
   1.142 +
   1.143 +			ST_Read: begin
   1.144 +					// Read cycle handler
   1.145 +					sdram_mode	<= M_ReadPrecharge;
   1.146 +					sdram_addr	<= column_addr;
   1.147 +					sdram_dq_oe	<= 1'b0;		// SDRAM drives the DQ bus
   1.148 +					sdram_dqm	<= 4'b0000;	// Grab all the data (it's just easier that way...)
   1.149 +					timer <= 32'd2 - 32'd1;	// CAS# Latency ---> TIMER HERE
   1.150 +					state <= ST_Read_Wait;
   1.151  				end
   1.152  				
   1.153 -			ST_Test_Read_Wait: begin
   1.154 -					// Wait for CAS latency
   1.155 -					sdram_mode <= M_Nop;
   1.156 -					sdram_dqm <= 4'b1111;		// Disable SDRAM output buffers
   1.157 +			ST_Read_Wait: begin
   1.158 +					// Wait for CAS# latency
   1.159 +					sdram_mode	<= M_Nop;
   1.160 +					sdram_dqm	<= 4'b1111;	// Make SDRAM DQ bus float
   1.161  					if (timer == 32'd0) begin
   1.162 -						state <= ST_Test_Read_Finish;
   1.163 -						captured_data <= sdram_dq;
   1.164 +						// Latch data
   1.165 +						wb_dat_o <= sdram_dq;
   1.166 +						// Wait T_rp (20ns)
   1.167 +						timer <= 32'd0;	// wait 1tcy (40ns)   ---> TIMER HERE
   1.168 +						state <=	ST_Wait_Trp;
   1.169  					end
   1.170  				end
   1.171  
   1.172 -			ST_Test_Read_Finish: begin
   1.173 -					// Additional NOP after read to avoid bus contention if next transaction is a write
   1.174 -					sdram_mode <= M_Nop;
   1.175 -					sdram_dqm <= 4'b1111;	// Disable SDRAM output buffers
   1.176 -					state <= ST_Test_Write;
   1.177 -				end
   1.178 -			
   1.179 -			ST_Test_Write: begin
   1.180 -					// Write to SDRAM
   1.181 -					sdram_mode <= M_Write;
   1.182 -					sdram_addr <= column_addr;
   1.183 -					sdram_dq_r <= ~captured_data; //32'h55AA_BCDE;
   1.184 -					sdram_dq_oe <= 1'b1;		// output enable
   1.185 -					sdram_dqm <= 4'b0000;		// Allow data through (DQM = OE# = 1 to mask off, 0 to allow)
   1.186 -					state <= ST_Test_Precharge_All;
   1.187 -				end
   1.188 -				
   1.189 -			ST_Test_Precharge_All: begin
   1.190 -					// Precharge All
   1.191 -					sdram_mode <= M_PrechargeAll;
   1.192 -					sdram_addr <= 12'd0;
   1.193 -					sdram_dq_oe <= 1'b0;		// output disable
   1.194 -					sdram_dqm <= 4'b1111;		// Disable SDRAM output buffers
   1.195 -					sdram_dq_r <= 32'd0;
   1.196 -					state <= ST_Spin;
   1.197 -					// Wait T_rp (20ns)
   1.198 -					timer <= 32'd0;	// wait 1tcy (40ns)   ---> TIMER HERE
   1.199 -					state <= ST_Test_Precharge_All_Wait;
   1.200 +			ST_Wait_Trp: begin
   1.201 +					// Wait for T_rp, then ack
   1.202 +					if (timer == 32'd0) begin
   1.203 +						state <= ST_Ack;
   1.204 +					end
   1.205  				end
   1.206  
   1.207 -			ST_Test_Precharge_All_Wait: begin
   1.208 -					// Wait for T_rp after Precharge All
   1.209 -					sdram_mode <= M_Nop;
   1.210 -					if (timer == 32'd0) begin
   1.211 -						// Timer hit zero. Continue
   1.212 -						state <= ST_Spin;
   1.213 +			ST_Ack: begin
   1.214 +					// Ack the transfer to the WISHBONE host
   1.215 +					sdram_mode	<= M_Nop;
   1.216 +					sdram_addr	<= 32'd0;
   1.217 +					sdram_dq_r	<= 32'd0;
   1.218 +					sdram_dq_oe	<= 1'b0;		// SDRAM drives the DQ bus
   1.219 +					sdram_dqm	<= 4'b1111;	// mask off DQM
   1.220 +					if (wb_cyc_i & wb_stb_i) begin
   1.221 +						// CYC and STB high, ack the transfer
   1.222 +						wb_ack_o		<= 1'b1;
   1.223 +						state			<= ST_Ack;
   1.224 +					end else begin
   1.225 +						// CYC and STB low, back to the start again...
   1.226 +						state			<= ST_Spin;
   1.227  					end
   1.228  				end
   1.229  		endcase