Skip to content

Commit 122be78

Browse files
wanda-phiwhitequark
authored andcommitted
sim: raise an error when overriding a combinationally-driven signal.
Fixes #557.
1 parent 16f187e commit 122be78

File tree

5 files changed

+19
-1
lines changed

5 files changed

+19
-1
lines changed

amaranth/sim/_base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class BaseSignalState:
1919
__slots__ = ()
2020

2121
signal = NotImplemented
22+
is_comb = NotImplemented
2223

2324
curr = NotImplemented
2425
next = NotImplemented

amaranth/sim/_pyeval.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from amaranth.hdl._ast import *
22
from amaranth.hdl._mem import MemoryData
3+
from amaranth.hdl._ir import DriverConflict
34

45

56
def _eval_matches(test, patterns):
@@ -165,6 +166,8 @@ def _eval_assign_inner(sim, lhs, lhs_start, rhs, rhs_len):
165166
if lhs_start >= len(lhs):
166167
return
167168
slot = sim.get_signal(lhs)
169+
if sim.slots[slot].is_comb:
170+
raise DriverConflict("Combinationally driven signals cannot be overriden by testbenches")
168171
value = sim.slots[slot].next
169172
mask = (1 << lhs_stop) - (1 << lhs_start)
170173
value &= ~mask

amaranth/sim/_pyrtl.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,7 @@ def __call__(self, fragment):
479479
if domain_name == "comb":
480480
for signal in domain_signals:
481481
signal_index = self.state.get_signal(signal)
482+
self.state.slots[signal_index].is_comb = True
482483
emitter.append(f"next_{signal_index} = {signal.init}")
483484

484485
inputs = SignalSet()

amaranth/sim/pysim.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,10 +303,11 @@ def advance(self):
303303

304304

305305
class _PySignalState(BaseSignalState):
306-
__slots__ = ("signal", "curr", "next", "waiters", "pending")
306+
__slots__ = ("signal", "is_comb", "curr", "next", "waiters", "pending")
307307

308308
def __init__(self, signal, pending):
309309
self.signal = signal
310+
self.is_comb = False
310311
self.pending = pending
311312
self.waiters = {}
312313
self.curr = self.next = signal.init

tests/test_sim.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,3 +1395,15 @@ def process():
13951395
self.assertEqual((yield C(0b1111, 4) ^ ~C(1, 1)), 0b1111)
13961396
sim.add_testbench(process)
13971397
sim.run()
1398+
1399+
def test_comb_assign(self):
1400+
c = Signal()
1401+
m = Module()
1402+
m.d.comb += c.eq(1)
1403+
sim = Simulator(m)
1404+
def testbench():
1405+
with self.assertRaisesRegex(DriverConflict,
1406+
r"^Combinationally driven signals cannot be overriden by testbenches$"):
1407+
yield c.eq(0)
1408+
sim.add_testbench(testbench)
1409+
sim.run()

0 commit comments

Comments
 (0)