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