$random and $urandom

So we are seeing some odd behavior generating some random numbers without the use of the constraint solver. I simplified the code here to simply print 3 unsigned random numbers, and three signed random number. Simple enough…

module rando;
  
initial
begin
  $display("Urandam 1", $urandom );
  $display("Urandam 2", $urandom );
  $display("Urandam 3", $urandom );

  $display("Randam 1",  $random );
  $display("Randam 2",  $random );
  $display("Randam 3",  $random );
end

endmodule

I then run this with our tool (Questa) with the -sv_seed set to random… Notice the $urandom values are different run to run with differing seeds (expected), but the $random values are the same run to run (not what I expected at least).

vsim -c -do "run 1; exit" -sv_seed random rando
** Note: (vsim-8009) Loading existing optimized design _opt
// Version 2022.2 linux_x86_64 Apr 25 2022
Sv_Seed = 4104478764
Urandam 12495546698
Urandam 23854710725
Urandam 31733257793
Randam 1 303379748
Randam 2-1064739199
Randam 3-2071669239

Repeat

vsim -c -do "run 1; exit" -sv_seed random rando
Sv_Seed = 3152372160
Urandam 11383566628
Urandam 22861028265
Urandam 33902325285
Randam 1 303379748
Randam 2-1064739199
Randam 3-2071669239

I found “something” on the topic in an Accelera bug report… but I am not sure if this is referencing this… It is a little vague what it means when there are no arguments…

The LRM should be clarified to show the argument to $urandom is input only, whereas the argument to $random is inout .

https://accellera.mantishub.io/view.php?id=5902

Is this the expected behavior? I was thinking of using $urandom in this instance to create a seed which is then used in both the $random and $urandom functions for the tests which don’t utilize the constraint solver. Thanks.

You should not be using $random; it is from legacy Verilog. It only has one global internal seed and that global seed can be manually changed using its inout argument.

SystemVerilog’s $urandom function gets its seed from the procedural thread/process calling the function. Each thread in a module has its own seed that gets seeded from a master seed. The master seed can be set from the simulation command line. See section 18.14 Random stability in the IEEE 1800-2017 SystemVerilog LRM