sim: raise an error when overriding a combinationally-driven signal.

Fixes #557.
This commit is contained in:
Wanda 2024-04-13 11:13:57 +02:00 committed by Catherine
parent 16f187e7fa
commit 122be7849c
5 changed files with 19 additions and 1 deletions

View file

@ -19,6 +19,7 @@ class BaseSignalState:
__slots__ = ()
signal = NotImplemented
is_comb = NotImplemented
curr = NotImplemented
next = NotImplemented

View file

@ -1,5 +1,6 @@
from amaranth.hdl._ast import *
from amaranth.hdl._mem import MemoryData
from amaranth.hdl._ir import DriverConflict
def _eval_matches(test, patterns):
@ -165,6 +166,8 @@ def _eval_assign_inner(sim, lhs, lhs_start, rhs, rhs_len):
if lhs_start >= len(lhs):
return
slot = sim.get_signal(lhs)
if sim.slots[slot].is_comb:
raise DriverConflict("Combinationally driven signals cannot be overriden by testbenches")
value = sim.slots[slot].next
mask = (1 << lhs_stop) - (1 << lhs_start)
value &= ~mask

View file

@ -479,6 +479,7 @@ class _FragmentCompiler:
if domain_name == "comb":
for signal in domain_signals:
signal_index = self.state.get_signal(signal)
self.state.slots[signal_index].is_comb = True
emitter.append(f"next_{signal_index} = {signal.init}")
inputs = SignalSet()

View file

@ -303,10 +303,11 @@ class _Timeline:
class _PySignalState(BaseSignalState):
__slots__ = ("signal", "curr", "next", "waiters", "pending")
__slots__ = ("signal", "is_comb", "curr", "next", "waiters", "pending")
def __init__(self, signal, pending):
self.signal = signal
self.is_comb = False
self.pending = pending
self.waiters = {}
self.curr = self.next = signal.init

View file

@ -1395,3 +1395,15 @@ class SimulatorRegressionTestCase(FHDLTestCase):
self.assertEqual((yield C(0b1111, 4) ^ ~C(1, 1)), 0b1111)
sim.add_testbench(process)
sim.run()
def test_comb_assign(self):
c = Signal()
m = Module()
m.d.comb += c.eq(1)
sim = Simulator(m)
def testbench():
with self.assertRaisesRegex(DriverConflict,
r"^Combinationally driven signals cannot be overriden by testbenches$"):
yield c.eq(0)
sim.add_testbench(testbench)
sim.run()