Archives mensuelles : décembre 2022

Un timeout dans cocotb

Avec Cocotb nous avons parfois des coroutines qui sont susceptible de rester «coincées» dans une boucle d’attente infinie. Si l’on y prête pas garde, on a vite fait de remplir son disque dur de traces totalement inutile.

# Une coroutine qui attend bien trop longtemps
async def too_long_coroutine(self):
    await Timer(1, units="sec")

Pour éviter ce problème, l’idéal serait de pouvoir ajouter un «timeout» à l’appel de la coroutine susceptible de bloquer.

Ça tombe bien, cocotb a prévu un trigger pour ça : with_timeout()

from cocotb.triggers import with_timeout
await with_timeout(testcls.too_long_coroutine(), 100, "ns")

Sauf que python n’a pas trop l’air d’accord pour exécuter notre coroutine comme un trigger.

TypeError: All triggers must be instances of Trigger! Got: coroutine

C’est dommage, on perd beaucoup de l’intérêt de ce trigger !

La solution donnée par marlonjames est d’«empaquetter» la coroutine dans la fonction start_soon() comme ceci :

await with_timeout(
     cocotb.start_soon(testcls.too_long_coroutine()),
     100, "ns")

De cette manière, le test s’interromps sur une levé d’interruption SimTimeoutError et le test est marqué FAIL sans ruiner notre disque dur.

    raise cocotb.result.SimTimeoutError
cocotb.result.SimTimeoutError