1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use crate::{FullAdder, HalfAdder, Signal16, Unit};
#[derive(Default)]
pub struct Add16 {
a: Signal16,
b: Signal16,
out: Signal16,
halfadder: HalfAdder,
fulladders: [FullAdder; 15],
}
impl Add16 {
pub fn sim(&mut self, a: Signal16, b: Signal16) -> Signal16 {
self.a = a;
self.b = b;
self.eval();
self.out
}
}
impl Unit for Add16 {
fn eval(&mut self) {
let (mut curr_sum, mut curr_carry) = self
.halfadder
.sim(self.a.get(0..1).into(), self.b.get(0..1).into());
self.out.set(0, curr_sum);
for i in 1..16 {
let fulladder = &mut self.fulladders[i - 1];
(curr_sum, curr_carry) = fulladder.sim(
self.a.get(i..i + 1).into(),
self.b.get(i..i + 1).into(),
curr_carry,
);
self.out.set(i, curr_sum);
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn run() {
let mut add = Add16::default();
add.eval();
assert_eq!(add.out, Signal16::FALSE);
add.a = Signal16::FALSE;
add.b = Signal16::TRUE;
add.eval();
assert_eq!(add.out, add.b);
add.a = Signal16::TRUE;
add.b = Signal16::TRUE;
add.eval();
assert_eq!(add.out, Signal16::from(0b1111111111111110u16));
add.a = Signal16::from(0b1010101010101010u16);
add.b = Signal16::from(0b0101010101010101i16);
add.eval();
assert_eq!(add.out, Signal16::TRUE);
add.a = Signal16::from(0b0011110011000011i16);
add.b = Signal16::from(0b0000111111110000i16);
add.eval();
assert_eq!(add.out, Signal16::from(0b0100110010110011i16));
add.a = Signal16::from(0b0001001000110100i16);
add.b = Signal16::from(0b1001100001110110u16);
add.eval();
assert_eq!(add.out, Signal16::from(0b1010101010101010u16));
}
}