Skip to main content

logicsim/circuits/
bus.rs

1use super::Wire;
2use crate::graph::*;
3
4fn mkname(name: String) -> String {
5    format!("BUS:{}", name)
6}
7
8/// Data structure that helps with managing buses, it allows you to connect &[[GateIndex]] to it as well as providing
9/// a &[[GateIndex]] to connect to other components.
10///
11/// It is basically syntactic sugar for a set of or gates.
12///
13/// # Example
14/// ```
15/// # use logicsim::{GateGraphBuilder,constant,Bus,ON};
16/// # let mut g = GateGraphBuilder::new();
17/// let input1 = constant(0x01u8);
18/// let input2 = constant(0x10u8);
19///
20/// let bus = Bus::new(&mut g, 8, "bus");
21/// bus.connect(&mut g, &input1);
22/// bus.connect(&mut g, &input2);
23///
24/// let output = g.output(bus.bits(), "result");
25///
26/// let ig = &g.init();
27/// assert_eq!(output.u8(ig), 0x11);
28/// ```
29#[derive(Debug, Clone)]
30pub struct Bus {
31    bits: Vec<GateIndex>,
32}
33impl Bus {
34    /// Returns a new [Bus] of width `width` with name `name`.
35    pub fn new<S: Into<String>>(g: &mut GateGraphBuilder, width: usize, name: S) -> Self {
36        let name = mkname(name.into());
37        Self {
38            bits: (0..width).map(|_| g.or(name.clone())).collect(),
39        }
40    }
41
42    /// Connects a &[[GateIndex]] to the bus, each bit of the output of the bus will be set to the or
43    /// of every corresponding bit in the inputs.
44    ///
45    /// # Panics
46    ///
47    /// Will panic if `other.len()` != `self.len()`. Use [connect_some](Bus::connect_some)
48    /// if this is not your desired behavior.
49    pub fn connect(&self, g: &mut GateGraphBuilder, other: &[GateIndex]) {
50        assert_eq!(
51            self.bits.len(),
52            other.len(),
53            "Use connect_some() to connect to a bus of a different width"
54        );
55        self.connect_some(g, other);
56    }
57
58    /// Connects a &[[GateIndex]] to the bus, each bit of the output of the bus will be set to the or
59    /// of every corresponding bit in the inputs.
60    ///
61    /// If there are excess bits in `other`, they won't get connected to the bus.
62    /// If there are missing bits in `other` only other.len() will be connected to the bus.
63    pub fn connect_some(&self, g: &mut GateGraphBuilder, other: &[GateIndex]) {
64        for (or, bit) in self.bits.iter().zip(other) {
65            g.dpush(*or, *bit);
66        }
67    }
68
69    /// Connects the bits of `other` to `self` and returns a clone of `self`.
70    // The signature is very intentional, one does not simply merge buses.
71    pub fn merge(&self, g: &mut GateGraphBuilder, other: Bus) -> Bus {
72        self.connect(g, other.bits());
73        self.clone()
74    }
75
76    /// Returns the width of the bus.
77    pub fn len(&self) -> usize {
78        self.bits.len()
79    }
80
81    /// Returns true if `self.len()` == 0.
82    pub fn is_empty(&self) -> bool {
83        self.bits.len() == 0
84    }
85
86    /// Returns a &[[GateIndex]] to connect to other components.
87    pub fn bits(&self) -> &[GateIndex] {
88        &self.bits
89    }
90
91    /// Returns the [GateIndex] of the `n`th bit in the bus.
92    ///
93    /// # Panics
94    ///
95    /// Will panic if `n` >=  `self.len()`.
96    pub fn bx(&self, n: usize) -> GateIndex {
97        self.bits[n]
98    }
99
100    /// Returns the [GateIndex] of the 0th bit in the bus.
101    ///
102    /// # Panics
103    ///
104    /// Will panic if `self.is_empty()`.
105    pub fn b0(&self) -> GateIndex {
106        self.bits[0]
107    }
108
109    /// Connects the bus to a series of [Wires](Wire).
110    ///
111    /// # Panics
112    ///
113    /// Will panic if `self.len()` != `other.len()`.
114    pub fn split_wires(&self, g: &mut GateGraphBuilder, other: &mut [Wire]) {
115        assert_eq!(self.len(), other.len());
116        for (bit, wire) in self.bits.iter().zip(other) {
117            wire.connect(g, *bit)
118        }
119    }
120}
121
122impl Into<Vec<GateIndex>> for Bus {
123    fn into(self) -> Vec<GateIndex> {
124        self.bits
125    }
126}