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