| // |
| //------------------------------------------------------------------------------ |
| // Copyright 2007-2011 Mentor Graphics Corporation |
| // Copyright 2007-2011 Cadence Design Systems, Inc. |
| // Copyright 2010-2011 Synopsys, Inc. |
| // All Rights Reserved Worldwide |
| // |
| // Licensed under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in |
| // compliance with the License. You may obtain a copy of |
| // the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in |
| // writing, software distributed under the License is |
| // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR |
| // CONDITIONS OF ANY KIND, either express or implied. See |
| // the License for the specific language governing |
| // permissions and limitations under the License. |
| //------------------------------------------------------------------------------ |
| |
| |
| //------------------------------------------------------------------------------ |
| // |
| // CLASS: uvm_root |
| // |
| // The ~uvm_root~ class serves as the implicit top-level and phase controller for |
| // all UVM components. Users do not directly instantiate ~uvm_root~. The UVM |
| // automatically creates a single instance of <uvm_root> that users can |
| // access via the global (uvm_pkg-scope) variable, ~uvm_top~. |
| // |
| // (see uvm_ref_root.gif) |
| // |
| // The ~uvm_top~ instance of ~uvm_root~ plays several key roles in the UVM. |
| // |
| // Implicit top-level - The ~uvm_top~ serves as an implicit top-level component. |
| // Any component whose parent is specified as NULL becomes a child of ~uvm_top~. |
| // Thus, all UVM components in simulation are descendants of ~uvm_top~. |
| // |
| // Phase control - ~uvm_top~ manages the phasing for all components. |
| // |
| // Search - Use ~uvm_top~ to search for components based on their |
| // hierarchical name. See <find> and <find_all>. |
| // |
| // Report configuration - Use ~uvm_top~ to globally configure |
| // report verbosity, log files, and actions. For example, |
| // ~uvm_top.set_report_verbosity_level_hier(UVM_FULL)~ would set |
| // full verbosity for all components in simulation. |
| // |
| // Global reporter - Because ~uvm_top~ is globally accessible (in uvm_pkg |
| // scope), UVM's reporting mechanism is accessible from anywhere |
| // outside ~uvm_component~, such as in modules and sequences. |
| // See <uvm_report_error>, <uvm_report_warning>, and other global |
| // methods. |
| // |
| // |
| // The ~uvm_top~ instance checks during the end_of_elaboration phase if any errors have |
| // been generated so far. If errors are found an UVM_FATAL error is being generated as result |
| // so that the simulation will not continue to the start_of_simulation_phase. |
| // |
| |
| //------------------------------------------------------------------------------ |
| |
| typedef class uvm_test_done_objection; |
| typedef class uvm_cmdline_processor; |
| |
| class uvm_root extends uvm_component; |
| |
| // Function: get() |
| // Get the factory singleton |
| // |
| extern static function uvm_root get(); |
| |
| uvm_cmdline_processor clp; |
| |
| // Task: run_test |
| // |
| // Phases all components through all registered phases. If the optional |
| // test_name argument is provided, or if a command-line plusarg, |
| // +UVM_TESTNAME=TEST_NAME, is found, then the specified component is created |
| // just prior to phasing. The test may contain new verification components or |
| // the entire testbench, in which case the test and testbench can be chosen from |
| // the command line without forcing recompilation. If the global (package) |
| // variable, finish_on_completion, is set, then $finish is called after |
| // phasing completes. |
| |
| extern virtual task run_test (string test_name=""); |
| |
| |
| // Variable: top_levels |
| // |
| // This variable is a list of all of the top level components in UVM. It |
| // includes the uvm_test_top component that is created by <run_test> as |
| // well as any other top level components that have been instantiated |
| // anywhere in the hierarchy. |
| |
| uvm_component top_levels[$]; |
| |
| |
| // Function: find |
| |
| extern function uvm_component find (string comp_match); |
| |
| // Function: find_all |
| // |
| // Returns the component handle (find) or list of components handles |
| // (find_all) matching a given string. The string may contain the wildcards, |
| // * and ?. Strings beginning with '.' are absolute path names. If optional |
| // comp arg is provided, then search begins from that component down |
| // (default=all components). |
| |
| extern function void find_all (string comp_match, |
| ref uvm_component comps[$], |
| input uvm_component comp=null); |
| |
| |
| virtual function string get_type_name(); |
| return "uvm_root"; |
| endfunction |
| |
| |
| // Function: print_topology |
| // |
| // Print the verification environment's component topology. The |
| // ~printer~ is a <uvm_printer> object that controls the format |
| // of the topology printout; a ~null~ printer prints with the |
| // default output. |
| |
| extern function void print_topology (uvm_printer printer=null); |
| |
| |
| // Variable: enable_print_topology |
| // |
| // If set, then the entire testbench topology is printed just after completion |
| // of the end_of_elaboration phase. |
| |
| bit enable_print_topology = 0; |
| |
| |
| // Variable: finish_on_completion |
| // |
| // If set, then run_test will call $finish after all phases are executed. |
| |
| |
| bit finish_on_completion = 1; |
| |
| |
| // Variable- phase_timeout |
| // |
| // Specifies the timeout for the run phase. Default is `UVM_DEFAULT_TIMEOUT |
| |
| |
| time phase_timeout = `UVM_DEFAULT_TIMEOUT; |
| |
| |
| // Function: set_timeout |
| // |
| // Specifies the timeout for the simulation. Default is <`UVM_DEFAULT_TIMEOUT> |
| // |
| // The timeout is simply the maximum absolute simulation time allowed before a |
| // ~FATAL~ occurs. If the timeout is set to 20ns, then the simulation must end |
| // before 20ns, or a ~FATAL~ timeout will occur. |
| // |
| // This is provided so that the user can prevent the simulation from potentially |
| // consuming too many resources (Disk, Memory, CPU, etc) when the testbench is |
| // essentially hung. |
| // |
| // |
| |
| |
| extern function void set_timeout(time timeout, bit overridable=1); |
| |
| |
| // PRIVATE members |
| extern function void m_find_all_recurse(string comp_match, |
| ref uvm_component comps[$], |
| input uvm_component comp=null); |
| |
| extern protected function new (); |
| extern protected virtual function bit m_add_child (uvm_component child); |
| extern function void build_phase(uvm_phase phase); |
| extern local function void m_do_verbosity_settings(); |
| extern local function void m_do_timeout_settings(); |
| extern local function void m_do_factory_settings(); |
| extern local function void m_process_inst_override(string ovr); |
| extern local function void m_process_type_override(string ovr); |
| extern local function void m_do_config_settings(); |
| extern local function void m_do_max_quit_settings(); |
| extern local function void m_do_dump_args(); |
| extern local function void m_process_config(string cfg, bit is_int); |
| extern function void m_check_verbosity(); |
| // singleton handle |
| static local uvm_root m_inst; |
| |
| // For error checking |
| extern virtual task run_phase (uvm_phase phase); |
| |
| |
| // phase_started |
| // ------------- |
| // At end of elab phase we need to do tlm binding resolution. |
| function void phase_started(uvm_phase phase); |
| if (phase == end_of_elaboration_ph) begin |
| do_resolve_bindings(); |
| if (enable_print_topology) print_topology(); |
| |
| begin |
| uvm_report_server srvr; |
| srvr = get_report_server(); |
| if(srvr.get_severity_count(UVM_ERROR) > 0) begin |
| uvm_report_fatal("BUILDERR", "stopping due to build errors", UVM_NONE); |
| end |
| end |
| end |
| endfunction |
| |
| bit m_phase_all_done; |
| |
| |
| `ifndef UVM_NO_DEPRECATED |
| // stop_request |
| // ------------ |
| |
| // backward compat only |
| // call global_stop_request() or uvm_test_done.stop_request() instead |
| function void stop_request(); |
| uvm_test_done_objection tdo; |
| tdo = uvm_test_done_objection::get(); |
| tdo.stop_request(); |
| endfunction |
| `endif |
| |
| |
| endclass |
| |
| |
| |
| //------------------------------------------------------------------------------ |
| // Variable: uvm_top |
| // |
| // This is the top-level that governs phase execution and provides component |
| // search interface. See <uvm_root> for more information. |
| //------------------------------------------------------------------------------ |
| |
| const uvm_root uvm_top = uvm_root::get(); |
| |
| // for backward compatibility |
| const uvm_root _global_reporter = uvm_root::get(); |
| |
| |
| |
| //----------------------------------------------------------------------------- |
| // |
| // Class- uvm_root_report_handler |
| // |
| //----------------------------------------------------------------------------- |
| // Root report has name "reporter" |
| |
| class uvm_root_report_handler extends uvm_report_handler; |
| virtual function void report(uvm_severity severity, |
| string name, |
| string id, |
| string message, |
| int verbosity_level=UVM_MEDIUM, |
| string filename="", |
| int line=0, |
| uvm_report_object client=null); |
| if(name == "") |
| name = "reporter"; |
| super.report(severity, name, id, message, verbosity_level, filename, line, client); |
| endfunction |
| endclass |
| |
| |
| |
| //----------------------------------------------------------------------------- |
| // IMPLEMENTATION |
| //----------------------------------------------------------------------------- |
| |
| // get |
| // --- |
| |
| function uvm_root uvm_root::get(); |
| if (m_inst == null) begin |
| m_inst = new(); |
| void'(uvm_domain::get_common_domain()); |
| m_inst.m_domain = uvm_domain::get_uvm_domain(); |
| end |
| return m_inst; |
| endfunction |
| |
| |
| // new |
| // --- |
| |
| function uvm_root::new(); |
| |
| uvm_root_report_handler rh; |
| |
| super.new("__top__", null); |
| |
| rh = new; |
| set_report_handler(rh); |
| |
| clp = uvm_cmdline_processor::get_inst(); |
| |
| report_header(); |
| |
| // This sets up the global verbosity. Other command line args may |
| // change individual component verbosity. |
| m_check_verbosity(); |
| endfunction |
| |
| |
| // run_test |
| // -------- |
| |
| task uvm_root::run_test(string test_name=""); |
| |
| uvm_factory factory= uvm_factory::get(); |
| bit testname_plusarg; |
| int test_name_count; |
| string test_names[$]; |
| string msg; |
| uvm_component uvm_test_top; |
| |
| process phase_runner_proc; // store thread forked below for final cleanup |
| |
| testname_plusarg = 0; |
| |
| // Set up the process that decouples the thread that drops objections from |
| // the process that processes drop/all_dropped objections. Thus, if the |
| // original calling thread (the "dropper") gets killed, it does not affect |
| // drain-time and propagation of the drop up the hierarchy. |
| // Needs to be done in run_test since it needs to be in an |
| // initial block to fork a process. |
| uvm_objection::m_init_objections(); |
| |
| `ifndef UVM_NO_DPI |
| |
| // Retrieve the test names provided on the command line. Command line |
| // overrides the argument. |
| test_name_count = clp.get_arg_values("+UVM_TESTNAME=", test_names); |
| |
| // If at least one, use first in queue. |
| if (test_name_count > 0) begin |
| test_name = test_names[0]; |
| testname_plusarg = 1; |
| end |
| |
| // If multiple, provided the warning giving the number, which one will be |
| // used and the complete list. |
| if (test_name_count > 1) begin |
| string test_list; |
| string sep; |
| for (int i = 0; i < test_names.size(); i++) begin |
| if (i != 0) |
| sep = ", "; |
| test_list = {test_list, sep, test_names[i]}; |
| end |
| uvm_report_warning("MULTTST", |
| $sformatf("Multiple (%0d) +UVM_TESTNAME arguments provided on the command line. '%s' will be used. Provided list: %s.", test_name_count, test_name, test_list), UVM_NONE); |
| end |
| |
| `else |
| |
| // plusarg overrides argument |
| if ($value$plusargs("UVM_TESTNAME=%s", test_name)) begin |
| `uvm_info("NO_DPI_TSTNAME", "UVM_NO_DPI defined--getting UVM_TESTNAME directly, without DPI", UVM_NONE) |
| testname_plusarg = 1; |
| end |
| |
| `endif |
| |
| // if test now defined, create it using common factory |
| if (test_name != "") begin |
| if(m_children.exists("uvm_test_top")) begin |
| uvm_report_fatal("TTINST", |
| "An uvm_test_top already exists via a previous call to run_test", UVM_NONE); |
| #0; // forces shutdown because $finish is forked |
| end |
| $cast(uvm_test_top, factory.create_component_by_name(test_name, |
| "", "uvm_test_top", null)); |
| |
| if (uvm_test_top == null) begin |
| msg = testname_plusarg ? {"command line +UVM_TESTNAME=",test_name} : |
| {"call to run_test(",test_name,")"}; |
| uvm_report_fatal("INVTST", |
| {"Requested test from ",msg, " not found." }, UVM_NONE); |
| end |
| end |
| |
| if (m_children.num() == 0) begin |
| uvm_report_fatal("NOCOMP", |
| {"No components instantiated. You must either instantiate", |
| " at least one component before calling run_test or use", |
| " run_test to do so. To run a test using run_test,", |
| " use +UVM_TESTNAME or supply the test name in", |
| " the argument to run_test(). Exiting simulation."}, UVM_NONE); |
| return; |
| end |
| |
| begin |
| if(test_name=="") |
| uvm_report_info("RNTST", "Running test ...", UVM_LOW); |
| else if (test_name == uvm_test_top.get_type_name()) |
| uvm_report_info("RNTST", {"Running test ",test_name,"..."}, UVM_LOW); |
| else |
| uvm_report_info("RNTST", {"Running test ",uvm_test_top.get_type_name()," (via factory override for test \"",test_name,"\")..."}, UVM_LOW); |
| end |
| |
| // phase runner, isolated from calling process |
| fork begin |
| // spawn the phase runner task |
| phase_runner_proc = process::self(); |
| uvm_phase::m_run_phases(); |
| end |
| join_none |
| #0; // let the phase runner start |
| |
| wait (m_phase_all_done == 1); |
| |
| // clean up after ourselves |
| phase_runner_proc.kill(); |
| |
| report_summarize(); |
| |
| if (finish_on_completion) |
| $finish; |
| |
| endtask |
| |
| |
| // find_all |
| // -------- |
| |
| function void uvm_root::find_all(string comp_match, ref uvm_component comps[$], |
| input uvm_component comp=null); |
| |
| if (comp==null) |
| comp = this; |
| m_find_all_recurse(comp_match, comps, comp); |
| |
| endfunction |
| |
| |
| // find |
| // ---- |
| |
| function uvm_component uvm_root::find (string comp_match); |
| uvm_component comp_list[$]; |
| |
| find_all(comp_match,comp_list); |
| |
| if (comp_list.size() > 1) |
| uvm_report_warning("MMATCH", |
| $sformatf("Found %0d components matching '%s'. Returning first match, %0s.", |
| comp_list.size(),comp_match,comp_list[0].get_full_name()), UVM_NONE); |
| |
| if (comp_list.size() == 0) begin |
| uvm_report_warning("CMPNFD", |
| {"Component matching '",comp_match, |
| "' was not found in the list of uvm_components"}, UVM_NONE); |
| return null; |
| end |
| |
| return comp_list[0]; |
| endfunction |
| |
| |
| // print_topology |
| // -------------- |
| |
| function void uvm_root::print_topology(uvm_printer printer=null); |
| |
| string s; |
| |
| uvm_report_info("UVMTOP", "UVM testbench topology:", UVM_LOW); |
| |
| if (m_children.num()==0) begin |
| uvm_report_warning("EMTCOMP", "print_topology - No UVM components to print.", UVM_NONE); |
| return; |
| end |
| |
| if (printer==null) |
| printer = uvm_default_printer; |
| |
| foreach (m_children[c]) begin |
| if(m_children[c].print_enabled) begin |
| printer.print_object("", m_children[c]); |
| end |
| end |
| $display(printer.emit()); |
| |
| endfunction |
| |
| |
| // set_timeout |
| // ----------- |
| |
| function void uvm_root::set_timeout(time timeout, bit overridable=1); |
| static bit m_uvm_timeout_overridable = 1; |
| if (m_uvm_timeout_overridable == 0) begin |
| uvm_report_info("NOTIMOUTOVR", |
| $sformatf("The global timeout setting of %0d is not overridable to %0d due to a previous setting.", |
| phase_timeout, timeout), UVM_NONE); |
| return; |
| end |
| m_uvm_timeout_overridable = overridable; |
| phase_timeout = timeout; |
| endfunction |
| |
| |
| |
| // m_find_all_recurse |
| // ------------------ |
| |
| function void uvm_root::m_find_all_recurse(string comp_match, ref uvm_component comps[$], |
| input uvm_component comp=null); |
| string name; |
| |
| if (comp.get_first_child(name)) |
| do begin |
| this.m_find_all_recurse(comp_match, comps, comp.get_child(name)); |
| end |
| while (comp.get_next_child(name)); |
| if (uvm_is_match(comp_match, comp.get_full_name()) && |
| comp.get_name() != "") /* uvm_top */ |
| comps.push_back(comp); |
| |
| endfunction |
| |
| |
| // m_add_child |
| // ----------- |
| |
| // Add to the top levels array |
| function bit uvm_root::m_add_child (uvm_component child); |
| if(super.m_add_child(child)) begin |
| if(child.get_name() == "uvm_test_top") |
| top_levels.push_front(child); |
| else |
| top_levels.push_back(child); |
| return 1; |
| end |
| else |
| return 0; |
| endfunction |
| |
| |
| // build_phase |
| // ----- |
| |
| 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 |
| |
| |
| // m_do_verbosity_settings |
| // ----------------------- |
| |
| function void uvm_root::m_do_verbosity_settings(); |
| string set_verbosity_settings[$]; |
| string split_vals[$]; |
| uvm_verbosity tmp_verb; |
| |
| // Retrieve them all into set_verbosity_settings |
| void'(clp.get_arg_values("+uvm_set_verbosity=", set_verbosity_settings)); |
| |
| for(int i = 0; i < set_verbosity_settings.size(); i++) begin |
| uvm_split_string(set_verbosity_settings[i], ",", split_vals); |
| if(split_vals.size() < 4 || split_vals.size() > 5) begin |
| uvm_report_warning("INVLCMDARGS", |
| $sformatf("Invalid number of arguments found on the command line for setting '+uvm_set_verbosity=%s'. Setting ignored.", |
| set_verbosity_settings[i]), UVM_NONE, "", ""); |
| end |
| // Invalid verbosity |
| if(!clp.m_convert_verb(split_vals[2], tmp_verb)) begin |
| uvm_report_warning("INVLCMDVERB", |
| $sformatf("Invalid verbosity found on the command line for setting '%s'.", |
| set_verbosity_settings[i]), UVM_NONE, "", ""); |
| end |
| end |
| endfunction |
| |
| |
| // m_do_timeout_settings |
| // --------------------- |
| |
| function void uvm_root::m_do_timeout_settings(); |
| string timeout_settings[$]; |
| string timeout; |
| string split_timeout[$]; |
| int timeout_count; |
| time timeout_int; |
| string override_spec; |
| timeout_count = clp.get_arg_values("+UVM_TIMEOUT=", timeout_settings); |
| if (timeout_count == 0) |
| return; |
| else begin |
| timeout = timeout_settings[0]; |
| if (timeout_count > 1) begin |
| string timeout_list; |
| string sep; |
| for (int i = 0; i < timeout_settings.size(); i++) begin |
| if (i != 0) |
| sep = "; "; |
| timeout_list = {timeout_list, sep, timeout_settings[i]}; |
| end |
| uvm_report_warning("MULTTIMOUT", |
| $sformatf("Multiple (%0d) +UVM_TIMEOUT arguments provided on the command line. '%s' will be used. Provided list: %s.", |
| timeout_count, timeout, timeout_list), UVM_NONE); |
| end |
| uvm_report_info("TIMOUTSET", |
| $sformatf("'+UVM_TIMEOUT=%s' provided on the command line is being applied.", timeout), UVM_NONE); |
| void'($sscanf(timeout,"%d,%s",timeout_int,override_spec)); |
| case(override_spec) |
| "YES" : set_timeout(timeout_int, 1); |
| "NO" : set_timeout(timeout_int, 0); |
| default : set_timeout(timeout_int, 1); |
| endcase |
| end |
| endfunction |
| |
| |
| // m_do_factory_settings |
| // --------------------- |
| |
| function void uvm_root::m_do_factory_settings(); |
| string args[$]; |
| |
| void'(clp.get_arg_matches("/^\\+(UVM_SET_INST_OVERRIDE|uvm_set_inst_override)=/",args)); |
| foreach(args[i]) begin |
| m_process_inst_override(args[i].substr(23, args[i].len()-1)); |
| end |
| void'(clp.get_arg_matches("/^\\+(UVM_SET_TYPE_OVERRIDE|uvm_set_type_override)=/",args)); |
| foreach(args[i]) begin |
| m_process_type_override(args[i].substr(23, args[i].len()-1)); |
| end |
| endfunction |
| |
| |
| // m_process_inst_override |
| // ----------------------- |
| |
| function void uvm_root::m_process_inst_override(string ovr); |
| string split_val[$]; |
| uvm_factory fact = uvm_factory::get(); |
| |
| uvm_split_string(ovr, ",", split_val); |
| |
| if(split_val.size() != 3 ) begin |
| uvm_report_error("UVM_CMDLINE_PROC", {"Invalid setting for +uvm_set_inst_override=", ovr, |
| ", setting must specify <requested_type>,<override_type>,<instance_path>"}, UVM_NONE); |
| return; |
| end |
| |
| uvm_report_info("INSTOVR", {"Applying instance override from the command line: +uvm_set_inst_override=", ovr}, UVM_NONE); |
| fact.set_inst_override_by_name(split_val[0], split_val[1], split_val[2]); |
| endfunction |
| |
| |
| // m_process_type_override |
| // ----------------------- |
| |
| function void uvm_root::m_process_type_override(string ovr); |
| string split_val[$]; |
| int replace=1; |
| uvm_factory fact = uvm_factory::get(); |
| |
| uvm_split_string(ovr, ",", split_val); |
| |
| if(split_val.size() > 3 || split_val.size() < 2) begin |
| uvm_report_error("UVM_CMDLINE_PROC", {"Invalid setting for +uvm_set_type_override=", ovr, |
| ", setting must specify <requested_type>,<override_type>[,<replace>]"}, UVM_NONE); |
| return; |
| end |
| |
| // Replace arg is optional. If set, must be 0 or 1 |
| if(split_val.size() == 3) begin |
| if(split_val[2]=="0") replace = 0; |
| else if (split_val[2] == "1") replace = 1; |
| else begin |
| uvm_report_error("UVM_CMDLINE_PROC", {"Invalid replace arg for +uvm_set_type_override=", ovr ," value must be 0 or 1"}, UVM_NONE); |
| return; |
| end |
| end |
| |
| uvm_report_info("UVM_CMDLINE_PROC", {"Applying type override from the command line: +uvm_set_type_override=", ovr}, UVM_NONE); |
| fact.set_type_override_by_name(split_val[0], split_val[1], replace); |
| endfunction |
| |
| |
| // m_process_config |
| // ---------------- |
| |
| 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(split_val.size() == 1) begin |
| uvm_report_error("UVM_CMDLINE_PROC", {"Invalid +uvm_set_config command\"", cfg, |
| "\" missing field and value: component is \"", split_val[0], "\""}, UVM_NONE); |
| return; |
| end |
| |
| if(split_val.size() == 2) begin |
| uvm_report_error("UVM_CMDLINE_PROC", {"Invalid +uvm_set_config command\"", cfg, |
| "\" missing value: component is \"", split_val[0], "\" field is \"", split_val[1], "\""}, UVM_NONE); |
| return; |
| end |
| |
| if(split_val.size() > 3) begin |
| uvm_report_error("UVM_CMDLINE_PROC", |
| $sformatf("Invalid +uvm_set_config command\"%s\" : expected only 3 fields (component, field and value).", cfg), UVM_NONE); |
| return; |
| end |
| |
| 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 |
| |
| endfunction |
| |
| |
| // m_do_config_settings |
| // -------------------- |
| |
| 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 |
| |
| |
| // m_do_max_quit_settings |
| // ---------------------- |
| |
| function void uvm_root::m_do_max_quit_settings(); |
| uvm_report_server srvr; |
| string max_quit_settings[$]; |
| int max_quit_count; |
| string max_quit; |
| string split_max_quit[$]; |
| int max_quit_int; |
| srvr = get_report_server(); |
| max_quit_count = clp.get_arg_values("+UVM_MAX_QUIT_COUNT=", max_quit_settings); |
| if (max_quit_count == 0) |
| return; |
| else begin |
| max_quit = max_quit_settings[0]; |
| if (max_quit_count > 1) begin |
| string max_quit_list; |
| string sep; |
| for (int i = 0; i < max_quit_settings.size(); i++) begin |
| if (i != 0) |
| sep = "; "; |
| max_quit_list = {max_quit_list, sep, max_quit_settings[i]}; |
| end |
| uvm_report_warning("MULTMAXQUIT", |
| $sformatf("Multiple (%0d) +UVM_MAX_QUIT_COUNT arguments provided on the command line. '%s' will be used. Provided list: %s.", |
| max_quit_count, max_quit, max_quit_list), UVM_NONE); |
| end |
| uvm_report_info("MAXQUITSET", |
| $sformatf("'+UVM_MAX_QUIT_COUNT=%s' provided on the command line is being applied.", max_quit), UVM_NONE); |
| uvm_split_string(max_quit, ",", split_max_quit); |
| max_quit_int = split_max_quit[0].atoi(); |
| case(split_max_quit[1]) |
| "YES" : srvr.set_max_quit_count(max_quit_int, 1); |
| "NO" : srvr.set_max_quit_count(max_quit_int, 0); |
| default : srvr.set_max_quit_count(max_quit_int, 1); |
| endcase |
| end |
| endfunction |
| |
| |
| // m_do_dump_args |
| // -------------- |
| |
| function void uvm_root::m_do_dump_args(); |
| string dump_args[$]; |
| string all_args[$]; |
| string out_string; |
| if(clp.get_arg_matches("+UVM_DUMP_CMDLINE_ARGS", dump_args)) begin |
| clp.get_args(all_args); |
| for (int i = 0; i < all_args.size(); i++) begin |
| if (all_args[i] == "__-f__") |
| continue; |
| out_string = {out_string, all_args[i], " "}; |
| end |
| uvm_report_info("DUMPARGS", out_string, UVM_NONE); |
| end |
| endfunction |
| |
| |
| // m_check_verbosity |
| // ---------------- |
| |
| function void uvm_root::m_check_verbosity(); |
| |
| string verb_string; |
| string verb_settings[$]; |
| int verb_count; |
| int plusarg; |
| int verbosity = UVM_MEDIUM; |
| |
| `ifndef UVM_CMDLINE_NO_DPI |
| // Retrieve the verbosities provided on the command line. |
| verb_count = clp.get_arg_values("+UVM_VERBOSITY=", verb_settings); |
| `else |
| verb_count = $value$plusargs("UVM_VERBOSITY=%s",verb_string); |
| if (verb_count) |
| verb_settings.push_back(verb_string); |
| `endif |
| |
| // If none provided, provide message about the default being used. |
| //if (verb_count == 0) |
| // uvm_report_info("DEFVERB", ("No verbosity specified on the command line. Using the default: UVM_MEDIUM"), UVM_NONE); |
| |
| // If at least one, use the first. |
| if (verb_count > 0) begin |
| verb_string = verb_settings[0]; |
| plusarg = 1; |
| end |
| |
| // If more than one, provide the warning stating how many, which one will |
| // be used and the complete list. |
| if (verb_count > 1) begin |
| string verb_list; |
| string sep; |
| for (int i = 0; i < verb_settings.size(); i++) begin |
| if (i != 0) |
| sep = ", "; |
| verb_list = {verb_list, sep, verb_settings[i]}; |
| end |
| uvm_report_warning("MULTVERB", |
| $sformatf("Multiple (%0d) +UVM_VERBOSITY arguments provided on the command line. '%s' will be used. Provided list: %s.", verb_count, verb_string, verb_list), UVM_NONE); |
| end |
| |
| if(plusarg == 1) begin |
| case(verb_string) |
| "UVM_NONE" : verbosity = UVM_NONE; |
| "NONE" : verbosity = UVM_NONE; |
| "UVM_LOW" : verbosity = UVM_LOW; |
| "LOW" : verbosity = UVM_LOW; |
| "UVM_MEDIUM" : verbosity = UVM_MEDIUM; |
| "MEDIUM" : verbosity = UVM_MEDIUM; |
| "UVM_HIGH" : verbosity = UVM_HIGH; |
| "HIGH" : verbosity = UVM_HIGH; |
| "UVM_FULL" : verbosity = UVM_FULL; |
| "FULL" : verbosity = UVM_FULL; |
| "UVM_DEBUG" : verbosity = UVM_DEBUG; |
| "DEBUG" : verbosity = UVM_DEBUG; |
| default : begin |
| verbosity = verb_string.atoi(); |
| if(verbosity > 0) |
| uvm_report_info("NSTVERB", $sformatf("Non-standard verbosity value, using provided '%0d'.", verbosity), UVM_NONE); |
| if(verbosity == 0) begin |
| verbosity = UVM_MEDIUM; |
| uvm_report_warning("ILLVERB", "Illegal verbosity value, using default of UVM_MEDIUM.", UVM_NONE); |
| end |
| end |
| endcase |
| end |
| |
| set_report_verbosity_level_hier(verbosity); |
| |
| endfunction |
| |
| // It is required that the run phase start at simulation time 0 |
| // TBD this looks wrong - taking advantage of uvm_root not doing anything else? |
| // TBD move to phase_started callback? |
| task uvm_root::run_phase (uvm_phase phase); |
| if($time > 0) |
| `uvm_fatal("RUNPHSTIME", {"The run phase must start at time 0, current time is ", |
| $sformatf("%0t", $realtime), ". No non-zero delays are allowed before ", |
| "run_test(), and pre-run user defined phases may not consume ", |
| "simulation time before the start of the run phase."}) |
| endtask |
| |