rust_hdl_core/
block.rs

1use crate::logic::Logic;
2use crate::probe::Probe;
3
4/// The [Block] trait is required for all circuitry that
5/// can be simulated by RustHDL.  If you want to be able
6/// to simulate a circuit, the corresponding struct must
7/// impl [Block].  Normally, this is done via the `#[derive(LogicBlock)]`
8/// construct, and you will rarely, if ever, need to
9/// impl the [Block] trait yourself.
10pub trait Block: Logic {
11    /// Connects the internal signals of the circuit - used to initialize the circuit
12    fn connect_all(&mut self);
13    /// Propogate changes from inputs to outputs within the circuit
14    fn update_all(&mut self);
15    /// Returns `true` if anything in the circuit has changed (outputs or internal state)
16    fn has_changed(&self) -> bool;
17    /// The visitor pattern - allows a circuit to be probed by a [Probe] struct.
18    fn accept(&self, name: &str, probe: &mut dyn Probe);
19}
20
21impl<B: Block> Block for Vec<B> {
22    fn connect_all(&mut self) {
23        for x in self {
24            x.connect_all();
25        }
26    }
27
28    fn update_all(&mut self) {
29        for x in self {
30            x.update_all();
31        }
32    }
33
34    fn has_changed(&self) -> bool {
35        for x in self {
36            if x.has_changed() {
37                return true;
38            }
39        }
40        false
41    }
42
43    fn accept(&self, name: &str, probe: &mut dyn Probe) {
44        for x in self.iter().enumerate() {
45            let name = format!("{}${}", name, x.0);
46            x.1.accept(&name, probe);
47        }
48    }
49}
50
51impl<B: Block, const P: usize> Block for [B; P] {
52    fn connect_all(&mut self) {
53        for x in self {
54            x.connect_all();
55        }
56    }
57
58    fn update_all(&mut self) {
59        for x in self {
60            x.update_all();
61        }
62    }
63
64    fn has_changed(&self) -> bool {
65        for x in self {
66            if x.has_changed() {
67                return true;
68            }
69        }
70        false
71    }
72
73    fn accept(&self, name: &str, probe: &mut dyn Probe) {
74        for x in self.iter().enumerate() {
75            let name = format!("{}${}", name, x.0);
76            x.1.accept(&name, probe);
77        }
78    }
79}