Reputation: 10240
I'm using UVM command line arguments to set configuration properties in the UVM hierarchy.
When I pass in a bad config option, I would like to see a UVM_ERROR
or another failure indication. What's the easiest way to accomplish this?
For example, if I pass in a bad option like:
+uvm_set_config_int=bad,mode,5
The sim completes, and I do not see any indication from the log that the option was bad:
# UVM_INFO @ 0: reporter [UVM_CMDLINE_PROC] Applying config setting from the command line: +uvm_set_config_int=bad,mode,5
Full code can be run here: http://www.edaplayground.com/s/4/673
Upvotes: 2
Views: 1245
Reputation: 10240
I created a uvm_component
that can flag a bad +uvm_set_config_
option. It throws a UVM_ERROR
if a bad option was passed in, like:
# UVM_ERROR cmd_line_checker.svh(112) @ 0: uvm_test_top.cmd_line_checker [BAD_CONFIG] UVM match for command line config bad,mode not found
Full example can be run here: http://www.edaplayground.com/s/4/766
The code:
/**
* This is a utility class to validate command line arguments in the form:
* +uvm_set_config_int=<inst_name>,<field_name>,<value>
* +uvm_set_config_string=<inst_name>,<field_name>,<value>
*/
class cmd_line_checker extends uvm_component;
/**
* The enable for this checker.
*/
bit enable = 1'b1;
`uvm_component_utils_begin(cmd_line_checker)
`uvm_field_int(enable, UVM_ALL_ON)
`uvm_component_utils_end
/**
* UVM constructor.
*/
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
/**
* UVM connect phase.
*/
function void connect_phase(uvm_phase phase);
if (enable) begin
check_command_line();
end
endfunction
/**
* Validate all command line arguments in the form:
* +uvm_set_config_int=<inst_name>,<field_name>,<value>
* +uvm_set_config_string=<inst_name>,<field_name>,<value>
*/
function void check_command_line();
string args[$];
uvm_root root = uvm_root::get();
void'(root.clp.get_arg_matches(
"/^\\+(UVM_SET_CONFIG_INT|uvm_set_config_int)=/",args));
foreach(args[i]) begin
check_config(args[i].substr(20, args[i].len()-1));
end
void'(root.clp.get_arg_matches(
"/^\\+(UVM_SET_CONFIG_STRING|uvm_set_config_string)=/",args));
foreach(args[i]) begin
check_config(args[i].substr(23, args[i].len()-1));
end
endfunction
/**
* Check a single command line argument.
* The instance name and field name should exist.
* @param cfg the command line argument in the form:
* <inst_name>,<field_name>,<value>
*/
function void check_config(string cfg);
string split_val[$];
string inst_name;
string field_name;
uvm_root root;
uvm_component components[$];
bit match_found;
uvm_split_string(cfg, ",", split_val);
inst_name = split_val[0];
field_name = split_val[1];
`uvm_info("CHECK_CONFIG",
$sformatf("checking inst_name:%s, field_name:%s",
inst_name, field_name), UVM_HIGH);
// Get every object in uvm hierarchy that matches
root = uvm_root::get();
root.find_all(inst_name, components);
// If object matches inst_name, check whether a match for field_name exists
foreach (components[i]) begin
if (match_found) begin
break;
end else begin
uvm_component component = components[i];
uvm_status_container status = component.__m_uvm_status_container;
component.__m_uvm_field_automation (null, UVM_CHECK_FIELDS, "");
if (uvm_has_wildcard(field_name)) begin
foreach (status.field_array[name]) begin
if (!(uvm_re_match(uvm_glob_to_re(field_name), name))) begin
match_found = 1;
break;
end
end
end else begin
// No wildcards to match
match_found = status.field_array[field_name];
end
status.field_array.delete();
if (match_found) begin
`uvm_info("MATCH_FOUND", $sformatf(
"UVM match for command line config %s,%s found in %s",
inst_name, field_name, component.get_full_name()), UVM_HIGH);
break;
end
end
end
if (!match_found) begin
`uvm_error("BAD_CONFIG",
$sformatf("UVM match for command line config %s,%s not found",
inst_name, field_name));
end
endfunction
endclass
SVUnit test for the above cmd_line_checker
here: http://www.edaplayground.com/s/4/768
Upvotes: 0
Reputation: 10240
UVM can output additional information on configuration settings using the static uvm_component::print_config_matches
bit.
In the example, set the following in your testbench:
uvm_component::print_config_matches = 1;
For a "good" configuration setting, you will see the following in the output:
# UVM_INFO @ 0: reporter [UVM_CMDLINE_PROC] Applying config setting from the command line: +uvm_set_config_int=*,mode,5
# UVM_INFO @ 0: uvm_test_top.my_agent [CFGAPL] applying configuration settings
# UVM_INFO @ 0: uvm_test_top.my_agent [CFGAPL] applying configuration to field mode
# UVM_INFO testbench(40) @ 0: uvm_test_top [my_test] Running test with mode 5
For a "bad" configuration setting, you will see the following in the output:
# UVM_INFO @ 0: reporter [UVM_CMDLINE_PROC] Applying config setting from the command line: +uvm_set_config_int=bad,mode,5
# UVM_INFO @ 0: uvm_test_top.my_agent [CFGAPL] applying configuration settings
# UVM_INFO testbench(40) @ 0: uvm_test_top [my_test] Running test with mode 0
So, now you can parse the output and check that that there is at least one [CFGAPL] applying configuration to field
that follows every [UVM_CMDLINE_PROC] Applying config settings
.
Modified code example: http://www.edaplayground.com/s/4/681
Upvotes: 0
Reputation: 7573
I'm not really sure what you mean with a bad configuration option. When you do a uvm_set_config_int, your first two arguments only specify the instance and the field names. There is no requirement that these two actually exist. You're basically just putting this configuration option in the config DB to be accessed later.
What you probably want is to put a check in your agent that makes sure that it is actually passed a value for its 'mode' field.
class my_agent extends uvm_agent;
//...
function void build_phase(uvm_phase phase);
if (!uvm_config_db #(int)::get(this, "", "mode", mode))
`uvm_fatal("CFGERR", "Agent was not passed a config")
endfunction
endclass
I tested this on EDAPlayground with your code, but I'm not sure if it got saved.
Upvotes: 1