Skip to content

Random Number Generation

Danny Nicholls edited this page Feb 27, 2014 · 2 revisions

The following code for generating packets at random instants produces bursts of several packets in a short time period even with a long warm up time. This can severely distort latency measurements.

logic [31:0] r32

// Generate random numbers for packet generation
always_ff @(posedge clk or posedge rst)
  if (rst) begin
    r32 <= (2^32)-(`SEED * (port_no+1));`
  end else begin	`
    r32 <= {r32[30:0], (r32[0] ^ r32[1] ^ r32[21] ^ r32[31])};	`

always_ff @(posedge clk or posedge rst)`
  if (r32< `RATE) begin 
    < process for packet generation>

In simulation, using the $dist_uniform function gives better results but this obviously does not help with FPGA networks:

integer r32_seed = (port_no+1) *`SEED;

// Generate random numbers for packet generation
always_ff @(posedge clk or posedge rst)
  if (rst)
    r32 <= 0;
  else 	
    r32 <= $dist_uniform(r32_seed, 0, 2147483647);	

Another function, similar to $dist_uniform that can be used in simulation is the $urandom_range function. Dave from mentor graphics explained that it increases random stability, where stability is the repeatability of a series of random numbers as you make changes to your testbench (18.14 Random stability in the 1800-2012 LRM).

Suppose you have two always blocks generating random numbers. Then you make a change to the testbench so that in one of the blocks the frequency of generating random numbers changes. Maybe you get two random numbers or skip a random number in one cycle. If all the random number generators share the same seed variable, then the sequence of random numbers in the always block where you did not make a change will be affected. On the other hand, if you give each always block a separate seed variable, you need to make sure each variable begins with a different seed value, otherwise you may wind up with the same series of random values in each always block.

SystemVerilog takes care of this automatically by a specific algorithm that creates a seed variable for each thread as well as giving each variable a unique starting value.

A discussion of weighting random numbers can be found on stack overflow

Clone this wiki locally