UVM provides several command line utils to change config. Two of these command line knobs are set_config_int
and set_config_string
. This is a deepdive into how they work.
Starting with src/base/uvm_root.svh, where m_do_config_settings
is called in the build_phase of the uvm_root.
function void uvm_root::build_phase(uvm_phase phase);
super.build_phase(phase);
m_set_cl_msg_args();
m_do_verbosity_settings();
m_do_timeout_settings();
m_do_factory_settings();
m_do_config_settings();
m_do_max_quit_settings();
m_do_dump_args();
endfunction
In the same file, m_do_config_settings
matches command line option with uvm_set_config_int and uvm_set_config_string and call m_process_config
with is_bit
argument to set to 1 with int.
function void uvm_root::m_do_config_settings();
string args[$];
void'(clp.get_arg_matches("/^\\+(UVM_SET_CONFIG_INT|uvm_set_config_int)=/",args));
foreach(args[i]) begin
m_process_config(args[i].substr(20, args[i].len()-1), 1);
end
void'(clp.get_arg_matches("/^\\+(UVM_SET_CONFIG_STRING|uvm_set_config_string)=/",args));
foreach(args[i]) begin
m_process_config(args[i].substr(23, args[i].len()-1), 0);
end
endfunction
in m_process_config
, the full string is split into 3 parts (path, config name, value). and it calls the set_config_int or set_config_string API from the m_uvm_top
(that would be component).
function void uvm_root::m_process_config(string cfg, bit is_int);
uvm_bitstream_t v;
string split_val[$];
uvm_root m_uvm_top = uvm_root::get();
uvm_split_string(cfg, ",", split_val);
if(is_int) begin
if(split_val[2].len() > 2) begin
string base, extval;
base = split_val[2].substr(0,1);
extval = split_val[2].substr(2,split_val[2].len()-1);
case(base)
"'b" : v = extval.atobin();
"0b" : v = extval.atobin();
"'o" : v = extval.atooct();
"'d" : v = extval.atoi();
"'h" : v = extval.atohex();
"'x" : v = extval.atohex();
"0x" : v = extval.atohex();
default : v = split_val[2].atoi();
endcase
end
else begin
v = split_val[2].atoi();
end
uvm_report_info("UVM_CMDLINE_PROC", {"Applying config setting from the command line: +uvm_set_config_int=", cfg}, UVM_NONE);
m_uvm_top.set_config_int(split_val[0], split_val[1], v);
end
else begin
uvm_report_info("UVM_CMDLINE_PROC", {"Applying config setting from the command line: +uvm_set_config_string=", cfg}, UVM_NONE);
m_uvm_top.set_config_string(split_val[0], split_val[1], split_val[2]);
end
So, we jump to uvm_component.svh
and we can see the actual call to config_db::set. Well, the shorthand typedef used there but you get the idea.
typedef uvm_config_db#(uvm_bitstream_t) uvm_config_int;
function void uvm_component::set_config_int(string inst_name,
string field_name,
uvm_bitstream_t value);
uvm_config_int::set(this, inst_name, field_name, value);
endfunction
fin.