Array randomization

V

Verictor

Guest
What are the techniques to randomize dynamic arrays? The array, in the
context, means these two cases mainly:

class array_2D;
rand int array;
endclass

and

class array_1D;
rand bit [i:0] array[j];
endclass

For the 2-D array case, we usually use pre_randomize() or
post_randomize(). Is there other way?

For the 1-D array case, I am not sure if it is the right class
construction. But if indeed a class has been defined like that, how do
we randomize it? It seems there are more randomize dimensions than the
2-D case.

Thanks in advance.
 
On Jul 16, 1:16 am, Verictor <stehu...@gmail.com> wrote:

class array_2D;
   rand int array;
endclass

and

class array_1D;
   rand bit [i:0] array[j];
endclass

I don't think these are different in any important way. But
these are not dynamic arrays; they are fixed-size arrays
and 'i' and 'j' must be constant expressions (parameters).

For the 2-D array case, we usually use pre_randomize() or
post_randomize(). Is there other way?
Yes, you can certainly randomize an array.

array_2D a2D=new;
a2D.randomize() with {
foreach (array[idx]) {
array[idx] inside {[idx:2*idx]};
}
};

If you have a true dynamic array or queue, things are a little
more complicated because the size of the array can also be
randomized. This is all described in IEEE Std.1800-2009,
clause 18.4 (Random variables). There are quite a few details
about rand_mode() of individual elements, but the basic idea
is simple:
- If there is no constraint on array.size, the rand array is
left with its original number of elements and each element
is randomized in accordance with your constraints.
- If array.size is constrained by one or more constraints,
the array is first resized to a randomly chosen size and
then all its elements are randomized.

Example: Let's construct a random message that obeys...
- first byte is exactly 0xAA
- second byte is total message length
- remaining bytes are random payload
- total length is in the range 3:100
- the even-numbered payload bytes are in an
incrementing sequence such as 4,??, 5, ??, 6, ...

class rand_msg;
rand bit [7:0] message[]; // dynamic array
constraint c_protocol {
message.size() inside {[3:100]};
message[0] == 8'hAA;
message[1] == message.size();
foreach (message) {
if ((i > 2) && (i%2 == 0)) {
message == message[i-2];
}
}
}
endclass

Hope this helps
--
Jonathan Bromley
 
On Jul 16, 9:30 am, Jonathan Bromley wrote:

Example: Let's construct a random message that obeys...
....
- the even-numbered payload bytes are in an
  incrementing sequence such as 4,??, 5, ??, 6, ...
....
        foreach (message) {
           if ((i > 2) && (i%2 == 0)) {
              message == message[i-2];

Oops, typo, sorry. That last line should have been

message == message[i-2] + 1'b1;

Pop quiz: why must it be "+1'b1"? Why not "+1" ???
--
Jonathan Bromley
 
On Jul 16, 5:08 am, Jonathan Bromley <s...@oxfordbromley.plus.com>
wrote:
On Jul 16, 9:30 am, Jonathan Bromley wrote:



Example: Let's construct a random message that obeys...
...
- the even-numbered payload bytes are in an
  incrementing sequence such as 4,??, 5, ??, 6, ...
...
        foreach (message) {
           if ((i > 2) && (i%2 == 0)) {
              message == message[i-2];

Oops, typo, sorry.  That last line should have been

                message == message[i-2] + 1'b1;

Pop quiz: why must it be "+1'b1"?   Why not "+1" ???
--
Jonathan Bromley

Because +1 is 32-bit :).

Thanks Jonathan. My oriignal question was about to randomize a dynamic
array, array size included. The array size is being randomized first
then the elements, like you said. I wonder if there are other ways.

Besides the 2-D array's size also needs to be randomize, in this case

rand bit [7:0] message[]; // dynamic array

The bit width, 7 above, also needs be randomized. The idea is that
some message may come in with more or less bits (this may be not a
good way to express it but let's assume that is the case).
 
On Fri, 16 Jul 2010 07:19:18 -0700 (PDT), Verictor wrote:

My oriignal question was about to randomize a dynamic
array, array size included. The array size is being randomized first
then the elements, like you said. I wonder if there are other ways.

Besides the 2-D array's size also needs to be randomize, in this case

rand bit [7:0] message[]; // dynamic array

The bit width, 7 above, also needs be randomized.
ah, you mean the *element* size needs to be randomized...

You simply can't do this in SV. There is no such thing
as a dynamically-sized vector. The bit width of any
vector MUST be known at elaboration time.

A vector is a "packed" object; a dynamic array is "unpacked".

I think your problem is probably best solved by inventing
some kind of data structure...

typedef struct {
int unsigned number_of_bits;
bit [63:0] data;
} flexi_vector;

rand flexi_vector stuff[];
constraint meaningful_flexi_vector {
foreach (stuff) {
stuff.number_of_bits > 0;
stuff.number_of_bits <= 64;
stuff.data < (65'b1<<stuff.number_of_bits);
}
}

Or maybe the number of bits per word is the same for
every element of the array. That would be even easier:

int unsigned number_of_bits;
bit [63:0] data[];
constraint sensible_vector_size {
number_of_bits > 0;
number_of_bits <= 64;
}
constraint meaningful_data {
foreach (stuff) {
data < (65'b1<<number_of_bits);
}
}

No dynamic vector size. Sorry.
--
Jonathan Bromley
 
On Jul 16, 5:30 pm, Jonathan Bromley <s...@oxfordbromley.plus.com>
wrote:
On Fri, 16 Jul 2010 07:19:18 -0700 (PDT), Verictor wrote:
My oriignal question was about to randomize a dynamic
array, array size included. The array size is being randomized first
then the elements, like you said. I wonder if there are other ways.

Besides the 2-D array's size also needs to be randomize, in this case

rand bit [7:0] message[];  // dynamic array

The bit width, 7 above, also needs be randomized.

ah, you mean the *element* size needs to be randomized...

You simply can't do this in SV.  There is no such thing
as a dynamically-sized vector.  The bit width of any
vector MUST be known at elaboration time.

A vector is a "packed" object; a dynamic array is "unpacked".

I think your problem is probably best solved by inventing
some kind of data structure...

  typedef struct {
    int unsigned number_of_bits;
    bit [63:0] data;
  } flexi_vector;

  rand flexi_vector stuff[];
  constraint meaningful_flexi_vector {
    foreach (stuff) {
      stuff.number_of_bits > 0;
      stuff.number_of_bits <= 64;
      stuff.data < (65'b1<<stuff.number_of_bits);
    }
  }

Or maybe the number of bits per word is the same for
every element of the array.  That would be even easier:

  int unsigned number_of_bits;
  bit [63:0] data[];
  constraint sensible_vector_size {
    number_of_bits > 0;
    number_of_bits <= 64;
  }
  constraint meaningful_data {
    foreach (stuff) {
      data < (65'b1<<number_of_bits);
    }
  }

No dynamic vector size.  Sorry.
--
Jonathan Bromley

When you declared stuff[] as flexi_vector,

rand flexi_vector stuff[];

the size is part of the randomization via the flexi_vector struct. How
about taking it out as an independent variable. Like this;

int unsigned number_of_bits;

typedef struct {
bit [number_of_bits:0] data;
} flexi_vector;

Before new a flex_vector, do something like this to randomize
number_of_bits:

class use_flexi_vector();
....
function new();
..
number_of_bits = $random(); // not using randomize but just
plain verilog $random() system function
endfunction
....
endclass

or put number_of_bits = $random() outside of any dynamic variable,
i.e., set it to be static.

Even though the size must be known at elaboration time, this may help?
 
On Sat, 17 Jul 2010 08:45:05 -0700 (PDT), Verictor wrote:

[me]
No dynamic vector size.  Sorry.
[Verictor]
as flexi_vector,
rand flexi_vector stuff[];
the size is part of the randomization via the flexi_vector struct. How
about taking it out as an independent variable. Like this;

int unsigned number_of_bits;

typedef struct {
bit [number_of_bits:0] data;
} flexi_vector;
But YOU CAN'T DO THAT.
The array bounds in a vector declaration must be
CONSTANT EXPRESSIONS, which basically means expressions
composed of parameters only (there are a few other things
you can do, but that's really the deal). NO VARIABLES.

Before new a flex_vector, do something like this to randomize
number_of_bits:

class use_flexi_vector();
...
function new();
..
number_of_bits = $random(); // not using randomize
// but just plain verilog $random() system function
[...]
or put number_of_bits = $random() outside of any dynamic variable,
i.e., set it to be static.
OK, we're getting confused about what "static" means. The size
of vectors must be known at elaboration time, which means they
can be based only on parameters, never on variables. Classes
and "randomize" have nothing to do with this problem.

For some applications, you may be able to use a queue or
dynamic array of bits to emulate a variable-size vector.
In practice, though, it will almost certainly be easier
to use the trick I suggested: store your bits in some
very large fixed-size vector, and keep another variable
to indicate how many of those bits are valid. I think
the code I posted gives a reasonable suggestion for how
that could be done.
--
Jonathan Bromley
 

Welcome to EDABoard.com

Sponsor

Back
Top