sim: raise an error when overriding a combinationally-driven signal.
Fixes #557.
This commit is contained in:
parent
16f187e7fa
commit
122be7849c
|
@ -19,6 +19,7 @@ class BaseSignalState:
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
signal = NotImplemented
|
signal = NotImplemented
|
||||||
|
is_comb = NotImplemented
|
||||||
|
|
||||||
curr = NotImplemented
|
curr = NotImplemented
|
||||||
next = NotImplemented
|
next = NotImplemented
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from amaranth.hdl._ast import *
|
from amaranth.hdl._ast import *
|
||||||
from amaranth.hdl._mem import MemoryData
|
from amaranth.hdl._mem import MemoryData
|
||||||
|
from amaranth.hdl._ir import DriverConflict
|
||||||
|
|
||||||
|
|
||||||
def _eval_matches(test, patterns):
|
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):
|
if lhs_start >= len(lhs):
|
||||||
return
|
return
|
||||||
slot = sim.get_signal(lhs)
|
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
|
value = sim.slots[slot].next
|
||||||
mask = (1 << lhs_stop) - (1 << lhs_start)
|
mask = (1 << lhs_stop) - (1 << lhs_start)
|
||||||
value &= ~mask
|
value &= ~mask
|
||||||
|
|
|
@ -479,6 +479,7 @@ class _FragmentCompiler:
|
||||||
if domain_name == "comb":
|
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)
|
||||||
|
self.state.slots[signal_index].is_comb = True
|
||||||
emitter.append(f"next_{signal_index} = {signal.init}")
|
emitter.append(f"next_{signal_index} = {signal.init}")
|
||||||
|
|
||||||
inputs = SignalSet()
|
inputs = SignalSet()
|
||||||
|
|
|
@ -303,10 +303,11 @@ class _Timeline:
|
||||||
|
|
||||||
|
|
||||||
class _PySignalState(BaseSignalState):
|
class _PySignalState(BaseSignalState):
|
||||||
__slots__ = ("signal", "curr", "next", "waiters", "pending")
|
__slots__ = ("signal", "is_comb", "curr", "next", "waiters", "pending")
|
||||||
|
|
||||||
def __init__(self, signal, pending):
|
def __init__(self, signal, pending):
|
||||||
self.signal = signal
|
self.signal = signal
|
||||||
|
self.is_comb = False
|
||||||
self.pending = pending
|
self.pending = pending
|
||||||
self.waiters = {}
|
self.waiters = {}
|
||||||
self.curr = self.next = signal.init
|
self.curr = self.next = signal.init
|
||||||
|
|
|
@ -1395,3 +1395,15 @@ class SimulatorRegressionTestCase(FHDLTestCase):
|
||||||
self.assertEqual((yield C(0b1111, 4) ^ ~C(1, 1)), 0b1111)
|
self.assertEqual((yield C(0b1111, 4) ^ ~C(1, 1)), 0b1111)
|
||||||
sim.add_testbench(process)
|
sim.add_testbench(process)
|
||||||
sim.run()
|
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()
|
||||||
|
|
Loading…
Reference in a new issue