Skip to content

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


Subscribe

Get Notified when a new article is published!


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"