virt_ic/chip/gates/
nand.rs

1use std::time::Duration;
2
3use crate::{
4    chip::{ChipBuilder, ChipRunner, ChipSet, Pin, PinId, PinType},
5    generate_chip, State,
6};
7
8/// # A chip with 4 bundled "NAND" gates
9///
10/// # Diagram
11/// ```
12///           ---__---
13///       A --|1   14|-- VCC
14///       B --|2   13|-- E
15///  !(A&B) --|3   12|-- F
16///       C --|4   11|-- !(E&F)
17///       D --|5   10|-- G
18///  !(C&D) --|6    9|-- H
19///     GND --|7    8|-- !(G&H)
20///           --------
21/// ```
22#[derive(Debug, Clone, Default)]
23#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
24pub struct NandGate {
25    pub vcc: Pin,
26    pub gnd: Pin,
27    pub a: Pin,
28    pub b: Pin,
29    pub ab: Pin,
30    pub c: Pin,
31    pub d: Pin,
32    pub cd: Pin,
33    pub e: Pin,
34    pub f: Pin,
35    pub ef: Pin,
36    pub g: Pin,
37    pub h: Pin,
38    pub gh: Pin,
39}
40
41impl NandGate {
42    pub const VCC: PinId = 14;
43    pub const GND: PinId = 7;
44    pub const A: PinId = 1;
45    pub const B: PinId = 2;
46    pub const AB: PinId = 3;
47    pub const C: PinId = 4;
48    pub const D: PinId = 5;
49    pub const CD: PinId = 6;
50    pub const E: PinId = 13;
51    pub const F: PinId = 12;
52    pub const EF: PinId = 11;
53    pub const G: PinId = 10;
54    pub const H: PinId = 9;
55    pub const GH: PinId = 8;
56}
57
58impl ChipBuilder<ChipSet> for NandGate {
59    fn build() -> ChipSet {
60        ChipSet::NandGate(NandGate {
61            vcc: Pin::from(PinType::Input),
62            gnd: Pin::from(PinType::Output),
63            a: Pin::from(PinType::Input),
64            b: Pin::from(PinType::Input),
65            ab: Pin::from(PinType::Output),
66            c: Pin::from(PinType::Input),
67            d: Pin::from(PinType::Input),
68            cd: Pin::from(PinType::Output),
69            e: Pin::from(PinType::Input),
70            f: Pin::from(PinType::Input),
71            ef: Pin::from(PinType::Output),
72            g: Pin::from(PinType::Input),
73            h: Pin::from(PinType::Input),
74            gh: Pin::from(PinType::Output),
75        })
76    }
77}
78
79generate_chip!(
80    NandGate,
81    vcc: NandGate::VCC,
82    gnd: NandGate::GND,
83    a: NandGate::A,
84    b: NandGate::B,
85    ab: NandGate::AB,
86    c: NandGate::C,
87    d: NandGate::D,
88    cd: NandGate::CD,
89    e: NandGate::E,
90    f: NandGate::F,
91    ef: NandGate::EF,
92    g: NandGate::G,
93    h: NandGate::H,
94    gh: NandGate::GH
95);
96
97impl ChipRunner for NandGate {
98    fn run(&mut self, _: Duration) {
99        if self.vcc.state.as_logic(3.3) == State::High {
100            self.gnd.state = State::Low;
101            self.ab.state = State::from(
102                !(self.a.state.as_logic(3.3).into() && self.b.state.as_logic(3.3).into()),
103            );
104            self.cd.state = State::from(
105                !(self.c.state.as_logic(3.3).into() && self.d.state.as_logic(3.3).into()),
106            );
107            self.ef.state = State::from(
108                !(self.e.state.as_logic(3.3).into() && self.f.state.as_logic(3.3).into()),
109            );
110            self.gh.state = State::from(
111                !(self.g.state.as_logic(3.3).into() && self.h.state.as_logic(3.3).into()),
112            );
113        }
114    }
115}
116
117/// # A chip with 3 bundled "3-Input AND" gates
118///
119/// # Diagram
120/// ```
121///            ---__---
122///        A --|1   14|-- VCC
123///        B --|2   13|-- C
124///        D --|3   12|-- !(A&B&C)
125///        E --|4   11|-- G
126///        F --|5   10|-- H
127/// !(D&E&F) --|6    9|-- I
128///      GND --|7    8|-- !(G&H&I)
129///            --------
130/// ```
131#[derive(Debug, Clone, Default)]
132#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
133pub struct ThreeInputNandGate {
134    pub vcc: Pin,
135    pub gnd: Pin,
136    pub a: Pin,
137    pub b: Pin,
138    pub c: Pin,
139    pub abc: Pin,
140    pub d: Pin,
141    pub e: Pin,
142    pub f: Pin,
143    pub def: Pin,
144    pub g: Pin,
145    pub h: Pin,
146    pub i: Pin,
147    pub ghi: Pin,
148}
149
150impl ThreeInputNandGate {
151    pub const VCC: PinId = 14;
152    pub const GND: PinId = 7;
153    pub const A: PinId = 1;
154    pub const B: PinId = 2;
155    pub const C: PinId = 13;
156    pub const ABC: PinId = 12;
157    pub const D: PinId = 3;
158    pub const E: PinId = 4;
159    pub const F: PinId = 5;
160    pub const DEF: PinId = 6;
161    pub const G: PinId = 11;
162    pub const H: PinId = 10;
163    pub const I: PinId = 9;
164    pub const GHI: PinId = 8;
165}
166
167impl ChipBuilder<ChipSet> for ThreeInputNandGate {
168    fn build() -> ChipSet {
169        ChipSet::ThreeInputNandGate(ThreeInputNandGate {
170            vcc: Pin::from(PinType::Input),
171            gnd: Pin::from(PinType::Output),
172            a: Pin::from(PinType::Input),
173            b: Pin::from(PinType::Input),
174            c: Pin::from(PinType::Input),
175            abc: Pin::from(PinType::Output),
176            d: Pin::from(PinType::Input),
177            e: Pin::from(PinType::Input),
178            f: Pin::from(PinType::Input),
179            def: Pin::from(PinType::Output),
180            g: Pin::from(PinType::Input),
181            h: Pin::from(PinType::Input),
182            i: Pin::from(PinType::Input),
183            ghi: Pin::from(PinType::Output),
184        })
185    }
186}
187
188generate_chip!(
189    ThreeInputNandGate,
190    vcc: ThreeInputNandGate::VCC,
191    gnd: ThreeInputNandGate::GND,
192    a: ThreeInputNandGate::A,
193    b: ThreeInputNandGate::B,
194    c: ThreeInputNandGate::C,
195    abc: ThreeInputNandGate::ABC,
196    d: ThreeInputNandGate::D,
197    e: ThreeInputNandGate::E,
198    f: ThreeInputNandGate::F,
199    def: ThreeInputNandGate::DEF,
200    g: ThreeInputNandGate::G,
201    h: ThreeInputNandGate::H,
202    i: ThreeInputNandGate::I,
203    ghi: ThreeInputNandGate::GHI
204);
205
206impl ChipRunner for ThreeInputNandGate {
207    fn run(&mut self, _: Duration) {
208        if self.vcc.state.as_logic(3.3) == State::High {
209            self.gnd.state = State::Low;
210            self.abc.state = State::from(
211                !(self.a.state.as_logic(3.3).into()
212                    && self.b.state.as_logic(3.3).into()
213                    && self.c.state.as_logic(3.3).into()),
214            );
215            self.def.state = State::from(
216                !(self.d.state.as_logic(3.3).into()
217                    && self.e.state.as_logic(3.3).into()
218                    && self.f.state.as_logic(3.3).into()),
219            );
220            self.ghi.state = State::from(
221                !(self.g.state.as_logic(3.3).into()
222                    && self.h.state.as_logic(3.3).into()
223                    && self.i.state.as_logic(3.3).into()),
224            );
225        }
226    }
227}