rust_hdl_widgets/sdram/
buffer.rs

1use crate::{dff::DFF, dff_setup, sdram::*};
2use rust_hdl_core::prelude::*;
3
4#[derive(LogicBlock, Clone, Default)]
5pub struct SDRAMOnChipBuffer<const D: usize> {
6    pub buf_in: SDRAMDevice<D>,
7    pub buf_out: SDRAMDriver<D>,
8    we_not_flop: DFF<Bit>,
9    cas_not_flop: DFF<Bit>,
10    ras_not_flop: DFF<Bit>,
11    cs_not_flop: DFF<Bit>,
12    bank_flop: DFF<Bits<2>>,
13    address_flop: DFF<Bits<13>>,
14    write_flop: DFF<Bits<D>>,
15    read_flop: DFF<Bits<D>>,
16    clock: Signal<Local, Clock>,
17}
18
19impl<const D: usize> Logic for SDRAMOnChipBuffer<D> {
20    #[hdl_gen]
21    fn update(&mut self) {
22        self.clock.next = self.buf_in.clk.val();
23        dff_setup!(
24            self,
25            clock,
26            we_not_flop,
27            cas_not_flop,
28            ras_not_flop,
29            cs_not_flop,
30            bank_flop,
31            address_flop,
32            write_flop,
33            read_flop
34        );
35        // Connect up the flop inputs
36        self.we_not_flop.d.next = self.buf_in.we_not.val();
37        self.cas_not_flop.d.next = self.buf_in.cas_not.val();
38        self.ras_not_flop.d.next = self.buf_in.ras_not.val();
39        self.cs_not_flop.d.next = self.buf_in.cs_not.val();
40        self.bank_flop.d.next = self.buf_in.bank.val();
41        self.address_flop.d.next = self.buf_in.address.val();
42        self.write_flop.d.next = self.buf_in.write_data.val();
43        self.read_flop.d.next = self.buf_out.read_data.val();
44        // Connect up the flop outputs
45        self.buf_out.we_not.next = self.we_not_flop.q.val();
46        self.buf_out.cas_not.next = self.cas_not_flop.q.val();
47        self.buf_out.ras_not.next = self.ras_not_flop.q.val();
48        self.buf_out.cs_not.next = self.cs_not_flop.q.val();
49        self.buf_out.bank.next = self.bank_flop.q.val();
50        self.buf_out.address.next = self.address_flop.q.val();
51        self.buf_out.write_enable.next = self.buf_in.write_enable.val();
52        self.buf_in.read_data.next = self.read_flop.q.val();
53        self.buf_out.write_data.next = self.write_flop.q.val();
54        // Forward the clock
55        self.buf_out.clk.next = self.buf_in.clk.val(); // FIXME - clock was inverted here...
56    }
57}
58
59#[test]
60fn test_buffer_synthesizes() {
61    let mut uut = TopWrap::new(SDRAMOnChipBuffer::<16>::default());
62    uut.uut.buf_in.link_connect_dest();
63    uut.uut.buf_out.link_connect_dest();
64    uut.connect_all();
65    yosys_validate("sdram_buffer", &generate_verilog(&uut)).unwrap();
66}