Получая сопрограмму в списке с cocotb
У меня есть сопрограмма, которая ждет события, которое будет установлено:
@cocotb.coroutine
def wb_RXDR_read(self):
""" waiting util RXDR is read """
if not self._RXDR_read_flag:
while True:
yield self._RXDR_read_event.wait()
break
Я хочу "уступить" этому с тайм-аутом. Затем, чтобы сделать это, я сделал это:
RXDR_timeout = Timer(250, units="us")
ret = yield [RXDR_timeout, self.wb_RXDR_read()]
if ret == RXDR_timeout:
self._dut._log.error("Timeout on waiting RXDR to be read")
raise TestError()
Но я получаю эту ошибку:
2ns ERROR Coroutine i2c_write yielded something the scheduler can't handle
Got type: <type 'list'> repr: [<cocotb.triggers.Timer object at 0x7f2098cb1350>, <cocotb.decorators.RunningCoroutine object at 0x7f2098cb1610>] str: [<cocotb.triggers.Timer object at 0x7f2098cb1350>, <cocotb.decorators.RunningCoroutine object at 0x7f2098cb1610>]
Did you forget to decorate with @cocotb.coroutine?
Моя сопрограмма украшена @cocotb.coroutine. Если я дам это в одиночку, это работает:
yield self.wb_RXDR_read() # <- that works
Но я не могу поместить это в список. Можно ли поместить сопрограмму в список, чтобы блокировать, как unix select()? Или это зарезервировано для класса Trigger?
1 ответ
Решение
Хорошо, я нашел решение. На самом деле Coroutine не может быть запущен в избранном, как сама мода. Сначала он должен быть запущен как поток, и для определения конца сопрограммы необходимо добавить метод.join() в список yield:
RXDR_timeout = Timer(250, units="us")
RXDR_readth = cocotb.fork(self.wb_RXDR_read()
ret = yield [RXDR_timeout, RXDR_readth.join()]
if ret == RXDR_timeout:
self._dut._log.error("Timeout on waiting RXDR to be read")
raise TestError()
Мысль помнить это:
- Мы можем дать одну сопрограмму
- Чтобы получить несколько сопрограмм, мы должны выполнить fork() и join ()