diff --git a/amaranth/sim/core.py b/amaranth/sim/core.py index 64686ce..a50e468 100644 --- a/amaranth/sim/core.py +++ b/amaranth/sim/core.py @@ -15,6 +15,12 @@ class Command: class Settle(Command): + @deprecated("The `Settle` command is deprecated per RFC 27. Use `add_testbench` to write " + "testbenches; in them, an equivalent of `yield Settle()` is performed " + "automatically.") + def __init__(self): + pass + def __repr__(self): return "(settle)" @@ -74,11 +80,12 @@ class Simulator: .format(process)) return process + @deprecated("The `add_process` method is deprecated per RFC 27. Use `add_testbench` instead.") def add_process(self, process): process = self._check_process(process) def wrapper(): # Only start a bench process after comb settling, so that the reset values are correct. - yield Settle() + yield object.__new__(Settle) yield from process() self._engine.add_coroutine_process(wrapper, default_cmd=None) @@ -87,10 +94,74 @@ class Simulator: def wrapper(): # Only start a sync process after the first clock edge (or reset edge, if the domain # uses an asynchronous reset). This matches the behavior of synchronous FFs. + generator = process() + result = None + exception = None yield Tick(domain) - yield from process() + while True: + try: + if exception is None: + command = generator.send(result) + else: + command = generator.throw(exception) + except StopIteration: + break + try: + if isinstance(command, (Settle, Delay, Tick)): + frame = generator.gi_frame + module_globals = frame.f_globals + if '__name__' in module_globals: + module = module_globals['__name__'] + else: + module = "" + # If the warning action is "error", this call will throw the warning, and + # the try block will redirect it into the generator. + warnings.warn_explicit( + f"Using `{command.__class__.__name__}` is deprecated within " + f"`add_sync_process` per RFC 27; use `add_testbench` instead.", + DeprecationWarning, + filename=frame.f_code.co_filename, + lineno=frame.f_lineno, + module=module, + registry=module_globals.setdefault("__warningregistry__", {}), + module_globals=module_globals, + ) + result = yield command + exception = None + except Exception as e: + result = None + exception = e self._engine.add_coroutine_process(wrapper, default_cmd=Tick(domain)) + def add_testbench(self, process): + process = self._check_process(process) + def wrapper(): + generator = process() + # Only start a bench process after power-on reset finishes. Use object.__new__ to + # avoid deprecation warning. + yield object.__new__(Settle) + result = None + exception = None + while True: + try: + if exception is None: + command = generator.send(result) + else: + command = generator.throw(exception) + except StopIteration: + break + if command is None or isinstance(command, Settle): + exception = TypeError(f"Command {command!r} is not allowed in testbenches") + else: + try: + result = yield command + exception = None + yield object.__new__(Settle) + except Exception as e: + result = None + exception = e + self._engine.add_coroutine_process(wrapper, default_cmd=None) + def add_clock(self, period, *, phase=None, domain="sync", if_exists=False): """Add a clock process. diff --git a/docs/changes.rst b/docs/changes.rst index bc25118..9b7d288 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -29,16 +29,21 @@ Apply the following changes to code written against Amaranth 0.4 to migrate it t * Replace uses of ``Value.matches()`` with no patterns with ``Const(1)`` * Update uses of ``amaranth.utils.log2_int(need_pow2=False)`` to :func:`amaranth.utils.ceil_log2` * Update uses of ``amaranth.utils.log2_int(need_pow2=True)`` to :func:`amaranth.utils.exact_log2` +* Update uses of ``Simulator.add_process`` to ``Simulator.add_testbench`` +* Convert uses of ``Simulator.add_sync_process`` used as testbenches to ``Simulator.add_testbench`` +* Convert uses of ``yield Tick()`` within remaining ``Simulator.add_sync_process`` to plain ``yield`` Implemented RFCs ---------------- .. _RFC 17: https://amaranth-lang.org/rfcs/0017-remove-log2-int.html +.. _RFC 27: https://amaranth-lang.org/rfcs/0027-simulator-testbenches.html .. _RFC 39: https://amaranth-lang.org/rfcs/0039-empty-case.html .. _RFC 46: https://amaranth-lang.org/rfcs/0046-shape-range-1.html * `RFC 17`_: Remove ``log2_int`` +* `RFC 27`_: Testbench processes for the simulator * `RFC 39`_: Change semantics of no-argument ``m.Case()`` * `RFC 46`_: Change ``Shape.cast(range(1))`` to ``unsigned(0)`` @@ -71,6 +76,14 @@ Standard library changes * Removed: (deprecated in 0.4) :class:`amaranth.lib.fifo.SyncFIFO` with ``fwft=False``. (`RFC 20`_) +Toolchain changes +----------------- + +* Added: ``Simulator.add_testbench``. (`RFC 27`_) +* Deprecated: ``Settle`` simulation command. (`RFC 27`_) +* Deprecated: ``Simulator.add_process``. (`RFC 27`_) + + Platform integration changes ---------------------------- diff --git a/tests/test_lib_cdc.py b/tests/test_lib_cdc.py index 0540be2..a271032 100644 --- a/tests/test_lib_cdc.py +++ b/tests/test_lib_cdc.py @@ -26,13 +26,13 @@ class FFSynchronizerTestCase(FHDLTestCase): def process(): self.assertEqual((yield o), 0) yield i.eq(1) - yield Tick() + yield self.assertEqual((yield o), 0) - yield Tick() + yield self.assertEqual((yield o), 0) - yield Tick() + yield self.assertEqual((yield o), 1) - sim.add_process(process) + sim.add_sync_process(process) sim.run() def test_reset_value(self): @@ -45,13 +45,13 @@ class FFSynchronizerTestCase(FHDLTestCase): def process(): self.assertEqual((yield o), 1) yield i.eq(0) - yield Tick() + yield self.assertEqual((yield o), 1) - yield Tick() + yield self.assertEqual((yield o), 1) - yield Tick() + yield self.assertEqual((yield o), 0) - sim.add_process(process) + sim.add_sync_process(process) sim.run() @@ -90,28 +90,27 @@ class AsyncFFSynchronizerTestCase(FHDLTestCase): # initial reset self.assertEqual((yield i), 0) self.assertEqual((yield o), 1) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield o), 1) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield o), 0) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield o), 0) - yield Tick(); yield Delay(1e-8) + yield Tick() yield i.eq(1) - yield Delay(1e-8) self.assertEqual((yield o), 1) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield o), 1) yield i.eq(0) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield o), 1) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield o), 0) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield o), 0) - yield Tick(); yield Delay(1e-8) - sim.add_process(process) + yield Tick() + sim.add_testbench(process) with sim.write_vcd("test.vcd"): sim.run() @@ -128,28 +127,27 @@ class AsyncFFSynchronizerTestCase(FHDLTestCase): # initial reset self.assertEqual((yield i), 1) self.assertEqual((yield o), 1) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield o), 1) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield o), 0) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield o), 0) - yield Tick(); yield Delay(1e-8) + yield Tick() yield i.eq(0) - yield Delay(1e-8) self.assertEqual((yield o), 1) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield o), 1) yield i.eq(1) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield o), 1) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield o), 0) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield o), 0) - yield Tick(); yield Delay(1e-8) - sim.add_process(process) + yield Tick() + sim.add_testbench(process) with sim.write_vcd("test.vcd"): sim.run() @@ -176,28 +174,28 @@ class ResetSynchronizerTestCase(FHDLTestCase): def process(): # initial reset self.assertEqual((yield s), 1) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield s), 1) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield s), 1) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield s), 0) - yield Tick(); yield Delay(1e-8) + yield Tick() yield arst.eq(1) yield Delay(1e-8) self.assertEqual((yield s), 0) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield s), 1) yield arst.eq(0) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield s), 1) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield s), 1) - yield Tick(); yield Delay(1e-8) + yield Tick() self.assertEqual((yield s), 0) - yield Tick(); yield Delay(1e-8) - sim.add_process(process) + yield Tick() + sim.add_testbench(process) with sim.write_vcd("test.vcd"): sim.run() @@ -223,17 +221,17 @@ class PulseSynchronizerTestCase(FHDLTestCase): yield ps.i.eq(0) # TODO: think about reset for n in range(5): - yield Tick() + yield # Make sure no pulses are generated in quiescent state for n in range(3): - yield Tick() + yield self.assertEqual((yield ps.o), 0) # Check conservation of pulses accum = 0 for n in range(10): yield ps.i.eq(1 if n < 4 else 0) - yield Tick() + yield accum += yield ps.o self.assertEqual(accum, 4) - sim.add_process(process) + sim.add_sync_process(process) sim.run() diff --git a/tests/test_lib_coding.py b/tests/test_lib_coding.py index e2f875d..41f77fe 100644 --- a/tests/test_lib_coding.py +++ b/tests/test_lib_coding.py @@ -14,22 +14,19 @@ class EncoderTestCase(FHDLTestCase): self.assertEqual((yield enc.o), 0) yield enc.i.eq(0b0001) - yield Settle() self.assertEqual((yield enc.n), 0) self.assertEqual((yield enc.o), 0) yield enc.i.eq(0b0100) - yield Settle() self.assertEqual((yield enc.n), 0) self.assertEqual((yield enc.o), 2) yield enc.i.eq(0b0110) - yield Settle() self.assertEqual((yield enc.n), 1) self.assertEqual((yield enc.o), 0) sim = Simulator(enc) - sim.add_process(process) + sim.add_testbench(process) sim.run() @@ -41,22 +38,19 @@ class PriorityEncoderTestCase(FHDLTestCase): self.assertEqual((yield enc.o), 0) yield enc.i.eq(0b0001) - yield Settle() self.assertEqual((yield enc.n), 0) self.assertEqual((yield enc.o), 0) yield enc.i.eq(0b0100) - yield Settle() self.assertEqual((yield enc.n), 0) self.assertEqual((yield enc.o), 2) yield enc.i.eq(0b0110) - yield Settle() self.assertEqual((yield enc.n), 0) self.assertEqual((yield enc.o), 1) sim = Simulator(enc) - sim.add_process(process) + sim.add_testbench(process) sim.run() @@ -67,19 +61,16 @@ class DecoderTestCase(FHDLTestCase): self.assertEqual((yield dec.o), 0b0001) yield dec.i.eq(1) - yield Settle() self.assertEqual((yield dec.o), 0b0010) yield dec.i.eq(3) - yield Settle() self.assertEqual((yield dec.o), 0b1000) yield dec.n.eq(1) - yield Settle() self.assertEqual((yield dec.o), 0b0000) sim = Simulator(dec) - sim.add_process(process) + sim.add_testbench(process) sim.run() diff --git a/tests/test_lib_data.py b/tests/test_lib_data.py index 42f2aca..486e1e0 100644 --- a/tests/test_lib_data.py +++ b/tests/test_lib_data.py @@ -870,7 +870,7 @@ class RFCExamplesTestCase(TestCase): def simulate(m): def wrapper(fn): sim = Simulator(m) - sim.add_process(fn) + sim.add_testbench(fn) sim.run() return wrapper diff --git a/tests/test_lib_fifo.py b/tests/test_lib_fifo.py index 004b7f3..e35c978 100644 --- a/tests/test_lib_fifo.py +++ b/tests/test_lib_fifo.py @@ -315,10 +315,10 @@ class AsyncFIFOSimCase(FHDLTestCase): for i in range(fill_in): yield fifo.w_data.eq(i) yield fifo.w_en.eq(1) - yield Tick("write") + yield yield fifo.w_en.eq(0) - yield Tick("write") - yield Tick("write") + yield + yield self.assertEqual((yield fifo.w_level), expected_level) yield write_done.eq(1) @@ -326,7 +326,7 @@ class AsyncFIFOSimCase(FHDLTestCase): if read: yield fifo.r_en.eq(1) while not (yield write_done): - yield Tick("read") + yield self.assertEqual((yield fifo.r_level), expected_level) simulator = Simulator(fifo) diff --git a/tests/test_sim.py b/tests/test_sim.py index 5eaf6df..ce776b0 100644 --- a/tests/test_sim.py +++ b/tests/test_sim.py @@ -35,9 +35,8 @@ class SimulatorUnitTestCase(FHDLTestCase): def process(): for isig, input in zip(isigs, inputs): yield isig.eq(input) - yield Settle() self.assertEqual((yield osig), output.value) - sim.add_process(process) + sim.add_testbench(process) with sim.write_vcd("test.vcd", "test.gtkw", traces=[*isigs, osig]): sim.run() @@ -436,28 +435,29 @@ class SimulatorIntegrationTestCase(FHDLTestCase): def test_counter_process(self): self.setUp_counter() - with self.assertSimulation(self.m) as sim: - def process(): - self.assertEqual((yield self.count), 4) - yield Delay(1e-6) - self.assertEqual((yield self.count), 4) - yield self.sync.clk.eq(1) - self.assertEqual((yield self.count), 4) - yield Settle() - self.assertEqual((yield self.count), 5) - yield Delay(1e-6) - self.assertEqual((yield self.count), 5) - yield self.sync.clk.eq(0) - self.assertEqual((yield self.count), 5) - yield Settle() - self.assertEqual((yield self.count), 5) - for _ in range(3): + with _ignore_deprecated(): + with self.assertSimulation(self.m) as sim: + def process(): + self.assertEqual((yield self.count), 4) yield Delay(1e-6) + self.assertEqual((yield self.count), 4) yield self.sync.clk.eq(1) + self.assertEqual((yield self.count), 4) + yield Settle() + self.assertEqual((yield self.count), 5) yield Delay(1e-6) + self.assertEqual((yield self.count), 5) yield self.sync.clk.eq(0) - self.assertEqual((yield self.count), 0) - sim.add_process(process) + self.assertEqual((yield self.count), 5) + yield Settle() + self.assertEqual((yield self.count), 5) + for _ in range(3): + yield Delay(1e-6) + yield self.sync.clk.eq(1) + yield Delay(1e-6) + yield self.sync.clk.eq(0) + self.assertEqual((yield self.count), 0) + sim.add_process(process) def test_counter_clock_and_sync_process(self): self.setUp_counter() @@ -611,10 +611,9 @@ class SimulatorIntegrationTestCase(FHDLTestCase): def process(): yield self.i.eq(0b10101010) yield self.i[:4].eq(-1) - yield Settle() self.assertEqual((yield self.i[:4]), 0b1111) self.assertEqual((yield self.i), 0b10101111) - sim.add_process(process) + sim.add_testbench(process) def test_run_until(self): m = Module() @@ -626,7 +625,7 @@ class SimulatorIntegrationTestCase(FHDLTestCase): for _ in range(101): yield Delay(1e-6) self.fail() - sim.add_process(process) + sim.add_testbench(process) def test_run_until_fail(self): m = Module() @@ -639,13 +638,13 @@ class SimulatorIntegrationTestCase(FHDLTestCase): for _ in range(99): yield Delay(1e-6) self.fail() - sim.add_process(process) + sim.add_testbench(process) def test_add_process_wrong(self): with self.assertSimulation(Module()) as sim: with self.assertRaisesRegex(TypeError, r"^Cannot add a process 1 because it is not a generator function$"): - sim.add_process(1) + sim.add_sync_process(1) def test_add_process_wrong_generator(self): with self.assertSimulation(Module()) as sim: @@ -653,7 +652,7 @@ class SimulatorIntegrationTestCase(FHDLTestCase): r"^Cannot add a process <.+?> because it is not a generator function$"): def process(): yield Delay() - sim.add_process(process()) + sim.add_sync_process(process()) def test_add_clock_wrong_twice(self): m = Module() @@ -679,14 +678,47 @@ class SimulatorIntegrationTestCase(FHDLTestCase): def test_command_wrong(self): survived = False - with self.assertSimulation(Module()) as sim: + with _ignore_deprecated(): + with self.assertSimulation(Module()) as sim: + def process(): + nonlocal survived + with self.assertRaisesRegex(TypeError, + r"Received unsupported command 1 from process .+?"): + yield 1 + survived = True + sim.add_process(process) + self.assertTrue(survived) + + def test_sync_command_deprecated(self): + survived = False + m = Module() + dummy = Signal() + m.d.sync += dummy.eq(1) + with self.assertSimulation(m) as sim: + def process(): + nonlocal survived + with self.assertWarnsRegex(DeprecationWarning, + r"Using `Delay` is deprecated within `add_sync_process`"): + yield Delay(1e-8) + survived = True + sim.add_sync_process(process) + sim.add_clock(1e-6) + self.assertTrue(survived) + + def test_sync_command_wrong(self): + survived = False + m = Module() + dummy = Signal() + m.d.sync += dummy.eq(1) + with self.assertSimulation(m) as sim: def process(): nonlocal survived with self.assertRaisesRegex(TypeError, r"Received unsupported command 1 from process .+?"): yield 1 survived = True - sim.add_process(process) + sim.add_sync_process(process) + sim.add_clock(1e-6) self.assertTrue(survived) def test_value_castable(self): @@ -701,13 +733,19 @@ class SimulatorIntegrationTestCase(FHDLTestCase): a = Array([1,2,3]) a[MyValue()] + def test_bench_command_wrong(self): survived = False with self.assertSimulation(Module()) as sim: def process(): nonlocal survived - yield MyValue() + with self.assertWarnsRegex(DeprecationWarning, + r"The `Settle` command is deprecated"): + settle = Settle() + with self.assertRaisesRegex(TypeError, + r"Command \(settle\) is not allowed in testbenches"): + yield settle survived = True - sim.add_process(process) + sim.add_testbench(process) self.assertTrue(survived) def setUp_memory(self, rd_synchronous=True, rd_transparent=True, wr_granularity=None): @@ -755,23 +793,23 @@ class SimulatorIntegrationTestCase(FHDLTestCase): def process(): yield self.wrport.data.eq(0x50) yield self.wrport.en.eq(0b00) - yield + yield Tick() yield self.wrport.en.eq(0) - yield + yield Tick() self.assertEqual((yield self.rdport.data), 0xaa) yield self.wrport.en.eq(0b10) - yield + yield Tick() yield self.wrport.en.eq(0) - yield + yield Tick() self.assertEqual((yield self.rdport.data), 0x5a) yield self.wrport.data.eq(0x33) yield self.wrport.en.eq(0b01) - yield + yield Tick() yield self.wrport.en.eq(0) - yield + yield Tick() self.assertEqual((yield self.rdport.data), 0x53) sim.add_clock(1e-6) - sim.add_sync_process(process) + sim.add_testbench(process) def test_memory_read_before_write(self): self.setUp_memory(rd_transparent=False) @@ -779,52 +817,46 @@ class SimulatorIntegrationTestCase(FHDLTestCase): def process(): yield self.wrport.data.eq(0x33) yield self.wrport.en.eq(1) - yield + yield Tick() self.assertEqual((yield self.rdport.data), 0xaa) - yield - self.assertEqual((yield self.rdport.data), 0xaa) - yield Settle() + yield Tick() self.assertEqual((yield self.rdport.data), 0x33) sim.add_clock(1e-6) - sim.add_sync_process(process) + sim.add_testbench(process) def test_memory_write_through(self): self.setUp_memory(rd_transparent=True) with self.assertSimulation(self.m) as sim: def process(): + yield Tick() yield self.wrport.data.eq(0x33) yield self.wrport.en.eq(1) - yield self.assertEqual((yield self.rdport.data), 0xaa) - yield Settle() + yield Tick() self.assertEqual((yield self.rdport.data), 0x33) - yield + yield Tick() yield self.rdport.addr.eq(1) - yield Settle() self.assertEqual((yield self.rdport.data), 0x33) sim.add_clock(1e-6) - sim.add_sync_process(process) + sim.add_testbench(process) def test_memory_async_read_write(self): self.setUp_memory(rd_synchronous=False) with self.assertSimulation(self.m) as sim: def process(): yield self.rdport.addr.eq(0) - yield Settle() self.assertEqual((yield self.rdport.data), 0xaa) yield self.rdport.addr.eq(1) - yield Settle() self.assertEqual((yield self.rdport.data), 0x55) yield self.rdport.addr.eq(0) yield self.wrport.addr.eq(0) yield self.wrport.data.eq(0x33) yield self.wrport.en.eq(1) - yield Tick("sync") self.assertEqual((yield self.rdport.data), 0xaa) - yield Settle() + yield Tick("sync") self.assertEqual((yield self.rdport.data), 0x33) sim.add_clock(1e-6) - sim.add_process(process) + sim.add_testbench(process) def test_memory_read_only(self): self.m = Module() @@ -841,6 +873,49 @@ class SimulatorIntegrationTestCase(FHDLTestCase): sim.add_clock(1e-6) sim.add_sync_process(process) + def test_comb_bench_process(self): + m = Module() + a = Signal(reset=1) + b = Signal() + m.d.comb += b.eq(a) + with self.assertSimulation(m) as sim: + def process(): + self.assertEqual((yield a), 1) + self.assertEqual((yield b), 1) + yield a.eq(0) + self.assertEqual((yield a), 0) + self.assertEqual((yield b), 0) + sim.add_testbench(process) + + def test_sync_bench_process(self): + m = Module() + a = Signal(reset=1) + b = Signal() + m.d.sync += b.eq(a) + t = Signal() + m.d.sync += t.eq(~t) + with self.assertSimulation(m) as sim: + def process(): + self.assertEqual((yield a), 1) + self.assertEqual((yield b), 0) + self.assertEqual((yield t), 0) + yield Tick() + self.assertEqual((yield a), 1) + self.assertEqual((yield b), 1) + self.assertEqual((yield t), 1) + yield Tick() + self.assertEqual((yield a), 1) + self.assertEqual((yield b), 1) + self.assertEqual((yield t), 0) + yield a.eq(0) + self.assertEqual((yield a), 0) + self.assertEqual((yield b), 1) + yield Tick() + self.assertEqual((yield a), 0) + self.assertEqual((yield b), 0) + sim.add_clock(1e-6) + sim.add_testbench(process) + def test_memory_transparency_simple(self): m = Module() init = [0x11, 0x22, 0x33, 0x44] @@ -850,41 +925,35 @@ class SimulatorIntegrationTestCase(FHDLTestCase): with self.assertSimulation(m) as sim: def process(): yield rdport.addr.eq(0) - yield - yield Settle() + yield Tick() self.assertEqual((yield rdport.data), 0x11) yield rdport.addr.eq(1) - yield - yield Settle() + yield Tick() self.assertEqual((yield rdport.data), 0x22) yield wrport.addr.eq(0) yield wrport.data.eq(0x44444444) yield wrport.en.eq(1) - yield - yield Settle() + yield Tick() self.assertEqual((yield rdport.data), 0x22) yield wrport.addr.eq(1) yield wrport.data.eq(0x55) yield wrport.en.eq(1) - yield - yield Settle() + yield Tick() self.assertEqual((yield rdport.data), 0x55) yield wrport.addr.eq(1) yield wrport.data.eq(0x66) yield wrport.en.eq(1) yield rdport.en.eq(0) - yield - yield Settle() + yield Tick() self.assertEqual((yield rdport.data), 0x55) yield wrport.addr.eq(2) yield wrport.data.eq(0x77) yield wrport.en.eq(1) yield rdport.en.eq(1) - yield - yield Settle() + yield Tick() self.assertEqual((yield rdport.data), 0x66) sim.add_clock(1e-6) - sim.add_sync_process(process) + sim.add_testbench(process) def test_memory_transparency_multibit(self): m = Module() @@ -895,41 +964,35 @@ class SimulatorIntegrationTestCase(FHDLTestCase): with self.assertSimulation(m) as sim: def process(): yield rdport.addr.eq(0) - yield - yield Settle() + yield Tick() self.assertEqual((yield rdport.data), 0x11111111) yield rdport.addr.eq(1) - yield - yield Settle() + yield Tick() self.assertEqual((yield rdport.data), 0x22222222) yield wrport.addr.eq(0) yield wrport.data.eq(0x44444444) yield wrport.en.eq(1) - yield - yield Settle() + yield Tick() self.assertEqual((yield rdport.data), 0x22222222) yield wrport.addr.eq(1) yield wrport.data.eq(0x55555555) yield wrport.en.eq(1) - yield - yield Settle() + yield Tick() self.assertEqual((yield rdport.data), 0x22222255) yield wrport.addr.eq(1) yield wrport.data.eq(0x66666666) yield wrport.en.eq(2) yield rdport.en.eq(0) - yield - yield Settle() + yield Tick() self.assertEqual((yield rdport.data), 0x22222255) yield wrport.addr.eq(1) yield wrport.data.eq(0x77777777) yield wrport.en.eq(4) yield rdport.en.eq(1) - yield - yield Settle() + yield Tick() self.assertEqual((yield rdport.data), 0x22776655) sim.add_clock(1e-6) - sim.add_sync_process(process) + sim.add_testbench(process) def test_vcd_wrong_nonzero_time(self): s = Signal() @@ -977,7 +1040,7 @@ class SimulatorRegressionTestCase(FHDLTestCase): sim = Simulator(Module()) def process(): self.assertEqual((yield -(Const(0b11, 2).as_signed())), 1) - sim.add_process(process) + sim.add_testbench(process) sim.run() def test_bug_595(self): @@ -1018,5 +1081,5 @@ class SimulatorRegressionTestCase(FHDLTestCase): self.assertEqual((yield C(0b0000, 4) | ~C(1, 1)), 0b0000) self.assertEqual((yield C(0b1111, 4) & ~C(1, 1)), 0b0000) self.assertEqual((yield C(0b1111, 4) ^ ~C(1, 1)), 0b1111) - sim.add_process(process) + sim.add_testbench(process) sim.run()