Constrained Random Stimulus-$urandom

Hi,

module Tb_mem();

  reg clock;
  reg read_write;
  reg [31:0] data;
  integer address;
  
  initial
  begin
    clock = 0;
  forever #10 clock = ~clock;
  end
  
  initial
  begin
   repeat(5) @(negedge clock)
   begin
     read_write = $random ; data = $random; address = $urandom;
     $display($time," read_write = %d ; data = %d ; address = %d;",read_write,data,address);
   end
   #10 $finish;
  end


endmodule

Qusta output:-

VSIM 1> run -a
#                   20 read_write = 0 ; data = 3230228097 ; address =  -949724053;
#                   40 read_write = 1 ; data = 2985317987 ; address =    90095195;
#                   60 read_write = 1 ; data = 1189058957 ; address =   319555061;
#                   80 read_write = 1 ; data = 2302104082 ; address =  1804312861;
#                  100 read_write = 1 ; data =  114806029 ; address = -1891643016;

Doubt-We know that $urandom generates positive values,but am getting negative i.e signed values.The problem is solved if I use “integer unsigned address”,but in that case what’s the use of $urandom then?

regards
sunny

Both $random and $urandom return 32-bit int unsigned typed values. When you make an assignment to a signed type from an unsigned value of the same size, the MSB becomes the sign bit.

You should not be using signed data types like int or integer to represent values that are always considered positive or unsigned. And you should not use 4-state types like reg or integer to represent values that can never be X.

Good programming practice to is to use typedef’s that represent the types of all your variables.

module Tb_mem();
   typedef bit [31:0] data_t;
   typedef bit [31:0] address_t;
  bit clock;
  bit read_write;
  data_t data;
  address_t address;

This way if the width of your address changes, you only need to change one statement.

One more thing, do not use $random - just use $urandom. SystemVerilog added $urandom to solve many random stability problems. $random was left in for legacy Verilog.

In reply to dave_59:

Dave,
As per LRM 20.15.1, $random returns “signed integer”.

Now to Sunny:

Here is our explanation for this interesting test (after some discussion with Srini as well).

$urandom by default generates a 32-bit UNSIGNED random number. But in this example “address” is a 32-bit SIGNED number, hence the moment 32nd bit is “1” it shows/displays/gets stored as 31-bit, negative number.

To better understand one could try declaring address as 33-bit number as below:


// integer address;
bit signed [32:0] address;

Now see what Questa does:

20 read_write = 0 ; data = 3230228097 ; address = 318257127;

40 read_write = 1 ; data = 2985317987 ; address = 1182951324;

60 read_write = 1 ; data = 1189058957 ; address = 1369112040;

80 read_write = 1 ; data = 2302104082 ; address = 1633699606;

100 read_write = 1 ; data = 114806029 ; address = 1215951616;

With due regards
Ajeetha, CVC

So, which function does the randomize internally uses?

18.6.1 Randomize() Variables in an object are randomized using the randomize() class method. Every class has a built-in randomize() virtual method, declared as follows: virtual function int randomize(); The randomize() method is a virtual function that generates random values for all the active random variables in the object, subject to the active constraints.

In reply to ben@SystemVerilog.us:

The randomize() method is not defined in terms $urandom (or $random) it can randomize whatever bits it need to based on the type of the random variable being randomized. The implementation is not defined by the standard.

Thanks,

Dave & Ajeetha
It was really very helpful.

regards
sunny

In reply to sunny:

if i have 32 bit two reg where i have generate arithmetic addition overflow i.e carry should be generated. i m using
reg [0:31] A;
reg [0:31] B;

A = $urandom_range(8’hF0000000, 8’hFFFFFFFF);
B = $urandom_range(8’hF0000000, 8’hFFFFFFFF);
but its not wrking somehow… can you please help

In reply to rtawade:

What do you mean by ‘not working’? That’s fairly ambiguous and not really informative.

Is it only randomizing values between 0 and 256? That is because you are using the incorrect nomenclature for a 32-bit value. It should be 32’hF0000000, not 8’hF0000000.

Also, the function prototype is:

function int unsigned $urandom_range( int unsigned maxval, int unsigned minval = 0 );

The maxval should be specified first, and the minval second. Although, the LRM does state that the arguments will be internally reversed if you don’t do it correctly.

In reply to cgales:

ohh… my bad !! i understood.

Thank you so much … now my module is working fine there was an issue with 8’h00