$value$plusargs not setting the desired value

Hi all,
I have a class config in which I have some user defined variables as:


typedef enum { EOT, DELAY } end_type;
typedef enum { RANDOM, INCR, LOAD } data_type;
typedef enum { FAST, SLOW } mode;

I have a set_config() function in my test class in which I set values for these variables. The values are passed from the command line(VCS) via plusargs as :


 ./simv ... +end_type_handle=DELAY +data_type_handle=LOAD +mode_handle=FAST

Set config function is as follows:


function void set_cfg();
    cfg = new();
    $value$plusargs("end_type_handle= %s", cfg.end_type_handle);
    $value$plusargs("data_type_handle= %s", cfg.data_type_handle);
    $value$plusargs("mode_handle= %s", cfg.mode_handle);
    ...

My issue is that, whatever combination of configs I pass from command line, the first values in typedef declaration are the values for handles that always get set, i.e. when I display the cfg variables, they’d always be:


end_type = EOT
data_type = RANDOM
mode = FAST 

I am not able to understand where I am going wrong in this.
If there is some other way of doing this, please do let me know.

Thanks,
Sarvesh

In reply to __viking:

You are reading your arguments as strings, and assigning them to enumerated values.

You will need to read the arguments, compare them to a string value, and then assign the enumerated data variable appropriately.


function void set_cfg();
  string s_;
  cfg = new();
  $value$plusargs("end_type_handle=%s", s_);
  if (s_ == "EOT") cfg.end_type_handle = EOT;
  if (s_ == "DELAY") cfg.end_type_handle = DELAY;
... 

In reply to cgales:

Thanks for helping out but i’m afraid the behavior is still the same. Can you tell me why/how is this happening in the first place? I haven’t put any default case or anything in my code.

In reply to __viking:

The sample code works for me, so you will have to post a complete example that shows your issue.

In reply to __viking:

Hi,

A small workaround using static casting can be done to fulfill your requirement. Please find the below example. Please look at the way in which typedef enums are declared and how $value$plusargs and static casting is used. Instead of supplying string through the command line, I am supplying integer values. The command-line options can be like “+end_type=1 +data_type=2 +mode=0”. With this workaround, I am getting your expected output.


// Example compiled by Putta Satish

// Command line options can be as shown below.

// +end_type=1 +data_type=2 +mode=0 

module top;
  	`include "uvm_macros.svh"
	import uvm_pkg::*;
	
	typedef enum { EOT=0, DELAY=1} end_type;
	typedef enum { RANDOM=0, INCR=1, LOAD=2} data_type;
	typedef enum { FAST=0, SLOW=1} mode;
	
	class config_db extends uvm_object;
			
		end_type e_t;
		data_type d_t;
		mode m_e;
			
		function new(string name = "config_db");
			super.new(name);
		endfunction
	endclass

	class drv extends uvm_driver #(uvm_sequence_item);
		config_db cfg_h;
		
		function new(string name = "drv", uvm_component parent = null);
			super.new(name, parent);
		endfunction
		
		function void build_phase(uvm_phase phase);
          if(!uvm_config_db#(config_db)::get(this, "", "STR", cfg_h))
            `uvm_fatal(get_type_name,"getting failed");
		endfunction
		
		task run_phase(uvm_phase phase);
			phase.raise_objection(this);
			$display("end_type = %s", cfg_h.e_t);
			$display("data_type = %s", cfg_h.d_t);
			$display("mode = %s", cfg_h.m_e);
			#1;
			$display("Current simulation time is %t", $time);
			phase.drop_objection(this);
		endtask	
	endclass		
	
	config_db cfg_h_top;
	int end_i, data_i, mode_i;
	drv drv_h;
	
	initial
		begin
			drv_h = new("drv_h");
			if ($value$plusargs("end_type=%d", end_i))
				$display("got the end_type value");
			if ($value$plusargs("data_type=%d", data_i))
				$display("got the data_type value");
			if ($value$plusargs("mode=%d", mode_i))
				$display("got the mode value");	
						
			cfg_h_top = new("cfg_h_top");
			cfg_h_top.e_t = end_type'(end_i);
			cfg_h_top.d_t = data_type'(data_i);
			cfg_h_top.m_e = mode'(mode_i);
			
			uvm_config_db#(config_db)::set(null, "", "STR", cfg_h_top);
			
			run_test();
		end
endmodule		

In reply to puttasatish:

This is not a good solution, because if the order of the enumerations change, it is difficult to adapt to these changes.

Just use the enumerations as they are:


// Example compiled by Putta Satish
 
// Command line options can be as shown below.
 
// +end_type=DELAY +data_type=INCR +mode=SLOW

`include "uvm_macros.svh"
import uvm_pkg::*;

typedef enum { EOT, DELAY} end_type;
typedef enum { RANDOM, INCR, LOAD} data_type;
typedef enum { FAST, SLOW} mode;

class my_config extends uvm_object;
 
  end_type e_t;
  data_type d_t;
  mode m_e;
  
  `uvm_object_utils(my_config);
 
  function new(string name = "config_db");
    super.new(name);
  endfunction
endclass

class drv extends uvm_driver #(uvm_sequence_item);
  my_config cfg_h;

  `uvm_component_utils(drv);
  
  function new(string name = "drv", uvm_component parent = null);
    super.new(name, parent);
  endfunction
 
  function void build_phase(uvm_phase phase);
    if(!uvm_config_db#(my_config)::get(this, "", "STR", cfg_h))
      `uvm_fatal(get_type_name,"getting failed");
  endfunction
 
  task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    `uvm_info(get_name(), $sformatf("end_type = %s", cfg_h.e_t.name()), UVM_MEDIUM);
    `uvm_info(get_name(), $sformatf("data_type = %s", cfg_h.d_t.name()), UVM_MEDIUM);
    `uvm_info(get_name(), $sformatf("mode = %s", cfg_h.m_e.name()), UVM_MEDIUM);
    `uvm_info(get_name(), $sformatf("Current simulation time is %0t", $time), UVM_MEDIUM);
    phase.drop_objection(this);
  endtask	
endclass		

module top;
  my_config cfg_h_top;
  string str_;
 
  initial
    begin
      cfg_h_top = my_config::type_id::create("cfg_h_top");

      if ($value$plusargs("end_type=%s", str_)) begin
        if (str_ == "EOT") cfg_h_top.e_t = EOT; 
        if (str_ == "DELAY") cfg_h_top.e_t = DELAY; 
      end
      else begin
        `uvm_info("TOP", $sformatf("Using default END_TYPE value"), UVM_MEDIUM);
        cfg_h_top.e_t = EOT;
      end

      if ($value$plusargs("data_type=%s", str_)) begin
        if (str_ == "RANDOM") cfg_h_top.d_t = RANDOM; 
        if (str_ == "INCR") cfg_h_top.d_t = INCR; 
        if (str_ == "LOAD") cfg_h_top.d_t = LOAD; 
      end
      else begin
        `uvm_info("TOP", $sformatf("Using default DATA_TYPE value"), UVM_MEDIUM);
        cfg_h_top.d_t = RANDOM;
      end
      
      if ($value$plusargs("mode=%s", str_)) begin
        if (str_ == "FAST") cfg_h_top.m_e = FAST; 
        if (str_ == "SLOW") cfg_h_top.m_e = SLOW; 
      end
      else begin
        `uvm_info("TOP", $sformatf("Using default MODE value"), UVM_MEDIUM);
        cfg_h_top.m_e = FAST;
      end

      uvm_config_db#(my_config)::set(null, "", "STR", cfg_h_top);

      run_test("drv");
    end
endmodule

In reply to cgales:

Thanks, Cgales.