question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Simulation ends although it should wait 1000 Cycles

See original GitHub issue

I’m currently having a weird issue with cocotb 1.4 and verilator 4.100

I’m verifying an asynchronous FIFO design and have a basic 'manual, section which works perfectly, where I test reads and writes and the empty/full flags etc. then, I tried to do this to generate some more stress:

    # randomize
    cocotb.log.info(f"Test random read/write.")
    cocotb.fork(write_fifo(dut, vals))
    cocotb.fork(read_fifo(dut, vals))
    await ClockCycles(dut.clk_r_i, 1000)

So I am launching 2 coroutines, one of which is writing, the other one is reading and checking, both with random delays.

The coroutines look like this:

async def write_fifo(dut, vals):
    w_cnt = 0
    while True:
        cocotb.log.info(f"In write proc.")
        for _ in range(random.randrange(1, 32)):
            await FallingEdge(dut.clk_w_i)
        if dut.full_o == 0:
            cocotb.log.info(f"Random write number {w_cnt}.")
            dut.wen_i <= 1
            dut.wdata_i <= vals[w_cnt]
            await RisingEdge(dut.clk_w_i)
            dut.wen_i <= 0
            w_cnt = w_cnt + 1


async def read_fifo(dut, vals):
    r_cnt = 0
    while True:
        cocotb.log.info(f"In read proc.")
        for _ in range(random.randrange(0, 12)):
            await FallingEdge(dut.clk_r_i)
        if dut.empty_o == 0:
            cocotb.log.info(f"Random read number {r_cnt}.")
            dut.ren_i <= 1
            await RisingEdge(dut.clk_r_i)
            dut.ren_i <= 0
            await FallingEdge(dut.clk_r_i)
            assert dut.rdata_o == vals[r_cnt], f"Read Data mismatch at value {r_cnt}, got {hex(int(dut.rdata_o))} but expected {hex(int(vals[r_cnt]))}"
            r_cnt = r_cnt + 1

The weird thing is, the simulation does not wait for the 1000 cycles of the read clock, it just ends:

0.00ns INFO     Running test 1/2: test_afifo
     0.00ns INFO     Starting test: "test_afifo"
                     Description:  Test that data is being passed across clock domains.
     0.00ns INFO     Reset AFIFO on both sides.
     5.00ns INFO     Check empty and not full.
     5.00ns INFO     Fill FIFO with random values.
   285.00ns INFO     Test write error flag.
   305.00ns INFO     Read back previously written data.
  1535.50ns INFO     Test read error flag.
  1609.50ns INFO     Test random read/write.
  1609.50ns INFO     In write proc.
  1609.50ns INFO     In read proc.
  1625.00ns INFO     Random write number 0.
  1628.00ns INFO     Test Passed: test_afifo

You can see from the log that both coroutines do start and that the first write is apparently attempted. I can also confirm that from the waveform, the wen_i signal goes high, but everything ends before the RisingEdge of the write clock clk_w_i does occur.

Either I am overlooking something very stupid or something is wrong here. In my understanding, even if the coroutines were garbage, shouldn’t at least the waiting for the 1000 clocks work?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:58 (58 by maintainers)

github_iconTop GitHub Comments

2reactions
marlonjamescommented, Nov 16, 2020

@ktbarrett I don’t think that will work, because last may have erase called on it, invalidating the iterator. I had something similar to that, updating last = std::prev(last) if it was going to be erased, but I couldn’t solve the segfault I was getting.

My in-progress verilator loop update is also MUCH faster. The example test runs in ~0.6s vs 10.5s

1reaction
ktbarrettcommented, Oct 7, 2020

Opened verilator/verilator#2588.

Read more comments on GitHub >

github_iconTop Results From Across the Web

wait($time >1000); cannot work in system-verilog?
The simulator processes all events for the current time slot in a queue, and when that queue is empty, it advances time to...
Read more >
good technique to generate a random delay?
Following each command, I would like to wait for a random delay. ... num=$urandom_range(1000,0); cfg.wait_clk(num); end end endtask.
Read more >
Tutorial 2: Simulation
In this tutorial we will simulate our design. This will be the simplest ... In this case, I've chosen to run the simulation...
Read more >
Verilog Testbench - wait for specific number of clock cycle ...
In my testbench, I want to wait for two events in sequence: one after 60000 clock cycles and next after additional 5000 clock...
Read more >
System Verilog Assertions Simplified
In the above snippet, assertion finishes when signal “a” is asserted high and within 5 to 7 (MIN_DELAY:MAX_DELAY) clock cycles, signal “b” asserts...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found