I see similar comments frequently in UVM source code. Typically it is within a begin/end block with a “process” kept. A random seed is saved and restored before and after certain operation.
Can anyone comment why we need it and how it works? Thanks!
base/uvm_resource.svh
// ensure rand stability during lookup
begin
process p = process::self();
string s;
if(p!=null) s=p.get_randstate();
q=new();
if(p!=null) p.set_randstate(s);
end
base/uvm_task_phase.svh
fork
begin
process proc;
// reseed this process for random stability
proc = process::self();
proc.srandom(uvm_create_random_seed(phase.get_type_name(), comp.get_full_name()));
phase.m_num_procs_not_yet_returned++;
exec_task(comp,phase);
phase.m_num_procs_not_yet_returned--;
end
join_none
Certain operations, like constructing a class, change the random seeding of a process. There are many cases (for example, debugging) where you would like to modify your code without disturbing the random seed. If adding `uvm_info messages changed your random seeding, debugging could become impossible. The UVM puts the get/set_randstate() calls as guards around code to keep this from happening.
In the second piece of code, the UVM is using pathnames from uvm_component hierarchy to seed processes for all the time-consuming phases that run in parallel, instead of SV’s default, which uses the order the processes get created. This means you can add or remove components from your testbench without disturbing the random seeding of the existing components.