from __future__ import annotations import cocotb from cocotb.clock import Clock from cocotb.triggers import RisingEdge async def reset_read_noise(dut): dut.rst_n.value = 0 dut.valid_i.value = 0 dut.row_ids_i.value = 0 dut.hashes_i.value = 0 dut.lane_valid_i.value = 0 for _ in range(3): await RisingEdge(dut.clk) dut.rst_n.value = 1 for _ in range(2): await RisingEdge(dut.clk) @cocotb.test() async def read_noise_disabled_forwards_hashes_after_one_stage(dut): cocotb.start_soon(Clock(dut.clk, 10, unit="ns").start()) await reset_read_noise(dut) LANES = 8 ROW_BITS = len(dut.row_ids_i) // LANES HASH_BITS_PER_LANE = len(dut.hashes_i) // LANES hashes = 0 rows = 0 for lane in range(LANES): hashes |= (lane + 0x55) << (lane * HASH_BITS_PER_LANE) rows |= lane << (lane * ROW_BITS) dut.hashes_i.value = hashes dut.row_ids_i.value = rows dut.lane_valid_i.value = 0xFF dut.valid_i.value = 1 await RisingEdge(dut.clk) dut.valid_i.value = 0 await RisingEdge(dut.clk) await RisingEdge(dut.clk) assert int(dut.valid_o.value) == 1 assert int(dut.hashes_noisy_o.value) == hashes assert int(dut.row_ids_o.value) == rows assert int(dut.lane_valid_o.value) == 0xFF