cocotb / cocotb

cocotb, a coroutine based cosimulation library for writing VHDL and Verilog testbenches in Python
https://www.cocotb.org
BSD 3-Clause "New" or "Revised" License
1.76k stars 505 forks source link

asking for improving wake-up condition from yield #228

Open congeal opened 9 years ago

congeal commented 9 years ago

yield statements seem like wait or join in Verilog. I would like for Cocotb has more functionalities for event-waiting.

Systemverilog has three different kinds of join keywords, join, join_any, and join_none. I want Cocotb to have the same features. yield [event0, event1] waits for any event in the list happening. However, there is no way of waiting for all events in a list happening like join of Verilog. trigger.Combine seems to support this kind of situation, but it doesn't works well, especially, when a event is a forked coroutine that has done its function.

Additionally, I want Cocotb to have a feature like 'iff' clause in Verilog so that monitors are going to wake up only if the specified condition is met. I think this could speed up the simulation and make monitor codes simpler.

chiggs commented 9 years ago

Agreed. We should have a richer set of capabilities for combining triggers.

Can you elaborate on what the iff clause would look like in practice?

congeal commented 9 years ago

SystemVerilog iff is used to restrict an event to occurs to when the specified condition is met. I think Cocotb may have the same functionality like: yield Conditional(RisingEdge(dut.ACLK), dut.AWVALID) The yield statement should return only when AWVALID = 1 on the rising edge of ACLK. Then, one can rewrite the example code shown below:

while True:
    yield RisingEdge(dut.clk)
    if dut.AWVALID:
        handle_axi_write_address_channel()

like:

while True
    yield Conditional(RisingEdge(dut.clk), dut.AWVALID)
    handle_axi_write_addres_channel()

The later one has less code and it is efficient in terms of execution time.

eric-wieser commented 6 years ago

The later one has less code

You can spell that:

@cocotb.coroutine
def conditional(trigger, condition):
    while True:
        yield trigger
        if condition():
            break

And then you get your requested syntax:

while True
    yield conditional(RisingEdge(dut.clk), lambda: dut.AWVALID)
    handle_axi_write_addres_channel()

it is efficient in terms of execution time.

Only if the trigger combination machinery ends up faster than just using the scheduler, which if it's python side I see no reason to expect.

ktbarrett commented 4 years ago

xref #1689.