Verilog - generate weighted random numbers

system-verilog, verilog

Solution

The SystemVerilog solution has a distribution method within `randomize` called `dist`. Weights are assigned by `value_or_range := weight` or `value_or_range :/ distributed_weight`. This exert from the IEEE Std 1800-2012 § 18.5.4 page 476 gives a clear example:

When weights are applied to ranges, they can be applied to each value in the range, or they can be applied to the range as a whole. For example: `x dist { [100:102] := 1, 200 := 2, 300 := 5}` means x is equal to 100, 101, 102, 200, or 300 with a weighted ratio of 1-1-1-2-5, and `x dist { [100:102] :/ 1, 200 := 2, 300 := 5}` means x is equal to one of 100, 101, 102, 200, or 300 with a weighted ratio of 1/3-1/3-1/3-2-5.

`dist` is used in randomization so it needs to be mare of a `randomize() with` (or a class `constraint`). `randomize` returns a success bit, therefore it should be in called within an `assert`, `void'()`, or the RHS of an assignment.

In your we can set the weight of 0 to 6 and the weight of 1 to 4, creating a total weight of 10 with a 60/40 distribution. Example:

reg R;
initial begin
  assert( randomize(R) with { R dist { 0 := 6, 1 := 4 }; } );
end

From more about `dist` see IEEE Std 1800-2012 § 18.5.4 "Distribution".

Problem

I am trying to generate random single bits and this is simple as long as you want a normal randomization: ``` wire R; assign R = $random % 2; ``` What I am looking for is a sort of weighted probability like: ``` wire R; assign R = 60%(0) || 40%(1); ``` Forgive me if it is not conform to standard Verilog code, it is just to give an idea of what I want. Can anyone help me out? Thank you

Original source