Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/netlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1370,7 +1370,14 @@ where
with: &DrivenNet<I>,
) -> Result<Object<I>, Error> {
let unwrapped = of.clone().unwrap().unwrap();
if Rc::strong_count(&unwrapped) > 3 {
let i = of.get_output_index();
let k = with.get_output_index();

if of.clone().unwrap() == with.clone().unwrap() {
if i == k || Rc::strong_count(&unwrapped) > 4 {
return Err(Error::DanglingReference(of.unwrap().nets().collect()));
}
} else if Rc::strong_count(&unwrapped) > 3 {
return Err(Error::DanglingReference(of.unwrap().nets().collect()));
}

Expand Down
6 changes: 1 addition & 5 deletions tests/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,7 @@ fn test_detect_cycles() {
let inverted = netlist
.insert_gate(inverter, "inst_0".into(), std::slice::from_ref(&input))
.unwrap();
assert!(
netlist
.replace_net_uses(input, &inverted.get_output(0))
.is_ok()
);
assert!(netlist.replace_net_uses(input, &inverted.into()).is_ok());

// Now there is a cycle.
// We replaced the inverter input with invert output.
Expand Down
2 changes: 1 addition & 1 deletion tests/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ fn test_replace_gate() {
.unwrap();
assert!(
netlist
.replace_net_uses(and_gate.into(), &or_gate.get_output(0))
.replace_net_uses(and_gate.into(), &or_gate.clone().into())
.is_ok()
);
assert!(netlist.clean().is_err());
Expand Down
229 changes: 228 additions & 1 deletion tests/edits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ fn and_gate() -> Gate {
Gate::new_logical("AND".into(), vec!["A".into(), "B".into()], "Y".into())
}

fn or_gate() -> Gate {
Gate::new_logical("OR".into(), vec!["A".into(), "B".into()], "Y".into())
}

fn two_out_gate() -> Gate {
Gate::new_logical_multi(
"DUP".into(),
vec!["I".into()],
vec!["O0".into(), "O1".into()],
)
}

fn get_simple_example() -> Rc<GateNetlist> {
let netlist = Netlist::new("example".to_string());

Expand Down Expand Up @@ -87,7 +99,7 @@ fn test_replace2() {
// This errors, because input is not safe to delete. No replace is done.
assert!(
netlist
.replace_net_uses(input.clone(), &inverted.get_output(0))
.replace_net_uses(input.clone(), &inverted.clone().into())
.is_err()
);
inverted.find_input(&"I".into()).unwrap().connect(input);
Expand Down Expand Up @@ -119,3 +131,218 @@ fn test_replace2() {
endmodule\n"
);
}
// Testing edits for replace_net_uses using single and multiple output netrefs that have a
// DrivenNet that is fed as an argument
// TEST 1: SINGLE , SINGLE
// TEST2: SINGLE, MULTIPLE
// TEST3 MULTIPLE, SINGLE
// TEST4 MULTOPLE, MULTIPLE

#[test]
fn test_replace_single_single_v2() {
let netlist = Netlist::new("example".into());
let a = netlist.insert_input("a".into());
let b = netlist.insert_input("b".into());
let and_inst = netlist
.insert_gate(and_gate(), "and_0".into(), &[a.clone(), b.clone()])
.unwrap();
let or_inst = netlist
.insert_gate(or_gate(), "or_0".into(), &[a.clone(), b.clone()])
.unwrap();
let and_out = and_inst.get_output(0);
drop(and_inst);
assert!(
netlist
.replace_net_uses(and_out, &or_inst.clone().into())
.is_ok()
);
or_inst.get_output(0).expose_with_name("y".into());
assert!(netlist.verify().is_ok());
assert_verilog_eq!(
netlist.to_string(),
"module example (
a,
b,
y
);
input a;
wire a;
input b;
wire b;
output y;
wire y;
wire and_0_Y;
wire or_0_Y;
AND and_0 (
.A(a),
.B(b),
.Y(and_0_Y)
);
OR or_0 (
.A(a),
.B(b),
.Y(or_0_Y)
);
assign y = or_0_Y;
endmodule"
);
}
#[test]
fn test_replace_single_multiple() {
let netlist = Netlist::new("example".into());
let a = netlist.insert_input("a".into());
let b = netlist.insert_input("b".into());

let and_inst = netlist
.insert_gate(and_gate(), "and_0".into(), &[a.clone(), b.clone()])
.unwrap();

let dup = netlist
.insert_gate(two_out_gate(), "dup0".into(), &[a.clone()])
.unwrap();

dup.get_output(1).expose_with_name("y".into());

let and_out = and_inst.get_output(0);
let dup_out1 = dup.get_output(1);
drop(dup);
netlist
.replace_net_uses(dup_out1, &and_out.clone())
.unwrap();
assert!(netlist.verify().is_ok());
assert_verilog_eq!(
netlist.to_string(),
"module example (
a,
b,
y
);
input a;
wire a;
input b;
wire b;
output y;
wire y;
wire and_0_Y;
wire dup0_O0;
wire dup0_O1;
AND and_0 (
.A(a),
.B(b),
.Y(and_0_Y)
);
DUP dup0 (
.I(a),
.O0(dup0_O0),
.O1(dup0_O1)
);
assign y = and_0_Y;
endmodule"
);
}

#[test]
fn test_replace_multiple_single() {
let netlist = Netlist::new("example".into());
let a = netlist.insert_input("a".into());
let b = netlist.insert_input("b".into());

let and_inst = netlist
.insert_gate(and_gate(), "and_0".into(), &[a.clone(), b.clone()])
.unwrap();

let dup = netlist
.insert_gate(two_out_gate(), "dup0".into(), &[a.clone()])
.unwrap();

and_inst.get_output(0).expose_with_name("y".into());

let and_out = and_inst.get_output(0);
let dup_out0 = dup.get_output(0);
drop(and_inst);
netlist
.replace_net_uses(and_out, &dup_out0.clone())
.unwrap(); // todo: ask why
assert!(netlist.verify().is_ok());
assert_verilog_eq!(
netlist.to_string(),
"module example (
a,
b,
y
);
input a;
wire a;
input b;
wire b;
output y;
wire y;
wire and_0_Y;
wire dup0_O0;
wire dup0_O1;
AND and_0 (
.A(a),
.B(b),
.Y(and_0_Y)
);
DUP dup0 (
.I(a),
.O0(dup0_O0),
.O1(dup0_O1)
);
assign y = dup0_O0;
endmodule"
);
}

#[test]
fn test_replace_multiple_multiple() {
let netlist = Netlist::new("example".into());
let a = netlist.insert_input("a".into());

let dup1 = netlist
.insert_gate(two_out_gate(), "dup1".into(), &[a.clone()])
.unwrap();

let dup2 = netlist
.insert_gate(two_out_gate(), "dup2".into(), &[a.clone()])
.unwrap();

dup2.get_output(1).expose_with_name("y".into());
let dup2_out0 = dup2.get_output(0);
let dup2_out1 = dup2.get_output(1);

drop(dup1);
drop(dup2);
netlist.replace_net_uses(dup2_out1, &dup2_out0).unwrap();
assert!(netlist.verify().is_ok());
assert_verilog_eq!(
netlist.to_string(),
"module example (
a,
y
);
input a;
wire a;
output y;
wire y;
wire dup1_O0;
wire dup1_O1;
wire dup2_O0;
wire dup2_O1;
DUP dup1 (
.I(a),
.O0(dup1_O0),
.O1(dup1_O1)
);
DUP dup2 (
.I(a),
.O0(dup2_O0),
.O1(dup2_O1)
);
assign y = dup2_O0;
endmodule"
);
}

// Add test if you want
Loading