registers/vertical_reuse blk-level simulation fails with ghdl/VHDL DUT
When running the above-mentioned example, uvm_fatal is thrown. Looks like APB monitor does not register any items during simulation.
Commands to reproduce the issue:
cd test/examples/simple/registers/vertical_reuse
SIM=ghdl make TOPLEVEL_LANG=vhdl IMG=BLK SIMARGS="-- +UVM_TESTNAME=blk_R_test" SIM_BUILD=sim_build_blk
Expected result:
Test passes, and does not throw uvm_fatal.
Leaving out TOPLEVEL_LANG=vhdl and the -- makes this config pass with Questa but fail with a ValueError in Xcelium, and a segfault with VCS.
So I would consider this test a bit "special" already with Verilog, not necessarily with VHDL/ghdl only.
FWIW, cocotb master reports RuntimeWarning: Timer setup with value 0, which might exhibit undefined behavior in some simulators in src/uvm/base/uvm_globals.py:461, src/uvm/base/uvm_globals.py:351, src/uvm/base/uvm_globals.py:469, test/examples/integrated/apb/apb_master.py:152, test/examples/integrated/apb/apb_master.py:156, which may have something to do with it.
The Xcelium fail is the following:
UVM_INFO @ 0.0NS: reporter [DEFVERB] No verbosity specified on the command line. Using the default: UVM_MEDIUM
0.00ns INFO cocotb.regression regression.py:127 in __init__ Found test blk_run.initial
0.00ns INFO cocotb.regression regression.py:466 in _start_test Running test 1/1: initial
0.00ns INFO cocotb.test.initial.0x7f4c1a8db850 decorators.py:313 in _advance Starting test: "initial"
Description: None
/tmp/uvm-python/src/uvm/base/uvm_globals.py:461: RuntimeWarning: Timer setup with value 0, which might exhibit undefined behavior in some simulators
await Timer(0, "NS")
UVM_INFO @ 0.0NS: reporter [RNTST] Running test blk_R_test...
/tmp/uvm-python/src/uvm/base/uvm_globals.py:351: RuntimeWarning: Timer setup with value 0, which might exhibit undefined behavior in some simulators
await Timer(0)
UVM_INFO /tmp/uvm-python/test/examples/integrated/apb/apb_master.py(75) @ 0.0NS: env.apb.drv [APB_MASTER] apb_master run_phase started
UVM_INFO /tmp/uvm-python/src/uvm/base/uvm_phase.py(58) @ 0.0NS: reporter [PH_READY_TO_END] Phase 'uvm.uvm_sched.pre_reset' (id=93) PHASE READY TO END
UVM_INFO /tmp/uvm-python/src/uvm/base/uvm_phase.py(58) @ 0.0NS: reporter [PH_READY_TO_END] Phase 'uvm.uvm_sched.reset' (id=103) PHASE READY TO END
UVM_INFO /tmp/uvm-python/src/uvm/base/uvm_phase.py(58) @ 0.0NS: reporter [PH_READY_TO_END] Phase 'uvm.uvm_sched.post_reset' (id=113) PHASE READY TO END
UVM_INFO /tmp/uvm-python/src/uvm/base/uvm_phase.py(58) @ 0.0NS: reporter [PH_READY_TO_END] Phase 'uvm.uvm_sched.pre_configure' (id=123) PHASE READY TO END
UVM_INFO /tmp/uvm-python/src/uvm/base/uvm_phase.py(58) @ 0.0NS: reporter [PH_READY_TO_END] Phase 'uvm.uvm_sched.configure' (id=133) PHASE READY TO END
UVM_INFO /tmp/uvm-python/src/uvm/base/uvm_phase.py(58) @ 0.0NS: reporter [PH_READY_TO_END] Phase 'uvm.uvm_sched.post_configure' (id=143) PHASE READY TO END
UVM_INFO /tmp/uvm-python/src/uvm/base/uvm_phase.py(58) @ 0.0NS: reporter [PH_READY_TO_END] Phase 'uvm.uvm_sched.pre_main' (id=153) PHASE READY TO END
UVM_INFO /tmp/uvm-python/src/uvm/base/uvm_phase.py(58) @ 0.0NS: reporter [PH_READY_TO_END] Phase 'uvm.uvm_sched.main' (id=163) PHASE READY TO END
UVM_INFO /tmp/uvm-python/src/uvm/base/uvm_phase.py(58) @ 0.0NS: reporter [PH_READY_TO_END] Phase 'uvm.uvm_sched.post_main' (id=173) PHASE READY TO END
UVM_INFO /tmp/uvm-python/src/uvm/base/uvm_phase.py(58) @ 0.0NS: reporter [PH_READY_TO_END] Phase 'uvm.uvm_sched.pre_shutdown' (id=183) PHASE READY TO END
UVM_INFO /tmp/uvm-python/src/uvm/base/uvm_phase.py(58) @ 0.0NS: reporter [PH_READY_TO_END] Phase 'uvm.uvm_sched.shutdown' (id=193) PHASE READY TO END
UVM_INFO /tmp/uvm-python/src/uvm/seq/uvm_sequencer.py(97) @ 1.0NS: env.apb.sqr [UVM_SEQUENCER YYY] get_next_item called now
/tmp/uvm-python/src/uvm/base/uvm_globals.py:469: RuntimeWarning: Timer setup with value 0, which might exhibit undefined behavior in some simulators
await Timer(0, "NS")
UVM_INFO /tmp/uvm-python/src/uvm/reg/uvm_reg_map.py(1395) @ 45.0NS: reporter [UVMRegMap] Writing 0x8E at 0x0 via map reg_blk_B.default_map...
/tmp/uvm-python/test/examples/integrated/apb/apb_master.py:152: RuntimeWarning: Timer setup with value 0, which might exhibit undefined behavior in some simulators
await Timer(0, "NS")
UVM_INFO /tmp/uvm-python/test/examples/integrated/apb/apb_master.py(131) @ 51.0NS: env.apb.drv [APB_MASTER] Doing APB write to addr 0
UVM_INFO /tmp/uvm-python/test/examples/integrated/apb/apb_master.py(141) @ 71.0NS: env.apb.drv [APB_MASTER] Finished APB write to addr 0
/tmp/uvm-python/test/examples/integrated/apb/apb_master.py:156: RuntimeWarning: Timer setup with value 0, which might exhibit undefined behavior in some simulators
await Timer(0, "NS")
UVM_INFO /tmp/uvm-python/src/uvm/seq/uvm_sequencer.py(97) @ 81.0NS: env.apb.sqr [UVM_SEQUENCER YYY] get_next_item called now
UVM_INFO /tmp/uvm-python/src/uvm/reg/uvm_reg_map.py(1464) @ 81.0NS: reporter [UVMRegMap] Wrote 0x8E at 0x0 via map reg_blk_B.default_map: 0...
UVM_INFO /tmp/uvm-python/src/uvm/reg/uvm_reg_map.py(1549) @ 81.0NS: reporter [UVMRegMap] Reading address 'h0 via map "reg_blk_B.default_map"...
UVM_INFO /tmp/uvm-python/test/examples/integrated/apb/apb_master.py(115) @ 91.0NS: env.apb.drv [APB_MASTER] Doing APB read to addr 0
111.00ns ERROR ...coroutine.Task 68.0x7f4c1961b2d0 scheduler.py:506 in unschedule Exception raised by this forked coroutine
111.10ns ERROR cocotb.regression regression.py:399 in _score_test Test Failed: initial (result was ValueError)
Traceback (most recent call last):
File "/tmp/uvm-python/src/uvm/base/uvm_task_phase.py", line 209, in _execute_fork_join_none
await self.exec_task(comp, phase)
File "/tmp/uvm-python/src/uvm/base/uvm_common_phases.py", line 300, in exec_task
await comp.m_run_process
File "/tmp/cocotb/cocotb/decorators.py", line 255, in __await__
return (yield self)
File "/tmp/uvm-python/test/examples/integrated/apb/apb_monitor.py", line 93, in run_phase
tr.data = self.sigs.prdata.value.integer
File "/tmp/cocotb/cocotb/binary.py", line 294, in integer
return self._convert_from[self.binaryRepresentation](self._str)
File "/tmp/cocotb/cocotb/binary.py", line 200, in _convert_from_unsigned
return int(resolve(x), 2)
File "/tmp/cocotb/cocotb/binary.py", line 44, in resolve
raise ValueError("Unable to resolve to binary >%s<" % string)
ValueError: Unable to resolve to binary >zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz<
I saw this RuntimeWarning as well. I don't think it has been there in the previous versions in July/August. apb_master should work without it, but I don't think it will be so easy to remove from uvm_globals.
I think it has problems, as right now I'm assuming that await Timer(0) would be equal to #0 in SystemVerilog. But this is not really the case. This goes somewhat deep into scheduling and uvm_phases, and understanding how to solve it without await Timer(0) is not trivial.
I suppose the Xcelium error can be related to scheduling, if monitor tries to read the value before driver has driven it to known state. I will cross-check the time stamps with iverilog simulation, to see if there's something different.
Yes, the behavior has not changed, but the warning has been added - which is probably pointing us at the right place now.
A replacement for the Timer(0) might be ReadOnly.
It seems ReadOnly correspond to PostPoned region in SV. In uvm_globals, we would need to wait until NBA region only. In this region, values are not yet stable and signal updates can still occur before proceeding to next time step. I tried ReadWrite instead, and most of the tests pass using Icarus. I need to debug tomorrow the failures, and see if this is the correct solution.
However, I have another task uvm_zero_delay, which simply calls await Timer(0). This was added as UVM uses #0 in several places. I need to check if this task can be also changed to something else.
@tpoikela ReadWrite is the correct trigger. See my mostly-complete documentation on cocotb's timing model. Timer(0) is not safe and I have seen it crash simulators in certain circumstances.
@ktbarrett Thanks for this info! The documentation is excellent and very concise. It will be a slightly bigger effort to adapt uvm-python to follow this (unless removing zero delays works out of the box).
For verilator, I'm only using ReadWrite (no Timer(0)), but iverilog requires Timer(0) in order to make all the tests pass. verilator has problems with some of the tests though.
@tpoikela Timer(0) has also been used to unconditionally yield control to the scheduler to allow another coroutine to run. In those cases you could replace it with NullTrigger.
@ktbarrett Thanks for this tip. Sounds like NullTrigger might work here.
BTW: https://github.com/cocotb/cocotb/issues/1611
Modelsim and VCS fail when waiting on ReadWrite after RisingEdge.
@themperek Does this mean they need to be inside the same coroutine, RisingEdge followed by ReadWrite as next trigger?
@ktbarrett I've managed to remove Timer(0), and replaced it with NullTrigger. This seems to have improved verilator stability as well, and 2 testcases which were failing for verilator are now passing. Is NullTrigger something which does not interact with simulator at all since it's used for internal scheduling?
Is NullTrigger something which does not interact with simulator at all since it's used for internal scheduling?
That's correct, it does not interact with the simulator, it's a Python-only trigger. Glad to hear it fixed some things.