Passing parameters from command line

Hi everyone!

I am looking for a solution to pass some parameters from command line to the test in UVM, so that I can edit this parameters from the call of the simulation:

 vsim -voptargs=+acc +AXIS_MASTER_DW=14 +AXIS_SLAVE_DW=29 

and pass them to the DUT, the interfaces and the UVM components for the test.

I have tried a first option to read them using:

 if ($value$plusargs("AXIS_MASTER_DW=%d", i)) begin 

,

but the problem with that is that I cannot change the parameters using

 uvm_config_db 

because they cannot be edited.

I have also thought in extend the “test_base” class with parameters to another class as in this paper:

https://s3.amazonaws.com/verificationacademy-news/DVCon2016/Papers/dvcon-2016_paramaters-uvm-coverage-and-emulation-take-two-and-call-me-in-the-morning_paper.pdf,

but here also does not says anything to get the params from command line.

I also don’t know whether using “Factory Override Methods” or something like “uvm_cmdline_processor”.

What can I do?

Thank you very much in advance.

Kind regards,
German

In reply to germanbravolopez:

It would help to show the code where you plan to use this parameter, and the potential range of values you expect to have.

In reply to dave_59:

Hi Dave,

I solved the problem using “vsim uvm.test_top -GAXIS_MASTER_DW=16” when calling the simulation and having in the top file this paramater as:

module test_top #(AXIS_MASTER_DW = 32);

(32 by default).

Thank you very much!

Hello!

I have updated my testbench, as I referred in the last post, following this link (Parameters and OVM — Can’t They Just Get Along?); to summarize the changes I have:

  • Simulation call:
vsim uvm.test_top -voptargs=+acc -coverage -classdebug -onfinish final -uvmcontrol=all -msgmode both +UVM_TESTNAME="test_parameterizable" -GAXIS_MASTER_DW=16
  • params_defines:

// Declarations
`define params_declare #(int AXIS_MASTER_DW=32)
// Instantiations / Mappings
`define params_map #(.AXIS_MASTER_DW (AXIS_MASTER_DW))
// String Value
`define params_string $sformatf("#(%1d)",AXIS_MASTER_DW)

  • test_top:

module test_top #(AXIS_MASTER_DW = 32);
`include "params_defines.svh"
typedef test_parameterizable `params_map test_parameterizable_t;
initial begin
run_test();
end
endmodule

  • test_parameterizable:

class test_parameterizable `params_declare extends test_base;
typedef uvm_component_registry #(test_parameterizable `params_map, "test_parameterizable") type_id;
static function type_id get_type();
return type_id::get();
endfunction
virtual function uvm_object_wrapper get_object_type();
return type_id::get();
endfunction
const static string type_name = {"test_parameterizable", `params_string};
virtual function string get_type_name();
return type_name;
endfunction
//class constructor
function new (string name = "test_parameterizable", uvm_component parent = null);
super.new (name, parent);
endfunction
virtual function void build_phase (uvm_phase phase);
super.build_phase (phase);
endfunction
endclass : test_parameterizable

  • test_base:

class test_base `params_declare extends uvm_test;
`uvm_component_param_utils (test_base `params_map)
my_env `params_map	env;
//class constructor
function new(string name = "test_base", uvm_component parent);
super.new(name, parent);
endfunction
virtual function void build_phase (uvm_phase phase);
super.build_phase (phase);
env  = my_env `params_map::type_id::create ("env", this);
endfunction
endclass

  • env:

class my_env `params_declare extends uvm_env;
`uvm_component_param_utils (my_env `params_map)
my_scoreboard `params_map scbd;
function new (string name, uvm_component parent);
super.new (name, parent);
endfunction : new
virtual function void build_phase (uvm_phase phase);
super.build_phase (phase);
scbd = my_scoreboard `params_map::type_id::create ("scbd", this);
endfunction : build_phase
endclass

  • scbd:

class my_scoreboard `params_declare extends uvm_scoreboard;
`uvm_component_param_utils (my_scoreboard `params_map)
function new (string name = "my_scoreboard", uvm_component parent);
super.new (name, parent);
endfunction
task write ();
//here is where I need to use the params to build my model to test the dut.
`uvm_info("INFO", $sformatf("AXIS_MASTER_DW=%0d", AXIS_MASTER_DW), UVM_MEDIUM)
endtask

First of all, I do a parameterized test to be able to test with different parameters values. Then, I pass them from cmd line to simulate after complile without need to recompile after change parameter values.

The problem is that when I send different values from cmd line the uvm_info macro does not print the new value sent from cmd line.

What can be the problem?

Thank you very much!!

Kind regards,
German

In reply to germanbravolopez:

First of all, I do a parameterized test to be able to test with different parameters values. Then, I pass them from cmd line to simulate after complile without need to recompile after change parameter values.
The problem is that when I send different values from cmd line the uvm_info macro does not print the new value sent from cmd line.
What can be the problem?

The problem is that parameters are constant resolved at elaboration time from the LRM:

“6.20 Constants
Constants are named data objects that never change. SystemVerilog provides three elaboration-time
constants: parameter, localparam, and specparam.”

Macros on the other hand are basically text substitution done at compile time, thus you approach of single compile multiple values for `define X AFAIK is not going to work.

I need to ask again as in the other thread, do you really need this values to be parameters instead of a bunch of values contained in a configuration class that can be passed/modified at runtime or with config_db.

HTH,

-R

In reply to rgarcia07:

The point is that I need to solve an assign in this way:


if (WDW >= RDW) begin
	for (int i = 0; i < (WDW/RDW); i++) begin
		expected_tdata_pkg = data_in.tdata[RDW*i +: RDW];
	end
end

And for that, the value after “+:” must be constant.

One option is what you told me, import a package of parameters and from command line change this package, but in this case I will need to recompile (and I would like to find a solution after compile).

Another option is to find a different way to solve this assignment.

In my previous tests I did not need this assignment and I stored the values in the config_db in the test_top and get them in the build_phase of the scoreboard.

Using in the top:

uvm_config_db #(int)::set(null, "uvm_test_top.*", "FIFO_WAW", RDW);

And using in the scbd:


int RDW;
	
function void build_phase (uvm_phase phase);
	void'(uvm_config_db #(int)::get(this, "*", "RDW", RDW));

In reply to germanbravolopez:

Apologies if I’m not still getting the problem, but what is preventing you from doing a nested for loop, it may seem like more code but is simpler than trying to propagate parameters all over from the environment down to each component, in your code is not clear what type of data expected_tdata_pkg is but assuming is some sort of dynamic array to which you want to assign slices of tdata (in RDW chunks starting at index 0)


bit [7:0] data;// Or whatever size meets your requirement 
for (int i = 0; i < length; i++) begin // I'm assuming you know the length or use a foreach
   for (int j = 0; j < RDW; j++) begin
       data[j] = tdata[i*RDW + j]; 
   end
   expected[i] = data;
end 
// if not a dynamic array then just assign bit by bit in the for loop

Again apologies if I’m misunderstanding your problem

In reply to rgarcia07:

Please do not apologize, I am the first who dont explain very good the problem that I am having. Try this code in a simulator to see the differences between what I want and your idea of nested for loops:


typedef bit [127:0] tdata_t;
module tb;
	tdata_t expected_tdata_pkg;
  	tdata_t tdata;
	int WDW = 32, RDW = 16;
  	bit [7:0] data;
  
	initial begin
      $display ("tdata=%0h \n expected_tdata_pkg=%0h \n", tdata, expected_tdata_pkg);
	  tdata = 32'hcafeabcd;

      $display ("tdata=%0h \n expected_tdata_pkg=%0h \n", tdata, expected_tdata_pkg);
      
      for (int i = 0; i < (WDW/RDW); i++) begin
        //for (int j = 0; j < RDW; j++) begin
          expected_tdata_pkg = tdata[16*i +: 16]; // RDW
        //end
        $display ("tdata=%0h \n expected_tdata_pkg=%0h \n", tdata, expected_tdata_pkg);
      end 
      
      expected_tdata_pkg = 0;
      for (int i = 0; i < (WDW/RDW); i++) begin // I'm assuming you know the length or use a foreach
         for (int j = 0; j < RDW; j++) begin
             data[j] = tdata[i*RDW + j]; 
         end
         expected_tdata_pkg[i] = data;
         $display ("tdata=%0h \n expected_tdata_pkg=%0h \n", tdata, expected_tdata_pkg);
      end
	end
endmodule

In reply to germanbravolopez:

Hi,

Check the this code and modify according to your requirements, based on the expected results you showed and the type of data expected_tdata_pkgis, but I have to ask are you aware that in the code using ‘+:’ you are basically overriding the lower part expected_tdata_pkg (WDW/RDW) times, I’m not sure why, maybe you could explain the type of “packaging” you what to achieve.

// Code your testbench here
// or browse Examples
typedef bit [127:0] tdata_t;
module tb;
	tdata_t expected_tdata_pkg;
  	tdata_t tdata;

    int WDW = 32, RDW = 16;
 
	initial begin
      $display ("tdata=%0h \n expected_tdata_pkg=%0h \n", tdata, expected_tdata_pkg);
	  tdata = 32'hcafeabcd;
 
      $display ("tdata=%0h \n expected_tdata_pkg=%0h \n", tdata, expected_tdata_pkg);
 
      for (int i = 0; i < (WDW/RDW); i++) begin
        //for (int j = 0; j < RDW; j++) begin
          expected_tdata_pkg = tdata[16*i +: 16]; // RDW
        //end
        $display ("----> tdata=%0h \n expected_tdata_pkg=%0h \n", tdata, expected_tdata_pkg);
      end 
 
      expected_tdata_pkg = 0;
      for (int i = 0; i < (WDW/RDW); i++) begin // I'm assuming you know the length or use a foreach
         for (int j = 0; j < RDW; j++) begin
             expected_tdata_pkg [j] = tdata[i*RDW + j]; 
         end
        $display ("++++++> tdata=%0h \n expected_tdata_pkg=%0h \n", tdata, expected_tdata_pkg);
      end
	end
endmodule

In reply to rgarcia07:

Okey, thank you very much, this assignment solve the problem that I am having.

Thank you for the implication!