rust_hdl_widgets/ramrom/
sync_rom.rs

1use crate::ramrom::rom::make_btree_from_iterable;
2use rust_hdl_core::prelude::*;
3use rust_hdl_core::timing::TimingInfo;
4use std::collections::BTreeMap;
5
6#[derive(LogicBlock)]
7pub struct SyncROM<D: Synth, const N: usize> {
8    pub address: Signal<In, Bits<N>>,
9    pub clock: Signal<In, Clock>,
10    pub data: Signal<Out, D>,
11    _sim: Box<BTreeMap<Bits<N>, D>>,
12}
13
14impl<D: Synth, const N: usize> SyncROM<D, N> {
15    pub fn new(values: BTreeMap<Bits<N>, D>) -> Self {
16        Self {
17            address: Signal::default(),
18            data: Signal::new_with_default(D::default()),
19            clock: Signal::default(),
20            _sim: Box::new(values),
21        }
22    }
23}
24
25impl<I: Iterator<Item = D>, D: Synth, const N: usize> From<I> for SyncROM<D, N> {
26    fn from(v: I) -> Self {
27        Self::new(make_btree_from_iterable(v))
28    }
29}
30
31impl<D: Synth, const N: usize> Logic for SyncROM<D, N> {
32    fn update(&mut self) {
33        if self.clock.pos_edge() {
34            self.data.next = *self._sim.get(&self.address.val()).unwrap_or(&D::default());
35        }
36    }
37
38    fn connect(&mut self) {
39        self.data.connect();
40    }
41
42    fn hdl(&self) -> Verilog {
43        let init = self
44            ._sim
45            .iter()
46            .map(|x| {
47                format!(
48                    "mem[{}] = {}",
49                    x.0.verilog().to_string(),
50                    x.1.verilog().to_string()
51                )
52            })
53            .collect::<Vec<_>>()
54            .join(";\n");
55        Verilog::Custom(format!(
56            "\
57reg[{D}:0] mem [{Acount}:0];
58
59initial begin
60{init};
61end
62
63always @(posedge clock) begin
64   data <= mem[address];
65end",
66            D = D::BITS - 1,
67            Acount = (1 << N) - 1,
68            init = init
69        ))
70    }
71    fn timing(&self) -> Vec<TimingInfo> {
72        vec![TimingInfo {
73            name: "sync_rom".to_string(),
74            clock: "clock".to_string(),
75            inputs: vec!["address".to_string()],
76            outputs: vec!["data".to_string()],
77        }]
78    }
79}