Blame


1 8515162d 2024-02-02 benni
2 8515162d 2024-02-02 benni // SDRAM interface to AS4C32M16SB-7TCN
3 8515162d 2024-02-02 benni // 512 Mbit Single-Data-Rate SDRAM, 32Mx16 (8M x 16 x 4 Banks)
4 8515162d 2024-02-02 benni
5 8515162d 2024-02-02 benni // Matthias Koch, January 2022
6 8515162d 2024-02-02 benni
7 8515162d 2024-02-02 benni // With a lot of inspiration from Mike Field, Hamsterworks:
8 8515162d 2024-02-02 benni
9 8515162d 2024-02-02 benni // https://web.archive.org/web/20190215130043/http://hamsterworks.co.nz/mediawiki/index.php/Simple_SDRAM_Controller
10 8515162d 2024-02-02 benni // https://web.archive.org/web/20190215130043/http://hamsterworks.co.nz/mediawiki/index.php/File:Verilog_Memory_controller_v0.1.zip
11 8515162d 2024-02-02 benni
12 8515162d 2024-02-02 benni // Note: You may need to change all values marked with *** when changing clock frequency. This is for 40 MHz.
13 8515162d 2024-02-02 benni
14 8515162d 2024-02-02 benni module SDRAM (
15 8515162d 2024-02-02 benni
16 8515162d 2024-02-02 benni // Interface to SDRAM chip, fully registered
17 8515162d 2024-02-02 benni
18 8515162d 2024-02-02 benni output sd_clk, // Clock for SDRAM chip
19 8515162d 2024-02-02 benni output reg sd_cke, // Clock enabled
20 8515162d 2024-02-02 benni inout [15:0] sd_d, // Bidirectional data lines to/from SDRAM
21 8515162d 2024-02-02 benni output reg [12:0] sd_addr, // Address bus, multiplexed, 13 bits
22 8515162d 2024-02-02 benni output reg [1:0] sd_ba, // Bank select wires for 4 banks
23 8515162d 2024-02-02 benni output reg [1:0] sd_dqm, // Byte mask
24 8515162d 2024-02-02 benni output reg sd_cs, // Chip select
25 8515162d 2024-02-02 benni output reg sd_we, // Write enable
26 8515162d 2024-02-02 benni output reg sd_ras, // Row address select
27 8515162d 2024-02-02 benni output reg sd_cas, // Columns address select
28 8515162d 2024-02-02 benni
29 8515162d 2024-02-02 benni // Interface to processor
30 8515162d 2024-02-02 benni
31 8515162d 2024-02-02 benni input clk,
32 8515162d 2024-02-02 benni input resetn,
33 8515162d 2024-02-02 benni input [3:0] wmask,
34 8515162d 2024-02-02 benni input rd,
35 8515162d 2024-02-02 benni input [25:0] addr,
36 8515162d 2024-02-02 benni input [31:0] din,
37 8515162d 2024-02-02 benni output reg [31:0] dout,
38 8515162d 2024-02-02 benni output reg busy
39 8515162d 2024-02-02 benni );
40 8515162d 2024-02-02 benni
41 8515162d 2024-02-02 benni parameter sdram_startup_cycles = 10100; // *** -- 100us, plus a little more, @ 100MHz
42 8515162d 2024-02-02 benni parameter sdram_refresh_cycles = 195; // *** The refresh operation must be performed 8192 times within 64ms. --> One refresh every 7.8125 us.
43 8515162d 2024-02-02 benni // With a minimum clock of 25 MHz, this results in one refresh every 7.8125e-6 * 25e6 = 195 cycles.
44 8515162d 2024-02-02 benni
45 8515162d 2024-02-02 benni // ----------------------------------------------------------
46 8515162d 2024-02-02 benni // -- Connections and buffer primitives
47 8515162d 2024-02-02 benni // ----------------------------------------------------------
48 8515162d 2024-02-02 benni
49 8515162d 2024-02-02 benni assign sd_clk = ~clk; // Supply memory chip with a clock.
50 8515162d 2024-02-02 benni
51 8515162d 2024-02-02 benni wire [15:0] sd_data_in; // Bidirectional data from SDRAM
52 8515162d 2024-02-02 benni reg [15:0] sd_data_out; // Bidirectional data to SDRAM
53 8515162d 2024-02-02 benni reg sd_data_drive; // High: FPGA controls wires Low: SDRAM controls wires
54 8515162d 2024-02-02 benni
55 8515162d 2024-02-02 benni
56 8515162d 2024-02-02 benni `ifdef __ICARUS__
57 8515162d 2024-02-02 benni
58 8515162d 2024-02-02 benni reg [15:0] sd_data_in_buffered;
59 8515162d 2024-02-02 benni assign sd_d = sd_data_drive ? sd_data_out : 16'bz;
60 8515162d 2024-02-02 benni always @(posedge clk) sd_data_in_buffered <= sd_d;
61 8515162d 2024-02-02 benni assign sd_data_in = sd_data_in_buffered;
62 8515162d 2024-02-02 benni
63 8515162d 2024-02-02 benni `else
64 8515162d 2024-02-02 benni
65 8515162d 2024-02-02 benni wire [15:0] sd_data_in_unbuffered; // To connect primitives internally
66 8515162d 2024-02-02 benni
67 8515162d 2024-02-02 benni TRELLIS_IO #(.DIR("BIDIR"))
68 8515162d 2024-02-02 benni sdio_tristate[15:0] (
69 8515162d 2024-02-02 benni .B(sd_d),
70 8515162d 2024-02-02 benni .I(sd_data_out),
71 8515162d 2024-02-02 benni .O(sd_data_in_unbuffered),
72 8515162d 2024-02-02 benni .T(!sd_data_drive)
73 8515162d 2024-02-02 benni );
74 8515162d 2024-02-02 benni
75 8515162d 2024-02-02 benni // Registering the input is important for stability and delays data arrival by one clock cycle.
76 8515162d 2024-02-02 benni IFS1P3BX dbi_ff[15:0] (.D(sd_data_in_unbuffered), .Q(sd_data_in), .SCLK(clk), .PD({16{sd_data_drive}}));
77 8515162d 2024-02-02 benni
78 8515162d 2024-02-02 benni `endif
79 8515162d 2024-02-02 benni // ----------------------------------------------------------
80 8515162d 2024-02-02 benni // -- Configuration to initialise the SDRAM chip
81 8515162d 2024-02-02 benni // ----------------------------------------------------------
82 8515162d 2024-02-02 benni
83 8515162d 2024-02-02 benni // Taken from https://github.com/rxrbln/picorv32/blob/master/picosoc/sdram.v
84 8515162d 2024-02-02 benni
85 8515162d 2024-02-02 benni localparam NO_WRITE_BURST = 1'b0; // 0=write burst enabled, 1=only single access write
86 8515162d 2024-02-02 benni localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed
87 8515162d 2024-02-02 benni localparam CAS_LATENCY = 3'd2; // 2 or 3 cycles allowed
88 8515162d 2024-02-02 benni localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved
89 8515162d 2024-02-02 benni localparam BURST_LENGTH = 3'b001; // 000=1, 001=2, 010=4, 011=8
90 8515162d 2024-02-02 benni
91 8515162d 2024-02-02 benni localparam MODE = {3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH};
92 8515162d 2024-02-02 benni
93 8515162d 2024-02-02 benni // ----------------------------------------------------------
94 8515162d 2024-02-02 benni // -- All possible commands for the SDRAM chip
95 8515162d 2024-02-02 benni // ----------------------------------------------------------
96 8515162d 2024-02-02 benni
97 8515162d 2024-02-02 benni // CS, RAS, CAS, WE
98 8515162d 2024-02-02 benni localparam CMD_INHIBIT = 4'b1111;
99 8515162d 2024-02-02 benni
100 8515162d 2024-02-02 benni localparam CMD_NOP = 4'b0111;
101 8515162d 2024-02-02 benni localparam CMD_BURST_TERMINATE = 4'b0110;
102 8515162d 2024-02-02 benni localparam CMD_READ = 4'b0101;
103 8515162d 2024-02-02 benni localparam CMD_WRITE = 4'b0100;
104 8515162d 2024-02-02 benni localparam CMD_ACTIVE = 4'b0011;
105 8515162d 2024-02-02 benni localparam CMD_PRECHARGE = 4'b0010;
106 8515162d 2024-02-02 benni localparam CMD_AUTO_REFRESH = 4'b0001;
107 8515162d 2024-02-02 benni localparam CMD_LOAD_MODE = 4'b0000;
108 8515162d 2024-02-02 benni
109 8515162d 2024-02-02 benni // ----------------------------------------------------------
110 8515162d 2024-02-02 benni // -- States of the SDRAM controller
111 8515162d 2024-02-02 benni // ----------------------------------------------------------
112 8515162d 2024-02-02 benni
113 8515162d 2024-02-02 benni localparam s_init_bit = 0; localparam s_init = 1 << s_init_bit ;
114 8515162d 2024-02-02 benni localparam s_idle_bit = 1; localparam s_idle = 1 << s_idle_bit ;
115 8515162d 2024-02-02 benni localparam s_activate_bit = 2; localparam s_activate = 1 << s_activate_bit ;
116 8515162d 2024-02-02 benni localparam s_read_1_bit = 3; localparam s_read_1 = 1 << s_read_1_bit ;
117 8515162d 2024-02-02 benni localparam s_read_2_bit = 4; localparam s_read_2 = 1 << s_read_2_bit ;
118 8515162d 2024-02-02 benni localparam s_read_3_bit = 5; localparam s_read_3 = 1 << s_read_3_bit ;
119 8515162d 2024-02-02 benni localparam s_read_4_bit = 6; localparam s_read_4 = 1 << s_read_4_bit ;
120 8515162d 2024-02-02 benni localparam s_read_5_bit = 7; localparam s_read_5 = 1 << s_read_5_bit ;
121 8515162d 2024-02-02 benni localparam s_write_1_bit = 8; localparam s_write_1 = 1 << s_write_1_bit ;
122 8515162d 2024-02-02 benni localparam s_write_2_bit = 9; localparam s_write_2 = 1 << s_write_2_bit ;
123 8515162d 2024-02-02 benni
124 8515162d 2024-02-02 benni localparam s_idle_in_6_bit = 10; localparam s_idle_in_6 = 1 << s_idle_in_6_bit ;
125 8515162d 2024-02-02 benni localparam s_idle_in_5_bit = 11; localparam s_idle_in_5 = 1 << s_idle_in_5_bit ;
126 8515162d 2024-02-02 benni localparam s_idle_in_4_bit = 12; localparam s_idle_in_4 = 1 << s_idle_in_4_bit ;
127 8515162d 2024-02-02 benni localparam s_idle_in_3_bit = 13; localparam s_idle_in_3 = 1 << s_idle_in_3_bit ;
128 8515162d 2024-02-02 benni localparam s_idle_in_2_bit = 14; localparam s_idle_in_2 = 1 << s_idle_in_2_bit ;
129 8515162d 2024-02-02 benni localparam s_idle_in_1_bit = 15; localparam s_idle_in_1 = 1 << s_idle_in_1_bit ;
130 8515162d 2024-02-02 benni
131 8515162d 2024-02-02 benni (* onehot *)
132 8515162d 2024-02-02 benni reg [15:0] state = s_init;
133 8515162d 2024-02-02 benni
134 8515162d 2024-02-02 benni // ----------------------------------------------------------
135 8515162d 2024-02-02 benni // -- Access control wires
136 8515162d 2024-02-02 benni // ----------------------------------------------------------
137 8515162d 2024-02-02 benni
138 8515162d 2024-02-02 benni reg [14:0] reset_counter = sdram_startup_cycles;
139 8515162d 2024-02-02 benni reg [7:0] refresh_counter = 0;
140 8515162d 2024-02-02 benni reg refresh_pending = 1;
141 8515162d 2024-02-02 benni reg rd_sticky = 0;
142 8515162d 2024-02-02 benni reg [3:0] wmask_sticky = 4'b0000;
143 8515162d 2024-02-02 benni
144 8515162d 2024-02-02 benni wire stillatwork = ~(state[s_read_5_bit] | state[s_write_2_bit]);
145 8515162d 2024-02-02 benni wire [8:0] refresh_counterN = refresh_counter - 1;
146 8515162d 2024-02-02 benni
147 8515162d 2024-02-02 benni // ----------------------------------------------------------
148 8515162d 2024-02-02 benni // -- The memory controller
149 8515162d 2024-02-02 benni // ----------------------------------------------------------
150 8515162d 2024-02-02 benni
151 8515162d 2024-02-02 benni always @(posedge clk)
152 8515162d 2024-02-02 benni if(!resetn) begin
153 8515162d 2024-02-02 benni state <= s_init;
154 8515162d 2024-02-02 benni reset_counter <= sdram_startup_cycles; // Counts backwards to zero
155 8515162d 2024-02-02 benni busy <= 0; // Technically, we are busy with initialisation, but there are no ongoing read or write requests
156 8515162d 2024-02-02 benni rd_sticky <= 0;
157 8515162d 2024-02-02 benni wmask_sticky <= 4'b0000;
158 8515162d 2024-02-02 benni sd_cke <= 0;
159 8515162d 2024-02-02 benni end else begin
160 8515162d 2024-02-02 benni
161 8515162d 2024-02-02 benni // FemtoRV32 pulses read and write lines high for exactly one clock cycle.
162 8515162d 2024-02-02 benni // Address and data lines keep stable until busy is released.
163 8515162d 2024-02-02 benni // Therefore: Take note of the requested read or write, and assert busy flag immediately.
164 8515162d 2024-02-02 benni
165 8515162d 2024-02-02 benni busy <= ((|wmask) | rd) | (busy & stillatwork );
166 8515162d 2024-02-02 benni rd_sticky <= rd | (rd_sticky & stillatwork );
167 8515162d 2024-02-02 benni wmask_sticky <= wmask | (wmask_sticky & {4{stillatwork}} );
168 8515162d 2024-02-02 benni
169 8515162d 2024-02-02 benni // Schedule refreshes regularly
170 8515162d 2024-02-02 benni refresh_counter <= refresh_counterN[8] ? sdram_refresh_cycles : refresh_counterN[7:0];
171 8515162d 2024-02-02 benni refresh_pending <= (refresh_pending & ~state[s_idle_bit]) | refresh_counterN[8];
172 8515162d 2024-02-02 benni
173 8515162d 2024-02-02 benni (* parallel_case *)
174 8515162d 2024-02-02 benni case(1'b1)
175 8515162d 2024-02-02 benni
176 8515162d 2024-02-02 benni // Processor can already request the first read or write here, but has to wait then:
177 8515162d 2024-02-02 benni
178 8515162d 2024-02-02 benni state[s_init_bit]: begin
179 8515162d 2024-02-02 benni
180 8515162d 2024-02-02 benni //------------------------------------------------------------------------
181 8515162d 2024-02-02 benni //-- This is the initial startup state, where we wait for at least 100us
182 8515162d 2024-02-02 benni //-- before starting the start sequence
183 8515162d 2024-02-02 benni //--
184 8515162d 2024-02-02 benni //-- The initialisation is sequence is
185 8515162d 2024-02-02 benni //-- * de-assert SDRAM_CKE
186 8515162d 2024-02-02 benni //-- * 100us wait,
187 8515162d 2024-02-02 benni //-- * assert SDRAM_CKE
188 8515162d 2024-02-02 benni //-- * wait at least one cycle,
189 8515162d 2024-02-02 benni //-- * PRECHARGE
190 8515162d 2024-02-02 benni //-- * wait 2 cycles
191 8515162d 2024-02-02 benni //-- * REFRESH,
192 8515162d 2024-02-02 benni //-- * tREF wait
193 8515162d 2024-02-02 benni //-- * REFRESH,
194 8515162d 2024-02-02 benni //-- * tREF wait
195 8515162d 2024-02-02 benni //-- * LOAD_MODE_REG
196 8515162d 2024-02-02 benni //-- * 2 cycles wait
197 8515162d 2024-02-02 benni //------------------------------------------------------------------------
198 8515162d 2024-02-02 benni
199 8515162d 2024-02-02 benni sd_ba <= 2'b00; // Reserved for future use in mode configuration
200 8515162d 2024-02-02 benni sd_dqm <= 2'b11; // Data bus in High-Z state
201 8515162d 2024-02-02 benni sd_data_drive <= 0; // Do not drive the data bus now
202 8515162d 2024-02-02 benni
203 8515162d 2024-02-02 benni case (reset_counter) // Counts from a large value down to zero
204 8515162d 2024-02-02 benni
205 8515162d 2024-02-02 benni 33: begin sd_cke <= 1; end
206 8515162d 2024-02-02 benni
207 8515162d 2024-02-02 benni // Ensure all rows are closed
208 8515162d 2024-02-02 benni 31: begin {sd_cs, sd_ras, sd_cas, sd_we} <= CMD_PRECHARGE; sd_addr <= 13'b0010000000000; end
209 8515162d 2024-02-02 benni
210 8515162d 2024-02-02 benni // These refreshes need to be at least tRFC (63ns) apart
211 8515162d 2024-02-02 benni 23: begin {sd_cs, sd_ras, sd_cas, sd_we} <= CMD_AUTO_REFRESH; end
212 8515162d 2024-02-02 benni 15: begin {sd_cs, sd_ras, sd_cas, sd_we} <= CMD_AUTO_REFRESH; end
213 8515162d 2024-02-02 benni
214 8515162d 2024-02-02 benni // Now load the mode register
215 8515162d 2024-02-02 benni 7: begin {sd_cs, sd_ras, sd_cas, sd_we} <= CMD_LOAD_MODE; sd_addr <= MODE; end
216 8515162d 2024-02-02 benni
217 8515162d 2024-02-02 benni default: {sd_cs, sd_ras, sd_cas, sd_we} <= CMD_NOP;
218 8515162d 2024-02-02 benni endcase
219 8515162d 2024-02-02 benni
220 8515162d 2024-02-02 benni reset_counter <= reset_counter - 1;
221 8515162d 2024-02-02 benni if (reset_counter == 0) state <= s_idle;
222 8515162d 2024-02-02 benni end
223 8515162d 2024-02-02 benni
224 8515162d 2024-02-02 benni // New read or write requests from the processor may arrive in these states:
225 8515162d 2024-02-02 benni
226 8515162d 2024-02-02 benni //-----------------------------------------------------
227 8515162d 2024-02-02 benni //-- Additional NOPs to meet timing requirements
228 8515162d 2024-02-02 benni //-----------------------------------------------------
229 8515162d 2024-02-02 benni
230 8515162d 2024-02-02 benni state[s_idle_in_6_bit]: begin state <= s_idle_in_5; {sd_cs, sd_ras, sd_cas, sd_we} <= CMD_NOP; end
231 8515162d 2024-02-02 benni state[s_idle_in_5_bit]: begin state <= s_idle_in_4; {sd_cs, sd_ras, sd_cas, sd_we} <= CMD_NOP; end
232 8515162d 2024-02-02 benni state[s_idle_in_4_bit]: begin state <= s_idle_in_3; {sd_cs, sd_ras, sd_cas, sd_we} <= CMD_NOP; end
233 8515162d 2024-02-02 benni state[s_idle_in_3_bit]: begin state <= s_idle_in_2; {sd_cs, sd_ras, sd_cas, sd_we} <= CMD_NOP; end
234 8515162d 2024-02-02 benni state[s_idle_in_2_bit]: begin state <= s_idle_in_1; {sd_cs, sd_ras, sd_cas, sd_we} <= CMD_NOP; end
235 8515162d 2024-02-02 benni state[s_idle_in_1_bit]: begin state <= s_idle; {sd_cs, sd_ras, sd_cas, sd_we} <= CMD_NOP; end
236 8515162d 2024-02-02 benni
237 8515162d 2024-02-02 benni // Refresh cycle needs tRFC (63ns), so 6 idle cycles are needed @ 100MHz
238 8515162d 2024-02-02 benni
239 8515162d 2024-02-02 benni //-----------------------------------------------------
240 8515162d 2024-02-02 benni //-- Dispatch all possible actions while idling (NOP)
241 8515162d 2024-02-02 benni //-----------------------------------------------------
242 8515162d 2024-02-02 benni
243 8515162d 2024-02-02 benni state[s_idle_bit]: begin
244 8515162d 2024-02-02 benni sd_ba <= addr[23:22]; // Bank select, 2 bits
245 8515162d 2024-02-02 benni sd_addr <= {addr[25:24], addr[21:11]} ; // RA0-RA12: 8192 Row address
246 8515162d 2024-02-02 benni
247 8515162d 2024-02-02 benni {sd_cs, sd_ras, sd_cas, sd_we} <= refresh_pending ? CMD_AUTO_REFRESH :
248 8515162d 2024-02-02 benni (|wmask_sticky) | rd_sticky ? CMD_ACTIVE :
249 8515162d 2024-02-02 benni CMD_NOP;
250 8515162d 2024-02-02 benni
251 8515162d 2024-02-02 benni state <= refresh_pending ? s_idle_in_2 : // *** Experimental result: Direct transition to s_idle does not work @ 40 MHz, s_idle_in_1 is unstable, sd_idle_in_2 is fine.
252 8515162d 2024-02-02 benni (|wmask_sticky) | rd_sticky ? s_activate :
253 8515162d 2024-02-02 benni s_idle;
254 8515162d 2024-02-02 benni end
255 8515162d 2024-02-02 benni
256 8515162d 2024-02-02 benni // Busy flag is set while state machine is in the following states:
257 8515162d 2024-02-02 benni
258 8515162d 2024-02-02 benni //-----------------------------------------------------
259 8515162d 2024-02-02 benni //-- Opening the row ready for reads or writes
260 8515162d 2024-02-02 benni //-----------------------------------------------------
261 8515162d 2024-02-02 benni
262 8515162d 2024-02-02 benni state[s_activate_bit]: begin
263 8515162d 2024-02-02 benni sd_data_drive <= ~rd_sticky; // Drive or release bus early, before the SDRAM chip takes over to drive these lines
264 8515162d 2024-02-02 benni {sd_cs, sd_ras, sd_cas, sd_we} <= CMD_NOP;
265 8515162d 2024-02-02 benni state <= rd_sticky ? s_read_1 : s_write_1;
266 8515162d 2024-02-02 benni end
267 8515162d 2024-02-02 benni
268 8515162d 2024-02-02 benni // RAS-to-CAS delay, also necessary for precharge, used in this state machine: 2 cycles.
269 8515162d 2024-02-02 benni // Specification of AS4C32M16SB-7TCN: 21 ns --> Good for 1/(21e-9 / 2) = 95.23 MHz
270 8515162d 2024-02-02 benni
271 8515162d 2024-02-02 benni //-----------------------------------------------------
272 8515162d 2024-02-02 benni //-- Processing the read transaction
273 8515162d 2024-02-02 benni //-----------------------------------------------------
274 8515162d 2024-02-02 benni
275 8515162d 2024-02-02 benni state[s_read_1_bit]: begin
276 8515162d 2024-02-02 benni sd_dqm <= 2'b00; // SDRAM chip shall drive the bus lines
277 8515162d 2024-02-02 benni {sd_cs, sd_ras, sd_cas, sd_we} <= CMD_READ;
278 8515162d 2024-02-02 benni sd_addr <= {3'b001, addr[10:2], 1'b0}; // Bit 10: Auto-precharge. CA0-CA9: 1024 Column address.
279 8515162d 2024-02-02 benni state <= s_read_2;
280 8515162d 2024-02-02 benni end
281 8515162d 2024-02-02 benni
282 8515162d 2024-02-02 benni state[s_read_2_bit]: begin
283 8515162d 2024-02-02 benni {sd_cs, sd_ras, sd_cas, sd_we} <= CMD_NOP;
284 8515162d 2024-02-02 benni state <= s_read_3;
285 8515162d 2024-02-02 benni end
286 8515162d 2024-02-02 benni
287 8515162d 2024-02-02 benni state[s_read_3_bit]: state <= s_read_4;
288 8515162d 2024-02-02 benni
289 8515162d 2024-02-02 benni
290 8515162d 2024-02-02 benni state[s_read_4_bit]: begin
291 8515162d 2024-02-02 benni dout[15:0] <= sd_data_in;
292 8515162d 2024-02-02 benni state <= s_read_5;
293 8515162d 2024-02-02 benni end
294 8515162d 2024-02-02 benni
295 8515162d 2024-02-02 benni // Busy is cleared when reaching this state, fulfilling the request:
296 8515162d 2024-02-02 benni
297 8515162d 2024-02-02 benni state[s_read_5_bit]: begin
298 8515162d 2024-02-02 benni dout[31:16] <= sd_data_in;
299 8515162d 2024-02-02 benni state <= s_idle; // *** Experimental result: Direct transition to s_idle is fine @ 40 MHz
300 8515162d 2024-02-02 benni end
301 8515162d 2024-02-02 benni
302 8515162d 2024-02-02 benni // Precharge (which is automatic here) needs 21 ns, therefore 2 idle cycles need to be inserted
303 8515162d 2024-02-02 benni
304 8515162d 2024-02-02 benni //-----------------------------------------------------
305 8515162d 2024-02-02 benni // -- Processing the write transaction
306 8515162d 2024-02-02 benni //-----------------------------------------------------
307 8515162d 2024-02-02 benni
308 8515162d 2024-02-02 benni state[s_write_1_bit]: begin
309 8515162d 2024-02-02 benni sd_addr <= {3'b001, addr[10:2], 1'b0}; // Bit 10: Auto-precharge. CA0-CA9: 1024 Column address.
310 8515162d 2024-02-02 benni sd_data_out <= din[15:0];
311 8515162d 2024-02-02 benni sd_dqm <= ~wmask_sticky[1:0];
312 8515162d 2024-02-02 benni {sd_cs, sd_ras, sd_cas, sd_we} <= CMD_WRITE;
313 8515162d 2024-02-02 benni state <= s_write_2;
314 8515162d 2024-02-02 benni end
315 8515162d 2024-02-02 benni
316 8515162d 2024-02-02 benni // Busy is cleared when reaching this state, fulfilling the request:
317 8515162d 2024-02-02 benni
318 8515162d 2024-02-02 benni state[s_write_2_bit]: begin
319 8515162d 2024-02-02 benni sd_data_out <= din[31:16];
320 8515162d 2024-02-02 benni sd_dqm <= ~wmask_sticky[3:2];
321 8515162d 2024-02-02 benni {sd_cs, sd_ras, sd_cas, sd_we} <= CMD_NOP;
322 8515162d 2024-02-02 benni state <= s_idle_in_2; // *** Experimental result: s_idle_in_1 does not work @ 40 MHz, s_idle_in_2 is fine.
323 8515162d 2024-02-02 benni end
324 8515162d 2024-02-02 benni
325 8515162d 2024-02-02 benni // Write needs 14 ns internally, then Precharge needs 21 ns, therefore 3 idle cycles need to be inserted
326 8515162d 2024-02-02 benni
327 8515162d 2024-02-02 benni endcase
328 8515162d 2024-02-02 benni end
329 8515162d 2024-02-02 benni
330 8515162d 2024-02-02 benni endmodule