Skip to content

Commit 89eae72

Browse files
committed
sim: check type of testbench when adding one.
Fixes amaranth-lang#1363.
1 parent d9b9c49 commit 89eae72

File tree

2 files changed

+43
-14
lines changed

2 files changed

+43
-14
lines changed

amaranth/sim/core.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,15 @@ def __init__(self, fragment, *, engine="pysim"):
3535
self._engine = engine(self._design)
3636
self._clocked = set()
3737

38-
def _check_process(self, process):
39-
if not (inspect.isgeneratorfunction(process) or inspect.iscoroutinefunction(process)):
40-
raise TypeError("Cannot add a process {!r} because it is not a generator function"
41-
.format(process))
42-
return process
38+
def _check_function(self, function, *, kind):
39+
if not (inspect.isgeneratorfunction(function) or inspect.iscoroutinefunction(function)):
40+
raise TypeError(
41+
f"Cannot add a {kind} {function!r} because it is not an async function or "
42+
f"generator function")
43+
return function
4344

4445
def add_process(self, process):
45-
process = self._check_process(process)
46+
process = self._check_function(process, kind="process")
4647
if inspect.iscoroutinefunction(process):
4748
self._engine.add_async_process(self, process)
4849
else:
@@ -54,16 +55,17 @@ def wrapper():
5455
wrap_process = coro_wrapper(wrapper, testbench=False)
5556
self._engine.add_async_process(self, wrap_process)
5657

57-
def add_testbench(self, process, *, background=False):
58-
if inspect.iscoroutinefunction(process):
59-
self._engine.add_async_testbench(self, process, background=background)
58+
def add_testbench(self, testbench, *, background=False):
59+
testbench = self._check_function(testbench, kind="testbench")
60+
if inspect.iscoroutinefunction(testbench):
61+
self._engine.add_async_testbench(self, testbench, background=background)
6062
else:
61-
process = coro_wrapper(process, testbench=True)
62-
self._engine.add_async_testbench(self, process, background=background)
63+
testbench = coro_wrapper(testbench, testbench=True)
64+
self._engine.add_async_testbench(self, testbench, background=background)
6365

6466
@deprecated("The `add_sync_process` method is deprecated per RFC 27. Use `add_process` or `add_testbench` instead.")
6567
def add_sync_process(self, process, *, domain="sync"):
66-
process = self._check_process(process)
68+
process = self._check_function(process, kind="process")
6769
def wrapper():
6870
# Only start a sync process after the first clock edge (or reset edge, if the domain
6971
# uses an asynchronous reset). This matches the behavior of synchronous FFs.

tests/test_sim.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -718,17 +718,35 @@ async def process(ctx):
718718
def test_add_process_wrong(self):
719719
with self.assertSimulation(Module()) as sim:
720720
with self.assertRaisesRegex(TypeError,
721-
r"^Cannot add a process 1 because it is not a generator function$"):
721+
r"^Cannot add a process 1 because it is not an async function or "
722+
r"generator function$"):
722723
sim.add_process(1)
723724

724725
def test_add_process_wrong_generator(self):
725726
with self.assertSimulation(Module()) as sim:
726727
with self.assertRaisesRegex(TypeError,
727-
r"^Cannot add a process <.+?> because it is not a generator function$"):
728+
r"^Cannot add a process <.+?> because it is not an async function or "
729+
r"generator function$"):
728730
def process():
729731
yield Delay()
730732
sim.add_process(process())
731733

734+
def test_add_testbench_wrong(self):
735+
with self.assertSimulation(Module()) as sim:
736+
with self.assertRaisesRegex(TypeError,
737+
r"^Cannot add a testbench 1 because it is not an async function or "
738+
r"generator function$"):
739+
sim.add_testbench(1)
740+
741+
def test_add_testbench_wrong_generator(self):
742+
with self.assertSimulation(Module()) as sim:
743+
with self.assertRaisesRegex(TypeError,
744+
r"^Cannot add a testbench <.+?> because it is not an async function or "
745+
r"generator function$"):
746+
def testbench():
747+
yield Delay()
748+
sim.add_testbench(testbench())
749+
732750
def test_add_clock_wrong_twice(self):
733751
m = Module()
734752
s = Signal()
@@ -1935,3 +1953,12 @@ async def testbench(ctx):
19351953

19361954
self.assertTrue(reached_tb)
19371955
self.assertTrue(reached_proc)
1956+
1957+
def test_bug_1363(self):
1958+
sim = Simulator(Module())
1959+
with self.assertRaisesRegex(TypeError,
1960+
r"^Cannot add a testbench <.+?> because it is not an async function or "
1961+
r"generator function$"):
1962+
async def testbench():
1963+
yield Delay()
1964+
sim.add_testbench(testbench())

0 commit comments

Comments
 (0)