From d3034c9ff898c1bf7306d2ec1f1224789b29e0cf Mon Sep 17 00:00:00 2001 From: Marek Materzok Date: Wed, 13 Nov 2024 13:30:55 +0100 Subject: [PATCH] Renamings --- test/backend/test_annoucement.py | 16 +- test/backend/test_retirement.py | 23 +-- test/cache/test_icache.py | 58 +++--- test/core_structs/test_rat.py | 4 +- test/core_structs/test_reorder_buffer.py | 8 +- test/frontend/test_decode_stage.py | 8 +- test/frontend/test_fetch.py | 22 +-- test/func_blocks/csr/test_csr.py | 40 ++-- test/func_blocks/fu/common/test_rs.py | 15 +- test/func_blocks/fu/functional_common.py | 17 +- test/func_blocks/fu/test_fu_decoder.py | 2 +- .../func_blocks/fu/test_pipelined_mul_unit.py | 4 +- test/func_blocks/fu/test_unsigned_mul_unit.py | 6 +- test/func_blocks/lsu/test_dummylsu.py | 24 +-- test/func_blocks/lsu/test_pma.py | 12 +- test/peripherals/test_axi_lite.py | 14 +- test/peripherals/test_wishbone.py | 18 +- test/priv/traps/test_exception.py | 5 +- test/regression/pysim.py | 2 +- test/scheduler/test_rs_selection.py | 18 +- test/scheduler/test_scheduler.py | 26 +-- test/scheduler/test_wakeup_select.py | 8 +- test/test_core.py | 8 +- test/transactron/core/test_transactions.py | 10 +- test/transactron/lib/test_fifo.py | 12 +- test/transactron/lib/test_transaction_lib.py | 72 ++++---- test/transactron/test_adapter.py | 7 +- test/transactron/test_methods.py | 30 +-- test/transactron/test_metrics.py | 26 +-- test/transactron/test_simultaneous.py | 8 +- .../test_transactron_lib_storage.py | 2 +- .../testing/test_validate_arguments.py | 12 +- test/transactron/utils/test_amaranth_ext.py | 1 + transactron/testing/__init__.py | 3 + transactron/testing/functions.py | 30 +-- transactron/testing/infrastructure.py | 112 ++---------- transactron/testing/logging.py | 44 +++-- transactron/testing/profiler.py | 37 ++-- transactron/testing/sugar.py | 87 +-------- transactron/testing/testbenchio.py | 172 ++---------------- transactron/testing/tick_count.py | 25 +++ 41 files changed, 374 insertions(+), 674 deletions(-) create mode 100644 transactron/testing/tick_count.py diff --git a/test/backend/test_annoucement.py b/test/backend/test_annoucement.py index 901075fc8..e931a4ddd 100644 --- a/test/backend/test_annoucement.py +++ b/test/backend/test_annoucement.py @@ -9,7 +9,7 @@ from coreblocks.interface.layouts import * from coreblocks.params import GenParams from coreblocks.params.configurations import test_core_config -from transactron.testing import TestCaseWithSimulator, AsyncTestbenchIO +from transactron.testing import TestCaseWithSimulator, TestbenchIO class BackendTestCircuit(Elaboratable): @@ -38,7 +38,7 @@ def elaborate(self, platform): get_results.append(fifo.read) m.submodules[f"fu_fifo_{i}"] = fifo - fifo_in = AsyncTestbenchIO(AdapterTrans(fifo.write)) + fifo_in = TestbenchIO(AdapterTrans(fifo.write)) m.submodules[f"fu_fifo_{i}_in"] = fifo_in self.fu_fifo_ins.append(fifo_in) @@ -50,11 +50,11 @@ def elaborate(self, platform): ) # Create stubs for interfaces used by result announcement - self.rs_announce_val_tbio = AsyncTestbenchIO(Adapter(i=self.lay_rs_write, o=self.lay_rs_write)) + self.rs_announce_val_tbio = TestbenchIO(Adapter(i=self.lay_rs_write, o=self.lay_rs_write)) m.submodules.rs_announce_val_tbio = self.rs_announce_val_tbio - self.rf_announce_val_tbio = AsyncTestbenchIO(Adapter(i=self.lay_rf_write, o=self.lay_rf_write)) + self.rf_announce_val_tbio = TestbenchIO(Adapter(i=self.lay_rf_write, o=self.lay_rf_write)) m.submodules.rf_announce_val_tbio = self.rf_announce_val_tbio - self.rob_mark_done_tbio = AsyncTestbenchIO(Adapter(i=self.lay_rob_mark_done, o=self.lay_rob_mark_done)) + self.rob_mark_done_tbio = TestbenchIO(Adapter(i=self.lay_rob_mark_done, o=self.lay_rob_mark_done)) m.submodules.rob_mark_done_tbio = self.rob_mark_done_tbio # Create result announcement @@ -108,9 +108,9 @@ def generate_producer(self, i: int): async def producer(sim: TestbenchContext): inputs = self.fu_inputs[i] for rob_id, result, rp_dst in inputs: - io: AsyncTestbenchIO = self.m.fu_fifo_ins[i] + io: TestbenchIO = self.m.fu_fifo_ins[i] io.call_init(sim, rob_id=rob_id, result=result, rp_dst=rp_dst) - await self.async_random_wait(sim, self.max_wait) + await self.random_wait(sim, self.max_wait) self.producer_end[i] = True return producer @@ -146,7 +146,7 @@ async def consumer(self, sim: TestbenchContext): del self.expected_output[t] else: self.expected_output[t] -= 1 - await self.async_random_wait(sim, self.max_wait) + await self.random_wait(sim, self.max_wait) def test_one_out(self): self.fu_count = 1 diff --git a/test/backend/test_retirement.py b/test/backend/test_retirement.py index 750690e4d..4f8be80d1 100644 --- a/test/backend/test_retirement.py +++ b/test/backend/test_retirement.py @@ -12,6 +12,7 @@ from coreblocks.params import GenParams from coreblocks.interface.layouts import ROBLayouts, RFLayouts, SchedulerLayouts from coreblocks.params.configurations import test_core_config +from transactron.lib.adapters import AdapterTrans from transactron.testing import * from collections import deque @@ -39,28 +40,28 @@ def elaborate(self, platform): scheduler_layouts.free_rf_layout, 2**self.gen_params.phys_regs_bits ) - m.submodules.mock_rob_peek = self.mock_rob_peek = AsyncTestbenchIO( + m.submodules.mock_rob_peek = self.mock_rob_peek = TestbenchIO( Adapter(o=rob_layouts.peek_layout, nonexclusive=True) ) - m.submodules.mock_rob_retire = self.mock_rob_retire = AsyncTestbenchIO(Adapter()) + m.submodules.mock_rob_retire = self.mock_rob_retire = TestbenchIO(Adapter()) - m.submodules.mock_rf_free = self.mock_rf_free = AsyncTestbenchIO(Adapter(i=rf_layouts.rf_free)) + m.submodules.mock_rf_free = self.mock_rf_free = TestbenchIO(Adapter(i=rf_layouts.rf_free)) - m.submodules.mock_exception_cause = self.mock_exception_cause = AsyncTestbenchIO( + m.submodules.mock_exception_cause = self.mock_exception_cause = TestbenchIO( Adapter(o=exception_layouts.get, nonexclusive=True) ) - m.submodules.mock_exception_clear = self.mock_exception_clear = AsyncTestbenchIO(Adapter()) + m.submodules.mock_exception_clear = self.mock_exception_clear = TestbenchIO(Adapter()) m.submodules.generic_csr = self.generic_csr = GenericCSRRegisters(self.gen_params) DependencyContext.get().add_dependency(CSRInstancesKey(), self.generic_csr) - m.submodules.mock_fetch_continue = self.mock_fetch_continue = AsyncTestbenchIO(Adapter(i=fetch_layouts.resume)) - m.submodules.mock_instr_decrement = self.mock_instr_decrement = AsyncTestbenchIO( + m.submodules.mock_fetch_continue = self.mock_fetch_continue = TestbenchIO(Adapter(i=fetch_layouts.resume)) + m.submodules.mock_instr_decrement = self.mock_instr_decrement = TestbenchIO( Adapter(o=core_instr_counter_layouts.decrement) ) - m.submodules.mock_trap_entry = self.mock_trap_entry = AsyncTestbenchIO(Adapter()) - m.submodules.mock_async_interrupt_cause = self.mock_async_interrupt_cause = AsyncTestbenchIO( + m.submodules.mock_trap_entry = self.mock_trap_entry = TestbenchIO(Adapter()) + m.submodules.mock_async_interrupt_cause = self.mock_async_interrupt_cause = TestbenchIO( Adapter(o=interrupt_controller_layouts.interrupt_cause) ) @@ -81,10 +82,10 @@ def elaborate(self, platform): async_interrupt_cause=self.mock_async_interrupt_cause.adapter.iface, ) - m.submodules.free_rf_fifo_adapter = self.free_rf_adapter = AsyncTestbenchIO(AdapterTrans(self.free_rf.read)) + m.submodules.free_rf_fifo_adapter = self.free_rf_adapter = TestbenchIO(AdapterTrans(self.free_rf.read)) precommit = DependencyContext.get().get_dependency(InstructionPrecommitKey()) - m.submodules.precommit_adapter = self.precommit_adapter = AsyncTestbenchIO(AdapterTrans(precommit)) + m.submodules.precommit_adapter = self.precommit_adapter = TestbenchIO(AdapterTrans(precommit)) return m diff --git a/test/cache/test_icache.py b/test/cache/test_icache.py index c41a2e496..787ed803a 100644 --- a/test/cache/test_icache.py +++ b/test/cache/test_icache.py @@ -16,7 +16,7 @@ from coreblocks.params.configurations import test_core_config from coreblocks.cache.refiller import SimpleCommonBusCacheRefiller -from transactron.testing import TestCaseWithSimulator, AsyncTestbenchIO, async_def_method_mock +from transactron.testing import TestCaseWithSimulator, TestbenchIO, async_def_method_mock from transactron.testing.functions import MethodData from transactron.testing.sugar import MethodMock from transactron.testing.testbenchio import CallTrigger @@ -42,8 +42,8 @@ def elaborate(self, platform): self.gen_params.get(ICacheLayouts), self.cp, self.bus_master_adapter ) - self.start_refill = AsyncTestbenchIO(AdapterTrans(self.refiller.start_refill)) - self.accept_refill = AsyncTestbenchIO(AdapterTrans(self.refiller.accept_refill)) + self.start_refill = TestbenchIO(AdapterTrans(self.refiller.start_refill)) + self.accept_refill = TestbenchIO(AdapterTrans(self.refiller.accept_refill)) m.submodules.wb_master = self.wb_master m.submodules.bus_master_adapter = self.bus_master_adapter @@ -109,7 +109,7 @@ async def wishbone_slave(self, sim: TestbenchContext): # Wishbone is addressing words, so we need to shift it a bit to get the real address. addr = adr << exact_log2(self.cp.word_width_bytes) - await self.async_random_wait_geom(sim, 0.5) + await self.random_wait_geom(sim, 0.5) err = 1 if addr in self.bad_addresses else 0 @@ -169,8 +169,8 @@ def elaborate(self, platform): m.submodules.bypass = self.bypass = ICacheBypass( self.gen_params.get(ICacheLayouts), self.cp, self.bus_master_adapter ) - m.submodules.issue_req = self.issue_req = AsyncTestbenchIO(AdapterTrans(self.bypass.issue_req)) - m.submodules.accept_res = self.accept_res = AsyncTestbenchIO(AdapterTrans(self.bypass.accept_res)) + m.submodules.issue_req = self.issue_req = TestbenchIO(AdapterTrans(self.bypass.issue_req)) + m.submodules.accept_res = self.accept_res = TestbenchIO(AdapterTrans(self.bypass.accept_res)) self.wb_ctrl = WishboneInterfaceWrapper(self.wb_master.wb_master) @@ -225,7 +225,7 @@ async def wishbone_slave(self, sim: TestbenchContext): # Wishbone is addressing words, so we need to shift it a bit to get the real address. addr = adr << exact_log2(self.cp.word_width_bytes) - await self.async_random_wait_geom(sim, 0.5) + await self.random_wait_geom(sim, 0.5) err = 1 if addr in self.bad_addrs else 0 @@ -240,7 +240,7 @@ async def user_process(self, sim: TestbenchContext): req_addr = self.requests.popleft() & ~(self.cp.fetch_block_bytes - 1) await self.m.issue_req.call(sim, addr=req_addr) - await self.async_random_wait_geom(sim, 0.5) + await self.random_wait_geom(sim, 0.5) ret = await self.m.accept_res.call(sim) @@ -254,7 +254,7 @@ async def user_process(self, sim: TestbenchContext): data |= self.mem[req_addr + 4] << 32 assert ret["fetch_block"] == data - await self.async_random_wait_geom(sim, 0.5) + await self.random_wait_geom(sim, 0.5) def test(self): with self.run_simulation(self.m) as sim: @@ -266,8 +266,8 @@ class MockedCacheRefiller(Elaboratable, CacheRefillerInterface): def __init__(self, gen_params: GenParams): layouts = gen_params.get(ICacheLayouts) - self.start_refill_mock = AsyncTestbenchIO(Adapter(i=layouts.start_refill)) - self.accept_refill_mock = AsyncTestbenchIO(Adapter(o=layouts.accept_refill)) + self.start_refill_mock = TestbenchIO(Adapter(i=layouts.start_refill)) + self.accept_refill_mock = TestbenchIO(Adapter(o=layouts.accept_refill)) self.start_refill = self.start_refill_mock.adapter.iface self.accept_refill = self.accept_refill_mock.adapter.iface @@ -291,9 +291,9 @@ def elaborate(self, platform): m.submodules.refiller = self.refiller = MockedCacheRefiller(self.gen_params) m.submodules.cache = self.cache = ICache(self.gen_params.get(ICacheLayouts), self.cp, self.refiller) - m.submodules.issue_req = self.issue_req = AsyncTestbenchIO(AdapterTrans(self.cache.issue_req)) - m.submodules.accept_res = self.accept_res = AsyncTestbenchIO(AdapterTrans(self.cache.accept_res)) - m.submodules.flush_cache = self.flush_cache = AsyncTestbenchIO(AdapterTrans(self.cache.flush)) + m.submodules.issue_req = self.issue_req = TestbenchIO(AdapterTrans(self.cache.issue_req)) + m.submodules.accept_res = self.accept_res = TestbenchIO(AdapterTrans(self.cache.accept_res)) + m.submodules.flush_cache = self.flush_cache = TestbenchIO(AdapterTrans(self.cache.flush)) return m @@ -491,7 +491,7 @@ async def cache_process(sim: TestbenchContext): await self.call_cache(sim, addr) self.expect_refill(addr) - await self.async_tick(sim, 4) + await self.tick(sim, 4) # Create a stream of requests to ensure the pipeline is working self.m.accept_res.enable(sim) @@ -508,14 +508,14 @@ async def cache_process(sim: TestbenchContext): self.m.accept_res.disable(sim) - await self.async_tick(sim, 4) + await self.tick(sim, 4) # Check how the cache handles queuing the requests await self.send_req(sim, addr=0x00010000 + 3 * self.cp.line_size_bytes) await self.send_req(sim, addr=0x00010004) # Wait a few cycles. There are two requests queued - await self.async_tick(sim, 4) + await self.tick(sim, 4) self.m.accept_res.enable(sim) await self.expect_resp( @@ -531,7 +531,7 @@ async def cache_process(sim: TestbenchContext): self.m.accept_res.disable(sim) - await self.async_tick(sim, 4) + await self.tick(sim, 4) # Schedule two requests, the first one causing a cache miss await self.send_req(sim, addr=0x00020000) @@ -545,7 +545,7 @@ async def cache_process(sim: TestbenchContext): ) self.m.accept_res.disable(sim) - await self.async_tick(sim, 2) + await self.tick(sim, 2) # Schedule two requests, the second one causing a cache miss await self.send_req(sim, addr=0x00020004) @@ -559,7 +559,7 @@ async def cache_process(sim: TestbenchContext): await self.expect_resp(sim, wait=True) self.m.accept_res.disable(sim) - await self.async_tick(sim, 2) + await self.tick(sim, 2) # Schedule two requests, both causing a cache miss await self.send_req(sim, addr=0x00040000) @@ -686,13 +686,13 @@ async def cache_process(sim: TestbenchContext): await self.expect_resp(sim, wait=True) self.m.accept_res.disable(sim) - await self.async_tick(sim, 3) + await self.tick(sim, 3) # Schedule two requests, the second one causing an error await self.send_req(sim, addr=0x00021004) await self.send_req(sim, addr=0x00030000) - await self.async_tick(sim, 10) + await self.tick(sim, 10) self.m.accept_res.enable(sim) @@ -700,7 +700,7 @@ async def cache_process(sim: TestbenchContext): await self.expect_resp(sim, wait=True) self.m.accept_res.disable(sim) - await self.async_tick(sim, 3) + await self.tick(sim, 3) # Schedule two requests, both causing an error await self.send_req(sim, addr=0x00020000) @@ -716,7 +716,7 @@ async def cache_process(sim: TestbenchContext): await self.send_req(sim, addr=0x00021004) await self.send_req(sim, addr=0x00030000) - await self.async_tick(sim, 10) + await self.tick(sim, 10) # Accept the first response self.m.accept_res.enable(sim) @@ -724,7 +724,7 @@ async def cache_process(sim: TestbenchContext): # Wait before accepting the second response self.m.accept_res.disable(sim) - await self.async_tick(sim, 10) + await self.tick(sim, 10) self.m.accept_res.enable(sim) await self.expect_resp(sim, wait=True) @@ -747,16 +747,16 @@ def test_random(self): async def refiller_ctrl(sim: TestbenchContext): while True: - await self.async_random_wait_geom(sim, 0.4) + await self.random_wait_geom(sim, 0.4) self.accept_refill_request = False - await self.async_random_wait_geom(sim, 0.7) + await self.random_wait_geom(sim, 0.7) self.accept_refill_request = True async def sender(sim: TestbenchContext): for _ in range(iterations): await self.send_req(sim, random.randrange(0, max_addr, 4)) - await self.async_random_wait_geom(sim, 0.5) + await self.random_wait_geom(sim, 0.5) async def receiver(sim: TestbenchContext): for _ in range(iterations): @@ -764,7 +764,7 @@ async def receiver(sim: TestbenchContext): await sim.tick() self.assert_resp(await self.m.accept_res.call(sim)) - await self.async_random_wait_geom(sim, 0.2) + await self.random_wait_geom(sim, 0.2) with self.run_simulation(self.m) as sim: sim.add_testbench(sender) diff --git a/test/core_structs/test_rat.py b/test/core_structs/test_rat.py index 70e915ef5..7428d95f9 100644 --- a/test/core_structs/test_rat.py +++ b/test/core_structs/test_rat.py @@ -40,7 +40,7 @@ def test_single(self): self.rand = Random(0) self.test_steps = 2000 self.gen_params = GenParams(test_core_config.replace(phys_regs_bits=5, rob_entries_bits=6)) - m = SimpleTestCircuit(FRAT(gen_params=self.gen_params), async_tb=True) + m = SimpleTestCircuit(FRAT(gen_params=self.gen_params)) self.m = m self.log_regs = self.gen_params.isa.reg_cnt @@ -80,7 +80,7 @@ def test_single(self): self.rand = Random(0) self.test_steps = 2000 self.gen_params = GenParams(test_core_config.replace(phys_regs_bits=5, rob_entries_bits=6)) - m = SimpleTestCircuit(RRAT(gen_params=self.gen_params), async_tb=True) + m = SimpleTestCircuit(RRAT(gen_params=self.gen_params)) self.m = m self.log_regs = self.gen_params.isa.reg_cnt diff --git a/test/core_structs/test_reorder_buffer.py b/test/core_structs/test_reorder_buffer.py index e5007784f..9fc20e111 100644 --- a/test/core_structs/test_reorder_buffer.py +++ b/test/core_structs/test_reorder_buffer.py @@ -17,7 +17,7 @@ async def gen_input(self, sim: TestbenchContext): while self.regs_left_queue.empty(): await sim.tick() - await self.async_random_wait_geom(sim, 0.5) # to slow down puts + await self.random_wait_geom(sim, 0.5) # to slow down puts log_reg = self.rand.randint(0, self.log_regs - 1) phys_reg = self.regs_left_queue.get() regs = {"rl_dst": log_reg, "rp_dst": phys_reg} @@ -27,7 +27,7 @@ async def gen_input(self, sim: TestbenchContext): async def do_updates(self, sim: TestbenchContext): while True: - await self.async_random_wait_geom(sim, 0.5) # to slow down execution + await self.random_wait_geom(sim, 0.5) # to slow down execution if len(self.to_execute_list) == 0: await sim.tick() else: @@ -64,7 +64,7 @@ def test_single(self): self.gen_params = GenParams( test_core_config.replace(phys_regs_bits=5, rob_entries_bits=6) ) # smaller size means better coverage - m = SimpleTestCircuit(ReorderBuffer(self.gen_params), async_tb=True) + m = SimpleTestCircuit(ReorderBuffer(self.gen_params)) self.m = m self.regs_left_queue = Queue() @@ -115,7 +115,7 @@ def test_single(self): self.gen_params = GenParams(test_core_config) self.test_steps = 2**self.gen_params.rob_entries_bits - m = SimpleTestCircuit(ReorderBuffer(self.gen_params), async_tb=True) + m = SimpleTestCircuit(ReorderBuffer(self.gen_params)) self.m = m self.to_execute_list = [] diff --git a/test/frontend/test_decode_stage.py b/test/frontend/test_decode_stage.py index 6bbae2662..03d313921 100644 --- a/test/frontend/test_decode_stage.py +++ b/test/frontend/test_decode_stage.py @@ -1,8 +1,8 @@ from amaranth_types.types import TestbenchContext import pytest from transactron.lib import AdapterTrans, FIFO - -from transactron.testing import TestCaseWithSimulator, AsyncTestbenchIO, SimpleTestCircuit, ModuleConnector +from transactron.utils.amaranth_ext.elaboratables import ModuleConnector +from transactron.testing import TestCaseWithSimulator, TestbenchIO, SimpleTestCircuit from coreblocks.frontend.decoder.decode_stage import DecodeStage from coreblocks.params import GenParams @@ -19,8 +19,8 @@ def setup(self, fixture_initialize_testing_env): fifo_in = FIFO(self.gen_params.get(FetchLayouts).raw_instr, depth=2) fifo_out = FIFO(self.gen_params.get(DecodeLayouts).decoded_instr, depth=2) - self.fifo_in_write = AsyncTestbenchIO(AdapterTrans(fifo_in.write)) - self.fifo_out_read = AsyncTestbenchIO(AdapterTrans(fifo_out.read)) + self.fifo_in_write = TestbenchIO(AdapterTrans(fifo_in.write)) + self.fifo_out_read = TestbenchIO(AdapterTrans(fifo_out.read)) self.decode = DecodeStage(self.gen_params, fifo_in.read, fifo_out.write) self.m = SimpleTestCircuit( diff --git a/test/frontend/test_fetch.py b/test/frontend/test_fetch.py index fab1fb501..61fd6b137 100644 --- a/test/frontend/test_fetch.py +++ b/test/frontend/test_fetch.py @@ -15,7 +15,7 @@ from transactron.utils import ModuleConnector from transactron.testing import ( TestCaseWithSimulator, - AsyncTestbenchIO, + TestbenchIO, async_def_method_mock, SimpleTestCircuit, ) @@ -33,8 +33,8 @@ class MockedICache(Elaboratable, CacheInterface): def __init__(self, gen_params: GenParams): layouts = gen_params.get(ICacheLayouts) - self.issue_req_io = AsyncTestbenchIO(Adapter(i=layouts.issue_req)) - self.accept_res_io = AsyncTestbenchIO(Adapter(o=layouts.accept_res)) + self.issue_req_io = TestbenchIO(Adapter(i=layouts.issue_req)) + self.accept_res_io = TestbenchIO(Adapter(o=layouts.accept_res)) self.issue_req = self.issue_req_io.adapter.iface self.accept_res = self.accept_res_io.adapter.iface @@ -75,12 +75,12 @@ def setup(self, fixture_initialize_testing_env): self.icache = MockedICache(self.gen_params) fifo = BasicFifo(self.gen_params.get(FetchLayouts).raw_instr, depth=2) - self.io_out = AsyncTestbenchIO(AdapterTrans(fifo.read)) - self.clean_fifo = AsyncTestbenchIO(AdapterTrans(fifo.clear)) - self.fetch_resume_mock = AsyncTestbenchIO(Adapter()) + self.io_out = TestbenchIO(AdapterTrans(fifo.read)) + self.clean_fifo = TestbenchIO(AdapterTrans(fifo.clear)) + self.fetch_resume_mock = TestbenchIO(Adapter()) DependencyContext.get().add_dependency(FetchResumeKey(), self.fetch_resume_mock.adapter.iface) - self.fetch = SimpleTestCircuit(FetchUnit(self.gen_params, self.icache, fifo.write), async_tb=True) + self.fetch = SimpleTestCircuit(FetchUnit(self.gen_params, self.icache, fifo.write)) self.m = ModuleConnector(self.icache, fifo, self.io_out, self.clean_fifo, self.fetch) @@ -144,7 +144,7 @@ async def cache_process(self, sim: ProcessContext): while len(self.input_q) == 0: await sim.tick() - await self.async_random_wait_geom(sim, 0.5) + await self.random_wait_geom(sim, 0.5) req_addr = self.input_q.popleft() & ~(self.gen_params.fetch_block_bytes - 1) @@ -200,9 +200,9 @@ async def fetch_out_check(self, sim: TestbenchContext): assert v["instr"] == instr_data if (instr["jumps"] and (instr["branch_taken"] != v["predicted_taken"])) or access_fault: - await self.async_random_wait(sim, 5) + await self.random_wait(sim, 5) await self.fetch.stall_exception.call(sim) - await self.async_random_wait(sim, 5) + await self.random_wait(sim, 5) # Empty the pipeline await self.clean_fifo.call_try(sim) @@ -434,7 +434,7 @@ def setup(self, fixture_initialize_testing_env): test_core_config.replace(compressed=self.with_rvc, fetch_block_bytes_log=self.fetch_block_log) ) - self.m = SimpleTestCircuit(PredictionChecker(self.gen_params), async_tb=True) + self.m = SimpleTestCircuit(PredictionChecker(self.gen_params)) async def check( self, diff --git a/test/func_blocks/csr/test_csr.py b/test/func_blocks/csr/test_csr.py index 0902ed7ac..6fa8c95e7 100644 --- a/test/func_blocks/csr/test_csr.py +++ b/test/func_blocks/csr/test_csr.py @@ -1,5 +1,5 @@ from amaranth import * -from random import random +import random from transactron.lib import Adapter from transactron.core.tmodule import TModule @@ -17,6 +17,7 @@ CSRInstancesKey, ) from coreblocks.arch.isa_consts import PrivilegeLevel +from transactron.lib.adapters import AdapterTrans from transactron.utils.dependencies import DependencyContext from transactron.testing import * @@ -31,7 +32,7 @@ def __init__(self, gen_params: GenParams, csr_count: int, only_legal=True): def elaborate(self, platform): m = Module() - m.submodules.precommit = self.precommit = AsyncTestbenchIO( + m.submodules.precommit = self.precommit = TestbenchIO( Adapter( i=self.gen_params.get(RetirementLayouts).precommit_in, o=self.gen_params.get(RetirementLayouts).precommit_out, @@ -43,20 +44,20 @@ def elaborate(self, platform): m.submodules.dut = self.dut = CSRUnit(self.gen_params) - m.submodules.select = self.select = AsyncTestbenchIO(AdapterTrans(self.dut.select)) - m.submodules.insert = self.insert = AsyncTestbenchIO(AdapterTrans(self.dut.insert)) - m.submodules.update = self.update = AsyncTestbenchIO(AdapterTrans(self.dut.update)) - m.submodules.accept = self.accept = AsyncTestbenchIO(AdapterTrans(self.dut.get_result)) - m.submodules.exception_report = self.exception_report = AsyncTestbenchIO( + m.submodules.select = self.select = TestbenchIO(AdapterTrans(self.dut.select)) + m.submodules.insert = self.insert = TestbenchIO(AdapterTrans(self.dut.insert)) + m.submodules.update = self.update = TestbenchIO(AdapterTrans(self.dut.update)) + m.submodules.accept = self.accept = TestbenchIO(AdapterTrans(self.dut.get_result)) + m.submodules.exception_report = self.exception_report = TestbenchIO( Adapter(i=self.gen_params.get(ExceptionRegisterLayouts).report) ) m.submodules.csr_instances = self.csr_instances = GenericCSRRegisters(self.gen_params) - m.submodules.priv_io = self.priv_io = AsyncTestbenchIO(AdapterTrans(self.csr_instances.m_mode.priv_mode.write)) + m.submodules.priv_io = self.priv_io = TestbenchIO(AdapterTrans(self.csr_instances.m_mode.priv_mode.write)) DependencyContext.get().add_dependency(ExceptionReportKey(), self.exception_report.adapter.iface) DependencyContext.get().add_dependency(AsyncInterruptInsertSignalKey(), Signal()) DependencyContext.get().add_dependency(CSRInstancesKey(), self.csr_instances) - m.submodules.fetch_resume = self.fetch_resume = AsyncTestbenchIO(AdapterTrans(self.dut.fetch_resume)) + m.submodules.fetch_resume = self.fetch_resume = TestbenchIO(AdapterTrans(self.dut.fetch_resume)) self.csr = {} @@ -134,7 +135,7 @@ async def process_test(self, sim: TestbenchContext): self.dut.fetch_resume.enable(sim) self.dut.exception_report.enable(sim) for _ in range(self.cycles): - await self.async_random_wait_geom(sim) + await self.random_wait_geom(sim) op = self.generate_instruction(sim) @@ -142,17 +143,17 @@ async def process_test(self, sim: TestbenchContext): await self.dut.insert.call(sim, rs_data=op["instr"]) - await self.async_random_wait_geom(sim) + await self.random_wait_geom(sim) if op["exp"]["rs1"]["rp_s1"]: await self.dut.update.call(sim, reg_id=op["exp"]["rs1"]["rp_s1"], reg_val=op["exp"]["rs1"]["value"]) - await self.async_random_wait_geom(sim) + await self.random_wait_geom(sim) # TODO: this is a hack, a real method mock should be used for _, r in self.dut.precommit.adapter.validators: # type: ignore sim.set(r, 1) self.dut.precommit.call_init(sim, side_fx=1) # TODO: sensible precommit handling - await self.async_random_wait_geom(sim) + await self.random_wait_geom(sim) res, resume_res = await CallTrigger(sim).call(self.dut.accept).sample(self.dut.fetch_resume).until_done() self.dut.precommit.disable(sim) @@ -190,7 +191,7 @@ async def process_exception_test(self, sim: TestbenchContext): else: await self.dut.priv_io.call(sim, data=PrivilegeLevel.MACHINE) - await self.async_random_wait_geom(sim) + await self.random_wait_geom(sim) await self.dut.select.call(sim) @@ -209,13 +210,13 @@ async def process_exception_test(self, sim: TestbenchContext): }, ) - await self.async_random_wait_geom(sim) + await self.random_wait_geom(sim) # TODO: this is a hack, a real method mock should be used for _, r in self.dut.precommit.adapter.validators: # type: ignore sim.set(r, 1) self.dut.precommit.call_init(sim, side_fx=1) - await self.async_random_wait_geom(sim) + await self.random_wait_geom(sim) res, report = await CallTrigger(sim).call(self.dut.accept).sample(self.dut.exception_report).until_done() self.dut.precommit.disable(sim) @@ -293,7 +294,7 @@ def test_randomized(self): self.cycles = 200 self.ro_mask = 0b101 - self.dut = SimpleTestCircuit(CSRRegister(0, self.gen_params, ro_bits=self.ro_mask), async_tb=True) + self.dut = SimpleTestCircuit(CSRRegister(0, self.gen_params, ro_bits=self.ro_mask)) with self.run_simulation(self.dut) as sim: sim.add_testbench(self.randomized_process_test) @@ -345,7 +346,6 @@ def write_filtermap(m: TModule, v: Value): fu_read_map=lambda _, v: v << 1, fu_write_filtermap=write_filtermap, ), - async_tb=True, ) with self.run_simulation(self.dut) as sim: @@ -391,9 +391,7 @@ def test_comb(self): random.seed(4326) - self.dut = SimpleTestCircuit( - CSRRegister(None, gen_params, ro_bits=0b1111, fu_write_priority=False, init=0xAB), async_tb=True - ) + self.dut = SimpleTestCircuit(CSRRegister(None, gen_params, ro_bits=0b1111, fu_write_priority=False, init=0xAB)) with self.run_simulation(self.dut) as sim: sim.add_testbench(self.comb_process_test) diff --git a/test/func_blocks/fu/common/test_rs.py b/test/func_blocks/fu/common/test_rs.py index 473626ca8..33321b44b 100644 --- a/test/func_blocks/fu/common/test_rs.py +++ b/test/func_blocks/fu/common/test_rs.py @@ -67,9 +67,7 @@ def test_rs(self): random.seed(42) self.gen_params = GenParams(test_core_config) self.rs_entries_bits = self.gen_params.max_rs_entries_bits - self.m = SimpleTestCircuit( - self.rs_elaboratable(self.gen_params, 2**self.rs_entries_bits, 0, None), async_tb=True - ) + self.m = SimpleTestCircuit(self.rs_elaboratable(self.gen_params, 2**self.rs_entries_bits, 0, None)) self.data_list = create_data_list(self.gen_params, 10 * 2**self.rs_entries_bits) self.select_queue: deque[int] = deque() self.regs_to_update: set[int] = set() @@ -145,7 +143,7 @@ class TestRSMethodInsert(TestCaseWithSimulator): def test_insert(self): self.gen_params = GenParams(test_core_config) self.rs_entries_bits = self.gen_params.max_rs_entries_bits - self.m = SimpleTestCircuit(RS(self.gen_params, 2**self.rs_entries_bits, 0, None), async_tb=True) + self.m = SimpleTestCircuit(RS(self.gen_params, 2**self.rs_entries_bits, 0, None)) self.insert_list = [ { "rs_entry_id": id, @@ -188,7 +186,7 @@ class TestRSMethodSelect(TestCaseWithSimulator): def test_select(self): self.gen_params = GenParams(test_core_config) self.rs_entries_bits = self.gen_params.max_rs_entries_bits - self.m = SimpleTestCircuit(RS(self.gen_params, 2**self.rs_entries_bits, 0, None), async_tb=True) + self.m = SimpleTestCircuit(RS(self.gen_params, 2**self.rs_entries_bits, 0, None)) self.insert_list = [ { "rs_entry_id": id, @@ -246,7 +244,7 @@ class TestRSMethodUpdate(TestCaseWithSimulator): def test_update(self): self.gen_params = GenParams(test_core_config) self.rs_entries_bits = self.gen_params.max_rs_entries_bits - self.m = SimpleTestCircuit(RS(self.gen_params, 2**self.rs_entries_bits, 0, None), async_tb=True) + self.m = SimpleTestCircuit(RS(self.gen_params, 2**self.rs_entries_bits, 0, None)) self.insert_list = [ { "rs_entry_id": id, @@ -332,7 +330,7 @@ class TestRSMethodTake(TestCaseWithSimulator): def test_take(self): self.gen_params = GenParams(test_core_config) self.rs_entries_bits = self.gen_params.max_rs_entries_bits - self.m = SimpleTestCircuit(RS(self.gen_params, 2**self.rs_entries_bits, 0, None), async_tb=True) + self.m = SimpleTestCircuit(RS(self.gen_params, 2**self.rs_entries_bits, 0, None)) self.insert_list = [ { "rs_entry_id": id, @@ -424,7 +422,7 @@ class TestRSMethodGetReadyList(TestCaseWithSimulator): def test_get_ready_list(self): self.gen_params = GenParams(test_core_config) self.rs_entries_bits = self.gen_params.max_rs_entries_bits - self.m = SimpleTestCircuit(RS(self.gen_params, 2**self.rs_entries_bits, 0, None), async_tb=True) + self.m = SimpleTestCircuit(RS(self.gen_params, 2**self.rs_entries_bits, 0, None)) self.insert_list = [ { "rs_entry_id": id, @@ -478,7 +476,6 @@ def test_two_get_ready_lists(self): self.rs_entries_bits = self.gen_params.max_rs_entries_bits self.m = SimpleTestCircuit( RS(self.gen_params, 2**self.rs_entries_bits, 0, [[OpType(1), OpType(2)], [OpType(3), OpType(4)]]), - async_tb=True, ) self.insert_list = [ { diff --git a/test/func_blocks/fu/functional_common.py b/test/func_blocks/fu/functional_common.py index 3a32c7d41..f6dcb8072 100644 --- a/test/func_blocks/fu/functional_common.py +++ b/test/func_blocks/fu/functional_common.py @@ -21,8 +21,7 @@ from transactron.lib import Adapter from transactron.testing import ( RecordIntDict, - RecordIntDictRet, - AsyncTestbenchIO, + TestbenchIO, TestCaseWithSimulator, SimpleTestCircuit, ) @@ -106,20 +105,20 @@ def compute_result(i1: int, i2: int, i_imm: int, pc: int, fn: _T, xlen: int) -> def setup(self, fixture_initialize_testing_env): self.gen_params = GenParams(test_core_config) - self.report_mock = AsyncTestbenchIO(Adapter(i=self.gen_params.get(ExceptionRegisterLayouts).report)) + self.report_mock = TestbenchIO(Adapter(i=self.gen_params.get(ExceptionRegisterLayouts).report)) self.csrs = GenericCSRRegisters(self.gen_params) DependencyContext.get().add_dependency(ExceptionReportKey(), self.report_mock.adapter.iface) DependencyContext.get().add_dependency(AsyncInterruptInsertSignalKey(), Signal()) DependencyContext.get().add_dependency(CSRInstancesKey(), self.csrs) - self.m = SimpleTestCircuit(self.func_unit.get_module(self.gen_params), async_tb=True) + self.m = SimpleTestCircuit(self.func_unit.get_module(self.gen_params)) self.circ = ModuleConnector(dut=self.m, report_mock=self.report_mock, csrs=self.csrs) random.seed(self.seed) self.requests = deque[RecordIntDict]() - self.responses = deque[RecordIntDictRet]() - self.exceptions = deque[RecordIntDictRet]() + self.responses = deque[RecordIntDict]() + self.exceptions = deque[RecordIntDict]() max_int = 2**self.gen_params.isa.xlen - 1 functions = list(self.ops.keys()) @@ -170,13 +169,13 @@ async def consumer(self, sim: TestbenchContext): expected = self.responses.pop() result = await self.m.accept.call(sim) assert expected == data_const_to_dict(result) - await self.async_random_wait(sim, self.max_wait) + await self.random_wait(sim, self.max_wait) async def producer(self, sim: TestbenchContext): while self.requests: req = self.requests.pop() await self.m.issue.call(sim, req) - await self.async_random_wait(sim, self.max_wait) + await self.random_wait(sim, self.max_wait) async def exception_consumer(self, sim: TestbenchContext): # This is a background testbench so that extra calls can be detected reliably @@ -185,7 +184,7 @@ async def exception_consumer(self, sim: TestbenchContext): expected = self.exceptions.pop() result = await self.report_mock.call(sim) assert expected == data_const_to_dict(result) - await self.async_random_wait(sim, self.max_wait) + await self.random_wait(sim, self.max_wait) # keep partialy dependent tests from hanging up and detect extra calls result = await self.report_mock.call(sim) diff --git a/test/func_blocks/fu/test_fu_decoder.py b/test/func_blocks/fu/test_fu_decoder.py index b79941580..a4852d80a 100644 --- a/test/func_blocks/fu/test_fu_decoder.py +++ b/test/func_blocks/fu/test_fu_decoder.py @@ -55,7 +55,7 @@ async def process(sim: TestbenchContext): assert returned == expected - test_circuit = SimpleTestCircuit(decoder, async_tb=True) + test_circuit = SimpleTestCircuit(decoder) with self.run_simulation(test_circuit) as sim: sim.add_testbench(process) diff --git a/test/func_blocks/fu/test_pipelined_mul_unit.py b/test/func_blocks/fu/test_pipelined_mul_unit.py index 4e4377816..09be8ab4f 100644 --- a/test/func_blocks/fu/test_pipelined_mul_unit.py +++ b/test/func_blocks/fu/test_pipelined_mul_unit.py @@ -29,9 +29,7 @@ class TestPipelinedUnsignedMul(TestCaseWithSimulator): def setup_method(self): self.gen_params = GenParams(test_core_config) - self.m = SimpleTestCircuit( - PipelinedUnsignedMul(self.gen_params, self.dsp_width, self.dsp_number), async_tb=True - ) + self.m = SimpleTestCircuit(PipelinedUnsignedMul(self.gen_params, self.dsp_width, self.dsp_number)) self.n_padding = self.dsp_width * 2 ** (math.ceil(math.log2(self.gen_params.isa.xlen / self.dsp_width))) self.number_of_chunks = self.n_padding // self.dsp_width self.number_of_multiplications = self.number_of_chunks**2 diff --git a/test/func_blocks/fu/test_unsigned_mul_unit.py b/test/func_blocks/fu/test_unsigned_mul_unit.py index 1a30cd305..26258d3b7 100644 --- a/test/func_blocks/fu/test_unsigned_mul_unit.py +++ b/test/func_blocks/fu/test_unsigned_mul_unit.py @@ -43,7 +43,7 @@ class TestUnsignedMultiplicationUnit(TestCaseWithSimulator): def setup_method(self): self.gen_params = GenParams(test_core_config) - self.m = SimpleTestCircuit(self.mul_unit(self.gen_params), async_tb=True) + self.m = SimpleTestCircuit(self.mul_unit(self.gen_params)) self.waiting_time = 10 random.seed(1050) @@ -73,13 +73,13 @@ async def consumer(sim: TestbenchContext): expected = self.responses.pop() result = await self.m.accept.call(sim) assert expected == data_const_to_dict(result) - await self.async_random_wait(sim, self.waiting_time) + await self.random_wait(sim, self.waiting_time) async def producer(sim: TestbenchContext): while self.requests: req = self.requests.pop() await self.m.issue.call(sim, req) - await self.async_random_wait(sim, self.waiting_time) + await self.random_wait(sim, self.waiting_time) with self.run_simulation(self.m) as sim: sim.add_testbench(producer) diff --git a/test/func_blocks/lsu/test_dummylsu.py b/test/func_blocks/lsu/test_dummylsu.py index 40ac0c944..3facbaceb 100644 --- a/test/func_blocks/lsu/test_dummylsu.py +++ b/test/func_blocks/lsu/test_dummylsu.py @@ -14,7 +14,7 @@ from transactron.utils.dependencies import DependencyContext from coreblocks.interface.layouts import ExceptionRegisterLayouts, RetirementLayouts from coreblocks.peripherals.wishbone import * -from transactron.testing import AsyncTestbenchIO, TestCaseWithSimulator, async_def_method_mock +from transactron.testing import TestbenchIO, TestCaseWithSimulator, async_def_method_mock from coreblocks.peripherals.bus_adapter import WishboneMasterAdapter from test.peripherals.test_wishbone import WishboneInterfaceWrapper @@ -79,14 +79,14 @@ def elaborate(self, platform): self.bus = WishboneMaster(wb_params) self.bus_master_adapter = WishboneMasterAdapter(self.bus) - m.submodules.exception_report = self.exception_report = AsyncTestbenchIO( + m.submodules.exception_report = self.exception_report = TestbenchIO( Adapter(i=self.gen.get(ExceptionRegisterLayouts).report) ) DependencyContext.get().add_dependency(ExceptionReportKey(), self.exception_report.adapter.iface) layouts = self.gen.get(RetirementLayouts) - m.submodules.precommit = self.precommit = AsyncTestbenchIO( + m.submodules.precommit = self.precommit = TestbenchIO( Adapter( i=layouts.precommit_in, o=layouts.precommit_out, @@ -96,13 +96,13 @@ def elaborate(self, platform): ) DependencyContext.get().add_dependency(InstructionPrecommitKey(), self.precommit.adapter.iface) - m.submodules.core_state = self.core_state = AsyncTestbenchIO(Adapter(o=layouts.core_state, nonexclusive=True)) + m.submodules.core_state = self.core_state = TestbenchIO(Adapter(o=layouts.core_state, nonexclusive=True)) DependencyContext.get().add_dependency(CoreStateKey(), self.core_state.adapter.iface) m.submodules.func_unit = func_unit = LSUDummy(self.gen, self.bus_master_adapter) - m.submodules.issue_mock = self.issue = AsyncTestbenchIO(AdapterTrans(func_unit.issue)) - m.submodules.accept_mock = self.accept = AsyncTestbenchIO(AdapterTrans(func_unit.accept)) + m.submodules.issue_mock = self.issue = TestbenchIO(AdapterTrans(func_unit.issue)) + m.submodules.accept_mock = self.accept = TestbenchIO(AdapterTrans(func_unit.accept)) self.io_in = WishboneInterfaceWrapper(self.bus.wb_master) m.submodules.bus_master_adapter = self.bus_master_adapter m.submodules.bus = self.bus @@ -210,7 +210,7 @@ async def wishbone_slave(self, sim: TestbenchContext): mask = generated_data["mask"] sign = generated_data["sign"] await self.test_module.io_in.slave_wait_and_verify(sim, generated_data["addr"], 0, 0, mask) - await self.async_random_wait(sim, self.max_wait) + await self.random_wait(sim, self.max_wait) resp_data = int((generated_data["rnd_bytes"][:4]).hex(), 16) data_shift = (mask & -mask).bit_length() - 1 @@ -232,7 +232,7 @@ async def inserter(self, sim: TestbenchContext): await sim.tick() self.free_rob_id.remove(req["rob_id"]) await self.test_module.issue.call(sim, req) - await self.async_random_wait(sim, self.max_wait) + await self.random_wait(sim, self.max_wait) async def consumer(self, sim: TestbenchContext): for i in range(self.tests_number): @@ -247,7 +247,7 @@ async def consumer(self, sim: TestbenchContext): assert v["result"] == self.returned_data.pop() assert v["exception"] == exc["err"] - await self.async_random_wait(sim, self.max_wait) + await self.random_wait(sim, self.max_wait) def test(self): @async_def_method_mock(lambda: self.test_module.exception_report) @@ -394,7 +394,7 @@ async def wishbone_slave(self, sim: TestbenchContext): else: data = int(generated_data["data"][-4:].hex(), 16) await self.test_module.io_in.slave_wait_and_verify(sim, generated_data["addr"], data, 1, mask) - await self.async_random_wait(sim, self.max_wait) + await self.random_wait(sim, self.max_wait) await self.test_module.io_in.slave_respond(sim, 0) @@ -404,7 +404,7 @@ async def inserter(self, sim: TestbenchContext): self.get_result_data.appendleft(req["rob_id"]) await self.test_module.issue.call(sim, req) self.precommit_data.appendleft(req["rob_id"]) - await self.async_random_wait(sim, self.max_wait) + await self.random_wait(sim, self.max_wait) async def get_resulter(self, sim: TestbenchContext): for i in range(self.tests_number): @@ -412,7 +412,7 @@ async def get_resulter(self, sim: TestbenchContext): rob_id = self.get_result_data.pop() assert v["rob_id"] == rob_id assert v["rp_dst"] == 0 - await self.async_random_wait(sim, self.max_wait) + await self.random_wait(sim, self.max_wait) self.precommit_data.pop() # retire def precommit_validate(self, rob_id): diff --git a/test/func_blocks/lsu/test_pma.py b/test/func_blocks/lsu/test_pma.py index 1b46e7856..dee6d477c 100644 --- a/test/func_blocks/lsu/test_pma.py +++ b/test/func_blocks/lsu/test_pma.py @@ -12,7 +12,7 @@ from transactron.utils.dependencies import DependencyContext from coreblocks.interface.layouts import ExceptionRegisterLayouts, RetirementLayouts from coreblocks.peripherals.wishbone import * -from transactron.testing import AsyncTestbenchIO, TestCaseWithSimulator, async_def_method_mock +from transactron.testing import TestbenchIO, TestCaseWithSimulator, async_def_method_mock from coreblocks.peripherals.bus_adapter import WishboneMasterAdapter from test.peripherals.test_wishbone import WishboneInterfaceWrapper @@ -59,14 +59,14 @@ def elaborate(self, platform): self.bus = WishboneMaster(wb_params) self.bus_master_adapter = WishboneMasterAdapter(self.bus) - m.submodules.exception_report = self.exception_report = AsyncTestbenchIO( + m.submodules.exception_report = self.exception_report = TestbenchIO( Adapter(i=self.gen.get(ExceptionRegisterLayouts).report) ) DependencyContext.get().add_dependency(ExceptionReportKey(), self.exception_report.adapter.iface) layouts = self.gen.get(RetirementLayouts) - m.submodules.precommit = self.precommit = AsyncTestbenchIO( + m.submodules.precommit = self.precommit = TestbenchIO( Adapter( i=layouts.precommit_in, o=layouts.precommit_out, @@ -76,13 +76,13 @@ def elaborate(self, platform): ) DependencyContext.get().add_dependency(InstructionPrecommitKey(), self.precommit.adapter.iface) - m.submodules.core_state = self.core_state = AsyncTestbenchIO(Adapter(o=layouts.core_state, nonexclusive=True)) + m.submodules.core_state = self.core_state = TestbenchIO(Adapter(o=layouts.core_state, nonexclusive=True)) DependencyContext.get().add_dependency(CoreStateKey(), self.core_state.adapter.iface) m.submodules.func_unit = func_unit = LSUDummy(self.gen, self.bus_master_adapter) - m.submodules.issue_mock = self.issue = AsyncTestbenchIO(AdapterTrans(func_unit.issue)) - m.submodules.accept_mock = self.accept = AsyncTestbenchIO(AdapterTrans(func_unit.accept)) + m.submodules.issue_mock = self.issue = TestbenchIO(AdapterTrans(func_unit.issue)) + m.submodules.accept_mock = self.accept = TestbenchIO(AdapterTrans(func_unit.accept)) self.io_in = WishboneInterfaceWrapper(self.bus.wb_master) m.submodules.bus = self.bus m.submodules.bus_master_adapter = self.bus_master_adapter diff --git a/test/peripherals/test_axi_lite.py b/test/peripherals/test_axi_lite.py index 7b2c13f84..6681c7166 100644 --- a/test/peripherals/test_axi_lite.py +++ b/test/peripherals/test_axi_lite.py @@ -96,18 +96,18 @@ def __init__(self, params: AXILiteParameters): def elaborate(self, platform): m = TModule() m.submodules.alm = alm = self.axi_lite_master = AXILiteMaster(self.params) - m.submodules.rar = self.read_address_request_adapter = AsyncTestbenchIO(AdapterTrans(alm.ra_request)) - m.submodules.rdr = self.read_data_response_adapter = AsyncTestbenchIO(AdapterTrans(alm.rd_response)) - m.submodules.war = self.write_address_request_adapter = AsyncTestbenchIO(AdapterTrans(alm.wa_request)) - m.submodules.wdr = self.write_data_request_adapter = AsyncTestbenchIO(AdapterTrans(alm.wd_request)) - m.submodules.wrr = self.write_response_response_adapter = AsyncTestbenchIO(AdapterTrans(alm.wr_response)) + m.submodules.rar = self.read_address_request_adapter = TestbenchIO(AdapterTrans(alm.ra_request)) + m.submodules.rdr = self.read_data_response_adapter = TestbenchIO(AdapterTrans(alm.rd_response)) + m.submodules.war = self.write_address_request_adapter = TestbenchIO(AdapterTrans(alm.wa_request)) + m.submodules.wdr = self.write_data_request_adapter = TestbenchIO(AdapterTrans(alm.wd_request)) + m.submodules.wrr = self.write_response_response_adapter = TestbenchIO(AdapterTrans(alm.wr_response)) @def_method(m, self.write_request, ready=alm.wa_request.ready & alm.wd_request.ready) def _(arg): alm.wa_request(m, addr=arg.addr, prot=arg.prot) alm.wd_request(m, data=arg.data, strb=arg.strb) - m.submodules.wr = self.write_request_adapter = AsyncTestbenchIO(AdapterTrans(self.write_request)) + m.submodules.wr = self.write_request_adapter = TestbenchIO(AdapterTrans(self.write_request)) return m @@ -194,7 +194,7 @@ async def slave_process(sim: TestbenchContext): await slave.slave_wr_respond(sim, 0) slave.slave_ra_get(sim) - await self.async_tick(sim, 2) + await self.tick(sim, 2) slave.slave_ra_ready(sim, 1) slave.slave_ra_get_and_verify(sim, 1, 1) # wait for next rising edge diff --git a/test/peripherals/test_wishbone.py b/test/peripherals/test_wishbone.py index f99e03099..1e5424509 100644 --- a/test/peripherals/test_wishbone.py +++ b/test/peripherals/test_wishbone.py @@ -3,7 +3,7 @@ from collections import deque from amaranth.lib.wiring import connect -from amaranth_types.types import TestbenchContext +from amaranth_types import AnySimulatorContext, ValueLike from coreblocks.peripherals.wishbone import * @@ -100,8 +100,8 @@ def __init__(self): def elaborate(self, platform): m = Module() m.submodules.wbm = self.wbm = wbm = WishboneMaster(WishboneParameters()) - m.submodules.rqa = self.requestAdapter = AsyncTestbenchIO(AdapterTrans(wbm.request)) - m.submodules.rsa = self.resultAdapter = AsyncTestbenchIO(AdapterTrans(wbm.result)) + m.submodules.rqa = self.requestAdapter = TestbenchIO(AdapterTrans(wbm.request)) + m.submodules.rsa = self.resultAdapter = TestbenchIO(AdapterTrans(wbm.result)) return m def test_manual(self): @@ -259,7 +259,7 @@ def test_randomized(self): random.seed(42) wb_params = WishboneParameters() - pwbm = SimpleTestCircuit(PipelinedWishboneMaster((wb_params)), async_tb=True) + pwbm = SimpleTestCircuit(PipelinedWishboneMaster((wb_params))) async def request_process(sim: TestbenchContext): for _ in range(requests): @@ -274,7 +274,7 @@ async def request_process(sim: TestbenchContext): async def verify_process(sim: TestbenchContext): for _ in range(requests): - await self.async_random_wait_geom(sim, 0.8) + await self.random_wait_geom(sim, 0.8) result = await pwbm.result.call(sim) cres = res_queue.pop() @@ -322,8 +322,8 @@ def elaborate(self, platform): m.submodules.mem_slave = self.mem_slave = WishboneMemorySlave(self.wb_params, **self.mem_args) m.submodules.mem_master = self.mem_master = WishboneMaster(self.wb_params) - m.submodules.request = self.request = AsyncTestbenchIO(AdapterTrans(self.mem_master.request)) - m.submodules.result = self.result = AsyncTestbenchIO(AdapterTrans(self.mem_master.result)) + m.submodules.request = self.request = TestbenchIO(AdapterTrans(self.mem_master.request)) + m.submodules.result = self.result = TestbenchIO(AdapterTrans(self.mem_master.result)) connect(m, self.mem_master.wb_master, self.mem_slave.bus) @@ -358,12 +358,12 @@ async def request_process(sim: TestbenchContext): } req_queue.appendleft(req) - await self.async_random_wait_geom(sim, 0.2) + await self.random_wait_geom(sim, 0.2) await self.m.request.call(sim, req) async def result_process(sim: TestbenchContext): for _ in range(self.iters): - await self.async_random_wait_geom(sim, 0.2) + await self.random_wait_geom(sim, 0.2) res = await self.m.result.call(sim) req = req_queue.pop() diff --git a/test/priv/traps/test_exception.py b/test/priv/traps/test_exception.py index e8842609b..a63832a80 100644 --- a/test/priv/traps/test_exception.py +++ b/test/priv/traps/test_exception.py @@ -33,13 +33,12 @@ def test_randomized(self): self.cycles = 256 - self.rob_idx_mock = AsyncTestbenchIO(Adapter(o=self.gen_params.get(ROBLayouts).get_indices)) - self.fetch_stall_mock = AsyncTestbenchIO(Adapter()) + self.rob_idx_mock = TestbenchIO(Adapter(o=self.gen_params.get(ROBLayouts).get_indices)) + self.fetch_stall_mock = TestbenchIO(Adapter()) self.dut = SimpleTestCircuit( ExceptionInformationRegister( self.gen_params, self.rob_idx_mock.adapter.iface, self.fetch_stall_mock.adapter.iface ), - async_tb=True, ) m = ModuleConnector(self.dut, rob_idx_mock=self.rob_idx_mock, fetch_stall_mock=self.fetch_stall_mock) diff --git a/test/regression/pysim.py b/test/regression/pysim.py index 21585af9e..e74fa00ef 100644 --- a/test/regression/pysim.py +++ b/test/regression/pysim.py @@ -7,6 +7,7 @@ from amaranth_types.types import TestbenchContext from transactron.core.keys import TransactionManagerKey +from transactron.profiler import Profile from .memory import * from .common import SimulationBackend, SimulationExecutionResult @@ -14,7 +15,6 @@ from transactron.testing import ( PysimSimulator, profiler_process, - Profile, make_logging_process, parse_logging_level, ) diff --git a/test/scheduler/test_rs_selection.py b/test/scheduler/test_rs_selection.py index 99cb0f195..b92564fc0 100644 --- a/test/scheduler/test_rs_selection.py +++ b/test/scheduler/test_rs_selection.py @@ -11,7 +11,7 @@ from coreblocks.params.configurations import test_core_config from coreblocks.scheduler.scheduler import RSSelection from transactron.lib import FIFO, Adapter, AdapterTrans -from transactron.testing import TestCaseWithSimulator, AsyncTestbenchIO +from transactron.testing import TestCaseWithSimulator, TestbenchIO from transactron.testing.functions import data_const_to_dict from transactron.testing.sugar import MethodMock, async_def_method_mock @@ -34,10 +34,10 @@ def elaborate(self, platform): m.submodules.out_fifo = out_fifo = FIFO(scheduler_layouts.rs_select_out, 2) # mocked input and output - m.submodules.instr_in = self.instr_in = AsyncTestbenchIO(AdapterTrans(instr_fifo.write)) - m.submodules.instr_out = self.instr_out = AsyncTestbenchIO(AdapterTrans(out_fifo.read)) - m.submodules.rs1_alloc = self.rs1_alloc = AsyncTestbenchIO(Adapter(o=rs_layouts.rs.select_out)) - m.submodules.rs2_alloc = self.rs2_alloc = AsyncTestbenchIO(Adapter(o=rs_layouts.rs.select_out)) + m.submodules.instr_in = self.instr_in = TestbenchIO(AdapterTrans(instr_fifo.write)) + m.submodules.instr_out = self.instr_out = TestbenchIO(AdapterTrans(out_fifo.read)) + m.submodules.rs1_alloc = self.rs1_alloc = TestbenchIO(Adapter(o=rs_layouts.rs.select_out)) + m.submodules.rs2_alloc = self.rs2_alloc = TestbenchIO(Adapter(o=rs_layouts.rs.select_out)) # rs selector m.submodules.selector = self.selector = RSSelection( @@ -94,13 +94,11 @@ async def process(sim: TestbenchContext): self.instr_in.append(instr) await self.m.instr_in.call(sim, instr) - await self.async_random_wait(sim, random_wait) + await self.random_wait(sim, random_wait) return process - def create_rs_alloc_process( - self, io: AsyncTestbenchIO, rs_id: int, rs_optypes: set[OpType], enable_prob: float = 1 - ): + def create_rs_alloc_process(self, io: TestbenchIO, rs_id: int, rs_optypes: set[OpType], enable_prob: float = 1): @async_def_method_mock(lambda: io, enable=lambda: random.random() <= enable_prob) def process(): random_entry = random.randrange(self.gen_params.max_rs_entries) @@ -123,7 +121,7 @@ async def process(sim: TestbenchContext): result = await self.m.instr_out.call(sim) outputs = self.expected_out.popleft() - await self.async_random_wait(sim, random_wait) + await self.random_wait(sim, random_wait) assert data_const_to_dict(result) == outputs return process diff --git a/test/scheduler/test_scheduler.py b/test/scheduler/test_scheduler.py index 84a671e87..5cffe007a 100644 --- a/test/scheduler/test_scheduler.py +++ b/test/scheduler/test_scheduler.py @@ -23,7 +23,7 @@ from coreblocks.params.configurations import test_core_config from coreblocks.core_structs.rob import ReorderBuffer from coreblocks.func_blocks.interface.func_protocols import FuncBlock -from transactron.testing import TestCaseWithSimulator, AsyncTestbenchIO, async_def_method_mock +from transactron.testing import TestCaseWithSimulator, TestbenchIO, async_def_method_mock class SchedulerTestCircuit(Elaboratable): @@ -70,8 +70,8 @@ def elaborate(self, platform): alloc_adapter = Adapter(o=rs_layouts.rs.select_out) insert_adapter = Adapter(i=rs_layouts.rs.insert_in) - select_test = AsyncTestbenchIO(alloc_adapter) - insert_test = AsyncTestbenchIO(insert_adapter) + select_test = TestbenchIO(alloc_adapter) + insert_test = TestbenchIO(insert_adapter) method_rs_alloc.append(alloc_adapter) method_rs_insert.append(insert_adapter) @@ -83,13 +83,13 @@ def elaborate(self, platform): m.submodules[f"rs_insert_{i}"] = self.rs_insert[i] # mocked input and output - m.submodules.rf_write = self.rf_write = AsyncTestbenchIO(AdapterTrans(self.rf.write)) - m.submodules.rf_free = self.rf_free = AsyncTestbenchIO(AdapterTrans(self.rf.free)) - m.submodules.rob_markdone = self.rob_done = AsyncTestbenchIO(AdapterTrans(self.rob.mark_done)) - m.submodules.rob_retire = self.rob_retire = AsyncTestbenchIO(AdapterTrans(self.rob.retire)) - m.submodules.instr_input = self.instr_inp = AsyncTestbenchIO(AdapterTrans(instr_fifo.write)) - m.submodules.free_rf_inp = self.free_rf_inp = AsyncTestbenchIO(AdapterTrans(free_rf_fifo.write)) - m.submodules.core_state = self.core_state = AsyncTestbenchIO( + m.submodules.rf_write = self.rf_write = TestbenchIO(AdapterTrans(self.rf.write)) + m.submodules.rf_free = self.rf_free = TestbenchIO(AdapterTrans(self.rf.free)) + m.submodules.rob_markdone = self.rob_done = TestbenchIO(AdapterTrans(self.rob.mark_done)) + m.submodules.rob_retire = self.rob_retire = TestbenchIO(AdapterTrans(self.rob.retire)) + m.submodules.instr_input = self.instr_inp = TestbenchIO(AdapterTrans(instr_fifo.write)) + m.submodules.free_rf_inp = self.free_rf_inp = TestbenchIO(AdapterTrans(free_rf_fifo.write)) + m.submodules.core_state = self.core_state = TestbenchIO( Adapter(o=self.gen_params.get(RetirementLayouts).core_state) ) DependencyContext.get().add_dependency(CoreStateKey(), self.core_state.adapter.iface) @@ -184,7 +184,7 @@ async def queue_gather(self, sim: TestbenchContext, queues: Iterable[deque]): def make_queue_process( self, *, - io: AsyncTestbenchIO, + io: TestbenchIO, input_queues: Optional[Iterable[deque]] = None, output_queues: Optional[Iterable[deque]] = None, check: Optional[Callable[[TestbenchContext, MethodData, dict], None]] = None, @@ -267,7 +267,7 @@ async def queue_process(sim: TestbenchContext): return queue_process - def make_output_process(self, io: AsyncTestbenchIO, output_queues: Iterable[deque]): + def make_output_process(self, io: TestbenchIO, output_queues: Iterable[deque]): def check(sim: TestbenchContext, got: MethodData, expected: dict): print("check", expected) # TODO: better stubs for Memory? @@ -356,7 +356,7 @@ async def instr_input_process(sim: TestbenchContext): self.free_regs_queue.append(None) self.free_ROB_entries_queue.append(None) - def rs_alloc_process(io: AsyncTestbenchIO, rs_id: int): + def rs_alloc_process(io: TestbenchIO, rs_id: int): @async_def_method_mock(lambda: io) def process(): random_entry = random.randrange(self.gen_params.max_rs_entries) diff --git a/test/scheduler/test_wakeup_select.py b/test/scheduler/test_wakeup_select.py index 59f61b695..8b92769f2 100644 --- a/test/scheduler/test_wakeup_select.py +++ b/test/scheduler/test_wakeup_select.py @@ -17,7 +17,7 @@ from transactron.lib import Adapter from coreblocks.scheduler.wakeup_select import * -from transactron.testing import RecordIntDict, TestCaseWithSimulator, AsyncTestbenchIO +from transactron.testing import RecordIntDict, TestCaseWithSimulator, TestbenchIO from transactron.testing.functions import data_const_to_dict @@ -32,9 +32,9 @@ def elaborate(self, platform): ready_mock = Adapter(o=self.layouts.get_ready_list_out) take_row_mock = Adapter(i=self.layouts.take_in, o=self.layouts.take_out) issue_mock = Adapter(i=self.layouts.take_out) - m.submodules.ready_mock = self.ready_mock = AsyncTestbenchIO(ready_mock) - m.submodules.take_row_mock = self.take_row_mock = AsyncTestbenchIO(take_row_mock) - m.submodules.issue_mock = self.issue_mock = AsyncTestbenchIO(issue_mock) + m.submodules.ready_mock = self.ready_mock = TestbenchIO(ready_mock) + m.submodules.take_row_mock = self.take_row_mock = TestbenchIO(take_row_mock) + m.submodules.issue_mock = self.issue_mock = TestbenchIO(issue_mock) m.submodules.wakeup_select = WakeupSelect( gen_params=self.gen_params, get_ready=ready_mock.iface, take_row=take_row_mock.iface, issue=issue_mock.iface ) diff --git a/test/test_core.py b/test/test_core.py index cfeca8d66..620f09679 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -151,7 +151,7 @@ class TestCoreBasicAsm(TestCoreAsmSourceBase): configuration: CoreConfiguration async def run_and_check(self, sim: TestbenchContext): - await self.async_tick(sim, self.cycle_count) + await self.tick(sim, self.cycle_count) for reg_id, val in self.expected_regvals.items(): assert self.get_arch_reg_val(sim, reg_id) == val @@ -248,7 +248,7 @@ async def do_interrupt(): # run main code for some semi-random amount of cycles c = random.randrange(self.lo, self.hi) main_cycles += c - await self.async_tick(sim, c) + await self.tick(sim, c) # trigger an interrupt int_count += await do_interrupt() @@ -322,7 +322,7 @@ async def wait_or_timeout(cond: ValueLike, pred: Callable[[Any], bool]): break await wait_or_timeout(self.m.core.interrupt_controller.mie.value, lambda value: value != 0) - await self.async_random_wait(sim, 5) + await self.random_wait(sim, 5) while self.cycles < self.cycle_count: sim.set(self.m.interrupt_level, 1) @@ -343,7 +343,7 @@ async def wait_or_timeout(cond: ValueLike, pred: Callable[[Any], bool]): self.m.core.csr_generic.m_mode.priv_mode.value, lambda value: value != PrivilegeLevel.MACHINE ) - await self.async_random_wait(sim, 5) + await self.random_wait(sim, 5) for reg_id, val in self.expected_regvals.items(): assert self.get_arch_reg_val(sim, reg_id) == val diff --git a/test/transactron/core/test_transactions.py b/test/transactron/core/test_transactions.py index 4df957e1c..7a9cffdda 100644 --- a/test/transactron/core/test_transactions.py +++ b/test/transactron/core/test_transactions.py @@ -12,7 +12,7 @@ from typing import Iterable, Callable from parameterized import parameterized, parameterized_class -from transactron.testing import TestCaseWithSimulator, AsyncTestbenchIO, data_layout +from transactron.testing import TestCaseWithSimulator, TestbenchIO, data_layout from transactron import * from transactron.lib import Adapter, AdapterTrans @@ -113,9 +113,9 @@ def elaborate(self, platform): m = TModule() tm = TransactionModule(m, DependencyContext.get(), TransactionManager(self.scheduler)) adapter = Adapter(i=data_layout(32), o=data_layout(32)) - m.submodules.out = self.out = AsyncTestbenchIO(adapter) - m.submodules.in1 = self.in1 = AsyncTestbenchIO(AdapterTrans(adapter.iface)) - m.submodules.in2 = self.in2 = AsyncTestbenchIO(AdapterTrans(adapter.iface)) + m.submodules.out = self.out = TestbenchIO(adapter) + m.submodules.in1 = self.in1 = TestbenchIO(AdapterTrans(adapter.iface)) + m.submodules.in2 = self.in2 = TestbenchIO(AdapterTrans(adapter.iface)) return tm @@ -134,7 +134,7 @@ def setup_method(self): def make_process( self, - io: AsyncTestbenchIO, + io: TestbenchIO, prob: float, src: Iterable[int], tgt: Callable[[int], None], diff --git a/test/transactron/lib/test_fifo.py b/test/transactron/lib/test_fifo.py index d7b1ca461..1283d2051 100644 --- a/test/transactron/lib/test_fifo.py +++ b/test/transactron/lib/test_fifo.py @@ -3,7 +3,7 @@ from transactron.lib import AdapterTrans, BasicFifo -from transactron.testing import TestCaseWithSimulator, AsyncTestbenchIO, data_layout +from transactron.testing import TestCaseWithSimulator, TestbenchIO, data_layout from collections import deque from parameterized import parameterized_class import random @@ -18,9 +18,9 @@ def elaborate(self, platform): m.submodules.fifo = self.fifo = BasicFifo(layout=data_layout(8), depth=self.depth) - m.submodules.fifo_read = self.fifo_read = AsyncTestbenchIO(AdapterTrans(self.fifo.read)) - m.submodules.fifo_write = self.fifo_write = AsyncTestbenchIO(AdapterTrans(self.fifo.write)) - m.submodules.fifo_clear = self.fifo_clear = AsyncTestbenchIO(AdapterTrans(self.fifo.clear)) + m.submodules.fifo_read = self.fifo_read = TestbenchIO(AdapterTrans(self.fifo.read)) + m.submodules.fifo_write = self.fifo_write = TestbenchIO(AdapterTrans(self.fifo.write)) + m.submodules.fifo_clear = self.fifo_clear = TestbenchIO(AdapterTrans(self.fifo.clear)) return m @@ -46,7 +46,7 @@ def test_randomized(self): async def source(sim: TestbenchContext): for _ in range(cycles): - await self.async_random_wait_geom(sim, 0.5) + await self.random_wait_geom(sim, 0.5) v = random.randint(0, (2**fifoc.fifo.width) - 1) expq.appendleft(v) @@ -61,7 +61,7 @@ async def source(sim: TestbenchContext): async def target(sim: TestbenchContext): while not self.done or expq: - await self.async_random_wait_geom(sim, 0.5) + await self.random_wait_geom(sim, 0.5) v = await fifoc.fifo_read.call_try(sim) diff --git a/test/transactron/lib/test_transaction_lib.py b/test/transactron/lib/test_transaction_lib.py index 72c12e12f..0ef47fc6e 100644 --- a/test/transactron/lib/test_transaction_lib.py +++ b/test/transactron/lib/test_transaction_lib.py @@ -20,7 +20,7 @@ TestCaseWithSimulator, data_layout, async_def_method_mock, - AsyncTestbenchIO, + TestbenchIO, ) @@ -43,19 +43,19 @@ def do_test_fifo( ): iosize = 8 - m = SimpleTestCircuit(fifo_class(data_layout(iosize), **fifo_kwargs), async_tb=True) + m = SimpleTestCircuit(fifo_class(data_layout(iosize), **fifo_kwargs)) random.seed(1337) async def writer(sim: TestbenchContext): for i in range(2**iosize): await m.write.call(sim, data=i) - await self.async_random_wait(sim, writer_rand) + await self.random_wait(sim, writer_rand) async def reader(sim: TestbenchContext): for i in range(2**iosize): assert (await m.read.call(sim)).data == i - await self.async_random_wait(sim, reader_rand) + await self.random_wait(sim, reader_rand) with self.run_simulation(m) as sim: sim.add_testbench(reader) @@ -86,7 +86,7 @@ def test_fifo(self, writer_rand, reader_rand): def test_forwarding(self): iosize = 8 - m = SimpleTestCircuit(Forwarder(data_layout(iosize)), async_tb=True) + m = SimpleTestCircuit(Forwarder(data_layout(iosize))) async def forward_check(sim: TestbenchContext, x: int): read_res, write_res = await CallTrigger(sim).call(m.read).call(m.write, data=x) @@ -157,7 +157,6 @@ def test_mem( read_ports=read_ports, write_ports=write_ports, ), - async_tb=True, ) data: list[int] = [0 for _ in range(max_addr)] @@ -173,7 +172,7 @@ async def process(sim: TestbenchContext): await m.writes[i].call(sim, data={"data": d}, addr=a) await sim.delay(1e-9 * (i + 2 if not transparent else i)) data[a] = d - await self.async_random_wait(sim, writer_rand) + await self.random_wait(sim, writer_rand) return process @@ -185,7 +184,7 @@ async def process(sim: TestbenchContext): await sim.delay(1e-9 * (1 if not transparent else write_ports + 2)) d = data[a] read_req_queues[i].append(d) - await self.async_random_wait(sim, reader_req_rand) + await self.random_wait(sim, reader_req_rand) return process @@ -194,11 +193,11 @@ async def process(sim: TestbenchContext): for cycle in range(test_count): await sim.delay(1e-9 * (write_ports + 3)) while not read_req_queues[i]: - await self.async_random_wait(sim, reader_resp_rand or 1, min_cycle_cnt=1) + await self.random_wait(sim, reader_resp_rand or 1, min_cycle_cnt=1) await sim.delay(1e-9 * (write_ports + 3)) d = read_req_queues[i].popleft() assert (await m.read_resps[i].call(sim)).data == d - await self.async_random_wait(sim, reader_resp_rand) + await self.random_wait(sim, reader_resp_rand) return process @@ -227,7 +226,6 @@ def test_mem(self, max_addr: int, writer_rand: int, reader_rand: int, seed: int, AsyncMemoryBank( data_layout=[("data", data_width)], elem_count=max_addr, read_ports=read_ports, write_ports=write_ports ), - async_tb=True, ) data: list[int] = list(0 for i in range(max_addr)) @@ -242,7 +240,7 @@ async def process(sim: TestbenchContext): await m.writes[i].call(sim, data={"data": d}, addr=a) await sim.delay(1e-9 * (i + 2)) data[a] = d - await self.async_random_wait(sim, writer_rand, min_cycle_cnt=1) + await self.random_wait(sim, writer_rand, min_cycle_cnt=1) return process @@ -254,7 +252,7 @@ async def process(sim: TestbenchContext): await sim.delay(1e-9) expected_d = data[a] assert d["data"] == expected_d - await self.async_random_wait(sim, reader_rand, min_cycle_cnt=1) + await self.random_wait(sim, reader_rand, min_cycle_cnt=1) return process @@ -269,20 +267,20 @@ class ManyToOneConnectTransTestCircuit(Elaboratable): def __init__(self, count: int, lay: MethodLayout): self.count = count self.lay = lay - self.inputs: list[AsyncTestbenchIO] = [] + self.inputs: list[TestbenchIO] = [] def elaborate(self, platform): m = TModule() get_results = [] for i in range(self.count): - input = AsyncTestbenchIO(Adapter(o=self.lay)) + input = TestbenchIO(Adapter(o=self.lay)) get_results.append(input.adapter.iface) m.submodules[f"input_{i}"] = input self.inputs.append(input) # Create ManyToOneConnectTrans, which will serialize results from different inputs - output = AsyncTestbenchIO(Adapter(i=self.lay)) + output = TestbenchIO(Adapter(i=self.lay)) m.submodules.output = self.output = output m.submodules.fu_arbitration = ManyToOneConnectTrans(get_results=get_results, put_result=output.adapter.iface) @@ -331,7 +329,7 @@ async def producer(sim: TestbenchContext): inputs = self.inputs[i] for field1, field2 in inputs: self.m.inputs[i].call_init(sim, field1=field1, field2=field2) - await self.async_random_wait(sim, self.max_wait) + await self.random_wait(sim, self.max_wait) self.producer_end[i] = True return producer @@ -349,7 +347,7 @@ async def consumer(self, sim: TestbenchContext): del self.expected_output[t] else: self.expected_output[t] -= 1 - await self.async_random_wait(sim, self.max_wait) + await self.random_wait(sim, self.max_wait) @pytest.mark.parametrize("count", [1, 4]) def test(self, count: int): @@ -395,7 +393,7 @@ def otransform_dict(_, v: MethodStruct) -> RecordDict: itransform = itransform_rec otransform = otransform_rec - m.submodules.target = self.target = AsyncTestbenchIO(Adapter(i=layout, o=layout)) + m.submodules.target = self.target = TestbenchIO(Adapter(i=layout, o=layout)) if self.use_methods: imeth = Method(i=layout, o=layout) @@ -417,7 +415,7 @@ def _(arg: MethodStruct): o_transform=(layout, otransform), ) - m.submodules.source = self.source = AsyncTestbenchIO(AdapterTrans(trans.use(m))) + m.submodules.source = self.source = TestbenchIO(AdapterTrans(trans.use(m))) return m @@ -455,8 +453,8 @@ class TestMethodFilter(TestCaseWithSimulator): def initialize(self): self.iosize = 4 self.layout = data_layout(self.iosize) - self.target = AsyncTestbenchIO(Adapter(i=self.layout, o=self.layout)) - self.cmeth = AsyncTestbenchIO(Adapter(i=self.layout, o=data_layout(1))) + self.target = TestbenchIO(Adapter(i=self.layout, o=self.layout)) + self.cmeth = TestbenchIO(Adapter(i=self.layout, o=data_layout(1))) async def source(self, sim: TestbenchContext): for i in range(2**self.iosize): @@ -476,7 +474,7 @@ def cmeth_mock(self, data): def test_method_filter_with_methods(self): self.initialize() - self.tc = SimpleTestCircuit(MethodFilter(self.target.adapter.iface, self.cmeth.adapter.iface), async_tb=True) + self.tc = SimpleTestCircuit(MethodFilter(self.target.adapter.iface, self.cmeth.adapter.iface)) m = ModuleConnector(test_circuit=self.tc, target=self.target, cmeth=self.cmeth) with self.run_simulation(m) as sim: sim.add_testbench(self.source) @@ -488,9 +486,7 @@ def test_method_filter_plain(self, use_condition): def condition(_, v): return v.data[0] - self.tc = SimpleTestCircuit( - MethodFilter(self.target.adapter.iface, condition, use_condition=use_condition), async_tb=True - ) + self.tc = SimpleTestCircuit(MethodFilter(self.target.adapter.iface, condition, use_condition=use_condition)) m = ModuleConnector(test_circuit=self.tc, target=self.target, cmeth=self.cmeth) with self.run_simulation(m) as sim: sim.add_testbench(self.source) @@ -501,7 +497,7 @@ def __init__(self, iosize: int, targets: int, add_combiner: bool): self.iosize = iosize self.targets = targets self.add_combiner = add_combiner - self.target: list[AsyncTestbenchIO] = [] + self.target: list[TestbenchIO] = [] def elaborate(self, platform): m = TModule() @@ -511,7 +507,7 @@ def elaborate(self, platform): methods = [] for k in range(self.targets): - tgt = AsyncTestbenchIO(Adapter(i=layout, o=layout)) + tgt = TestbenchIO(Adapter(i=layout, o=layout)) methods.append(tgt.adapter.iface) self.target.append(tgt) m.submodules += tgt @@ -522,7 +518,7 @@ def elaborate(self, platform): product = MethodProduct(methods, combiner) - m.submodules.method = self.method = AsyncTestbenchIO(AdapterTrans(product.use(m))) + m.submodules.method = self.method = TestbenchIO(AdapterTrans(product.use(m))) return m @@ -582,8 +578,8 @@ def setup_method(self): layout = [("field", self.data_width)] - self.req_method = AsyncTestbenchIO(Adapter(i=layout)) - self.resp_method = AsyncTestbenchIO(Adapter(o=layout)) + self.req_method = TestbenchIO(Adapter(i=layout)) + self.resp_method = TestbenchIO(Adapter(o=layout)) self.test_circuit = SimpleTestCircuit( Serializer( @@ -591,7 +587,6 @@ def setup_method(self): serialized_req_method=self.req_method.adapter.iface, serialized_resp_method=self.resp_method.adapter.iface, ), - async_tb=True, ) self.m = ModuleConnector( test_circuit=self.test_circuit, req_method=self.req_method, resp_method=self.resp_method @@ -626,7 +621,7 @@ async def f(sim: TestbenchContext): d = random.randrange(2**self.data_width) await self.test_circuit.serialize_in[i].call(sim, field=d) self.port_data[i].append(d) - await self.async_random_wait(sim, self.requestor_rand, min_cycle_cnt=1) + await self.random_wait(sim, self.requestor_rand, min_cycle_cnt=1) return f @@ -635,7 +630,7 @@ async def f(sim: TestbenchContext): for _ in range(self.test_count): data_out = await self.test_circuit.serialize_out[i].call(sim) assert self.port_data[i].popleft() == data_out.field - await self.async_random_wait(sim, self.requestor_rand, min_cycle_cnt=1) + await self.random_wait(sim, self.requestor_rand, min_cycle_cnt=1) return f @@ -691,7 +686,7 @@ def __init__(self, iosize: int, targets: int, add_combiner: bool): self.iosize = iosize self.targets = targets self.add_combiner = add_combiner - self.target: list[AsyncTestbenchIO] = [] + self.target: list[TestbenchIO] = [] def elaborate(self, platform): m = TModule() @@ -701,7 +696,7 @@ def elaborate(self, platform): methods = [] for k in range(self.targets): - tgt = AsyncTestbenchIO(Adapter(i=layout, o=layout)) + tgt = TestbenchIO(Adapter(i=layout, o=layout)) methods.append(tgt.adapter.iface) self.target.append(tgt) m.submodules += tgt @@ -712,7 +707,7 @@ def elaborate(self, platform): product = MethodTryProduct(methods, combiner) - m.submodules.method = self.method = AsyncTestbenchIO(AdapterTrans(product.use(m))) + m.submodules.method = self.method = TestbenchIO(AdapterTrans(product.use(m))) return m @@ -749,11 +744,10 @@ class TestCondition(TestCaseWithSimulator): @pytest.mark.parametrize("priority", [False, True]) @pytest.mark.parametrize("catchall", [False, True]) def test_condition(self, nonblocking: bool, priority: bool, catchall: bool): - target = AsyncTestbenchIO(Adapter(i=[("cond", 2)])) + target = TestbenchIO(Adapter(i=[("cond", 2)])) circ = SimpleTestCircuit( ConditionTestCircuit(target.adapter.iface, nonblocking=nonblocking, priority=priority, catchall=catchall), - async_tb=True, ) m = ModuleConnector(test_circuit=circ, target=target) diff --git a/test/transactron/test_adapter.py b/test/transactron/test_adapter.py index 4180d5ac0..b5086f869 100644 --- a/test/transactron/test_adapter.py +++ b/test/transactron/test_adapter.py @@ -4,7 +4,8 @@ from transactron import Method, def_method, TModule -from transactron.testing import TestCaseWithSimulator, data_layout, SimpleTestCircuit, ModuleConnector +from transactron.testing import TestCaseWithSimulator, data_layout, SimpleTestCircuit +from transactron.utils.amaranth_ext.elaboratables import ModuleConnector class Echo(Elaboratable): @@ -54,8 +55,8 @@ async def proc(self, sim: TestbenchContext): assert expected == obtained def test_single(self): - self.echo = SimpleTestCircuit(Echo(), async_tb=True) - self.consumer = SimpleTestCircuit(Consumer(), async_tb=True) + self.echo = SimpleTestCircuit(Echo()) + self.consumer = SimpleTestCircuit(Consumer()) self.m = ModuleConnector(echo=self.echo, consumer=self.consumer) with self.run_simulation(self.m, max_cycles=100) as sim: diff --git a/test/transactron/test_methods.py b/test/transactron/test_methods.py index f62b0d8b7..e4a5ced78 100644 --- a/test/transactron/test_methods.py +++ b/test/transactron/test_methods.py @@ -4,7 +4,7 @@ from amaranth import * from amaranth.sim import * -from transactron.testing import TestCaseWithSimulator, AsyncTestbenchIO, data_layout +from transactron.testing import TestCaseWithSimulator, TestbenchIO, data_layout from transactron import * from transactron.testing.infrastructure import SimpleTestCircuit @@ -152,7 +152,7 @@ def test_basic_methods(self): def definition(idx: int, foo: Value): return {"foo": foo + idx} - circuit = SimpleTestCircuit(TestDefMethods.CircuitTestModule(definition), True) + circuit = SimpleTestCircuit(TestDefMethods.CircuitTestModule(definition)) async def test_process(sim): for k, method in enumerate(circuit.methods): @@ -365,7 +365,7 @@ def elaborate(self, platform): m = TModule() m.submodules.quadruple = self.quadruple - m.submodules.tb = self.tb = AsyncTestbenchIO(AdapterTrans(self.quadruple.quadruple)) + m.submodules.tb = self.tb = TestbenchIO(AdapterTrans(self.quadruple.quadruple)) return m @@ -407,8 +407,8 @@ def elaborate(self, platform): meth = Method(i=data_layout(1)) - m.submodules.tb = self.tb = AsyncTestbenchIO(AdapterTrans(meth)) - m.submodules.out = self.out = AsyncTestbenchIO(Adapter()) + m.submodules.tb = self.tb = TestbenchIO(AdapterTrans(meth)) + m.submodules.out = self.out = TestbenchIO(Adapter()) @def_method(m, meth) def _(arg): @@ -425,7 +425,7 @@ def elaborate(self, platform): meth = Method() self.ready = Signal() - m.submodules.tb = self.tb = AsyncTestbenchIO(AdapterTrans(meth)) + m.submodules.tb = self.tb = TestbenchIO(AdapterTrans(meth)) @def_method(m, meth, ready=self.ready) def _(arg): @@ -441,7 +441,7 @@ def elaborate(self, platform): meth = Method() self.ready = Signal() - m.submodules.tb = self.tb = AsyncTestbenchIO(AdapterTrans(meth)) + m.submodules.tb = self.tb = TestbenchIO(AdapterTrans(meth)) with m.If(self.ready): @@ -457,7 +457,7 @@ def elaborate(self, platform): m = TModule() self.ready = Signal() - m.submodules.tb = self.tb = AsyncTestbenchIO(Adapter()) + m.submodules.tb = self.tb = TestbenchIO(Adapter()) with Transaction().body(m, request=self.ready): self.tb.adapter.iface(m) @@ -470,7 +470,7 @@ def elaborate(self, platform): m = TModule() self.ready = Signal() - m.submodules.tb = self.tb = AsyncTestbenchIO(Adapter()) + m.submodules.tb = self.tb = TestbenchIO(Adapter()) with m.If(self.ready): with Transaction().body(m): @@ -545,8 +545,8 @@ def _(): m.d.comb += self.running.eq(1) return {"data": self.data} - m.submodules.t1 = self.t1 = AsyncTestbenchIO(AdapterTrans(method)) - m.submodules.t2 = self.t2 = AsyncTestbenchIO(AdapterTrans(method)) + m.submodules.t1 = self.t1 = TestbenchIO(AdapterTrans(method)) + m.submodules.t2 = self.t2 = TestbenchIO(AdapterTrans(method)) return m @@ -612,8 +612,8 @@ def _(): m.d.comb += self.running2.eq(1) return method_in(m) - m.submodules.t1 = self.t1 = AsyncTestbenchIO(AdapterTrans(method1)) - m.submodules.t2 = self.t2 = AsyncTestbenchIO(AdapterTrans(method2)) + m.submodules.t1 = self.t1 = TestbenchIO(AdapterTrans(method1)) + m.submodules.t2 = self.t2 = TestbenchIO(AdapterTrans(method2)) return m @@ -656,8 +656,8 @@ def _(data: Value): m.d.comb += self.running.eq(1) return {"data": data} - m.submodules.t1 = self.t1 = AsyncTestbenchIO(AdapterTrans(method)) - m.submodules.t2 = self.t2 = AsyncTestbenchIO(AdapterTrans(method)) + m.submodules.t1 = self.t1 = TestbenchIO(AdapterTrans(method)) + m.submodules.t2 = self.t2 = TestbenchIO(AdapterTrans(method)) return m diff --git a/test/transactron/test_metrics.py b/test/transactron/test_metrics.py index 431cce5e1..a171269ae 100644 --- a/test/transactron/test_metrics.py +++ b/test/transactron/test_metrics.py @@ -69,7 +69,7 @@ def setup_method(self) -> None: random.seed(42) def test_counter_in_method(self): - m = SimpleTestCircuit(CounterInMethodCircuit(), async_tb=True) + m = SimpleTestCircuit(CounterInMethodCircuit()) DependencyContext.get().add_dependency(HwMetricsEnabledKey(), True) async def test_process(sim): @@ -89,7 +89,7 @@ async def test_process(sim): sim.add_testbench(test_process) def test_counter_with_condition_in_method(self): - m = SimpleTestCircuit(CounterWithConditionInMethodCircuit(), async_tb=True) + m = SimpleTestCircuit(CounterWithConditionInMethodCircuit()) DependencyContext.get().add_dependency(HwMetricsEnabledKey(), True) async def test_process(sim): @@ -244,9 +244,7 @@ class TestHwHistogram(TestCaseWithSimulator): def test_histogram(self): random.seed(42) - m = SimpleTestCircuit( - ExpHistogramCircuit(bucket_cnt=self.bucket_count, sample_width=self.sample_width), async_tb=True - ) + m = SimpleTestCircuit(ExpHistogramCircuit(bucket_cnt=self.bucket_count, sample_width=self.sample_width)) DependencyContext.get().add_dependency(HwMetricsEnabledKey(), True) max_sample_value = 2**self.sample_width - 1 @@ -329,9 +327,7 @@ class TestFIFOLatencyMeasurer(TestLatencyMeasurerBase): def test_latency_measurer(self): random.seed(42) - m = SimpleTestCircuit( - FIFOLatencyMeasurer("latency", slots_number=self.slots_number, max_latency=300), async_tb=True - ) + m = SimpleTestCircuit(FIFOLatencyMeasurer("latency", slots_number=self.slots_number, max_latency=300)) DependencyContext.get().add_dependency(HwMetricsEnabledKey(), True) latencies: list[int] = [] @@ -357,7 +353,7 @@ async def producer(sim): await m._start.call(sim) event_queue.put(time) - await self.async_random_wait_geom(sim, 0.8) + await self.random_wait_geom(sim, 0.8) finish = True @@ -367,7 +363,7 @@ async def consumer(sim): latencies.append(time - event_queue.get()) - await self.async_random_wait_geom(sim, 1.0 / self.expected_consumer_wait) + await self.random_wait_geom(sim, 1.0 / self.expected_consumer_wait) self.check_latencies(sim, m, latencies) @@ -395,9 +391,7 @@ class TestIndexedLatencyMeasurer(TestLatencyMeasurerBase): def test_latency_measurer(self): random.seed(42) - m = SimpleTestCircuit( - TaggedLatencyMeasurer("latency", slots_number=self.slots_number, max_latency=300), async_tb=True - ) + m = SimpleTestCircuit(TaggedLatencyMeasurer("latency", slots_number=self.slots_number, max_latency=300)) DependencyContext.get().add_dependency(HwMetricsEnabledKey(), True) latencies: list[int] = [] @@ -433,7 +427,7 @@ async def producer(sim): free_slots.remove(slot_id) used_slots.append(slot_id) - await self.async_random_wait_geom(sim, 0.8) + await self.random_wait_geom(sim, 0.8) finish = True @@ -452,7 +446,7 @@ async def consumer(sim): used_slots.remove(slot_id) free_slots.append(slot_id) - await self.async_random_wait_geom(sim, 1.0 / self.expected_consumer_wait) + await self.random_wait_geom(sim, 1.0 / self.expected_consumer_wait) self.check_latencies(sim, m, latencies) @@ -522,7 +516,7 @@ def test_metrics_metadata(self): def test_returned_reg_values(self): random.seed(42) - m = SimpleTestCircuit(MetricManagerTestCircuit(), async_tb=True) + m = SimpleTestCircuit(MetricManagerTestCircuit()) metrics_manager = HardwareMetricsManager() DependencyContext.get().add_dependency(HwMetricsEnabledKey(), True) diff --git a/test/transactron/test_simultaneous.py b/test/transactron/test_simultaneous.py index 86d2899eb..066e7f591 100644 --- a/test/transactron/test_simultaneous.py +++ b/test/transactron/test_simultaneous.py @@ -5,7 +5,7 @@ from amaranth import * from amaranth.sim import * from transactron.testing.sugar import MethodMock, async_def_method_mock -from transactron.testing.testbenchio import AsyncTestbenchIO +from transactron.testing.testbenchio import TestbenchIO from transactron.utils import ModuleConnector @@ -45,7 +45,7 @@ def elaborate(self, platform): class TestSimultaneousDiamond(TestCaseWithSimulator): def test_diamond(self): - circ = SimpleTestCircuit(SimultaneousDiamondTestCircuit(), async_tb=True) + circ = SimpleTestCircuit(SimultaneousDiamondTestCircuit()) async def process(sim: TestbenchContext): methods = {"l": circ.method_l, "r": circ.method_r, "u": circ.method_u, "d": circ.method_d} @@ -141,11 +141,11 @@ def elaborate(self, platform): class TestTransitivity(TestCaseWithSimulator): def test_transitivity(self): - target = AsyncTestbenchIO(Adapter(i=[("data", 2)])) + target = TestbenchIO(Adapter(i=[("data", 2)])) req1 = Signal() req2 = Signal() - circ = SimpleTestCircuit(TransitivityTestCircuit(target.adapter.iface, req1, req2), async_tb=True) + circ = SimpleTestCircuit(TransitivityTestCircuit(target.adapter.iface, req1, req2)) m = ModuleConnector(test_circuit=circ, target=target) result: Optional[int] diff --git a/test/transactron/test_transactron_lib_storage.py b/test/transactron/test_transactron_lib_storage.py index db1f8efc6..d5513fe7c 100644 --- a/test/transactron/test_transactron_lib_storage.py +++ b/test/transactron/test_transactron_lib_storage.py @@ -16,7 +16,7 @@ def setUp(self): self.entries_count = 8 self.circ = SimpleTestCircuit( - ContentAddressableMemory(self.addr_layout, self.content_layout, self.entries_count), async_tb=True + ContentAddressableMemory(self.addr_layout, self.content_layout, self.entries_count) ) self.memory = {} diff --git a/test/transactron/testing/test_validate_arguments.py b/test/transactron/testing/test_validate_arguments.py index e0e6334b2..0f89286c5 100644 --- a/test/transactron/testing/test_validate_arguments.py +++ b/test/transactron/testing/test_validate_arguments.py @@ -3,7 +3,7 @@ from amaranth.sim import * from amaranth_types.types import TestbenchContext -from transactron.testing import TestCaseWithSimulator, AsyncTestbenchIO, data_layout +from transactron.testing import TestCaseWithSimulator, TestbenchIO, data_layout from transactron import * from transactron.testing.sugar import async_def_method_mock @@ -15,9 +15,9 @@ class ValidateArgumentsTestCircuit(Elaboratable): def elaborate(self, platform): m = Module() - self.method = AsyncTestbenchIO(Adapter(i=data_layout(1), o=data_layout(1)).set(with_validate_arguments=True)) - self.caller1 = AsyncTestbenchIO(AdapterTrans(self.method.adapter.iface)) - self.caller2 = AsyncTestbenchIO(AdapterTrans(self.method.adapter.iface)) + self.method = TestbenchIO(Adapter(i=data_layout(1), o=data_layout(1)).set(with_validate_arguments=True)) + self.caller1 = TestbenchIO(AdapterTrans(self.method.adapter.iface)) + self.caller2 = TestbenchIO(AdapterTrans(self.method.adapter.iface)) m.submodules += [self.method, self.caller1, self.caller2] @@ -25,7 +25,7 @@ def elaborate(self, platform): class TestValidateArguments(TestCaseWithSimulator): - def control_caller(self, caller: AsyncTestbenchIO, method: AsyncTestbenchIO): + def control_caller(self, caller: TestbenchIO, method: TestbenchIO): async def process(sim: TestbenchContext): await sim.tick() await sim.tick() @@ -46,7 +46,7 @@ def validate_arguments(self, data: int): async def changer(self, sim: TestbenchContext): for _ in range(50): - await sim.tick("sync_neg") + await sim.tick() self.accepted_val = 1 @async_def_method_mock(tb_getter=lambda self: self.m.method, validate_arguments=validate_arguments) diff --git a/test/transactron/utils/test_amaranth_ext.py b/test/transactron/utils/test_amaranth_ext.py index 863d1b76e..349fc0b87 100644 --- a/test/transactron/utils/test_amaranth_ext.py +++ b/test/transactron/utils/test_amaranth_ext.py @@ -1,5 +1,6 @@ from transactron.testing import * import random +import pytest from transactron.utils.amaranth_ext import MultiPriorityEncoder, RingMultiPriorityEncoder diff --git a/transactron/testing/__init__.py b/transactron/testing/__init__.py index aa215228e..9ed7265b1 100644 --- a/transactron/testing/__init__.py +++ b/transactron/testing/__init__.py @@ -1,3 +1,5 @@ +from amaranth_types import AnySimulatorContext # noqa: F401 +from amaranth.sim._async import TestbenchContext, ProcessContext, SimulatorContext # noqa: F401 from .input_generation import * # noqa: F401 from .functions import * # noqa: F401 from .infrastructure import * # noqa: F401 @@ -5,4 +7,5 @@ from .testbenchio import * # noqa: F401 from .profiler import * # noqa: F401 from .logging import * # noqa: F401 +from .tick_count import * # noqa: F401 from transactron.utils import data_layout # noqa: F401 diff --git a/transactron/testing/functions.py b/transactron/testing/functions.py index 65258708d..ee1225154 100644 --- a/transactron/testing/functions.py +++ b/transactron/testing/functions.py @@ -1,18 +1,7 @@ -from amaranth import * import amaranth.lib.data as data -from amaranth.lib.data import Layout, StructLayout, View -from amaranth.sim._pycoro import Command -from typing import TypeVar, Any, Generator, TypeAlias, TYPE_CHECKING, Union -from transactron.utils._typing import RecordIntDict +from typing import TypeAlias -if TYPE_CHECKING: - from amaranth.hdl._ast import Statement - from .infrastructure import CoreblocksCommand - - -T = TypeVar("T") -TestGen: TypeAlias = Generator[Union[Command, Value, "Statement", "CoreblocksCommand", None], Any, T] MethodData: TypeAlias = "data.Const[data.StructLayout]" @@ -24,20 +13,3 @@ def data_const_to_dict(c: "data.Const[data.Layout]"): v = data_const_to_dict(v) ret[k] = v return ret - - -def get_outputs(field: View) -> TestGen[RecordIntDict]: - # return dict of all signal values in a record because amaranth's simulator can't read all - # values of a View in a single yield - it can only read Values (Signals) - result = {} - layout = field.shape() - assert isinstance(layout, StructLayout) - for name, fld in layout: - val = field[name] - if isinstance(fld.shape, Layout): - result[name] = yield from get_outputs(View(fld.shape, val)) - elif isinstance(val, Value): - result[name] = yield val - else: - raise ValueError - return result diff --git a/transactron/testing/infrastructure.py b/transactron/testing/infrastructure.py index f0262fc3f..28fd9adcd 100644 --- a/transactron/testing/infrastructure.py +++ b/transactron/testing/infrastructure.py @@ -1,24 +1,21 @@ import sys -from amaranth_types import AnySimulatorContext, TestCoroutine +from amaranth_types import AnySimulatorContext import pytest import logging import os import random import functools -import warnings -import asyncio from contextlib import contextmanager, nullcontext -from typing import TypeVar, Generic, Type, TypeGuard, Any, Union, Callable, cast, TypeAlias, Optional -from abc import ABC +from collections.abc import Callable +from typing import TypeVar, Generic, Type, TypeGuard, Any, cast, TypeAlias, Optional from amaranth import * from amaranth.sim import * -from amaranth.sim._async import ProcessContext from transactron.utils.dependencies import DependencyContext, DependencyManager -from .testbenchio import AsyncTestbenchIO, TestbenchIO +from .testbenchio import TestbenchIO from .profiler import profiler_process, Profile -from .functions import TestGen from .logging import make_logging_process, parse_logging_level, _LogFormatter +from .tick_count import make_tick_count_process from .gtkw_extension import write_vcd_ext from transactron import Method from transactron.lib import AdapterTrans @@ -28,6 +25,9 @@ from transactron.testing.sugar import MethodMock +__all__ = ["SimpleTestCircuit", "PysimSimulator", "TestCaseWithSimulator"] + + T = TypeVar("T") _T_nested_collection: TypeAlias = T | list["_T_nested_collection[T]"] | dict[str, "_T_nested_collection[T]"] @@ -47,10 +47,9 @@ def guard_nested_collection(cont: Any, t: Type[T]) -> TypeGuard[_T_nested_collec class SimpleTestCircuit(Elaboratable, Generic[_T_HasElaborate]): - def __init__(self, dut: _T_HasElaborate, async_tb: bool = False): + def __init__(self, dut: _T_HasElaborate): self._dut = dut - self._io: dict[str, _T_nested_collection[TestbenchIO | AsyncTestbenchIO]] = {} - self._testbenchio = AsyncTestbenchIO if async_tb else TestbenchIO + self._io: dict[str, _T_nested_collection[TestbenchIO]] = {} def __getattr__(self, name: str) -> Any: try: @@ -62,8 +61,8 @@ def elaborate(self, platform): def transform_methods_to_testbenchios( container: _T_nested_collection[Method], ) -> tuple[ - _T_nested_collection["TestbenchIO | AsyncTestbenchIO"], - Union[ModuleConnector, "TestbenchIO | AsyncTestbenchIO"], + _T_nested_collection["TestbenchIO"], + "ModuleConnector | TestbenchIO", ]: if isinstance(container, list): tb_list = [] @@ -82,7 +81,7 @@ def transform_methods_to_testbenchios( mc_dict[name] = mc return tb_dict, ModuleConnector(*mc_dict) else: - tb = self._testbenchio(AdapterTrans(container)) + tb = TestbenchIO(AdapterTrans(container)) return tb, tb m = Module() @@ -127,43 +126,6 @@ def elaborate(self, platform) -> HasElaborate: return m -class CoreblocksCommand(ABC): - pass - - -class Now(CoreblocksCommand): - pass - - -class SyncProcessWrapper: - def __init__(self, f): - self.org_process = f - self.current_cycle = 0 - - def _wrapping_function(self): - response = None - org_coroutine = self.org_process() - try: - while True: - # call orginal test process and catch data yielded by it in `command` variable - command = org_coroutine.send(response) - # If process wait for new cycle - if command is None or isinstance(command, Tick): - command = command or Tick() - # TODO: use of other domains can mess up the counter! - if command.domain == "sync": - self.current_cycle += 1 - # forward to amaranth - yield command - elif isinstance(command, Now): - response = self.current_cycle - # Pass everything else to amaranth simulator without modifications - else: - response = yield command - except StopIteration: - pass - - class PysimSimulator(Simulator): def __init__( self, @@ -205,13 +167,6 @@ def __init__( self.deadline = clk_period * max_cycles - def add_process(self, process: Callable[[], TestGen[None]] | Callable[[ProcessContext], TestCoroutine[None]]): - if asyncio.iscoroutinefunction(process): - super().add_process(process) - else: - f_wrapped = SyncProcessWrapper(process) - super().add_process(f_wrapped._wrapping_function) - def run(self) -> bool: with self.ctx: self.run_until(self.deadline) @@ -317,6 +272,7 @@ def reinitialize_fixtures(self): self._configure_traces() with self._configure_profiles(): with self._configure_logging(): + self._transactron_sim_processes_to_add.append(make_tick_count_process) yield self._transactron_hypothesis_iter_counter += 1 @@ -353,55 +309,25 @@ def run_simulation(self, module: HasElaborate, max_cycles: float = 10e4, add_tra if ret is not None: sim.add_process(ret) - with warnings.catch_warnings(): - # TODO: figure out testing without settles! - warnings.filterwarnings("ignore", r"The `Settle` command is deprecated per RFC 27\.") - - res = sim.run() + res = sim.run() assert res, "Simulation time limit exceeded" - def tick(self, cycle_cnt: int = 1): - """ - Yields for the given number of cycles. - """ - - for _ in range(cycle_cnt): - yield Tick() - - def random_wait(self, max_cycle_cnt: int, *, min_cycle_cnt: int = 0): - """ - Wait for a random amount of cycles in range [min_cycle_cnt, max_cycle_cnt] - """ - yield from self.tick(random.randrange(min_cycle_cnt, max_cycle_cnt + 1)) - - def random_wait_geom(self, prob: float = 0.5): - """ - Wait till the first success, where there is `prob` probability for success in each cycle. - """ - while random.random() > prob: - yield Tick() - - async def async_tick(self, sim: AnySimulatorContext, cycle_cnt: int = 1): + async def tick(self, sim: AnySimulatorContext, cycle_cnt: int = 1): """ Yields for the given number of cycles. """ - for _ in range(cycle_cnt): await sim.tick() - async def async_random_wait(self, sim: AnySimulatorContext, max_cycle_cnt: int, *, min_cycle_cnt: int = 0): + async def random_wait(self, sim: AnySimulatorContext, max_cycle_cnt: int, *, min_cycle_cnt: int = 0): """ Wait for a random amount of cycles in range [min_cycle_cnt, max_cycle_cnt] """ - await self.async_tick(sim, random.randrange(min_cycle_cnt, max_cycle_cnt + 1)) + await self.tick(sim, random.randrange(min_cycle_cnt, max_cycle_cnt + 1)) - async def async_random_wait_geom(self, sim: AnySimulatorContext, prob: float = 0.5): + async def random_wait_geom(self, sim: AnySimulatorContext, prob: float = 0.5): """ Wait till the first success, where there is `prob` probability for success in each cycle. """ while random.random() > prob: await sim.tick() - - def multi_settle(self, settle_count: int = 1): - for _ in range(settle_count): - yield Settle() diff --git a/transactron/testing/logging.py b/transactron/testing/logging.py index 7c8edf1dc..2a40d6f1b 100644 --- a/transactron/testing/logging.py +++ b/transactron/testing/logging.py @@ -1,9 +1,12 @@ -from collections.abc import Callable +from collections.abc import Callable, Iterable from typing import Any import logging +import itertools -from amaranth.sim import Passive, Tick +from amaranth.sim._async import ProcessContext from transactron.lib import logging as tlog +from transactron.utils.dependencies import DependencyContext +from .tick_count import TicksKey __all__ = ["make_logging_process", "parse_logging_level"] @@ -31,7 +34,7 @@ def parse_logging_level(str: str) -> tlog.LogLevel: raise ValueError("Log level must be either {error, warn, info, debug} or a non-negative integer.") -_sim_cycle = 0 +_sim_cycle: int = 0 class _LogFormatter(logging.Formatter): @@ -65,17 +68,15 @@ def make_logging_process(level: tlog.LogLevel, namespace_regexp: str, on_error: root_logger = logging.getLogger() - def handle_logs(): - if not (yield combined_trigger): - return + def handle_logs(record_vals: Iterable[int]) -> None: + it = iter(record_vals) for record in records: - if not (yield record.trigger): - continue + trigger = next(it) + values = [next(it) for _ in record.fields] - values: list[int] = [] - for field in record.fields: - values.append((yield field)) + if not trigger: + continue formatted_msg = record.format(*values) @@ -91,15 +92,18 @@ def handle_logs(): if record.level >= logging.ERROR: on_error() - def log_process(): + async def log_process(sim: ProcessContext) -> None: global _sim_cycle - _sim_cycle = 0 - - yield Passive() - while True: - yield Tick("sync_neg") - yield from handle_logs() - yield Tick() - _sim_cycle += 1 + ticks = DependencyContext.get().get_dependency(TicksKey()) + + async for _, _, ticks_val, combined_trigger_val, *record_vals in ( + sim.tick("sync_neg") + .sample(ticks, combined_trigger) + .sample(*itertools.chain(*([record.trigger] + record.fields for record in records))) + ): + if not combined_trigger_val: + continue + _sim_cycle = ticks_val + handle_logs(record_vals) return log_process diff --git a/transactron/testing/profiler.py b/transactron/testing/profiler.py index 795c7f293..608a001c4 100644 --- a/transactron/testing/profiler.py +++ b/transactron/testing/profiler.py @@ -1,37 +1,46 @@ -from amaranth.sim import * +from amaranth import Cat +from amaranth.lib.data import StructLayout, View +from amaranth_types.types import ProcessContext from transactron.core import TransactionManager from transactron.core.manager import MethodMap from transactron.profiler import CycleProfile, MethodSamples, Profile, ProfileData, ProfileSamples, TransactionSamples -from .functions import TestGen __all__ = ["profiler_process"] def profiler_process(transaction_manager: TransactionManager, profile: Profile): - def process() -> TestGen: + async def process(sim: ProcessContext) -> None: profile_data, get_id = ProfileData.make(transaction_manager) method_map = MethodMap(transaction_manager.transactions) profile.transactions_and_methods = profile_data.transactions_and_methods - yield Passive() - while True: - yield Tick("sync_neg") + transaction_sample_layout = StructLayout({"request": 1, "runnable": 1, "grant": 1}) + async for _, _, *data in ( + sim.tick() + .sample( + *( + View(transaction_sample_layout, Cat(transaction.request, transaction.runnable, transaction.grant)) + for transaction in method_map.transactions + ) + ) + .sample(*(method.run for method in method_map.methods)) + ): + transaction_data = data[: len(method_map.transactions)] + method_data = data[len(method_map.transactions) :] samples = ProfileSamples() - for transaction in method_map.transactions: + for transaction, tsample in zip(method_map.transactions, transaction_data): samples.transactions[get_id(transaction)] = TransactionSamples( - bool((yield transaction.request)), - bool((yield transaction.runnable)), - bool((yield transaction.grant)), + bool(tsample.request), + bool(tsample.runnable), + bool(tsample.grant), ) - for method in method_map.methods: - samples.methods[get_id(method)] = MethodSamples(bool((yield method.run))) + for method, run in zip(method_map.methods, method_data): + samples.methods[get_id(method)] = MethodSamples(bool(run)) cprof = CycleProfile.make(samples, profile_data) profile.cycles.append(cprof) - yield Tick() - return process diff --git a/transactron/testing/sugar.py b/transactron/testing/sugar.py index c937bca8a..e262f62a1 100644 --- a/transactron/testing/sugar.py +++ b/transactron/testing/sugar.py @@ -6,10 +6,13 @@ from transactron.lib.adapters import Adapter from transactron.utils.transactron_helpers import async_mock_def_helper -from .testbenchio import AsyncTestbenchIO, TestbenchIO, TestGen +from .testbenchio import TestbenchIO from transactron.utils._typing import RecordIntDict +__all__ = ["MethodMock", "async_def_method_mock"] + + class MethodMock: def __init__( self, @@ -96,86 +99,8 @@ async def effect_process(self, sim: AnySimulatorContext) -> None: sim.set(self.adapter.en, self.enable()) -def def_method_mock( - tb_getter: Callable[[], TestbenchIO] | Callable[[Any], TestbenchIO], sched_prio: int = 0, **kwargs -) -> Callable[[Callable[..., Optional[RecordIntDict]]], Callable[[], TestGen[None]]]: - """ - Decorator function to create method mock handlers. It should be applied on - a function which describes functionality which we want to invoke on method call. - Such function will be wrapped by `method_handle_loop` and called on each - method invocation. - - Function `f` should take only one argument `arg` - data used in function - invocation - and should return data to be sent as response to the method call. - - Function `f` can also be a method and take two arguments `self` and `arg`, - the data to be passed on to invoke a method. It should return data to be sent - as response to the method call. - - Instead of the `arg` argument, the data can be split into keyword arguments. - - Make sure to defer accessing state, since decorators are evaluated eagerly - during function declaration. - - Parameters - ---------- - tb_getter : Callable[[], TestbenchIO] | Callable[[Any], TestbenchIO] - Function to get the TestbenchIO providing appropriate `method_handle_loop`. - **kwargs - Arguments passed to `method_handle_loop`. - - Example - ------- - ``` - m = TestCircuit() - def target_process(k: int): - @def_method_mock(lambda: m.target[k]) - def process(arg): - return {"data": arg["data"] + k} - return process - ``` - or equivalently - ``` - m = TestCircuit() - def target_process(k: int): - @def_method_mock(lambda: m.target[k], settle=1, enable=False) - def process(data): - return {"data": data + k} - return process - ``` - or for class methods - ``` - @def_method_mock(lambda self: self.target[k], settle=1, enable=False) - def process(self, data): - return {"data": data + k} - ``` - """ - - def decorator(func: Callable[..., Optional[RecordIntDict]]) -> Callable[[], TestGen[None]]: - @functools.wraps(func) - def mock(func_self=None, /) -> TestGen[None]: - f = func - getter: Any = tb_getter - kw = kwargs - if func_self is not None: - getter = getter.__get__(func_self) - f = f.__get__(func_self) - kw = {} - for k, v in kwargs.items(): - bind = getattr(v, "__get__", None) - kw[k] = bind(func_self) if bind else v - tb = getter() - assert isinstance(tb, TestbenchIO) - yield from tb.method_handle_loop(f, extra_settle_count=sched_prio, **kw) - - mock._transactron_testing_process = 1 # type: ignore - return mock - - return decorator - - def async_def_method_mock( - tb_getter: Callable[[], AsyncTestbenchIO] | Callable[[Any], AsyncTestbenchIO], **kwargs + tb_getter: Callable[[], TestbenchIO] | Callable[[Any], TestbenchIO], **kwargs ) -> Callable[[Callable[..., Optional[RecordIntDict]]], Callable[[], MethodMock]]: """ TODO: better description! @@ -245,7 +170,7 @@ def mock(func_self=None, /) -> MethodMock: bind = getattr(v, "__get__", None) kw[k] = bind(func_self) if bind else v tb = getter() - assert isinstance(tb, AsyncTestbenchIO) + assert isinstance(tb, TestbenchIO) assert isinstance(tb.adapter, Adapter) return MethodMock(tb.adapter, f, **kw) diff --git a/transactron/testing/testbenchio.py b/transactron/testing/testbenchio.py index aee2255e6..924372065 100644 --- a/transactron/testing/testbenchio.py +++ b/transactron/testing/testbenchio.py @@ -1,37 +1,37 @@ from collections.abc import Generator, Iterable from amaranth import * from amaranth.lib.data import View, StructLayout -from amaranth.sim import Settle, Passive, Tick -from typing import Any, Optional, Callable +from typing import Any, Optional from amaranth_types import AnySimulatorContext from amaranth_types.types import TestbenchContext from transactron.lib import AdapterBase -from transactron.lib.adapters import Adapter -from transactron.utils import ValueLike, SignalBundle, mock_def_helper, assign -from transactron.utils._typing import RecordIntDictRet, RecordValueDict, RecordIntDict -from .functions import MethodData, get_outputs, TestGen +from transactron.utils import ValueLike +from .functions import MethodData + + +__all__ = ["CallTrigger", "TestbenchIO"] class CallTrigger: def __init__( self, sim: AnySimulatorContext, - calls: Iterable[ValueLike | tuple["AsyncTestbenchIO", Optional[dict[str, Any]]]] = (), + calls: Iterable[ValueLike | tuple["TestbenchIO", Optional[dict[str, Any]]]] = (), ): self.sim = sim - self.calls_and_values: list[ValueLike | tuple[AsyncTestbenchIO, Optional[dict[str, Any]]]] = list(calls) + self.calls_and_values: list[ValueLike | tuple[TestbenchIO, Optional[dict[str, Any]]]] = list(calls) - def sample(self, *values: "ValueLike | AsyncTestbenchIO"): - new_calls_and_values: list[ValueLike | tuple["AsyncTestbenchIO", None]] = [] + def sample(self, *values: "ValueLike | TestbenchIO"): + new_calls_and_values: list[ValueLike | tuple["TestbenchIO", None]] = [] for value in values: - if isinstance(value, AsyncTestbenchIO): + if isinstance(value, TestbenchIO): new_calls_and_values.append((value, None)) else: new_calls_and_values.append(value) return CallTrigger(self.sim, (*self.calls_and_values, *new_calls_and_values)) - def call(self, tbio: "AsyncTestbenchIO", data: dict[str, Any] = {}, /, **kwdata): + def call(self, tbio: "TestbenchIO", data: dict[str, Any] = {}, /, **kwdata): if data and kwdata: raise TypeError("call() takes either a single dict or keyword arguments") return CallTrigger(self.sim, (*self.calls_and_values, (tbio, data or kwdata))) @@ -51,7 +51,7 @@ def __await__(self) -> Generator: if data is not None: tbio.call_init(self.sim, data) - def layout_for(tbio: AsyncTestbenchIO): + def layout_for(tbio: TestbenchIO): return StructLayout({"outputs": tbio.adapter.data_out.shape(), "done": 1}) trigger = ( @@ -82,7 +82,7 @@ async def __aiter__(self): yield await self -class AsyncTestbenchIO(Elaboratable): +class TestbenchIO(Elaboratable): def __init__(self, adapter: AdapterBase): self.adapter = adapter @@ -159,147 +159,3 @@ async def call_try(self, sim: AnySimulatorContext, data={}, /, **kwdata) -> Opti async def call(self, sim: AnySimulatorContext, data={}, /, **kwdata) -> MethodData: return (await CallTrigger(sim).call(self, data, **kwdata).until_done())[0] - - -class TestbenchIO(Elaboratable): - def __init__(self, adapter: AdapterBase): - self.adapter = adapter - - def elaborate(self, platform): - m = Module() - m.submodules += self.adapter - return m - - # Low-level operations - - def set_enable(self, en) -> TestGen[None]: - yield self.adapter.en.eq(1 if en else 0) - - def enable(self) -> TestGen[None]: - yield from self.set_enable(True) - - def disable(self) -> TestGen[None]: - yield from self.set_enable(False) - - def done(self) -> TestGen[int]: - return (yield self.adapter.done) - - def wait_until_done(self) -> TestGen[None]: - while (yield self.adapter.done) != 1: - yield Tick() - - def set_inputs(self, data: RecordValueDict = {}) -> TestGen[None]: - yield from assign(self.adapter.data_in, data) - - def get_outputs(self) -> TestGen[RecordIntDictRet]: - return (yield from get_outputs(self.adapter.data_out)) - - # Operations for AdapterTrans - - def call_init(self, data: RecordValueDict = {}, /, **kwdata: ValueLike | RecordValueDict) -> TestGen[None]: - if data and kwdata: - raise TypeError("call_init() takes either a single dict or keyword arguments") - if not data: - data = kwdata - yield from self.enable() - yield from self.set_inputs(data) - - def call_result(self) -> TestGen[Optional[RecordIntDictRet]]: - if (yield from self.done()): - return (yield from self.get_outputs()) - return None - - def call_do(self) -> TestGen[RecordIntDict]: - while (outputs := (yield from self.call_result())) is None: - yield Tick() - yield from self.disable() - return outputs - - def call_try( - self, data: RecordIntDict = {}, /, **kwdata: int | RecordIntDict - ) -> TestGen[Optional[RecordIntDictRet]]: - if data and kwdata: - raise TypeError("call_try() takes either a single dict or keyword arguments") - if not data: - data = kwdata - yield from self.call_init(data) - yield Tick() - outputs = yield from self.call_result() - yield from self.disable() - return outputs - - def call(self, data: RecordIntDict = {}, /, **kwdata: int | RecordIntDict) -> TestGen[RecordIntDictRet]: - if data and kwdata: - raise TypeError("call() takes either a single dict or keyword arguments") - if not data: - data = kwdata - yield from self.call_init(data) - yield Tick() - return (yield from self.call_do()) - - # Operations for Adapter - - def method_argument(self) -> TestGen[Optional[RecordIntDictRet]]: - return (yield from self.call_result()) - - def method_return(self, data: RecordValueDict = {}) -> TestGen[None]: - yield from self.set_inputs(data) - - def method_handle( - self, - function: Callable[..., Optional[RecordIntDict]], - *, - enable: Optional[Callable[[], bool]] = None, - validate_arguments: Optional[Callable[..., bool]] = None, - extra_settle_count: int = 0, - ) -> TestGen[None]: - enable = enable or (lambda: True) - yield from self.set_enable(enable()) - - def handle_validate_arguments(): - if validate_arguments is not None: - assert isinstance(self.adapter, Adapter) - for a, r in self.adapter.validators: - ret_out = mock_def_helper(self, validate_arguments, (yield from get_outputs(a))) - yield r.eq(ret_out) - for _ in range(extra_settle_count + 1): - yield Settle() - - # One extra Settle() required to propagate enable signal. - for _ in range(extra_settle_count + 1): - yield Settle() - yield from handle_validate_arguments() - while (arg := (yield from self.method_argument())) is None: - yield Tick() - - yield from self.set_enable(enable()) - for _ in range(extra_settle_count + 1): - yield Settle() - yield from handle_validate_arguments() - - ret_out = mock_def_helper(self, function, arg) - yield from self.method_return(ret_out or {}) - yield Tick() - yield from self.set_enable(False) - - def method_handle_loop( - self, - function: Callable[..., Optional[RecordIntDict]], - *, - enable: Optional[Callable[[], bool]] = None, - validate_arguments: Optional[Callable[..., bool]] = None, - extra_settle_count: int = 0, - ) -> TestGen[None]: - yield Passive() - while True: - yield from self.method_handle( - function, - enable=enable, - validate_arguments=validate_arguments, - extra_settle_count=extra_settle_count, - ) - - # Debug signals - - def debug_signals(self) -> SignalBundle: - return self.adapter.debug_signals() diff --git a/transactron/testing/tick_count.py b/transactron/testing/tick_count.py new file mode 100644 index 000000000..a2d3828d6 --- /dev/null +++ b/transactron/testing/tick_count.py @@ -0,0 +1,25 @@ +from dataclasses import dataclass + +from amaranth import Signal +from amaranth.sim._async import ProcessContext + +from transactron.utils.dependencies import DependencyContext, SimpleKey + + +__all__ = ["TicksKey", "make_tick_count_process"] + + +@dataclass(frozen=True) +class TicksKey(SimpleKey[Signal]): + pass + + +def make_tick_count_process(): + ticks = Signal(64) + DependencyContext.get().add_dependency(TicksKey(), ticks) + + async def process(sim: ProcessContext): + async for _, _, ticks_val in sim.tick().sample(ticks): + sim.set(ticks, ticks_val + 1) + + return process