Using Plusargs in UVM Testbench

Test plusargs.


Systemverilog system function for plusargs

Systemverilog has two system functions for retriving the arguments (aka plusargs) from the command line, these are $test$plusargs and $value$plusargs.

$test$plusargs(string)

This system function receives a string as input argument, then search through the plusargs in the command line. If the prefix of any of the plusargs is matched with the provided string of the system function, this function return non-zero value. Usually, we will use this function as an expression in the consditional statement if-else as below example:

// Simulator command line argument: +PLUSARGS_TEST

if($test$plusargs(PLUSARGS_TEST)) begin 
  $display("Found plusargs +PLUSARGS_TEST");
end

//
if($test$plusargs(PLUSARGS)) begin 
  $display("Found +PLUSARGS, substring of command line string ");
end

// output will be 
// Found plusargs +PLUSARGS_TEST
// Found +PLUSARGS, substring of command line string
//

$value$plusargs(“PLUSARGS=format string”, var)

Similar to $test$plusargs, but the plusargs now comes with a value, and we can assign that value to a variable as below example.

// Simulator command line argument: +PLUSARGS_TEST=20 +PLUSARGS_TEST2+100 +PLUSARGS_TEST3+300+400

int m_var;
int m_var2;

if($value$plusargs("PLUSARGS_TEST=%d", m_var )) begin 
  $display ("Found plusargs +PLUSARGS_TEST = %d", m_var);
end 

// notice we will use the "+", not "=" character
// we actually do not need any special character at all
if($value$plusargs("PLUSARGS_TEST2+%d", m_var )) begin    
  $display ("Found plusargs +PLUSARGS_TEST2 = %d", m_var);
end 

// we can even has more than one value passed from command line
if($value$plusargs("PLUSARGS_TEST3+%d+%d", m_var, m_var2 )) begin    
  $display ("Found plusargs +PLUSARGS_TEST3 = %d, %d", m_var, m_var2);
end 

// The output will be:
// Found plusargs +PLUSARGS_TEST = 20
// Found plusargs +PLUSARGS_TEST2 = 100
// Found plusargs +PLUSARGS_TEST3 = 300, 400
// 

string format for plusargs

We can use below format string when get the value from plusargs

  
%ddecimal conversion
%ooctal conversion
%h,%xhexadecimal conversion
%bbinary conversion
%ereal exponential conversion
%freal decimal conversion
%greal decimal or exponential conversion
%sstring (no conversion)

UVM built-in functions those help

Some uvm functions those make handling test plusargs easier

Plusargs for enum variable

Assuming we have a enum type sha_mode_e, and the plusargs input value is stored in a string. Instead of using switch-case to match the string to each enum name constant, we can use uvm_enum_wrapper#(<enum type>)::from_name() function to cast the plusarg string to the enum variable.

 //
 // Example simulator command line argument: +SHA_MODE=SHA_256
 //

 string     m_tmp_str;
 sha_mode_e m_sha_mode;

 if($value$plusargs("SHA_MODE=%s", m_tmp_str)) begin
    if (uvm_enum_wrapper#(sha_mode_e)::from_name(m_tmp_str, m_sha_mode)) begin
       `uvm_info("[PLUSARGS]", $psprintf("Sha mode: %s", m_sha_mode.name()), UVM_LOW )
    end
 end

uvm_cmdline_processor sigleton class

This uvm class supports many functions that handle the plusargs. There is a global variable of uvm_cmdline_processor class called uvm_cmdline_proc and can be used to access command line information.

Let’s check some examples below.

plusarg containing a list of values

In this example we will use the uvm_cmdline_proc.get_arg_value() function to get the argument as a string. Then use the uvm_split_string() to split this string to entries based on the sepapartor.

 //
 // Example simulator command line argument: +QUEUE_EN_LIST=0,5,10,15
 //

 string queue_en_lst;

 if (uvm_cmdline_proc.get_arg_value("+QUEUE_EN_LIST=", queue_en_lst)) begin
    string queue_en_s[$];
    int    queue_en[$];  // list of queue id that will be enable

    uvm_split_string(queue_en, "," , queue_en_s);  // split the list with "," as separator
    foreach (queue_en_s[i]) begin
       queue_en[i] = queue_en_s[i].atoi();  // string to int
    end
 end

multiple plusargs with the same name, but different values

Assuming we need a plusarg with this format to configure one aes encryption operation : +AES_OPR_CFG=<AES_MODE>,<KEY_LEN>.

We also need to have multiple aes encryption operations in 1 test, each receiving plusarg will corresponding to 1 operation.

In this example, we will use the uvm_cmdline_proc.get_arg_values() function instead of uvm_cmdline_proc.get_arg_value().

 //
 // Example simulator command line argument: +AES_OBJ_CFG=AES_CBC,128 +AES_OBJ_CFG=AES_ECB,256
 // Expect 2 aes operations:
 //               1st aes operation: aes mode is AES_CBC, key length 128
 //               2nd aes operation: aes mode is AES_ECB, key length 256
 //

 string aes_opr_lst[$];

 if (uvm_cmdline_proc.get_arg_values("+AES_OPR_CFG=", aes_opr_lst)) begin
    // the aes_opr_lst will contain 2 entries:
    //  "AES_CBC,1" and "AES_ECB,256"

    foreach(aes_opr_lst[i]) begin
       aes_mode_e m_aes_mode;
       string     tmp_q[$];

       uvm_split_string(aes_opr_lst[i], ",", tmp_q);
       // tmp_q queue will have 2 entries, 
       // 1st entry is the string of AES_MODE
       // 2nd entry is the string of key length
       // now we need to cast these entries to aes_mode_e and int type respectively

       if (uvm_enum_wrapper#(aes_mode_e)::from_name(tmp_q[0], m_aes_mode)) begin
          $display("AES mode %s", m_aes_mode.name()));
       end 
       $display("Key length %d", tmp_q[1].atoi());
    end 
 end

Finding more information

  1. Systemverilog LRM, section 21.6 Command line input
  2. uvm_cmdline_processor


[Tags uvm  ]