10 SystemVerilog Utilities¶
Compiler Directives¶
0. `__FILE__
&`__LINE__
¶
Useful directives that are typically used with a display statement. They help you identify which file and line the execution it currently at.
program automatic utils;
`define debug(msg) \
if ($test$plusargs("debug")) \
$display(">> %s, %d: %s", `__FILE__, `__LINE__, msg)
initial begin
`debug("At the beginning");
`debug("At the end");
end
endprogram
# CONSOLE OUTPUT
>> utils.sv, 7: At the beginning
>> utils.sv, 8: At the end
Utility System Functions¶
1. $bits¶
The $bits()
system function returns the number of bits required to hold an expression as a bit stream. In the example below it is used to get the bitstream size of a struct
and an array.
One big advantage of the $bits()
function is that it can be used as an elaboration time constant. Hence, it can be used in the declaration of other data types or variables.
logic [7:0] fa[10];
typedef struct {
logic valid;
bit [7:0] data;
} MyType;
logic [$bits(MyType)-1 : 0] mytype_bitstream;
logic [$bits(fa)-1 : 0] fa_bitstream;
initial begin
$display("Bitstream size of MyType: %0d", $bits(MyType));
$display("Bitstream size of Fixed Array: %0d", $size(fa_bitstream));
end
# Bitstream size of MyType: 9
# Bitstream size of Fixed Array: 80
2. $countbits¶
Returns the number of bits that have the requested control bit value. It is of the form:
$countbits(expression, control_bit {, control_bit})
//returns the number of bits in the expression having the value 1
$countbits(expression, '1)
// returns the number of bits in the expression that have value 0 or X
$countbits(expression, '0, 'x)
// returns the number of bits in the expression that have value X or Z
$countbits(expression, 'x, 'z)
The control_bit
argument has to be a 1-bit logic.
There are a few convenience functions associated with $countbits()
:
// counts the number of 1s
$countones()
// returns true if $countbits(expression, '1)==1
$onehot()
// returns true if $countbits(expression, '1)<=1
$onehot0()
// returns true if any bits are X or Z
$isunknown()
program automatic utils;
logic [31:0] monkey;
initial begin
monkey = 32'hxx1801zz;
$display("Count ones : %0d", $countbits(monkey, '1));
$display("Count Xs : %0d", $countbits(monkey, 'X));
$display("Xs : %0d", $countbits(monkey, 'X));
monkey = 32'h00008000;
$display("0x%x Is one hot : %0d", monkey, $onehot(monkey));
monkey = 32'h80008000;
$display("0x%x Is one hot : %0d", monkey, $onehot(monkey));
monkey = 32'h00000000;
$display("0x%x Is one hot : %0d", monkey, $onehot(monkey));
$display("0x%x Is onehot0 : %0d", monkey, $onehot0(monkey));
end
endprogram
Count ones : 3
Count Xs : 8
Xs : 8
0x00008000 Is one hot : 1
0x80008000 Is one hot : 0
0x00000000 Is one hot : 0
0x00000000 Is onehot0 : 1
3. $system¶
Let's you execute a command on the unix shell.
$system("echo \"Bacon Bacon Bacon!\"");
4. $size¶
Returns the size of the array. When used on a dynamic array, associative array or queue, it returns information about the current state of the array.
/* $size() */
$display("Fixed array size - Dimension 1: %0d", $size(fa));
// Dimension numbers
// 3 4 1 2
//logic [3:0][2:1] n [1:5][2:8];
$display("Fixed array size - Dimension 2: %0d", $size(fa, 2));
$display("Queue size before push: %0d", $size(q));
q.push_back(20);
q.push_back(21);
$display("Queue size - after push: %0d", $size(q));
$display("Associative Array size - before insert: %0d", $size(aa));
aa["hero"] = "sherlock";
aa["sidekick"] = "watson";
aa["villan"] = "moriarty";
$display("Associative Array size - after insert: %0d", $size(aa));
$display("Dynamic Array size - before new: %0d", $size(da));
da = new[4];
$display("Dynamic Array size - after new: %0d", $size(da));
# Fixed array size - Dimension 1: 10
# Fixed array size - Dimension 2: 8
# Queue size before push: 0
# Queue size - after push: 2
# Associative Array size - before insert: 0
# Associative Array size - after insert: 3
# Dynamic Array size - before new: 0
# Dynamic Array size - after new: 4
5. $clog2¶
Returns ceil of the log base 2 of the argument. It helps you figure out the number of bits necessary to address a memory of a given size
.
addr_width = $clog2(mem.get_size());
Display Utils¶
6. %m
¶
%m
displays the hierarchical name of the module where the print is executed from. See example below.
7. %t
¶
%t
along with $time
lets you identify the time at which a display statement was executed. It is printed as per the timepresicion parameter, for example, the code below had timescale set as `timescale 1ns/1ns
. It would have printed @0ns
and @2000
if it had been set as `timescale 1ns/1ps
.
$display("%m, @%0t: Bits are necessary to address a 100 deep memory: %0d", $time, $clog2(100));
#2ns;
$display("%m, @%0t: Bits are necessary to address a 10000 deep memory: %0d", $time, $clog2(10000));
utils, @0: Bits are necessary to address a 100 deep memory: 7
utils, @2: Bits are necessary to address a 10000 deep memory: 14
I/O System Functions¶
8. $test$plusargs
¶
The $test$plusargs()
function lets you control actions at run-time by passing a command line argument. In this example by default no prints are displayed. When I need more information, I pass the +debug
command line argument to enable display statements. This is how you pass a plusarg into your simulation.
program automatic utils;
`define debug(msg) \
if ($test$plusargs("debug")) \
$display(">> %s, %d: %s", `__FILE__, `__LINE__, msg)
initial begin
`debug("At the beginning");
`debug("At the end");
end
endprogram
# Synopsys VCS
./simv +debug
# Mentor Graphics QuestaSim
./vsim +debug
One thing to keep in mind is, if the prefix of one of the supplied plusargs matches all characters in the provided string, the function returns a nonzero integer. For example, if I pass +HELLO
as a plusarg, all 3 $test$plusargs()
function calls will match and return TRUE
.
if ($test$plusargs("HELLO")) begin
$display("Hello argument found.");
end
if ($test$plusargs("HE")) begin
$display("The HE subset string is detected.");
end
if ($test$plusargs("H")) begin
$display("Argument starting with H found.");
end
9. $value$plusargs
¶
$value$plusargs()
is another flavor of $test$plusargs()
which lets you set your command line argument to a specific value.
Let's look at this example below - I pass the name of a test at run-time, the remainder string of the matching plusarg (the remainder is the part of the plusarg string after the portion that matches the TESTNAME=
& CFGTYPE=
in the example below) is converted from a string into the format indicated by the format string (%s
& %d
, respectively, in the example below) and stored in the variable provided. If there is no remaining string, the value stored into the variable is either a zero or an empty string value.
if ($value$plusargs("TESTNAME=%s", testname)) begin
$display("Running TEST = %s", testname);
end
if ($value$plusargs("CFGTYPE=%d", cfgtype)) begin
$display("Configuring DUT to config = %0d", cfgtype);
end
./simv +TESTNAME="utils_test" +CFGTYPE="2"