Skip to content

Commit 60f62db

Browse files
authored
Fix replace (#52)
1 parent 873a0f6 commit 60f62db

File tree

5 files changed

+38
-18
lines changed

5 files changed

+38
-18
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "safety-net"
3-
version = "0.2.7"
3+
version = "0.2.8"
44
edition = "2024"
55
license = "MIT OR Apache-2.0"
66

src/netlist.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -798,16 +798,16 @@ where
798798
///
799799
/// # Panics
800800
///
801-
/// Panics if either `self` or `other` is a multi-output circuit node.
801+
/// Panics if either `self` is a multi-output circuit node.
802802
/// Panics if the weak reference to the netlist is lost.
803-
pub fn replace_uses_with(self, other: &Self) -> Result<Object<I>, Error> {
803+
pub fn replace_uses_with(self, other: &DrivenNet<I>) -> Result<Object<I>, Error> {
804804
let netlist = self
805805
.netref
806806
.borrow()
807807
.owner
808808
.upgrade()
809809
.expect("NetRef is unlinked from netlist");
810-
netlist.replace_net_uses(self, other)
810+
netlist.replace_net_uses(self.into(), other)
811811
}
812812

813813
/// Clears the attribute with the given key on this circuit node.
@@ -1364,17 +1364,25 @@ where
13641364
}
13651365

13661366
/// Replaces the uses of a circuit node with another circuit node. The [Object] stored at `of` is returned.
1367-
/// Panics if `of` and `with` are not single-output nodes.
1368-
pub fn replace_net_uses(&self, of: NetRef<I>, with: &NetRef<I>) -> Result<Object<I>, Error> {
1369-
let unwrapped = of.clone().unwrap();
1367+
pub fn replace_net_uses(
1368+
&self,
1369+
of: DrivenNet<I>,
1370+
with: &DrivenNet<I>,
1371+
) -> Result<Object<I>, Error> {
1372+
let unwrapped = of.clone().unwrap().unwrap();
13701373
if Rc::strong_count(&unwrapped) > 3 {
1371-
return Err(Error::DanglingReference(of.nets().collect()));
1374+
return Err(Error::DanglingReference(of.unwrap().nets().collect()));
13721375
}
13731376

1374-
let old_tag: DrivenNet<I> = of.clone().into();
1375-
let old_index = old_tag.get_operand();
1376-
let new_tag: DrivenNet<I> = with.clone().into();
1377-
let new_index = new_tag.get_operand();
1377+
let old_index = of.get_operand();
1378+
1379+
if let Some(v) = self.outputs.borrow().get(&old_index)
1380+
&& *v == *of.as_net()
1381+
{
1382+
return Err(Error::NonuniqueNets(vec![v.clone()]));
1383+
}
1384+
1385+
let new_index = with.get_operand();
13781386
let objects = self.objects.borrow();
13791387
for oref in objects.iter() {
13801388
let operands = &mut oref.borrow_mut().operands;
@@ -1396,7 +1404,7 @@ where
13961404
self.outputs.borrow_mut().insert(new_index, v.clone());
13971405
}
13981406

1399-
Ok(of.unwrap().borrow().get().clone())
1407+
Ok(of.unwrap().unwrap().borrow().get().clone())
14001408
}
14011409
}
14021410

tests/analysis.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ fn test_detect_cycles() {
4141
let inverted = netlist
4242
.insert_gate(inverter, "inst_0".into(), std::slice::from_ref(&input))
4343
.unwrap();
44-
assert!(netlist.replace_net_uses(input.unwrap(), &inverted).is_ok());
44+
assert!(
45+
netlist
46+
.replace_net_uses(input, &inverted.get_output(0))
47+
.is_ok()
48+
);
4549

4650
// Now there is a cycle.
4751
// We replaced the inverter input with invert output.

tests/api.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,11 @@ fn test_replace_gate_bad() {
363363
let or_gate = netlist
364364
.insert_gate(or_gate, "inst_0".into(), &inputs)
365365
.unwrap();
366-
assert!(netlist.replace_net_uses(and_gate, &or_gate).is_ok());
366+
assert!(
367+
netlist
368+
.replace_net_uses(and_gate.into(), &or_gate.into())
369+
.is_ok()
370+
);
367371
// Both the AND and OR gate are driving the same wire name (subtle).
368372
// The instance name has to be different, or the user has to manualy rename it.
369373
// Will need to consider how to make this more user-friendly.
@@ -379,7 +383,11 @@ fn test_replace_gate() {
379383
let or_gate = netlist
380384
.insert_gate(or_gate, "inst_0".into(), &inputs)
381385
.unwrap();
382-
assert!(netlist.replace_net_uses(and_gate, &or_gate).is_ok());
386+
assert!(
387+
netlist
388+
.replace_net_uses(and_gate.into(), &or_gate.get_output(0))
389+
.is_ok()
390+
);
383391
assert!(netlist.clean().is_err());
384392
or_gate.set_instance_name("inst_1".into());
385393
or_gate.as_net_mut().set_identifier("inst_1_Y".into());

tests/edits.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ fn test_replace() {
4848
let inverted = netlist
4949
.insert_gate(inverter, "inst_0".into(), std::slice::from_ref(&input))
5050
.unwrap();
51-
assert!(netlist.replace_net_uses(input.unwrap(), &inverted).is_ok());
51+
assert!(netlist.replace_net_uses(input, &inverted.into()).is_ok());
5252
assert_verilog_eq!(
5353
netlist.to_string(),
5454
"module example (
@@ -87,7 +87,7 @@ fn test_replace2() {
8787
// This errors, because input is not safe to delete. No replace is done.
8888
assert!(
8989
netlist
90-
.replace_net_uses(input.clone().unwrap(), &inverted)
90+
.replace_net_uses(input.clone(), &inverted.get_output(0))
9191
.is_err()
9292
);
9393
inverted.find_input(&"I".into()).unwrap().connect(input);

0 commit comments

Comments
 (0)