Merge pull request #26 from antmicro/net_attr_fix
Reworked net attribute retrieval
diff --git a/tests/net_attr/README.rst b/tests/net_attr/README.rst
new file mode 100644
index 0000000..d0d98ed
--- /dev/null
+++ b/tests/net_attr/README.rst
@@ -0,0 +1,4 @@
+Test for handling nets consisting of multiple wires
++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+This test verifies correct handling of nets that pass through multiple wires. In such cases Yosys assigns multiple names to that net.
\ No newline at end of file
diff --git a/tests/net_attr/child/child.model.xml b/tests/net_attr/child/child.model.xml
new file mode 100644
index 0000000..90cfeb8
--- /dev/null
+++ b/tests/net_attr/child/child.model.xml
@@ -0,0 +1,10 @@
+<models xmlns:xi="http://www.w3.org/2001/XInclude">
+ <model name="CHILD">
+ <input_ports>
+ <port name="I"/>
+ </input_ports>
+ <output_ports>
+ <port name="O"/>
+ </output_ports>
+ </model>
+</models>
diff --git a/tests/net_attr/child/child.pb_type.xml b/tests/net_attr/child/child.pb_type.xml
new file mode 100644
index 0000000..0cba455
--- /dev/null
+++ b/tests/net_attr/child/child.pb_type.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0' encoding='utf-8'?>
+<pb_type xmlns:xi="http://www.w3.org/2001/XInclude" name="CHILD" num_pb="1">
+ <blif_model>.subckt CHILD</blif_model>
+ <input name="I" num_pins="1"/>
+ <output name="O" num_pins="1"/>
+</pb_type>
diff --git a/tests/net_attr/child/child.sim.v b/tests/net_attr/child/child.sim.v
new file mode 100644
index 0000000..e09db94
--- /dev/null
+++ b/tests/net_attr/child/child.sim.v
@@ -0,0 +1,6 @@
+module CHILD(
+ input wire I,
+ output wire O
+);
+
+endmodule
diff --git a/tests/net_attr/golden.model.xml b/tests/net_attr/golden.model.xml
new file mode 100644
index 0000000..0d2461a
--- /dev/null
+++ b/tests/net_attr/golden.model.xml
@@ -0,0 +1,3 @@
+<models xmlns:xi="http://www.w3.org/2001/XInclude">
+ <xi:include href="./child/child.model.xml" xpointer="xpointer(models/child::node())"/>
+</models>
diff --git a/tests/net_attr/golden.pb_type.xml b/tests/net_attr/golden.pb_type.xml
new file mode 100644
index 0000000..354b299
--- /dev/null
+++ b/tests/net_attr/golden.pb_type.xml
@@ -0,0 +1,19 @@
+<?xml version='1.0' encoding='utf-8'?>
+<pb_type xmlns:xi="http://www.w3.org/2001/XInclude" name="PARENT" num_pb="1">
+ <input name="I" num_pins="1"/>
+ <output name="O" num_pins="1"/>
+ <pb_type name="child" num_pb="1">
+ <!--old_name CHILD-->
+ <xi:include href="./child/child.pb_type.xml" xpointer="xpointer(pb_type/child::node())"/>
+ </pb_type>
+ <interconnect>
+ <direct>
+ <port name="I" type="input"/>
+ <port from="child" name="I" type="output"/>
+ </direct>
+ <direct>
+ <port from="child" name="O" type="input"/>
+ <port name="O" type="output"/>
+ </direct>
+ </interconnect>
+</pb_type>
diff --git a/tests/net_attr/parent.sim.v b/tests/net_attr/parent.sim.v
new file mode 100644
index 0000000..599456a
--- /dev/null
+++ b/tests/net_attr/parent.sim.v
@@ -0,0 +1,15 @@
+`include "./child/child.sim.v"
+
+module PARENT(
+ input wire I,
+ output wire O
+);
+
+ wire hop1 = I;
+
+ CHILD child (
+ .I(hop1),
+ .O(O)
+ );
+
+endmodule
diff --git a/v2x/vlog_to_pbtype.py b/v2x/vlog_to_pbtype.py
index cef2102..f981113 100755
--- a/v2x/vlog_to_pbtype.py
+++ b/v2x/vlog_to_pbtype.py
@@ -212,7 +212,7 @@
smod = yj.module(sink_type)
potential_attrs.append(filter_src(smod.port_attrs(sink_pin)))
- net_attrs = filter_src(mod.net_attrs(mod.net_name(netid)))
+ net_attrs = filter_src(mod.net_attrs_by_netid(netid))
copy_attrs(net_attrs, potential_attrs)
return net_attrs
diff --git a/v2x/yosys/json.py b/v2x/yosys/json.py
index 7278773..93a32da 100755
--- a/v2x/yosys/json.py
+++ b/v2x/yosys/json.py
@@ -273,10 +273,49 @@
for n, props in self.data["netnames"].items():
if netid in props['bits']:
names.append(n)
+ # FIXME: This fails when there are two wires with different names
+ # connected to the same netid (yes, that's possible). Which name
+ # should be returned in that case ?
if len(names) != 1:
raise KeyError("Net id {} not found".format(netid))
return names[0]
+ def net_attrs_by_netid(self, netid):
+ """
+ Returns attributes of a given netid. Raises RuntimeError if the same
+ attribute is defined for two or more wires belonging to the same net.
+ The attribute 'src' is an exception, 'src' strings are concatenated
+ when defined for more than one wire.
+
+ Returns dict:
+ -------
+ netid : int
+ """
+
+ attributes = {}
+
+ for name, data in self.data["netnames"].items():
+ if netid in data['bits']:
+
+ # Join attributes
+ for attr, value in data['attributes'].items():
+
+ # Allow multiple definitions of the same attribute only
+ # for the 'src'. Otherwise raise an exception
+ if attr in attributes and attr != 'src':
+ raise RuntimeError(
+ "Conflicting attributes '{}' on netid {}".format(
+ attr, netid))
+
+ # Join 'src' attribute strings
+ if attr in attributes and attr == 'src':
+ attributes[attr] += ";{}".format(value)
+ # Store the value
+ else:
+ attributes[attr] = value
+
+ return attributes
+
def net_drivers(self, net):
"""Returns a list of drivers of a given net, both top level inputs.
and cell outputs. "cell" is set to the name of the module for top level