UVM 2020-2.0 early release is out and i thought it would be fun to deep dive into one of the differences and try to understand why that change was made.
I thought that was an interesting one!
< // we use a queue here only to avoid any problems on writing to variables
< // inside an always_comb/latch/ff in case those call UVM
< uvm_core_state m_uvm_core_state[$];
---
> uvm_core_state m_uvm_core_state = UVM_CORE_UNINITIALIZED;
So, what does this comment mean? Let’s start with uvm_core_state
. well, that was easy.
typedef enum {
UVM_CORE_UNINITIALIZED,
UVM_CORE_PRE_INIT,
UVM_CORE_INITIALIZING,
UVM_CORE_INITIALIZED, // UVM_CORE_POST_INIT
UVM_CORE_PRE_RUN,
UVM_CORE_RUNNING,
UVM_CORE_POST_RUN,
UVM_CORE_FINISHED,
UVM_CORE_PRE_ABORT,
UVM_CORE_ABORTED
} uvm_core_state;
grepping through src
./base/uvm_object_globals.svh:uvm_core_state m_uvm_core_state[$];
./base/uvm_root.svh: m_uvm_core_state.push_front(UVM_CORE_PRE_ABORT);
./base/uvm_root.svh: m_uvm_core_state.push_front(UVM_CORE_ABORTED);
./base/uvm_root.svh: m_uvm_core_state.push_front(UVM_CORE_PRE_RUN);
./base/uvm_root.svh: m_uvm_core_state.push_front(UVM_CORE_POST_RUN);
./base/uvm_root.svh: m_uvm_core_state.push_front(UVM_CORE_FINISHED);
./base/uvm_globals.svh: if (m_uvm_core_state.size() == 0) return UVM_CORE_UNINITIALIZED;
./base/uvm_globals.svh: else return m_uvm_core_state[0];
./base/uvm_globals.svh: m_uvm_core_state.push_front(UVM_CORE_PRE_INIT);
./base/uvm_globals.svh: m_uvm_core_state.push_front(UVM_CORE_INITIALIZING);
./base/uvm_globals.svh: m_uvm_core_state.push_front(UVM_CORE_INITIALIZED);
./base/uvm_phase.svh: m_uvm_core_state.push_front(UVM_CORE_RUNNING);
There is a getter in ./base/uvm_globals.svh
which returns the first element in the queue
function uvm_core_state get_core_state();
if (m_uvm_core_state.size() == 0) return UVM_CORE_UNINITIALIZED;
else return m_uvm_core_state[0];
endfunction
Which is called from the following places
./base/uvm_root.svh: if (get_core_state() inside {UVM_CORE_PRE_ABORT,UVM_CORE_ABORTED})
./base/uvm_globals.svh: if(get_core_state()!=UVM_CORE_UNINITIALIZED) begin
./base/uvm_globals.svh: if (get_core_state() == UVM_CORE_PRE_INIT) begin
./base/uvm_registry.svh: if (uvm_pkg::get_core_state() != UVM_CORE_UNINITIALIZED) begin
./base/uvm_registry.svh: if (uvm_pkg::get_core_state() == UVM_CORE_UNINITIALIZED) begin
From what i see, state gets pushed in several places but never pop’ed out. hmmmm! At this point, I am still baffled. The comment says
// we use a queue here only to avoid any problems on writing to variables
// inside an always_comb/latch/ff in case those call UVM
but who calls UVM inside always
!???? Now i have to do part2.