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
use super::constant;
use super::decoder::decoder;
use crate::{data_structures::BitIter, graph::*};
fn mkname(name: String) -> String {
format!("ROM:{}", name)
}
pub fn rom<T: Copy + 'static + Sized, S: Into<String>>(
g: &mut GateGraphBuilder,
read: GateIndex,
address: &[GateIndex],
data: &[T],
name: S,
) -> Vec<GateIndex> {
assert!(
2usize.pow(address.len() as u32) >= data.len(),
"`address` doesn't have enough bits to address every input, address bits: {} input len:{}",
address.len(),
data.len(),
);
let name = mkname(name.into());
let word_length = std::mem::size_of::<T>() * 8;
let decoded = decoder(g, address, name.clone());
let out: Vec<GateIndex> = (0..word_length).map(|_| g.or(name.clone())).collect();
for (word, d) in data.iter().zip(decoded.into_iter()) {
if BitIter::new(*word).is_zero() {
continue;
}
for (or, node) in out.iter().zip(constant(*word).into_iter()) {
let and = g.and2(d, node, name.clone());
g.dpush(*or, and);
}
}
out.into_iter()
.map(|or| g.and2(or, read, name.clone()))
.collect()
}