0

I have a coroutine which wait for an event to be set :

@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

I want to «yield» on it with a timeout. Then to do that I did this :

        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()

But I get this error :

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?

My coroutine is decorated with @cocotb.coroutine. If I yield it alone that works :

yield self.wb_RXDR_read() # <- that works

But I can't put it in a list. Is it possible to put coroutine in a list to block like unix select() ? Or is it reserved to Trigger class ?

4

1 回答 1

0

好的,我找到了解决方案。实际上 Coroutine 不能像时尚本身一样在 select 中触发。它应该首先作为一个线程启动,并且要检测协程的结束,.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()
于 2018-10-29T15:15:15.147 回答