hdl: consistently use "comb" for combinatorial domain.

Fixes #1097.
This commit is contained in:
Wanda 2024-02-09 20:27:25 +01:00 committed by Catherine
parent b6c5294e50
commit 45dbce13df
11 changed files with 104 additions and 115 deletions

View file

@ -794,7 +794,7 @@ def _convert_fragment(builder, fragment, name_map, hierarchy):
rd_clk_polarity = 0 rd_clk_polarity = 0
rd_transparency_mask = 0 rd_transparency_mask = 0
for index, port in enumerate(fragment._read_ports): for index, port in enumerate(fragment._read_ports):
if port._domain is not None: if port._domain != "comb":
cd = fragment.domains[port._domain] cd = fragment.domains[port._domain]
rd_clk.append(cd.clk) rd_clk.append(cd.clk)
if cd.clk_edge == "pos": if cd.clk_edge == "pos":
@ -870,7 +870,7 @@ def _convert_fragment(builder, fragment, name_map, hierarchy):
# affects further codegen; e.g. whether \sig$next signals will be generated and used. # affects further codegen; e.g. whether \sig$next signals will be generated and used.
for domain, statements in fragment.statements.items(): for domain, statements in fragment.statements.items():
for signal in statements._lhs_signals(): for signal in statements._lhs_signals():
compiler_state.add_driven(signal, sync=domain is not None) compiler_state.add_driven(signal, sync=domain != "comb")
# Transform all signals used as ports in the current fragment eagerly and outside of # Transform all signals used as ports in the current fragment eagerly and outside of
# any hierarchy, to make sure they get sensible (non-prefixed) names. # any hierarchy, to make sure they get sensible (non-prefixed) names.
@ -943,7 +943,7 @@ def _convert_fragment(builder, fragment, name_map, hierarchy):
# For every signal in sync domains, assign \sig$next to the current # For every signal in sync domains, assign \sig$next to the current
# value (\sig). # value (\sig).
for signal in group_signals: for signal in group_signals:
if domain is None: if domain == "comb":
prev_value = _ast.Const(signal.reset, signal.width) prev_value = _ast.Const(signal.reset, signal.width)
else: else:
prev_value = signal prev_value = signal

View file

@ -48,11 +48,7 @@ class _ModuleBuilderDomains(_ModuleBuilderProxy):
"did you mean <module>.{} instead?" "did you mean <module>.{} instead?"
.format(name, name, name), .format(name, name, name),
SyntaxWarning, stacklevel=2) SyntaxWarning, stacklevel=2)
if name == "comb": return _ModuleBuilderDomain(self._builder, self._depth, name)
domain = None
else:
domain = name
return _ModuleBuilderDomain(self._builder, self._depth, domain)
def __getitem__(self, name): def __getitem__(self, name):
return self.__getattr__(name) return self.__getattr__(name)
@ -520,20 +516,13 @@ class Module(_ModuleBuilderRoot, Elaboratable):
for name in fsm_states})) for name in fsm_states}))
def _add_statement(self, assigns, domain, depth): def _add_statement(self, assigns, domain, depth):
def domain_name(domain):
if domain is None:
return "comb"
else:
return domain
while len(self._ctrl_stack) > self.domain._depth: while len(self._ctrl_stack) > self.domain._depth:
self._pop_ctrl() self._pop_ctrl()
for stmt in Statement.cast(assigns): for stmt in Statement.cast(assigns):
if not isinstance(stmt, (Assign, Property)): if not isinstance(stmt, (Assign, Property)):
raise SyntaxError( raise SyntaxError(
"Only assignments and property checks may be appended to d.{}" f"Only assignments and property checks may be appended to d.{domain}")
.format(domain_name(domain)))
stmt._MustUse__used = True stmt._MustUse__used = True
@ -543,9 +532,8 @@ class Module(_ModuleBuilderRoot, Elaboratable):
elif self._driving[signal] != domain: elif self._driving[signal] != domain:
cd_curr = self._driving[signal] cd_curr = self._driving[signal]
raise SyntaxError( raise SyntaxError(
"Driver-driver conflict: trying to drive {!r} from d.{}, but it is " f"Driver-driver conflict: trying to drive {signal!r} from d.{domain}, but it is "
"already driven from d.{}" f"already driven from d.{cd_curr}")
.format(signal, domain_name(domain), domain_name(cd_curr)))
self._statements.setdefault(domain, []).append(stmt) self._statements.setdefault(domain, []).append(stmt)

View file

@ -86,7 +86,8 @@ class Fragment:
if port_dir == dir: if port_dir == dir:
yield port yield port
def add_driver(self, signal, domain=None): def add_driver(self, signal, domain="comb"):
assert isinstance(domain, str)
if domain not in self.drivers: if domain not in self.drivers:
self.drivers[domain] = SignalSet() self.drivers[domain] = SignalSet()
self.drivers[domain].add(signal) self.drivers[domain].add(signal)
@ -97,12 +98,12 @@ class Fragment:
yield domain, signal yield domain, signal
def iter_comb(self): def iter_comb(self):
if None in self.drivers: if "comb" in self.drivers:
yield from self.drivers[None] yield from self.drivers["comb"]
def iter_sync(self): def iter_sync(self):
for domain, signals in self.drivers.items(): for domain, signals in self.drivers.items():
if domain is None: if domain == "comb":
continue continue
for signal in signals: for signal in signals:
yield domain, signal yield domain, signal
@ -111,7 +112,7 @@ class Fragment:
signals = SignalSet() signals = SignalSet()
signals |= self.ports.keys() signals |= self.ports.keys()
for domain, domain_signals in self.drivers.items(): for domain, domain_signals in self.drivers.items():
if domain is not None: if domain != "comb":
cd = self.domains[domain] cd = self.domains[domain]
signals.add(cd.clk) signals.add(cd.clk)
if cd.rst is not None: if cd.rst is not None:
@ -129,7 +130,7 @@ class Fragment:
yield from self.domains yield from self.domains
def add_statements(self, domain, *stmts): def add_statements(self, domain, *stmts):
assert domain is None or isinstance(domain, str) assert isinstance(domain, str)
for stmt in Statement.cast(stmts): for stmt in Statement.cast(stmts):
stmt._MustUse__used = True stmt._MustUse__used = True
self.statements.setdefault(domain, _StatementList()).append(stmt) self.statements.setdefault(domain, _StatementList()).append(stmt)
@ -338,7 +339,7 @@ class Fragment:
new_domains = [] new_domains = []
for domain_name in collector.used_domains - collector.defined_domains: for domain_name in collector.used_domains - collector.defined_domains:
if domain_name is None: if domain_name == "comb":
continue continue
value = missing_domain(domain_name) value = missing_domain(domain_name)
if value is None: if value is None:
@ -589,7 +590,7 @@ class Fragment:
add_signal_name(port) add_signal_name(port)
for domain_name, domain_signals in self.drivers.items(): for domain_name, domain_signals in self.drivers.items():
if domain_name is not None: if domain_name != "comb":
domain = self.domains[domain_name] domain = self.domains[domain_name]
add_signal_name(domain.clk) add_signal_name(domain.clk)
if domain.rst is not None: if domain.rst is not None:

View file

@ -34,16 +34,14 @@ class MemorySimWrite:
class MemoryInstance(Fragment): class MemoryInstance(Fragment):
class _ReadPort: class _ReadPort:
def __init__(self, *, domain, addr, data, en, transparency): def __init__(self, *, domain, addr, data, en, transparency):
assert domain is None or isinstance(domain, str) assert isinstance(domain, str)
if domain == "comb":
domain = None
self._domain = domain self._domain = domain
self._addr = Value.cast(addr) self._addr = Value.cast(addr)
self._data = Value.cast(data) self._data = Value.cast(data)
self._en = Value.cast(en) self._en = Value.cast(en)
self._transparency = tuple(transparency) self._transparency = tuple(transparency)
assert len(self._en) == 1 assert len(self._en) == 1
if domain is None: if domain == "comb":
assert isinstance(self._en, Const) assert isinstance(self._en, Const)
assert self._en.width == 1 assert self._en.width == 1
assert self._en.value == 1 assert self._en.value == 1

View file

@ -333,7 +333,7 @@ class DomainCollector(ValueVisitor, StatementVisitor):
self._local_domains = set() self._local_domains = set()
def _add_used_domain(self, domain_name): def _add_used_domain(self, domain_name):
if domain_name is None: if domain_name == "comb":
return return
if domain_name in self._local_domains: if domain_name in self._local_domains:
return return
@ -517,7 +517,7 @@ class DomainLowerer(FragmentTransformer, ValueTransformer, StatementTransformer)
def _insert_resets(self, fragment): def _insert_resets(self, fragment):
for domain_name, signals in fragment.drivers.items(): for domain_name, signals in fragment.drivers.items():
if domain_name is None: if domain_name == "comb":
continue continue
domain = fragment.domains[domain_name] domain = fragment.domains[domain_name]
if domain.rst is None: if domain.rst is None:
@ -629,12 +629,14 @@ class _ControlInserter(FragmentTransformer):
self.src_loc = None self.src_loc = None
if isinstance(controls, Value): if isinstance(controls, Value):
controls = {"sync": controls} controls = {"sync": controls}
if "comb" in controls:
raise ValueError("Cannot add controls on the 'comb' domain")
self.controls = OrderedDict(controls) self.controls = OrderedDict(controls)
def on_fragment(self, fragment): def on_fragment(self, fragment):
new_fragment = super().on_fragment(fragment) new_fragment = super().on_fragment(fragment)
for domain, signals in fragment.drivers.items(): for domain, signals in fragment.drivers.items():
if domain is None or domain not in self.controls: if domain == "comb" or domain not in self.controls:
continue continue
self._insert_control(new_fragment, domain, signals) self._insert_control(new_fragment, domain, signals)
return new_fragment return new_fragment

View file

@ -421,7 +421,7 @@ class _FragmentCompiler:
for domain_name in domains: for domain_name in domains:
domain_stmts = fragment.statements.get(domain_name, _StatementList()) domain_stmts = fragment.statements.get(domain_name, _StatementList())
domain_process = PyRTLProcess(is_comb=domain_name is None) domain_process = PyRTLProcess(is_comb=domain_name == "comb")
domain_signals = domain_stmts._lhs_signals() domain_signals = domain_stmts._lhs_signals()
if isinstance(fragment, MemoryInstance): if isinstance(fragment, MemoryInstance):
@ -433,7 +433,7 @@ class _FragmentCompiler:
emitter.append(f"def run():") emitter.append(f"def run():")
emitter._level += 1 emitter._level += 1
if domain_name is None: if domain_name == "comb":
for signal in domain_signals: for signal in domain_signals:
signal_index = self.state.get_signal(signal) signal_index = self.state.get_signal(signal)
emitter.append(f"next_{signal_index} = {signal.reset}") emitter.append(f"next_{signal_index} = {signal.reset}")
@ -448,7 +448,7 @@ class _FragmentCompiler:
lhs = _LHSValueCompiler(self.state, emitter, rhs=rhs) lhs = _LHSValueCompiler(self.state, emitter, rhs=rhs)
for port in fragment._read_ports: for port in fragment._read_ports:
if port._domain is not None: if port._domain != "comb":
continue continue
addr = rhs(port._addr) addr = rhs(port._addr)

View file

@ -33,8 +33,8 @@ class DSLTestCase(FHDLTestCase):
m = Module() m = Module()
m.d.comb += self.c1.eq(1) m.d.comb += self.c1.eq(1)
m._flush() m._flush()
self.assertEqual(m._driving[self.c1], None) self.assertEqual(m._driving[self.c1], "comb")
self.assertRepr(m._statements[None], """( self.assertRepr(m._statements["comb"], """(
(eq (sig c1) (const 1'd1)) (eq (sig c1) (const 1'd1))
)""") )""")
@ -118,7 +118,7 @@ class DSLTestCase(FHDLTestCase):
def test_clock_signal(self): def test_clock_signal(self):
m = Module() m = Module()
m.d.comb += ClockSignal("pix").eq(ClockSignal()) m.d.comb += ClockSignal("pix").eq(ClockSignal())
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(eq (clk pix) (clk sync)) (eq (clk pix) (clk sync))
) )
@ -127,7 +127,7 @@ class DSLTestCase(FHDLTestCase):
def test_reset_signal(self): def test_reset_signal(self):
m = Module() m = Module()
m.d.comb += ResetSignal("pix").eq(1) m.d.comb += ResetSignal("pix").eq(1)
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(eq (rst pix) (const 1'd1)) (eq (rst pix) (const 1'd1))
) )
@ -138,7 +138,7 @@ class DSLTestCase(FHDLTestCase):
with m.If(self.s1): with m.If(self.s1):
m.d.comb += self.c1.eq(1) m.d.comb += self.c1.eq(1)
m._flush() m._flush()
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(switch (cat (sig s1)) (switch (cat (sig s1))
(case 1 (eq (sig c1) (const 1'd1))) (case 1 (eq (sig c1) (const 1'd1)))
@ -153,7 +153,7 @@ class DSLTestCase(FHDLTestCase):
with m.Elif(self.s2): with m.Elif(self.s2):
m.d.comb += self.c2.eq(0) m.d.comb += self.c2.eq(0)
m._flush() m._flush()
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(switch (cat (sig s1) (sig s2)) (switch (cat (sig s1) (sig s2))
(case -1 (eq (sig c1) (const 1'd1))) (case -1 (eq (sig c1) (const 1'd1)))
@ -169,7 +169,7 @@ class DSLTestCase(FHDLTestCase):
with m.Elif(self.s2): with m.Elif(self.s2):
m.d.sync += self.c2.eq(0) m.d.sync += self.c2.eq(0)
m._flush() m._flush()
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(switch (cat (sig s1) (sig s2)) (switch (cat (sig s1) (sig s2))
(case -1 (eq (sig c1) (const 1'd1))) (case -1 (eq (sig c1) (const 1'd1)))
@ -195,7 +195,7 @@ class DSLTestCase(FHDLTestCase):
with m.Else(): with m.Else():
m.d.comb += self.c3.eq(1) m.d.comb += self.c3.eq(1)
m._flush() m._flush()
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(switch (cat (sig s1) (sig s2)) (switch (cat (sig s1) (sig s2))
(case -1 (eq (sig c1) (const 1'd1))) (case -1 (eq (sig c1) (const 1'd1)))
@ -221,7 +221,7 @@ class DSLTestCase(FHDLTestCase):
with m.If(self.s2): with m.If(self.s2):
m.d.comb += self.c2.eq(1) m.d.comb += self.c2.eq(1)
m._flush() m._flush()
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(switch (cat (sig s1)) (switch (cat (sig s1))
(case 1 (eq (sig c1) (const 1'd1))) (case 1 (eq (sig c1) (const 1'd1)))
@ -239,7 +239,7 @@ class DSLTestCase(FHDLTestCase):
with m.If(self.s2): with m.If(self.s2):
m.d.comb += self.c2.eq(1) m.d.comb += self.c2.eq(1)
m._flush() m._flush()
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(switch (cat (sig s1)) (switch (cat (sig s1))
(case 1 (eq (sig c1) (const 1'd1)) (case 1 (eq (sig c1) (const 1'd1))
@ -260,7 +260,7 @@ class DSLTestCase(FHDLTestCase):
with m.Else(): with m.Else():
m.d.comb += self.c3.eq(1) m.d.comb += self.c3.eq(1)
m._flush() m._flush()
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(switch (cat (sig s1)) (switch (cat (sig s1))
(case 1 (case 1
@ -331,7 +331,7 @@ class DSLTestCase(FHDLTestCase):
with m.If(self.w1): with m.If(self.w1):
m.d.comb += self.c1.eq(1) m.d.comb += self.c1.eq(1)
m._flush() m._flush()
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(switch (cat (b (sig w1))) (switch (cat (b (sig w1)))
(case 1 (eq (sig c1) (const 1'd1))) (case 1 (eq (sig c1) (const 1'd1)))
@ -389,7 +389,7 @@ class DSLTestCase(FHDLTestCase):
with m.Case("1 0--"): with m.Case("1 0--"):
m.d.comb += self.c2.eq(1) m.d.comb += self.c2.eq(1)
m._flush() m._flush()
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(switch (sig w1) (switch (sig w1)
(case 0011 (eq (sig c1) (const 1'd1))) (case 0011 (eq (sig c1) (const 1'd1)))
@ -407,7 +407,7 @@ class DSLTestCase(FHDLTestCase):
with m.Case(): with m.Case():
m.d.comb += self.c2.eq(1) m.d.comb += self.c2.eq(1)
m._flush() m._flush()
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(switch (sig w1) (switch (sig w1)
(case 0011 (eq (sig c1) (const 1'd1))) (case 0011 (eq (sig c1) (const 1'd1)))
@ -423,7 +423,7 @@ class DSLTestCase(FHDLTestCase):
with m.Default(): with m.Default():
m.d.comb += self.c2.eq(1) m.d.comb += self.c2.eq(1)
m._flush() m._flush()
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(switch (sig w1) (switch (sig w1)
(case 0011 (eq (sig c1) (const 1'd1))) (case 0011 (eq (sig c1) (const 1'd1)))
@ -438,7 +438,7 @@ class DSLTestCase(FHDLTestCase):
with m.Case(1): with m.Case(1):
m.d.comb += self.c1.eq(1) m.d.comb += self.c1.eq(1)
m._flush() m._flush()
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(switch (const 1'd1) (switch (const 1'd1)
(case 1 (eq (sig c1) (const 1'd1))) (case 1 (eq (sig c1) (const 1'd1)))
@ -455,7 +455,7 @@ class DSLTestCase(FHDLTestCase):
with m.Switch(se): with m.Switch(se):
with m.Case(Color.RED): with m.Case(Color.RED):
m.d.comb += self.c1.eq(1) m.d.comb += self.c1.eq(1)
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(switch (sig se) (switch (sig se)
(case 01 (eq (sig c1) (const 1'd1))) (case 01 (eq (sig c1) (const 1'd1)))
@ -472,7 +472,7 @@ class DSLTestCase(FHDLTestCase):
with m.Switch(se): with m.Switch(se):
with m.Case(Cat(Color.RED, Color.BLUE)): with m.Case(Cat(Color.RED, Color.BLUE)):
m.d.comb += self.c1.eq(1) m.d.comb += self.c1.eq(1)
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(switch (sig se) (switch (sig se)
(case 10 (eq (sig c1) (const 1'd1))) (case 10 (eq (sig c1) (const 1'd1)))
@ -579,7 +579,7 @@ class DSLTestCase(FHDLTestCase):
with m.If(c): with m.If(c):
m.next = "FIRST" m.next = "FIRST"
m._flush() m._flush()
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(switch (sig fsm_state) (switch (sig fsm_state)
(case 0 (case 0
@ -606,7 +606,7 @@ class DSLTestCase(FHDLTestCase):
) )
""") """)
self.assertEqual({repr(k): v for k, v in m._driving.items()}, { self.assertEqual({repr(k): v for k, v in m._driving.items()}, {
"(sig a)": None, "(sig a)": "comb",
"(sig fsm_state)": "sync", "(sig fsm_state)": "sync",
"(sig b)": "sync", "(sig b)": "sync",
}) })
@ -633,7 +633,7 @@ class DSLTestCase(FHDLTestCase):
with m.State("SECOND"): with m.State("SECOND"):
m.next = "FIRST" m.next = "FIRST"
m._flush() m._flush()
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(switch (sig fsm_state) (switch (sig fsm_state)
(case 0 (case 0
@ -670,7 +670,7 @@ class DSLTestCase(FHDLTestCase):
m._flush() m._flush()
self.assertEqual(m._generated["fsm"].state.reset, 1) self.assertEqual(m._generated["fsm"].state.reset, 1)
self.maxDiff = 10000 self.maxDiff = 10000
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(eq (sig b) (== (sig fsm_state) (const 1'd0))) (eq (sig b) (== (sig fsm_state) (const 1'd0)))
(eq (sig a) (== (sig fsm_state) (const 1'd1))) (eq (sig a) (== (sig fsm_state) (const 1'd1)))
@ -753,7 +753,7 @@ class DSLTestCase(FHDLTestCase):
with m.If(self.w1): with m.If(self.w1):
m.d.comb += self.c1.eq(1) m.d.comb += self.c1.eq(1)
m.d.comb += self.c2.eq(1) m.d.comb += self.c2.eq(1)
self.assertRepr(m._statements[None], """ self.assertRepr(m._statements["comb"], """
( (
(switch (cat (b (sig w1))) (switch (cat (b (sig w1)))
(case 1 (eq (sig c1) (const 1'd1))) (case 1 (eq (sig c1) (const 1'd1)))
@ -870,18 +870,18 @@ class DSLTestCase(FHDLTestCase):
m1.submodules.foo = m2 m1.submodules.foo = m2
f1 = m1.elaborate(platform=None) f1 = m1.elaborate(platform=None)
self.assertRepr(f1.statements[None], """ self.assertRepr(f1.statements["comb"], """
( (
(eq (sig c1) (sig s1)) (eq (sig c1) (sig s1))
) )
""") """)
self.assertEqual(f1.drivers, { self.assertEqual(f1.drivers, {
None: SignalSet((self.c1,)) "comb": SignalSet((self.c1,))
}) })
self.assertEqual(len(f1.subfragments), 1) self.assertEqual(len(f1.subfragments), 1)
(f2, f2_name), = f1.subfragments (f2, f2_name), = f1.subfragments
self.assertEqual(f2_name, "foo") self.assertEqual(f2_name, "foo")
self.assertRepr(f2.statements[None], """ self.assertRepr(f2.statements["comb"], """
( (
(eq (sig c2) (sig s2)) (eq (sig c2) (sig s2))
) )
@ -892,7 +892,7 @@ class DSLTestCase(FHDLTestCase):
) )
""") """)
self.assertEqual(f2.drivers, { self.assertEqual(f2.drivers, {
None: SignalSet((self.c2,)), "comb": SignalSet((self.c2,)),
"sync": SignalSet((self.c3,)) "sync": SignalSet((self.c3,))
}) })
self.assertEqual(len(f2.subfragments), 0) self.assertEqual(len(f2.subfragments), 0)

View file

@ -100,7 +100,7 @@ class FragmentPortsTestCase(FHDLTestCase):
def test_self_contained(self): def test_self_contained(self):
f = Fragment() f = Fragment()
f.add_statements( f.add_statements(
None, "comb",
self.c1.eq(self.s1), self.c1.eq(self.s1),
self.s1.eq(self.c1) self.s1.eq(self.c1)
) )
@ -111,7 +111,7 @@ class FragmentPortsTestCase(FHDLTestCase):
def test_infer_input(self): def test_infer_input(self):
f = Fragment() f = Fragment()
f.add_statements( f.add_statements(
None, "comb",
self.c1.eq(self.s1) self.c1.eq(self.s1)
) )
@ -123,7 +123,7 @@ class FragmentPortsTestCase(FHDLTestCase):
def test_request_output(self): def test_request_output(self):
f = Fragment() f = Fragment()
f.add_statements( f.add_statements(
None, "comb",
self.c1.eq(self.s1) self.c1.eq(self.s1)
) )
@ -136,12 +136,12 @@ class FragmentPortsTestCase(FHDLTestCase):
def test_input_in_subfragment(self): def test_input_in_subfragment(self):
f1 = Fragment() f1 = Fragment()
f1.add_statements( f1.add_statements(
None, "comb",
self.c1.eq(self.s1) self.c1.eq(self.s1)
) )
f2 = Fragment() f2 = Fragment()
f2.add_statements( f2.add_statements(
None, "comb",
self.s1.eq(0) self.s1.eq(0)
) )
f1.add_subfragment(f2) f1.add_subfragment(f2)
@ -155,7 +155,7 @@ class FragmentPortsTestCase(FHDLTestCase):
f1 = Fragment() f1 = Fragment()
f2 = Fragment() f2 = Fragment()
f2.add_statements( f2.add_statements(
None, "comb",
self.c1.eq(self.s1) self.c1.eq(self.s1)
) )
f1.add_subfragment(f2) f1.add_subfragment(f2)
@ -170,12 +170,12 @@ class FragmentPortsTestCase(FHDLTestCase):
def test_output_from_subfragment(self): def test_output_from_subfragment(self):
f1 = Fragment() f1 = Fragment()
f1.add_statements( f1.add_statements(
None, "comb",
self.c1.eq(0) self.c1.eq(0)
) )
f2 = Fragment() f2 = Fragment()
f2.add_statements( f2.add_statements(
None, "comb",
self.c2.eq(1) self.c2.eq(1)
) )
f1.add_subfragment(f2) f1.add_subfragment(f2)
@ -191,18 +191,18 @@ class FragmentPortsTestCase(FHDLTestCase):
def test_output_from_subfragment_2(self): def test_output_from_subfragment_2(self):
f1 = Fragment() f1 = Fragment()
f1.add_statements( f1.add_statements(
None, "comb",
self.c1.eq(self.s1) self.c1.eq(self.s1)
) )
f2 = Fragment() f2 = Fragment()
f2.add_statements( f2.add_statements(
None, "comb",
self.c2.eq(self.s1) self.c2.eq(self.s1)
) )
f1.add_subfragment(f2) f1.add_subfragment(f2)
f3 = Fragment() f3 = Fragment()
f3.add_statements( f3.add_statements(
None, "comb",
self.s1.eq(0) self.s1.eq(0)
) )
f2.add_subfragment(f3) f2.add_subfragment(f3)
@ -216,13 +216,13 @@ class FragmentPortsTestCase(FHDLTestCase):
f1 = Fragment() f1 = Fragment()
f2 = Fragment() f2 = Fragment()
f2.add_statements( f2.add_statements(
None, "comb",
self.c1.eq(self.c2) self.c1.eq(self.c2)
) )
f1.add_subfragment(f2) f1.add_subfragment(f2)
f3 = Fragment() f3 = Fragment()
f3.add_statements( f3.add_statements(
None, "comb",
self.c2.eq(0) self.c2.eq(0)
) )
f3.add_driver(self.c2) f3.add_driver(self.c2)
@ -235,14 +235,14 @@ class FragmentPortsTestCase(FHDLTestCase):
f1 = Fragment() f1 = Fragment()
f2 = Fragment() f2 = Fragment()
f2.add_statements( f2.add_statements(
None, "comb",
self.c2.eq(0) self.c2.eq(0)
) )
f2.add_driver(self.c2) f2.add_driver(self.c2)
f1.add_subfragment(f2) f1.add_subfragment(f2)
f3 = Fragment() f3 = Fragment()
f3.add_statements( f3.add_statements(
None, "comb",
self.c1.eq(self.c2) self.c1.eq(self.c2)
) )
f1.add_subfragment(f3) f1.add_subfragment(f3)
@ -440,7 +440,7 @@ class FragmentDomainsTestCase(FHDLTestCase):
fa.add_domains(cda) fa.add_domains(cda)
fb = Fragment() fb = Fragment()
fb.add_domains(cdb) fb.add_domains(cdb)
fb.add_driver(ResetSignal("sync"), None) fb.add_driver(ResetSignal("sync"), "comb")
f = Fragment() f = Fragment()
f.add_subfragment(fa, "a") f.add_subfragment(fa, "a")
f.add_subfragment(fb, "b") f.add_subfragment(fb, "b")
@ -448,7 +448,7 @@ class FragmentDomainsTestCase(FHDLTestCase):
f._propagate_domains_up() f._propagate_domains_up()
fb_new, _ = f.subfragments[1] fb_new, _ = f.subfragments[1]
self.assertEqual(fb_new.drivers, OrderedDict({ self.assertEqual(fb_new.drivers, OrderedDict({
None: SignalSet((ResetSignal("b_sync"),)) "comb": SignalSet((ResetSignal("b_sync"),))
})) }))
def test_domain_conflict_rename_drivers_before_creating_missing(self): def test_domain_conflict_rename_drivers_before_creating_missing(self):
@ -618,7 +618,7 @@ class FragmentHierarchyConflictTestCase(FHDLTestCase):
) )
""") """)
self.assertEqual(self.f1.drivers, { self.assertEqual(self.f1.drivers, {
None: SignalSet((self.s1,)), "comb": SignalSet((self.s1,)),
"sync": SignalSet((self.c1, self.c2)), "sync": SignalSet((self.c1, self.c2)),
}) })
@ -646,12 +646,12 @@ class FragmentHierarchyConflictTestCase(FHDLTestCase):
self.f2 = Fragment() self.f2 = Fragment()
self.f2.add_driver(self.s1) self.f2.add_driver(self.s1)
self.f2.add_statements(None, self.c1.eq(0)) self.f2.add_statements("comb", self.c1.eq(0))
self.f1.add_subfragment(self.f2) self.f1.add_subfragment(self.f2)
self.f3 = Fragment() self.f3 = Fragment()
self.f3.add_driver(self.s1) self.f3.add_driver(self.s1)
self.f3.add_statements(None, self.c2.eq(1)) self.f3.add_statements("comb", self.c2.eq(1))
self.f1.add_subfragment(self.f3) self.f1.add_subfragment(self.f3)
def test_conflict_sub_sub(self): def test_conflict_sub_sub(self):
@ -659,7 +659,7 @@ class FragmentHierarchyConflictTestCase(FHDLTestCase):
self.f1._resolve_hierarchy_conflicts(mode="silent") self.f1._resolve_hierarchy_conflicts(mode="silent")
self.assertEqual(self.f1.subfragments, []) self.assertEqual(self.f1.subfragments, [])
self.assertRepr(self.f1.statements[None], """ self.assertRepr(self.f1.statements["comb"], """
( (
(eq (sig c1) (const 1'd0)) (eq (sig c1) (const 1'd0))
(eq (sig c2) (const 1'd1)) (eq (sig c2) (const 1'd1))
@ -675,12 +675,12 @@ class FragmentHierarchyConflictTestCase(FHDLTestCase):
self.f1.add_driver(self.s1) self.f1.add_driver(self.s1)
self.f2 = Fragment() self.f2 = Fragment()
self.f2.add_statements(None, self.c1.eq(0)) self.f2.add_statements("comb", self.c1.eq(0))
self.f1.add_subfragment(self.f2) self.f1.add_subfragment(self.f2)
self.f3 = Fragment() self.f3 = Fragment()
self.f3.add_driver(self.s1) self.f3.add_driver(self.s1)
self.f3.add_statements(None, self.c2.eq(1)) self.f3.add_statements("comb", self.c2.eq(1))
self.f2.add_subfragment(self.f3) self.f2.add_subfragment(self.f3)
def test_conflict_self_subsub(self): def test_conflict_self_subsub(self):
@ -688,7 +688,7 @@ class FragmentHierarchyConflictTestCase(FHDLTestCase):
self.f1._resolve_hierarchy_conflicts(mode="silent") self.f1._resolve_hierarchy_conflicts(mode="silent")
self.assertEqual(self.f1.subfragments, []) self.assertEqual(self.f1.subfragments, [])
self.assertRepr(self.f1.statements[None], """ self.assertRepr(self.f1.statements["comb"], """
( (
(eq (sig c1) (const 1'd0)) (eq (sig c1) (const 1'd0))
(eq (sig c2) (const 1'd1)) (eq (sig c2) (const 1'd1))
@ -865,8 +865,8 @@ class InstanceTestCase(FHDLTestCase):
f.add_domains(cd_sync_norst := ClockDomain(reset_less=True)) f.add_domains(cd_sync_norst := ClockDomain(reset_less=True))
f.add_ports((i, rst), dir="i") f.add_ports((i, rst), dir="i")
f.add_ports((o1, o2, o3), dir="o") f.add_ports((o1, o2, o3), dir="o")
f.add_statements(None, [o1.eq(0)]) f.add_statements("comb", [o1.eq(0)])
f.add_driver(o1, domain=None) f.add_driver(o1, domain="comb")
f.add_statements("sync", [o2.eq(i1)]) f.add_statements("sync", [o2.eq(i1)])
f.add_driver(o2, domain="sync") f.add_driver(o2, domain="sync")
f.add_statements("sync_norst", [o3.eq(i1)]) f.add_statements("sync_norst", [o3.eq(i1)])

View file

@ -26,7 +26,7 @@ class DomainRenamerTestCase(FHDLTestCase):
def test_rename_signals(self): def test_rename_signals(self):
f = Fragment() f = Fragment()
f.add_statements( f.add_statements(
None, "comb",
self.s1.eq(ClockSignal()), self.s1.eq(ClockSignal()),
ResetSignal().eq(self.s2), ResetSignal().eq(self.s2),
self.s4.eq(ClockSignal("other")), self.s4.eq(ClockSignal("other")),
@ -36,12 +36,12 @@ class DomainRenamerTestCase(FHDLTestCase):
"sync", "sync",
self.s3.eq(0), self.s3.eq(0),
) )
f.add_driver(self.s1, None) f.add_driver(self.s1, "comb")
f.add_driver(self.s2, None) f.add_driver(self.s2, "comb")
f.add_driver(self.s3, "sync") f.add_driver(self.s3, "sync")
f = DomainRenamer("pix")(f) f = DomainRenamer("pix")(f)
self.assertRepr(f.statements[None], """ self.assertRepr(f.statements["comb"], """
( (
(eq (sig s1) (clk pix)) (eq (sig s1) (clk pix))
(eq (rst pix) (sig s2)) (eq (rst pix) (sig s2))
@ -56,20 +56,20 @@ class DomainRenamerTestCase(FHDLTestCase):
""") """)
self.assertFalse("sync" in f.statements) self.assertFalse("sync" in f.statements)
self.assertEqual(f.drivers, { self.assertEqual(f.drivers, {
None: SignalSet((self.s1, self.s2)), "comb": SignalSet((self.s1, self.s2)),
"pix": SignalSet((self.s3,)), "pix": SignalSet((self.s3,)),
}) })
def test_rename_multi(self): def test_rename_multi(self):
f = Fragment() f = Fragment()
f.add_statements( f.add_statements(
None, "comb",
self.s1.eq(ClockSignal()), self.s1.eq(ClockSignal()),
self.s2.eq(ResetSignal("other")), self.s2.eq(ResetSignal("other")),
) )
f = DomainRenamer({"sync": "pix", "other": "pix2"})(f) f = DomainRenamer({"sync": "pix", "other": "pix2"})(f)
self.assertRepr(f.statements[None], """ self.assertRepr(f.statements["comb"], """
( (
(eq (sig s1) (clk pix)) (eq (sig s1) (clk pix))
(eq (sig s2) (rst pix2)) (eq (sig s2) (rst pix2))
@ -96,13 +96,13 @@ class DomainRenamerTestCase(FHDLTestCase):
f = Fragment() f = Fragment()
f.add_domains(cd_pix) f.add_domains(cd_pix)
f.add_statements( f.add_statements(
None, "comb",
self.s1.eq(ResetSignal(allow_reset_less=True)), self.s1.eq(ResetSignal(allow_reset_less=True)),
) )
f = DomainRenamer("pix")(f) f = DomainRenamer("pix")(f)
f = DomainLowerer()(f) f = DomainLowerer()(f)
self.assertRepr(f.statements[None], """ self.assertRepr(f.statements["comb"], """
( (
(eq (sig s1) (const 1'd0)) (eq (sig s1) (const 1'd0))
) )
@ -162,12 +162,12 @@ class DomainLowererTestCase(FHDLTestCase):
f = Fragment() f = Fragment()
f.add_domains(sync) f.add_domains(sync)
f.add_statements( f.add_statements(
None, "comb",
self.s.eq(ClockSignal("sync")) self.s.eq(ClockSignal("sync"))
) )
f = DomainLowerer()(f) f = DomainLowerer()(f)
self.assertRepr(f.statements[None], """ self.assertRepr(f.statements["comb"], """
( (
(eq (sig s) (sig clk)) (eq (sig s) (sig clk))
) )
@ -178,12 +178,12 @@ class DomainLowererTestCase(FHDLTestCase):
f = Fragment() f = Fragment()
f.add_domains(sync) f.add_domains(sync)
f.add_statements( f.add_statements(
None, "comb",
self.s.eq(ResetSignal("sync")) self.s.eq(ResetSignal("sync"))
) )
f = DomainLowerer()(f) f = DomainLowerer()(f)
self.assertRepr(f.statements[None], """ self.assertRepr(f.statements["comb"], """
( (
(eq (sig s) (sig rst)) (eq (sig s) (sig rst))
) )
@ -194,12 +194,12 @@ class DomainLowererTestCase(FHDLTestCase):
f = Fragment() f = Fragment()
f.add_domains(sync) f.add_domains(sync)
f.add_statements( f.add_statements(
None, "comb",
self.s.eq(ResetSignal("sync", allow_reset_less=True)) self.s.eq(ResetSignal("sync", allow_reset_less=True))
) )
f = DomainLowerer()(f) f = DomainLowerer()(f)
self.assertRepr(f.statements[None], """ self.assertRepr(f.statements["comb"], """
( (
(eq (sig s) (const 1'd0)) (eq (sig s) (const 1'd0))
) )
@ -210,19 +210,19 @@ class DomainLowererTestCase(FHDLTestCase):
pix = ClockDomain() pix = ClockDomain()
f = Fragment() f = Fragment()
f.add_domains(sync, pix) f.add_domains(sync, pix)
f.add_driver(ClockSignal("pix"), None) f.add_driver(ClockSignal("pix"), "comb")
f.add_driver(ResetSignal("pix"), "sync") f.add_driver(ResetSignal("pix"), "sync")
f = DomainLowerer()(f) f = DomainLowerer()(f)
self.assertEqual(f.drivers, { self.assertEqual(f.drivers, {
None: SignalSet((pix.clk,)), "comb": SignalSet((pix.clk,)),
"sync": SignalSet((pix.rst,)) "sync": SignalSet((pix.rst,))
}) })
def test_lower_wrong_domain(self): def test_lower_wrong_domain(self):
f = Fragment() f = Fragment()
f.add_statements( f.add_statements(
None, "comb",
self.s.eq(ClockSignal("xxx")) self.s.eq(ClockSignal("xxx"))
) )
@ -235,7 +235,7 @@ class DomainLowererTestCase(FHDLTestCase):
f = Fragment() f = Fragment()
f.add_domains(sync) f.add_domains(sync)
f.add_statements( f.add_statements(
None, "comb",
self.s.eq(ResetSignal("sync")) self.s.eq(ResetSignal("sync"))
) )

View file

@ -889,7 +889,7 @@ class ConnectTestCase(unittest.TestCase):
m = Module() m = Module()
connect(m, src=src, snk=snk) connect(m, src=src, snk=snk)
self.assertEqual([repr(stmt) for stmt in m._statements[None]], [ self.assertEqual([repr(stmt) for stmt in m._statements["comb"]], [
'(eq (sig snk__addr) (sig src__addr))', '(eq (sig snk__addr) (sig src__addr))',
'(eq (sig snk__cycle) (sig src__cycle))', '(eq (sig snk__cycle) (sig src__cycle))',
'(eq (sig src__r_data) (sig snk__r_data))', '(eq (sig src__r_data) (sig snk__r_data))',
@ -912,7 +912,7 @@ class ConnectTestCase(unittest.TestCase):
a=NS(signature=Signature({"f": Out(1)}), f=Signal(name='p__a'))), a=NS(signature=Signature({"f": Out(1)}), f=Signal(name='p__a'))),
q=NS(signature=Signature({"a": In(Signature({"f": Out(1)}))}), q=NS(signature=Signature({"a": In(Signature({"f": Out(1)}))}),
a=NS(signature=Signature({"f": Out(1)}).flip(), f=Signal(name='q__a')))) a=NS(signature=Signature({"f": Out(1)}).flip(), f=Signal(name='q__a'))))
self.assertEqual([repr(stmt) for stmt in m._statements[None]], [ self.assertEqual([repr(stmt) for stmt in m._statements["comb"]], [
'(eq (sig q__a) (sig p__a))' '(eq (sig q__a) (sig p__a))'
]) ])
@ -931,7 +931,7 @@ class ConnectTestCase(unittest.TestCase):
g=Signal(name="q__b__g"), g=Signal(name="q__b__g"),
f=Signal(name="q__b__f")), f=Signal(name="q__b__f")),
a=Signal(name="q__a"))) a=Signal(name="q__a")))
self.assertEqual([repr(stmt) for stmt in m._statements[None]], [ self.assertEqual([repr(stmt) for stmt in m._statements["comb"]], [
'(eq (sig q__a) (sig p__a))', '(eq (sig q__a) (sig p__a))',
'(eq (sig q__b__f) (sig p__b__f))', '(eq (sig q__b__f) (sig p__b__f))',
'(eq (sig q__b__g) (sig p__b__g))', '(eq (sig q__b__g) (sig p__b__g))',
@ -942,7 +942,7 @@ class ConnectTestCase(unittest.TestCase):
m = Module() m = Module()
connect(m, p=sig.create(path=('p',)), q=sig.flip().create(path=('q',))) connect(m, p=sig.create(path=('p',)), q=sig.flip().create(path=('q',)))
self.assertEqual([repr(stmt) for stmt in m._statements[None]], [ self.assertEqual([repr(stmt) for stmt in m._statements["comb"]], [
'(eq (sig q__a__0) (sig p__a__0))', '(eq (sig q__a__0) (sig p__a__0))',
'(eq (sig q__a__1) (sig p__a__1))' '(eq (sig q__a__1) (sig p__a__1))'
]) ])
@ -952,7 +952,7 @@ class ConnectTestCase(unittest.TestCase):
m = Module() m = Module()
connect(m, p=sig.create(path=('p',)), q=sig.flip().create(path=('q',))) connect(m, p=sig.create(path=('p',)), q=sig.flip().create(path=('q',)))
self.assertEqual([repr(stmt) for stmt in m._statements[None]], [ self.assertEqual([repr(stmt) for stmt in m._statements["comb"]], [
'(eq (sig q__a__0__0) (sig p__a__0__0))', '(eq (sig q__a__0__0) (sig p__a__0__0))',
]) ])

View file

@ -27,7 +27,7 @@ class SimulatorUnitTestCase(FHDLTestCase):
stmt = stmt(osig, *isigs) stmt = stmt(osig, *isigs)
frag = Fragment() frag = Fragment()
frag.add_statements(None, stmt) frag.add_statements("comb", stmt)
for signal in flatten(s._lhs_signals() for s in Statement.cast(stmt)): for signal in flatten(s._lhs_signals() for s in Statement.cast(stmt)):
frag.add_driver(signal) frag.add_driver(signal)