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