// //------------------------------------------------------------------------------ // Copyright 2007-2011 Mentor Graphics Corporation // Copyright 2007-2011 Cadence Design Systems, Inc. // Copyright 2010 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. //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ // // Topic: 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; //---------------------------------------------------------------------------- // // 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_vector_to_string // // function string uvm_vector_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); value &= (1 << size)-1; case(radix) UVM_BIN: return $sformatf("%0s%0b", radix_str, value); UVM_OCT: return $sformatf("%0s%0o", radix_str, value); UVM_UNSIGNED: return $sformatf("%0s%0d", radix_str, value); UVM_STRING: return $sformatf("%0s%0s", radix_str, value); UVM_TIME: return $sformatf("%0s%0t", radix_str, value); UVM_DEC: return $sformatf("%0s%0d", radix_str, value); default: return $sformatf("%0s%0x", radix_str, value); endcase endfunction // Function- uvm_get_array_index_int // // The following functions check to see if a string is representing an array // index, and if so, what the index is. function int uvm_get_array_index_int(string arg, output bit is_wildcard); int i; uvm_get_array_index_int = 0; is_wildcard = 1; i = arg.len() - 1; if(arg[i] == "]") while(i > 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 //------------------------------------------------------------------------------ // CLASS: uvm_utils // // This class contains useful template functions. // //------------------------------------------------------------------------------ typedef class uvm_component; typedef class uvm_root; typedef class uvm_object; 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; top = uvm_root::get(); 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; 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 (!comp.get_config_object(FIELD, obj, 0)) 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