1use crate::dff::DFF;
2use crate::dff_setup;
3use crate::prelude::{DelayLine, MemoryTimings};
4use crate::sdram::cmd::{SDRAMCommand, SDRAMCommandEncoder};
5use crate::sdram::{OutputBuffer, SDRAMDriver};
6use rust_hdl_core::prelude::*;
7
8#[derive(Copy, Clone, PartialEq, Debug, LogicState)]
10enum State {
11 Boot,
12 Precharge1,
13 AutoRefresh1,
14 AutoRefresh2,
15 LoadModeRegister,
16 Idle,
17 IssueRead,
18 IssueWrite,
19 Refresh,
20 ReadActivate,
21 ReadCycle,
22 WriteActivate,
23 WriteCycle,
24 Recovery,
25 Precharge,
26 Error,
27}
28
29#[derive(LogicBlock)]
38pub struct SDRAMBaseController<const R: usize, const C: usize, const L: usize, const D: usize> {
39 pub clock: Signal<In, Clock>,
40 pub sdram: SDRAMDriver<D>,
41 pub data_in: Signal<In, Bits<L>>,
43 pub write_not_read: Signal<In, Bit>,
44 pub cmd_strobe: Signal<In, Bit>,
45 pub cmd_address: Signal<In, Bits<32>>,
46 pub busy: Signal<Out, Bit>,
47 pub data_out: Signal<Out, Bits<L>>,
48 pub data_valid: Signal<Out, Bit>,
49 pub error: Signal<Out, Bit>,
50 cmd: Signal<Local, SDRAMCommand>,
51 encode: SDRAMCommandEncoder,
52 boot_delay: Constant<Bits<16>>,
53 t_rp: Constant<Bits<16>>,
54 t_rfc: Constant<Bits<16>>,
55 t_refresh_max: Constant<Bits<16>>,
56 t_rcd: Constant<Bits<16>>,
57 t_wr: Constant<Bits<16>>,
58 max_transfer_size: Constant<Bits<5>>,
59 mode_register: Constant<Bits<13>>,
60 cas_delay: Constant<Bits<3>>,
61 state: DFF<State>,
62 reg_data_write: DFF<Bits<L>>,
63 reg_data_read: DFF<Bits<L>>,
64 reg_address: DFF<Bits<32>>,
65 reg_cmd_address: DFF<Bits<32>>,
66 delay_counter: DFF<Bits<16>>,
67 refresh_counter: DFF<Bits<16>>,
68 transfer_counter: DFF<Bits<5>>,
69 read_valid: DelayLine<Bit, 8, 3>,
70 addr_bank: Signal<Local, Bits<2>>,
71 addr_row: Signal<Local, Bits<13>>,
72 addr_col: Signal<Local, Bits<13>>,
73 write_pending: DFF<Bit>,
74 read_pending: DFF<Bit>,
75 read_ready: DFF<Bit>,
76 refresh_needed: DFF<Bit>,
77 row_bits: Constant<Bits<32>>,
78 col_bits: Constant<Bits<32>>,
79 data_bits: Constant<Bits<L>>,
80 data_shift_in: Constant<Bits<L>>,
81 data_out_counter: DFF<Bits<5>>,
82}
83
84impl<const R: usize, const C: usize, const L: usize, const D: usize>
85 SDRAMBaseController<R, C, L, D>
86{
87 pub fn new(
88 cas_delay: u32,
89 timings: MemoryTimings,
90 buffer: OutputBuffer,
91 ) -> SDRAMBaseController<R, C, L, D> {
92 assert_eq!(L % D, 0);
93 assert!(L / D <= 16);
94 assert_eq!((1 << C) % (L / D), 0);
95 let mode_register = cas_delay << 4;
103 Self {
104 clock: Default::default(),
105 sdram: Default::default(),
106 cmd: Default::default(),
107 data_in: Default::default(),
108 write_not_read: Default::default(),
109 cmd_strobe: Default::default(),
110 cmd_address: Default::default(),
111 busy: Default::default(),
112 data_out: Default::default(),
113 data_valid: Default::default(),
114 error: Default::default(),
115 boot_delay: Constant::new((timings.t_boot() + 50).to_bits()),
116 t_rp: Constant::new((timings.t_rp()).to_bits()),
117 t_rfc: Constant::new((timings.t_rfc()).to_bits()),
118 t_refresh_max: Constant::new((timings.t_refresh_max() * 9 / 10).to_bits()),
119 t_rcd: Constant::new((timings.t_rcd()).to_bits()),
120 t_wr: Constant::new((timings.t_wr()).to_bits()),
121 max_transfer_size: Constant::new({ L / D }.to_bits()),
122 mode_register: Constant::new(mode_register.to_bits()),
123 cas_delay: Constant::new(
129 match buffer {
130 OutputBuffer::Wired => cas_delay,
131 OutputBuffer::DelayOne => cas_delay + 1,
132 OutputBuffer::DelayTwo => cas_delay + 2,
133 }
134 .to_bits(),
135 ),
136 state: Default::default(),
137 reg_data_write: Default::default(),
138 reg_data_read: Default::default(),
139 reg_address: Default::default(),
140 reg_cmd_address: Default::default(),
141 delay_counter: Default::default(),
142 refresh_counter: Default::default(),
143 transfer_counter: Default::default(),
144 read_valid: Default::default(),
145 addr_bank: Default::default(),
146 addr_row: Default::default(),
147 addr_col: Default::default(),
148 write_pending: Default::default(),
149 row_bits: Constant::new(R.to_bits()),
150 col_bits: Constant::new(C.to_bits()),
151 data_bits: Constant::new(D.to_bits()),
152 data_shift_in: Constant::new({ L - D }.to_bits()),
153 read_pending: Default::default(),
154 data_out_counter: Default::default(),
155 read_ready: Default::default(),
156 encode: Default::default(),
157 refresh_needed: Default::default(),
158 }
159 }
160}
161
162impl<const R: usize, const C: usize, const L: usize, const D: usize> Logic
163 for SDRAMBaseController<R, C, L, D>
164{
165 #[hdl_gen]
166 fn update(&mut self) {
167 dff_setup!(
168 self,
169 clock,
170 state,
171 reg_data_write,
172 reg_data_read,
173 reg_address,
174 reg_cmd_address,
175 delay_counter,
176 refresh_counter,
177 transfer_counter,
178 write_pending,
179 read_pending,
180 read_ready,
181 refresh_needed,
182 data_out_counter
183 );
184 clock!(self, clock, read_valid);
185 self.delay_counter.d.next = self.delay_counter.q.val() + 1;
186 self.refresh_counter.d.next = self.refresh_counter.q.val() + 1;
187 self.cmd.next = SDRAMCommand::NOP;
188 self.sdram.address.next = 0.into();
189 self.sdram.bank.next = 0.into();
190 self.data_out.next = self.reg_data_read.q.val();
191 self.data_out_counter.d.next =
192 self.data_out_counter.q.val() + self.read_valid.data_out.val();
193 self.data_valid.next = self.read_ready.q.val();
194 self.sdram.write_enable.next = false;
195 self.sdram.write_data.next = self.reg_data_write.q.val().get_bits::<D>(0);
196 self.read_valid.data_in.next = false;
197 self.read_valid.delay.next = self.cas_delay.val();
198 self.addr_col.next = bit_cast::<13, C>(self.reg_address.q.val().get_bits::<C>(0));
200 self.addr_row.next = bit_cast::<13, R>(
201 self.reg_address
202 .q
203 .val()
204 .get_bits::<R>(self.col_bits.val().index()),
205 );
206 self.addr_bank.next = self
207 .reg_address
208 .q
209 .val()
210 .get_bits::<2>(self.col_bits.val().index() + self.row_bits.val().index());
211 self.transfer_counter.d.next = self.transfer_counter.q.val();
212 self.busy.next = (self.state.q.val() != State::Idle)
214 | self.write_pending.q.val()
215 | self.read_pending.q.val();
216 match self.state.q.val() {
217 State::Boot => {
218 if self.delay_counter.q.val() == self.boot_delay.val() {
219 self.state.d.next = State::Precharge1;
220 self.cmd.next = SDRAMCommand::Precharge;
221 self.sdram.address.next = 0xFFF.into();
222 self.delay_counter.d.next = 0.into();
223 }
224 }
225 State::Precharge1 => {
226 if self.delay_counter.q.val() == self.t_rp.val() {
227 self.state.d.next = State::AutoRefresh1;
228 self.cmd.next = SDRAMCommand::AutoRefresh;
229 self.delay_counter.d.next = 0.into();
230 }
231 }
232 State::AutoRefresh1 => {
233 if self.delay_counter.q.val() == self.t_rfc.val() {
234 self.state.d.next = State::AutoRefresh2;
235 self.cmd.next = SDRAMCommand::AutoRefresh;
236 self.delay_counter.d.next = 0.into();
237 }
238 }
239 State::AutoRefresh2 => {
240 if self.delay_counter.q.val() == self.t_rfc.val() {
241 self.state.d.next = State::LoadModeRegister;
242 self.cmd.next = SDRAMCommand::LoadModeRegister;
243 self.sdram.address.next = self.mode_register.val();
244 self.delay_counter.d.next = 0.into();
245 }
246 }
247 State::LoadModeRegister => {
248 if self.delay_counter.q.val() == 4 {
249 self.state.d.next = State::Idle;
250 }
251 }
252 State::Idle => {
253 self.delay_counter.d.next = 0.into();
254 self.transfer_counter.d.next = 0.into();
255 if self.refresh_needed.q.val() {
256 self.cmd.next = SDRAMCommand::AutoRefresh;
258 self.state.d.next = State::Refresh;
259 self.refresh_counter.d.next = 0.into();
260 self.refresh_needed.d.next = false;
261 } else if self.read_pending.q.val() {
262 self.reg_address.d.next = self.reg_cmd_address.q.val();
263 self.state.d.next = State::IssueRead;
264 } else if self.write_pending.q.val() {
265 self.reg_address.d.next = self.reg_cmd_address.q.val();
266 self.state.d.next = State::IssueWrite;
267 }
268 }
269 State::IssueRead => {
270 self.cmd.next = SDRAMCommand::Active;
271 self.sdram.bank.next = self.addr_bank.val();
272 self.sdram.address.next = self.addr_row.val();
273 self.state.d.next = State::ReadActivate;
274 self.read_pending.d.next = false;
275 self.data_out_counter.d.next = 0.into();
276 }
277 State::IssueWrite => {
278 self.cmd.next = SDRAMCommand::Active;
279 self.sdram.bank.next = self.addr_bank.val();
280 self.sdram.address.next = self.addr_row.val();
281 self.state.d.next = State::WriteActivate;
282 self.write_pending.d.next = false;
283 self.sdram.write_enable.next = true;
284 }
285 State::Refresh => {
286 if self.delay_counter.q.val() == self.t_rfc.val() {
287 self.state.d.next = State::Idle;
288 }
289 }
290 State::ReadActivate => {
291 if self.delay_counter.q.val() == self.t_rcd.val() {
292 self.state.d.next = State::ReadCycle;
293 self.transfer_counter.d.next = 0.into();
294 }
295 }
296 State::WriteActivate => {
297 self.sdram.write_enable.next = true;
298 if self.delay_counter.q.val() == self.t_rcd.val() {
299 self.state.d.next = State::WriteCycle;
300 self.transfer_counter.d.next = 0.into();
301 }
302 }
303 State::WriteCycle => {
304 self.sdram.write_enable.next = true;
305 if self.transfer_counter.q.val() < self.max_transfer_size.val() {
306 self.sdram.bank.next = self.addr_bank.val();
307 self.sdram.address.next = self.addr_col.val();
308 self.cmd.next = SDRAMCommand::Write;
309 self.transfer_counter.d.next = self.transfer_counter.q.val() + 1;
310 self.reg_data_write.d.next =
311 self.reg_data_write.q.val() >> self.data_bits.val();
312 self.reg_address.d.next = self.reg_address.q.val() + 1;
313 } else {
314 self.delay_counter.d.next = 0.into();
315 self.state.d.next = State::Recovery;
316 }
317 }
318 State::Recovery => {
319 self.sdram.write_enable.next = true;
320 if self.delay_counter.q.val() == self.t_wr.val() {
321 self.cmd.next = SDRAMCommand::Precharge;
322 self.sdram.address.next = 0x1FFF.into();
323 self.delay_counter.d.next = 0.into();
324 self.state.d.next = State::Precharge;
325 }
326 }
327 State::Precharge => {
328 if self.delay_counter.q.val() == self.t_rp.val() {
329 self.state.d.next = State::Idle;
330 }
331 }
332 State::ReadCycle => {
333 if self.transfer_counter.q.val() < self.max_transfer_size.val() {
334 self.sdram.bank.next = self.addr_bank.val();
335 self.sdram.address.next = self.addr_col.val();
336 self.cmd.next = SDRAMCommand::Read;
337 self.transfer_counter.d.next = self.transfer_counter.q.val() + 1;
338 self.read_valid.data_in.next = true;
339 self.reg_address.d.next = self.reg_address.q.val() + 1;
340 } else {
341 self.delay_counter.d.next = 0.into();
342 self.state.d.next = State::Recovery;
343 }
344 }
345 State::Error => {}
346 _ => {
347 self.state.d.next = State::Boot;
348 }
349 }
350 self.error.next = self.state.q.val() == State::Error;
351 if self.cmd_strobe.val() & !self.read_pending.q.val() & !self.write_pending.q.val() {
353 self.reg_cmd_address.d.next = self.cmd_address.val();
354 if self.write_not_read.val() {
355 self.write_pending.d.next = true;
356 self.reg_data_write.d.next = self.data_in.val();
357 } else {
358 self.read_pending.d.next = true;
359 }
360 }
361 if self.read_valid.data_out.val() {
362 self.reg_data_read.d.next = bit_cast::<L, D>(self.sdram.read_data.val())
363 << self.data_shift_in.val()
364 | (self.reg_data_read.q.val() >> self.data_bits.val());
365 }
366 self.read_ready.d.next = !self.read_ready.q.val()
367 & (self.data_out_counter.q.val() == self.max_transfer_size.val());
368 if self.read_ready.q.val() {
369 self.data_out_counter.d.next = 0.into();
370 }
371 if self.refresh_counter.q.val() >= self.t_refresh_max.val() {
372 self.refresh_needed.d.next = true;
373 }
374 self.sdram.cs_not.next = self.encode.cs_not.val();
376 self.sdram.cas_not.next = self.encode.cas_not.val();
377 self.sdram.ras_not.next = self.encode.ras_not.val();
378 self.sdram.we_not.next = self.encode.we_not.val();
379 self.encode.cmd.next = self.cmd.val();
380 self.sdram.clk.next = self.clock.val();
381 }
382}