// //------------------------------------------------------------------------------ // Copyright 2007-2011 Mentor Graphics Corporation // Copyright 2007-2011 Cadence Design Systems, Inc. // Copyright 2010 Synopsys, Inc. // Copyright 2014 NVIDIA Corporation // 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. //------------------------------------------------------------------------------ // File: Miscellaneous Structures //------------------------------------------------------------------------------ // // Class: uvm_void // // The ~uvm_void~ class is the base class for all UVM classes. It is an abstract // class with no data members or functions. It allows for generic containers of // objects to be created, similar to a void pointer in the C programming // language. User classes derived directly from ~uvm_void~ inherit none of the // UVM functionality, but such classes may be placed in ~uvm_void~-typed // containers along with other UVM objects. // //------------------------------------------------------------------------------ virtual class uvm_void; endclass // Append/prepend symbolic values for order-dependent APIs typedef enum {UVM_APPEND, UVM_PREPEND} uvm_apprepend; // Forward declaration since scope stack uses uvm_objects now typedef class uvm_object; typedef class uvm_coreservice_t; typedef class uvm_factory; typedef class uvm_config_db; // m_uvm_config_obj_misc is an internal typedef for the uvm_misc.svh file // to use. UVM users should use the uvm_config_object typedef typedef uvm_config_db#(uvm_object) m_uvm_config_obj_misc; //---------------------------------------------------------------------------- // // CLASS- uvm_scope_stack // //---------------------------------------------------------------------------- class uvm_scope_stack; local string m_arg; local string m_stack[$]; // depth // ----- function int depth(); return m_stack.size(); endfunction // scope // ----- function string get(); string v; if(m_stack.size() == 0) return m_arg; get = m_stack[0]; for(int i=1; i"; uvm_object_value_str.itoa(v.get_inst_id()); uvm_object_value_str = {"@",uvm_object_value_str}; endfunction // Function- uvm_leaf_scope // // function string uvm_leaf_scope (string full_name, byte scope_separator = "."); byte bracket_match; int pos; int bmatches; bmatches = 0; case(scope_separator) "[": bracket_match = "]"; "(": bracket_match = ")"; "<": bracket_match = ">"; "{": bracket_match = "}"; default: bracket_match = ""; endcase //Only use bracket matching if the input string has the end match if(bracket_match != "" && bracket_match != full_name[full_name.len()-1]) bracket_match = ""; for(pos=full_name.len()-1; pos>0; --pos) begin if(full_name[pos] == bracket_match) bmatches++; else if(full_name[pos] == scope_separator) begin bmatches--; if(!bmatches || (bracket_match == "")) break; end end if(pos) begin if(scope_separator != ".") pos--; uvm_leaf_scope = full_name.substr(pos+1,full_name.len()-1); end else begin uvm_leaf_scope = full_name; end endfunction // Function- uvm_bitstream_to_string // // function string uvm_bitstream_to_string (uvm_bitstream_t value, int size, uvm_radix_enum radix=UVM_NORADIX, string radix_str=""); // sign extend & don't show radix for negative values if (radix == UVM_DEC && value[size-1] === 1) return $sformatf("%0d", value); // TODO $countbits(value,'z) would be even better if($isunknown(value)) begin uvm_bitstream_t _t; _t=0; for(int idx=0;idx 0 && (arg[i] != "[")) begin --i; if((arg[i] == "*") || (arg[i] == "?")) i=0; else if((arg[i] < "0") || (arg[i] > "9") && (arg[i] != "[")) begin uvm_get_array_index_int = -1; //illegal integral index i=0; end end else begin is_wildcard = 0; return 0; end if(i>0) begin arg = arg.substr(i+1, arg.len()-2); uvm_get_array_index_int = arg.atoi(); is_wildcard = 0; end endfunction // Function- uvm_get_array_index_string // // function string uvm_get_array_index_string(string arg, output bit is_wildcard); int i; uvm_get_array_index_string = ""; is_wildcard = 1; i = arg.len() - 1; if(arg[i] == "]") while(i > 0 && (arg[i] != "[")) begin if((arg[i] == "*") || (arg[i] == "?")) i=0; --i; end if(i>0) begin uvm_get_array_index_string = arg.substr(i+1, arg.len()-2); is_wildcard = 0; end endfunction // Function- uvm_is_array // // function bit uvm_is_array(string arg); return arg[arg.len()-1] == "]"; endfunction // Function- uvm_has_wildcard // // function automatic bit uvm_has_wildcard (string arg); uvm_has_wildcard = 0; //if it is a regex then return true if( (arg.len() > 1) && (arg[0] == "/") && (arg[arg.len()-1] == "/") ) return 1; //check if it has globs foreach(arg[i]) if( (arg[i] == "*") || (arg[i] == "+") || (arg[i] == "?") ) uvm_has_wildcard = 1; endfunction typedef class uvm_component; typedef class uvm_root; typedef class uvm_report_object; //------------------------------------------------------------------------------ // CLASS: uvm_utils #(TYPE,FIELD) // // This class contains useful template functions. // //------------------------------------------------------------------------------ class uvm_utils #(type TYPE=int, string FIELD="config"); typedef TYPE types_t[$]; // Function: find_all // // Recursively finds all component instances of the parameter type ~TYPE~, // starting with the component given by ~start~. Uses . static function types_t find_all(uvm_component start); uvm_component list[$]; types_t types; uvm_root top; uvm_coreservice_t cs; cs = uvm_coreservice_t::get(); top = cs.get_root(); top.find_all("*",list,start); foreach (list[i]) begin TYPE typ; if ($cast(typ,list[i])) types.push_back(typ); end if (types.size() == 0) begin `uvm_warning("find_type-no match",{"Instance of type '",TYPE::type_name, " not found in component hierarchy beginning at ",start.get_full_name()}) end return types; endfunction static function TYPE find(uvm_component start); types_t types = find_all(start); if (types.size() == 0) return null; if (types.size() > 1) begin `uvm_warning("find_type-multi match",{"More than one instance of type '",TYPE::type_name, " found in component hierarchy beginning at ",start.get_full_name()}) return null; end return types[0]; endfunction static function TYPE create_type_by_name(string type_name, string contxt); uvm_object obj; TYPE typ; uvm_coreservice_t cs = uvm_coreservice_t::get(); uvm_factory factory=cs.get_factory(); obj = factory.create_object_by_name(type_name,contxt,type_name); if (!$cast(typ,obj)) uvm_report_error("WRONG_TYPE",{"The type_name given '",type_name, "' with context '",contxt,"' did not produce the expected type."}); return typ; endfunction // Function: get_config // // This method gets the object config of type ~TYPE~ // associated with component ~comp~. // We check for the two kinds of error which may occur with this kind of // operation. static function TYPE get_config(uvm_component comp, bit is_fatal); uvm_object obj; TYPE cfg; if (!m_uvm_config_obj_misc::get(comp,"",FIELD, obj)) begin if (is_fatal) comp.uvm_report_fatal("NO_SET_CFG", {"no set_config to field '", FIELD, "' for component '",comp.get_full_name(),"'"}, UVM_MEDIUM, `uvm_file , `uvm_line ); else comp.uvm_report_warning("NO_SET_CFG", {"no set_config to field '", FIELD, "' for component '",comp.get_full_name(),"'"}, UVM_MEDIUM, `uvm_file , `uvm_line ); return null; end if (!$cast(cfg, obj)) begin if (is_fatal) comp.uvm_report_fatal( "GET_CFG_TYPE_FAIL", {"set_config_object with field name ",FIELD, " is not of type '",TYPE::type_name,"'"}, UVM_NONE , `uvm_file , `uvm_line ); else comp.uvm_report_warning( "GET_CFG_TYPE_FAIL", {"set_config_object with field name ",FIELD, " is not of type '",TYPE::type_name,"'"}, UVM_NONE , `uvm_file , `uvm_line ); end return cfg; endfunction endclass `ifdef UVM_USE_PROCESS_CONTAINER class process_container_c; process p; function new(process p_); p=p_; endfunction endclass `endif // this is an internal function and provides a string join independent of a streaming pack function automatic string m_uvm_string_queue_join(ref string i[$]); `ifndef QUESTA m_uvm_string_queue_join = {>>{i}}; `else foreach(i[idx]) m_uvm_string_queue_join = {m_uvm_string_queue_join,i[idx]}; `endif endfunction