rust_hdl_widgets/ramrom/
rom.rs1use rust_hdl_core::prelude::*;
2use std::collections::BTreeMap;
3
4#[derive(LogicBlock)]
5pub struct ROM<D: Synth, const N: usize> {
6 pub address: Signal<In, Bits<N>>,
7 pub data: Signal<Out, D>,
8 _sim: Box<BTreeMap<Bits<N>, D>>,
9}
10
11impl<D: Synth, const N: usize> ROM<D, N> {
12 pub fn new(values: BTreeMap<Bits<N>, D>) -> Self {
13 Self {
14 address: Signal::default(),
15 data: Signal::new_with_default(D::default()),
16 _sim: Box::new(values),
17 }
18 }
19}
20
21pub fn make_btree_from_iterable<I: Iterator<Item = D>, D: Synth, const N: usize>(
22 v: I,
23) -> BTreeMap<Bits<N>, D> {
24 let mut values = BTreeMap::new();
25 for (index, val) in v.enumerate() {
26 let address: Bits<N> = index.to_bits();
27 values.insert(address, val);
28 }
29 values
30}
31
32impl<I: Iterator<Item = D>, D: Synth, const N: usize> From<I> for ROM<D, N> {
33 fn from(v: I) -> Self {
34 Self::new(make_btree_from_iterable(v))
35 }
36}
37
38impl<D: Synth, const N: usize> Logic for ROM<D, N> {
39 fn update(&mut self) {
40 self.data.next = *self._sim.get(&self.address.val()).unwrap_or(&D::default());
41 }
42
43 fn connect(&mut self) {
44 self.data.connect();
45 }
46
47 fn hdl(&self) -> Verilog {
48 let cases = self
49 ._sim
50 .iter()
51 .map(|x| {
52 format!(
53 " {}: data = {};",
54 x.0.verilog().to_string(),
55 x.1.verilog().to_string()
56 )
57 })
58 .collect::<Vec<_>>()
59 .join("\n");
60 Verilog::Custom(format!(
61 "\
62always @*
63case (address)
64 {cases}
65 default: data = {default};
66endcase
67 ",
68 cases = cases,
69 default = D::default().verilog().to_string()
70 ))
71 }
72}