Consider Instances a part of containing fragment for use-def purposes.

Fixes #70.
This commit is contained in:
whitequark 2019-05-25 20:09:26 +00:00
parent 699fe5a675
commit 3392708e2b
2 changed files with 37 additions and 22 deletions

View file

@ -366,31 +366,34 @@ class Fragment:
# Collect all signals we're driving (on LHS of statements), and signals we're using # Collect all signals we're driving (on LHS of statements), and signals we're using
# (on RHS of statements, or in clock domains). # (on RHS of statements, or in clock domains).
if isinstance(self, Instance): for stmt in self.statements:
for port_name, (value, dir) in self.named_ports.items(): add_uses(stmt._rhs_signals())
if dir == "i": add_defs(stmt._lhs_signals())
add_uses(value._rhs_signals())
if dir == "o":
add_defs(value._lhs_signals())
if dir == "io":
add_io(value)
else:
for stmt in self.statements:
add_uses(stmt._rhs_signals())
add_defs(stmt._lhs_signals())
for domain, _ in self.iter_sync(): for domain, _ in self.iter_sync():
cd = self.domains[domain] cd = self.domains[domain]
add_uses(cd.clk) add_uses(cd.clk)
if cd.rst is not None: if cd.rst is not None:
add_uses(cd.rst) add_uses(cd.rst)
# Repeat for subfragments. # Repeat for subfragments.
for subfrag, name in self.subfragments: for subfrag, name in self.subfragments:
parent[subfrag] = self if isinstance(subfrag, Instance):
level [subfrag] = level[self] + 1 for port_name, (value, dir) in subfrag.named_ports.items():
if dir == "i":
subfrag.add_ports(value._rhs_signals(), dir=dir)
add_uses(value._rhs_signals())
if dir == "o":
subfrag.add_ports(value._lhs_signals(), dir=dir)
add_defs(value._lhs_signals())
if dir == "io":
subfrag.add_ports(value, dir=dir)
add_io(value)
else:
parent[subfrag] = self
level [subfrag] = level[self] + 1
subfrag._prepare_use_def_graph(parent, level, uses, defs, ios, top) subfrag._prepare_use_def_graph(parent, level, uses, defs, ios, top)
def _propagate_ports(self, ports, all_undef_as_ports): def _propagate_ports(self, ports, all_undef_as_ports):
# Take this fragment graph: # Take this fragment graph:

View file

@ -561,6 +561,8 @@ class InstanceTestCase(FHDLTestCase):
o_data=Cat(self.datal, self.datah), o_data=Cat(self.datal, self.datah),
io_pins=self.pins io_pins=self.pins
) )
self.wrap = Fragment()
self.wrap.add_subfragment(self.inst)
def test_init(self): def test_init(self):
self.setUp_cpu() self.setUp_cpu()
@ -572,7 +574,7 @@ class InstanceTestCase(FHDLTestCase):
def test_prepare(self): def test_prepare(self):
self.setUp_cpu() self.setUp_cpu()
f = self.inst.prepare() f = self.wrap.prepare()
sync_clk = f.domains["sync"].clk sync_clk = f.domains["sync"].clk
self.assertEqual(f.ports, SignalDict([ self.assertEqual(f.ports, SignalDict([
(sync_clk, "i"), (sync_clk, "i"),
@ -582,7 +584,7 @@ class InstanceTestCase(FHDLTestCase):
def test_prepare_explicit_ports(self): def test_prepare_explicit_ports(self):
self.setUp_cpu() self.setUp_cpu()
f = self.inst.prepare(ports=[self.rst, self.stb]) f = self.wrap.prepare(ports=[self.rst, self.stb])
sync_clk = f.domains["sync"].clk sync_clk = f.domains["sync"].clk
sync_rst = f.domains["sync"].rst sync_rst = f.domains["sync"].rst
self.assertEqual(f.ports, SignalDict([ self.assertEqual(f.ports, SignalDict([
@ -592,3 +594,13 @@ class InstanceTestCase(FHDLTestCase):
(self.stb, "o"), (self.stb, "o"),
(self.pins, "io"), (self.pins, "io"),
])) ]))
def test_prepare_slice_in_port(self):
s = Signal(2)
f = Fragment()
f.add_subfragment(Instance("foo", o_O=s[0]))
f.add_subfragment(Instance("foo", o_O=s[1]))
fp = f.prepare(ports=[s], ensure_sync_exists=False)
self.assertEqual(fp.ports, SignalDict([
(s, "o"),
]))