在cocotb列表中产生协程

时间:2018-10-17 12:46:44

标签: python 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 个答案:

答案 0 :(得分:0)

好的,我找到了解决方案。实际上,协程不能像时尚本身那样在选择中触发。它应该首先作为线程启动,并且要检测协程的结束,必须将.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()