Timeout is such an important pattern that cocotb provide with_timeout for coroutines to call other routines with timeouts and return SimTimeoutError if coroutine times out.
Wait on any awaitable, throw an exception if it waits longer than the given time.
When a coroutine is passed, the callee coroutine is started, the caller blocks until the callee completes, and the callee’s result is returned to the caller. If timeout occurs, the callee is killed and SimTimeoutError is raised.
await with_timeout(coro, 100, "ns")
I thought it would be good to create with_cycles_timeout to do something but using number of clock cycles (posedge).
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge, ClockCycles, First
from cocotb.result import SimTimeoutError
async def with_cycle_timeout(coro, clock, cycles):
func_task = cocotb.start_soon(coro)
timeout_trigger = ClockCycles(clock, cycles)
results = await First(func_task, timeout_trigger)
if results is timeout_trigger:
raise SimTimeoutError(f"Timeout after {cycles} cycles")
else:
return results
async def dummy_write(dut, cycles):
for i in range(cycles):
await RisingEdge(dut.clk)
cocotb.log.info(f"cycle {i+1}/{cycles}")
cocotb.log.info(f"Finished after {cycles} cycles")
return 0xDEADBEEF
@cocotb.test()
async def test_timeout(dut):
cocotb.start_soon(Clock(dut.clk, 10, unit='ns').start())
try:
value = await with_cycle_timeout(dummy_write(dut, cycles=10),clock=dut.clk,cycles=20,)
cocotb.log.info(f"Result: {value:#010x}")
value = await with_cycle_timeout(dummy_write(dut, cycles=10),clock=dut.clk,cycles=3,)
cocotb.log.info(f"Result: {value:#010x}")
except SimTimeoutError as e:
cocotb.log.error(f"Timeout: {e}")
in the first case, the routine returns the value but in the second case, it raise SimTimeoutError which is caught by the caller.
0.00ns INFO test cycle 1/10
10.00ns INFO test cycle 2/10
20.00ns INFO test cycle 3/10
30.00ns INFO test cycle 4/10
40.00ns INFO test cycle 5/10
50.00ns INFO test cycle 6/10
60.00ns INFO test cycle 7/10
70.00ns INFO test cycle 8/10
80.00ns INFO test cycle 9/10
90.00ns INFO test cycle 10/10
90.00ns INFO test Finished after 10 cycles
90.00ns INFO test Result: 0xdeadbeef
100.00ns INFO test cycle 1/10
110.00ns INFO test cycle 2/10
120.00ns INFO test cycle 3/10
120.00ns ERROR test Timeout: Timeout after 3 cycles