Variables that are declared as rand
or randc
inside a class are randomized using the built-in randomize()
method. The method returns 1 if randomization was successful, and 0 if it failed. It can fail due to a variety of reasons like conflicting constraints, solver could not come up with a value that meets all constraints and such. Class objects are not randomized automatically, and hence we should always call the randomize()
method to do randomization.
Syntax
virtual function int randomize ();
Let's look at a simple example to see how randomize()
can be called.
class Beverage;
rand bit [7:0] beer_id;
constraint c_beer_id { beer_id >= 10;
beer_id <= 50; };
endclass
module tb;
Beverage b;
initial begin
b = new ();
$display ("Initial beerId = %0d", b.beer_id);
if (b.randomize ())
$display ("Randomization successful !");
$display ("After randomization beerId = %0d", b.beer_id);
end
endmodule
When size of a collection is unknown or the data space is sparse, an associative array is a better option. Associative arrays do not have any storage allocated until it is used, and the index expression is not restricted to integral expressions, but can be of any type.
An associative array implements a look-up table of the elements of its declared type. The data type to be used as an index serves as the lookup key and imposes an ordering.
Syntax
// Value Array_Name [ key ];
data_type array_identifier [ index_type ];
Initialization Example
module tb;
int array1 [int]; // An integer array with integer index
int array2 [string]; // An integer array with string index
string array3 [string]; // A string array with string index
initial begin
// Initialize each dynamic array with some values
array1 = '{ 1 : 22,
6 : 34 };
array2 = '{ "Ross" : 100,
"Joey" : 60 };
array3 = '{ "Apples" : "Oranges",
"Pears" : "44" };
// Print each array
$display ("array1 = %p", array1);
$display ("array2 = %p", array2);
$display ("array3 = %p", array3);
end
endmodule
ncsim> run array1 = '{1:22, 6:34} array2 = '{"Joey":60, "Ross":100} array3 = '{"Apples":"Oranges", "Pears":"44"} ncsim: *W,RNQUIE: Simulation is complete.
A dynamic array is an unpacked array whose size can be set or changed at run time, and hence is quite different from a static array where the size is pre-determined during declaration of the array. The default size of a dynamic array is zero until it is set by the new()
constructor.
Syntax
A dynamic array dimensions are specified by the empty square brackets [ ]
.
[data_type] [identifier_name] [];
bit [7:0] stack []; // A dynamic array of 8-bit vector
string names []; // A dynamic array that can contain strings
The new()
function is used to allocate a size for the array and initialize its elements if required.
Dynamic Array Example
module tb;
// Create a dynamic array that can hold elements of type int
int array [];
initial begin
// Create a size for the dynamic array -> size here is 5
// so that it can hold 5 values
array = new [5];
// Initialize the array with five values
array = '{31, 67, 10, 4, 99};
// Loop through the array and print their values
foreach (array[i])
$display ("array[%0d] = %0d", i, array[i]);
end
endmodule
ncsim> run array[0] = 31 array[1] = 67 array[2] = 10 array[3] = 4 array[4] = 99 ncsim: *W,RNQUIE: Simulation is complete.
A SystemVerilog queue is a First In First Out scheme which can have a variable size to store elements of the same data type.
It is similar to a one-dimensional unpacked array that grows and shrinks automatically. They can also be manipulated by indexing, concatenation and slicing operators. Queues can be passed to tasks/functions as ref or non-ref arguments.
Types of Queues
A bounded queue has a specific size and can hold a limited number of entries. Shown below is a bounded queue of depth N and is full with N items and cannot accept more.
[data_type] [name_of_queue] [$:N];
int bounded_queue [$:10]; // Depth 10
An unbounded queue can have an unlimited number of entries. Shown below is an unbounded queue which has 5 items and can accept more.

[data_type] [name_of_queue] [$];
int unbounded_queue [$]; // Unlimited entries
A SystemVerilog case
statement checks whether an expression matches one of a number of expressions and branches appropriately. The behavior is the same as in Verilog.
Click here to learn about Verilog case statements !
unique,unique0 case
All case statements can be qualified by unique
or unique0
keywords to perform violation checks like we saw in if-else-if construct.
unique
and unique0
ensure that there is no overlapping case items and hence can be evaluated in parallel. If there are overlapping case items, then a violation is reported.
- If more than one case item is found to match the given expression, then a violation is reported and the first matching expression is executed
- If no case item is found to match the given expression, then a violation is reported only for
unqiue
unique0 does not report a violation if no items match the expression
unique : No items match for given expression
module tb;
bit [1:0] abc;
initial begin
abc = 1;
// None of the case items match the value in "abc"
// A violation is reported here
unique case (abc)
0 : $display ("Found to be 0");
2 : $display ("Found to be 2");
endcase
end
endmodule
ncsim> run
ncsim: *W,NOCOND: Unique case violation: Every case item expression was false.
File: ./testbench.sv, line = 9, pos = 14
Scope: tb
Time: 0 FS + 1
ncsim: *W,RNQUIE: Simulation is complete.
unique : More than one case item matches
module tb;
bit [1:0] abc;
initial begin
abc = 0;
// Multiple case items match the value in "abc"
// A violation is reported here
unique case (abc)
0 : $display ("Found to be 0");
0 : $display ("Again found to be 0");
2 : $display ("Found to be 2");
endcase
end
endmodule
ncsim> run
Found to be 0
ncsim: *W,MCONDE: Unique case violation: Multiple matching case item expressions at {line=10:pos=6 and line=11:pos=6}.
File: ./testbench.sv, line = 9, pos = 14
Scope: tb
Time: 0 FS + 1
ncsim: *W,RNQUIE: Simulation is complete.
priority case
module tb;
bit [1:0] abc;
initial begin
abc = 0;
// First match is executed
priority case (abc)
0 : $display ("Found to be 0");
0 : $display ("Again found to be 0");
2 : $display ("Found to be 2");
endcase
end
endmodule
ncsim> run
Found to be 0
ncsim: *W,RNQUIE: Simulation is complete.