Skip to main content

pretty/
pretty.rs

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    // Add the the inputs
18    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        // Instantiate a full adder for each bit
26        let fa = netlist.insert_gate_disconnected(full_adder(), format_id!("fa_{i}"));
27
28        // Connect A_i and B_i
29        fa.get_input(1).connect(a_vec[i].clone());
30        fa.get_input(2).connect(b_vec[i].clone());
31
32        // Connect with the prev carry
33        carry.connect(fa.get_input(0));
34
35        // Expose the sum
36        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            // Last full adder, expose the carry out
43            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}