Skip to content

Commit 262e24b

Browse files
wanda-phiwhitequark
authored andcommitted
hdl._ir: Remove uses of _[lr]hs_signals and _ioports.
1 parent 0e6d802 commit 262e24b

File tree

3 files changed

+71
-50
lines changed

3 files changed

+71
-50
lines changed

amaranth/hdl/_ast.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3000,10 +3000,6 @@ def __getitem__(self, key):
30003000
else:
30013001
raise TypeError(f"Cannot index IO value with {key!r}")
30023002

3003-
@abstractmethod
3004-
def _ioports(self):
3005-
raise NotImplementedError # :nocov:
3006-
30073003

30083004
@final
30093005
class IOPort(IOValue):
@@ -3035,9 +3031,6 @@ def attrs(self):
30353031
def metadata(self):
30363032
return self._metadata
30373033

3038-
def _ioports(self):
3039-
return {self}
3040-
30413034
def __repr__(self):
30423035
return f"(io-port {self.name})"
30433036

@@ -3059,9 +3052,6 @@ def __len__(self):
30593052
def metadata(self):
30603053
return tuple(obj for part in self._parts for obj in part.metadata)
30613054

3062-
def _ioports(self):
3063-
return {port for part in self._parts for port in part._ioports()}
3064-
30653055
def __repr__(self):
30663056
return "(io-cat {})".format(" ".join(map(repr, self.parts)))
30673057

@@ -3115,9 +3105,6 @@ def __len__(self):
31153105
def metadata(self):
31163106
return self._value.metadata[self.start:self.stop]
31173107

3118-
def _ioports(self):
3119-
return self.value._ioports()
3120-
31213108
def __repr__(self):
31223109
return f"(io-slice {self.value!r} {self.start}:{self.stop})"
31233110

amaranth/hdl/_ir.py

Lines changed: 71 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -498,50 +498,96 @@ def _use_io_port(self, fragment: Fragment, port: _ast.IOPort):
498498
if frag_info.parent is not None:
499499
self._use_io_port(frag_info.parent, port)
500500

501+
def _collect_used_signals_format(self, fragment: Fragment, fmt: _ast.Format):
502+
for chunk in fmt._chunks:
503+
if not isinstance(chunk, str):
504+
obj, _spec = chunk
505+
self._collect_used_signals_value(fragment, obj)
506+
507+
def _collect_used_signals_value(self, fragment: Fragment, value: _ast.Value):
508+
if isinstance(value, (_ast.Const, _ast.Initial, _ast.AnyValue)):
509+
pass
510+
elif isinstance(value, _ast.Signal):
511+
self._use_signal(fragment, value)
512+
elif isinstance(value, _ast.Operator):
513+
for op in value.operands:
514+
self._collect_used_signals_value(fragment, op)
515+
elif isinstance(value, _ast.Slice):
516+
self._collect_used_signals_value(fragment, value.value)
517+
elif isinstance(value, _ast.Part):
518+
self._collect_used_signals_value(fragment, value.value)
519+
self._collect_used_signals_value(fragment, value.offset)
520+
elif isinstance(value, _ast.SwitchValue):
521+
self._collect_used_signals_value(fragment, value.test)
522+
for _patterns, elem in value.cases:
523+
self._collect_used_signals_value(fragment, elem)
524+
elif isinstance(value, _ast.Concat):
525+
for part in value.parts:
526+
self._collect_used_signals_value(fragment, part)
527+
else:
528+
raise NotImplementedError # :nocov:
529+
530+
def _collect_used_signals_io_value(self, fragment: Fragment, value: _ast.IOValue):
531+
if isinstance(value, _ast.IOPort):
532+
self._use_io_port(fragment, value)
533+
elif isinstance(value, _ast.IOSlice):
534+
self._collect_used_signals_io_value(fragment, value.value)
535+
elif isinstance(value, _ast.IOConcat):
536+
for part in value.parts:
537+
self._collect_used_signals_io_value(fragment, part)
538+
else:
539+
raise NotImplementedError # :nocov:
540+
541+
def _collect_used_signals_stmt(self, fragment: Fragment, stmt: _ast.Statement):
542+
if isinstance(stmt, _ast.Assign):
543+
self._collect_used_signals_value(fragment, stmt.lhs)
544+
self._collect_used_signals_value(fragment, stmt.rhs)
545+
elif isinstance(stmt, _ast.Print):
546+
self._collect_used_signals_format(fragment, stmt.message)
547+
elif isinstance(stmt, _ast.Property):
548+
self._collect_used_signals_value(fragment, stmt.test)
549+
if stmt.message is not None:
550+
self._collect_used_signals_format(fragment, stmt.message)
551+
elif isinstance(stmt, _ast.Switch):
552+
self._collect_used_signals_value(fragment, stmt.test)
553+
for _patterns, stmts, _src_loc in stmt.cases:
554+
for s in stmts:
555+
self._collect_used_signals_stmt(fragment, s)
556+
else:
557+
raise NotImplementedError # :nocov:
558+
501559
def _collect_used_signals(self, fragment: Fragment):
502560
"""Collects used signals and IO ports for a fragment and all its subfragments."""
503561
from . import _mem
504562
if isinstance(fragment, _ir.Instance):
505563
for conn, kind in fragment.ports.values():
506564
if isinstance(conn, _ast.IOValue):
507-
for port in conn._ioports():
508-
self._use_io_port(fragment, port)
565+
self._collect_used_signals_io_value(fragment, conn)
509566
elif isinstance(conn, _ast.Value):
510-
for signal in conn._rhs_signals():
511-
self._use_signal(fragment, signal)
567+
self._collect_used_signals_value(fragment, conn)
512568
else:
513569
assert False # :nocov:
514570
elif isinstance(fragment, _ir.IOBufferInstance):
515-
for port in fragment.port._ioports():
516-
self._use_io_port(fragment, port)
571+
self._collect_used_signals_io_value(fragment, fragment.port)
517572
if fragment.i is not None:
518-
for signal in fragment.i._rhs_signals():
519-
self._use_signal(fragment, signal)
573+
self._collect_used_signals_value(fragment, fragment.i)
520574
if fragment.o is not None:
521-
for signal in fragment.o._rhs_signals():
522-
self._use_signal(fragment, signal)
523-
for signal in fragment.oe._rhs_signals():
524-
self._use_signal(fragment, signal)
575+
self._collect_used_signals_value(fragment, fragment.o)
576+
self._collect_used_signals_value(fragment, fragment.oe)
525577
elif isinstance(fragment, _mem.MemoryInstance):
526578
for port in fragment._read_ports:
527-
for signal in port._addr._rhs_signals():
528-
self._use_signal(fragment, signal)
529-
for signal in port._data._rhs_signals():
530-
self._use_signal(fragment, signal)
531-
for signal in port._en._rhs_signals():
532-
self._use_signal(fragment, signal)
579+
self._collect_used_signals_value(fragment, port._addr)
580+
self._collect_used_signals_value(fragment, port._data)
581+
self._collect_used_signals_value(fragment, port._en)
533582
if port._domain != "comb":
534583
domain = fragment.domains[port._domain]
535584
self._use_signal(fragment, domain.clk)
536585
if domain.rst is not None:
537586
self._use_signal(fragment, domain.rst)
538587
for port in fragment._write_ports:
539-
for signal in port._addr._rhs_signals():
540-
self._use_signal(fragment, signal)
541-
for signal in port._data._rhs_signals():
542-
self._use_signal(fragment, signal)
543-
for signal in port._en._rhs_signals():
544-
self._use_signal(fragment, signal)
588+
self._collect_used_signals_value(fragment, port._addr)
589+
self._collect_used_signals_value(fragment, port._data)
590+
self._collect_used_signals_value(fragment, port._en)
545591
domain = fragment.domains[port._domain]
546592
self._use_signal(fragment, domain.clk)
547593
if domain.rst is not None:
@@ -554,9 +600,7 @@ def _collect_used_signals(self, fragment: Fragment):
554600
if domain.rst is not None:
555601
self._use_signal(fragment, domain.rst)
556602
for statement in statements:
557-
for signal in statement._lhs_signals() | statement._rhs_signals():
558-
if not isinstance(signal, (_ast.ClockSignal, _ast.ResetSignal)):
559-
self._use_signal(fragment, signal)
603+
self._collect_used_signals_stmt(fragment, statement)
560604
for subfragment, _name, _src_loc in fragment.subfragments:
561605
self._collect_used_signals(subfragment)
562606

tests/test_hdl_ast.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1821,13 +1821,11 @@ def test_ioport(self):
18211821
self.assertEqual(len(a), 4)
18221822
self.assertEqual(a.attrs, {})
18231823
self.assertEqual(a.metadata, (None, None, None, None))
1824-
self.assertEqual(a._ioports(), {a})
18251824
self.assertRepr(a, "(io-port a)")
18261825
b = IOPort(3, name="b", attrs={"a": "b"}, metadata=["x", "y", "z"])
18271826
self.assertEqual(len(b), 3)
18281827
self.assertEqual(b.attrs, {"a": "b"})
18291828
self.assertEqual(b.metadata, ("x", "y", "z"))
1830-
self.assertEqual(b._ioports(), {b})
18311829
self.assertRepr(b, "(io-port b)")
18321830

18331831
def test_ioport_wrong(self):
@@ -1849,32 +1847,26 @@ def test_ioslice(self):
18491847
s = a[2:5]
18501848
self.assertEqual(len(s), 3)
18511849
self.assertEqual(s.metadata, ("c", "d", "e"))
1852-
self.assertEqual(s._ioports(), {a})
18531850
self.assertRepr(s, "(io-slice (io-port a) 2:5)")
18541851
s = a[-5:-2]
18551852
self.assertEqual(len(s), 3)
18561853
self.assertEqual(s.metadata, ("d", "e", "f"))
1857-
self.assertEqual(s._ioports(), {a})
18581854
self.assertRepr(s, "(io-slice (io-port a) 3:6)")
18591855
s = IOSlice(a, -5, -2)
18601856
self.assertEqual(len(s), 3)
18611857
self.assertEqual(s.metadata, ("d", "e", "f"))
1862-
self.assertEqual(s._ioports(), {a})
18631858
self.assertRepr(s, "(io-slice (io-port a) 3:6)")
18641859
s = a[5]
18651860
self.assertEqual(len(s), 1)
18661861
self.assertEqual(s.metadata, ("f",))
1867-
self.assertEqual(s._ioports(), {a})
18681862
self.assertRepr(s, "(io-slice (io-port a) 5:6)")
18691863
s = a[-1]
18701864
self.assertEqual(len(s), 1)
18711865
self.assertEqual(s.metadata, ("h",))
1872-
self.assertEqual(s._ioports(), {a})
18731866
self.assertRepr(s, "(io-slice (io-port a) 7:8)")
18741867
s = a[::2]
18751868
self.assertEqual(len(s), 4)
18761869
self.assertEqual(s.metadata, ("a", "c", "e", "g"))
1877-
self.assertEqual(s._ioports(), {a})
18781870
self.assertRepr(s, "(io-cat (io-slice (io-port a) 0:1) (io-slice (io-port a) 2:3) (io-slice (io-port a) 4:5) (io-slice (io-port a) 6:7))")
18791871

18801872
def test_ioslice_wrong(self):
@@ -1902,12 +1894,10 @@ def test_iocat(self):
19021894
c = Cat(a, b)
19031895
self.assertEqual(len(c), 5)
19041896
self.assertEqual(c.metadata, ("a", "b", "c", "x", "y"))
1905-
self.assertEqual(c._ioports(), {a, b})
19061897
self.assertRepr(c, "(io-cat (io-port a) (io-port b))")
19071898
c = Cat(a, Cat())
19081899
self.assertEqual(len(c), 3)
19091900
self.assertEqual(c.metadata, ("a", "b", "c"))
1910-
self.assertEqual(c._ioports(), {a})
19111901
self.assertRepr(c, "(io-cat (io-port a) (io-cat ))")
19121902
c = Cat(a, Cat()[:])
19131903
self.assertEqual(len(c), 3)

0 commit comments

Comments
 (0)