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