1use safety_net::format_id;
2use safety_net::{DrivenNet, Gate, Netlist};
3
4#[allow(dead_code)]
5fn full_adder() -> Gate {
6 Gate::new_logical_multi(
7 "FA".into(),
8 vec!["CIN".into(), "A".into(), "B".into()],
9 vec!["S".into(), "COUT".into()],
10 )
11}
12
13#[allow(dead_code)]
14fn ripple_adder() -> Netlist<Gate> {
15 let netlist = Netlist::new("ripple_adder".to_string());
16 let bitwidth = 4;
17
18 let a_vec = netlist.insert_input_escaped_logic_bus("a".to_string(), bitwidth);
20 let b_vec = netlist.insert_input_escaped_logic_bus("b".to_string(), bitwidth);
21 let mut carry: DrivenNet<Gate> = netlist.insert_input("cin".into());
22
23 for i in 0..bitwidth {
24 let fa = netlist.insert_gate_disconnected(full_adder(), format_id!("fa_{i}"));
26
27 fa.get_input(1).connect(a_vec[i].clone());
29 fa.get_input(2).connect(b_vec[i].clone());
30
31 carry.connect(fa.get_input(0));
33
34 fa.expose_net(&fa.get_net(0)).unwrap();
36
37 carry = fa.get_output(1);
38
39 if i == bitwidth - 1 {
40 fa.get_net_mut(1).set_identifier("cout".into());
42 fa.expose_net(&fa.get_net(1)).unwrap();
43 }
44 }
45
46 netlist.reclaim().unwrap()
47}
48
49fn main() {
50 #[cfg(feature = "graph")]
51 {
52 let netlist = ripple_adder();
53 eprintln!("{netlist}");
54 println!("{}", netlist.dot_string().unwrap());
55 }
56}