Skip to main content

connections/
connections.rs

1#[cfg(feature = "graph")]
2use safety_net::graph::MultiDiGraph;
3use safety_net::{DrivenNet, Gate, Identifier, Netlist, format_id};
4
5#[allow(dead_code)]
6fn full_adder() -> Gate {
7    Gate::new_logical_multi(
8        "FA".into(),
9        vec!["CIN".into(), "A".into(), "B".into()],
10        vec!["S".into(), "COUT".into()],
11    )
12}
13
14#[allow(dead_code)]
15fn ripple_adder() -> Netlist<Gate> {
16    let netlist = Netlist::new("ripple_adder".to_string());
17    let bitwidth = 4;
18
19    // Add the the inputs
20    let a_vec = netlist.insert_input_logic_bus("a".to_string(), bitwidth);
21    let b_vec = netlist.insert_input_logic_bus("b".to_string(), bitwidth);
22    let s_vec = Identifier::new_bus("s".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.get_output(0).expose_with_name(s_vec[i].clone());
38
39        carry = fa.get_output(1);
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        let analysis = netlist.get_analysis::<MultiDiGraph<_>>().unwrap();
56        let graph = analysis.get_graph();
57        let dot = petgraph::dot::Dot::with_config(graph, &[]);
58        println!("{dot}");
59    }
60}