connections/
connections.rs

1#[cfg(feature = "graph")]
2use safety_net::MultiDiGraph;
3use safety_net::format_id;
4use safety_net::{DrivenNet, Gate, Netlist};
5
6#[allow(dead_code)]
7fn full_adder() -> Gate {
8    Gate::new_logical_multi(
9        "FA".into(),
10        vec!["CIN".into(), "A".into(), "B".into()],
11        vec!["S".into(), "COUT".into()],
12    )
13}
14
15#[allow(dead_code)]
16fn ripple_adder() -> Netlist<Gate> {
17    let netlist = Netlist::new("ripple_adder".to_string());
18    let bitwidth = 4;
19
20    // Add the the inputs
21    let a_vec = netlist.insert_input_escaped_logic_bus("a".to_string(), bitwidth);
22    let b_vec = netlist.insert_input_escaped_logic_bus("b".to_string(), bitwidth);
23    let mut carry: DrivenNet<Gate> = netlist.insert_input("cin".into());
24
25    for i in 0..bitwidth {
26        // Instantiate a full adder for each bit
27        let fa = netlist.insert_gate_disconnected(full_adder(), format_id!("fa_{i}"));
28
29        // Connect A_i and B_i
30        fa.get_input(1).connect(a_vec[i].clone());
31        fa.get_input(2).connect(b_vec[i].clone());
32
33        // Connect with the prev carry
34        carry.connect(fa.get_input(0));
35
36        // Expose the sum
37        fa.expose_net(&fa.get_net(0)).unwrap();
38
39        carry = fa.get_output(1);
40
41        if i == bitwidth - 1 {
42            // Last full adder, expose the carry out
43            fa.get_net_mut(1).set_identifier("cout".into());
44            fa.expose_net(&fa.get_net(1)).unwrap();
45        }
46    }
47
48    netlist.reclaim().unwrap()
49}
50
51fn main() {
52    #[cfg(feature = "graph")]
53    {
54        let netlist = ripple_adder();
55        eprintln!("{netlist}");
56        let analysis = netlist.get_analysis::<MultiDiGraph<_>>().unwrap();
57        let graph = analysis.get_graph();
58        let dot = petgraph::dot::Dot::with_config(graph, &[]);
59        println!("{dot}");
60    }
61}