Search code examples
command-line-argumentssystem-veriloguvm

Can UVM flag a bad command line argument?


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


Solution

  • 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