// //------------------------------------------------------------------------------ // Copyright 2010-2012 AMD // Copyright 2007-2018 Cadence Design Systems, Inc. // Copyright 2017 Cisco Systems, Inc. // Copyright 2014 Intel Corporation // Copyright 2007-2014 Mentor Graphics Corporation // Copyright 2013-2020 NVIDIA Corporation // Copyright 2010-2014 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. //------------------------------------------------------------------------------ typedef class uvm_root; typedef class uvm_report_object; typedef class uvm_report_message; // Title -- NODOCS -- Globals //------------------------------------------------------------------------------ // // Group -- NODOCS -- Simulation Control // //------------------------------------------------------------------------------ // Task -- NODOCS -- run_test // // Convenience function for uvm_top.run_test(). See for more // information. // @uvm-ieee 1800.2-2020 auto F.3.1.2 task run_test (string test_name=""); uvm_root top; uvm_coreservice_t cs; cs = uvm_coreservice_t::get(); top = cs.get_root(); top.run_test(test_name); endtask //---------------------------------------------------------------------------- // // Group -- NODOCS -- Reporting // //---------------------------------------------------------------------------- // @uvm-ieee 1800.2-2020 auto F.3.2.1 function uvm_report_object uvm_get_report_object(); uvm_root top; uvm_coreservice_t cs; cs = uvm_coreservice_t::get(); top = cs.get_root(); return top; endfunction // Function -- NODOCS -- uvm_report_enabled // // Returns 1 if the configured verbosity in ~uvm_top~ for this // severity/id is greater than or equal to ~verbosity~ else returns 0. // // See also . // // Static methods of an extension of uvm_report_object, e.g. uvm_component-based // objects, cannot call ~uvm_report_enabled~ because the call will resolve to // the , which is non-static. // Static methods cannot call non-static methods of the same class. // @uvm-ieee 1800.2-2020 auto F.3.2.2 function int uvm_report_enabled (int verbosity, uvm_severity severity=UVM_INFO, string id=""); uvm_root top; uvm_coreservice_t cs; cs = uvm_coreservice_t::get(); top = cs.get_root(); return top.uvm_report_enabled(verbosity,severity,id); endfunction // Function -- NODOCS -- uvm_report // @uvm-ieee 1800.2-2020 auto F.3.2.3 function void uvm_report( uvm_severity severity, string id, string message, int verbosity = (severity == uvm_severity'(UVM_ERROR)) ? UVM_LOW : (severity == uvm_severity'(UVM_FATAL)) ? UVM_NONE : UVM_MEDIUM, string filename = "", int line = 0, string context_name = "", bit report_enabled_checked = 0); uvm_root top; uvm_coreservice_t cs; cs = uvm_coreservice_t::get(); top = cs.get_root(); top.uvm_report(severity, id, message, verbosity, filename, line, context_name, report_enabled_checked); endfunction // Undocumented DPI available version of uvm_report export "DPI-C" function m__uvm_report_dpi; function void m__uvm_report_dpi(int severity, string id, string message, int verbosity, string filename, int line); uvm_report(uvm_severity'(severity), id, message, verbosity, filename, line); endfunction : m__uvm_report_dpi // Function -- NODOCS -- uvm_report_info // @uvm-ieee 1800.2-2020 auto F.3.2.3 function void uvm_report_info(string id, string message, int verbosity = UVM_MEDIUM, string filename = "", int line = 0, string context_name = "", bit report_enabled_checked = 0); uvm_root top; uvm_coreservice_t cs; cs = uvm_coreservice_t::get(); top = cs.get_root(); top.uvm_report_info(id, message, verbosity, filename, line, context_name, report_enabled_checked); endfunction // Function -- NODOCS -- uvm_report_warning // @uvm-ieee 1800.2-2020 auto F.3.2.3 function void uvm_report_warning(string id, string message, int verbosity = UVM_MEDIUM, string filename = "", int line = 0, string context_name = "", bit report_enabled_checked = 0); uvm_root top; uvm_coreservice_t cs; cs = uvm_coreservice_t::get(); top = cs.get_root(); top.uvm_report_warning(id, message, verbosity, filename, line, context_name, report_enabled_checked); endfunction // Function -- NODOCS -- uvm_report_error // @uvm-ieee 1800.2-2020 auto F.3.2.3 function void uvm_report_error(string id, string message, int verbosity = UVM_NONE, string filename = "", int line = 0, string context_name = "", bit report_enabled_checked = 0); uvm_root top; uvm_coreservice_t cs; cs = uvm_coreservice_t::get(); top = cs.get_root(); top.uvm_report_error(id, message, verbosity, filename, line, context_name, report_enabled_checked); endfunction // Function -- NODOCS -- uvm_report_fatal // // These methods, defined in package scope, are convenience functions that // delegate to the corresponding component methods in ~uvm_top~. They can be // used in module-based code to use the same reporting mechanism as class-based // components. See for details on the reporting mechanism. // // *Note:* Verbosity is ignored for warnings, errors, and fatals to ensure users // do not inadvertently filter them out. It remains in the methods for backward // compatibility. // @uvm-ieee 1800.2-2020 auto F.3.2.3 function void uvm_report_fatal(string id, string message, int verbosity = UVM_NONE, string filename = "", int line = 0, string context_name = "", bit report_enabled_checked = 0); uvm_root top; uvm_coreservice_t cs; cs = uvm_coreservice_t::get(); top = cs.get_root(); top.uvm_report_fatal(id, message, verbosity, filename, line, context_name, report_enabled_checked); endfunction // Function -- NODOCS -- uvm_process_report_message // // This method, defined in package scope, is a convenience function that // delegate to the corresponding component method in ~uvm_top~. It can be // used in module-based code to use the same reporting mechanism as class-based // components. See for details on the reporting mechanism. // @uvm-ieee 1800.2-2020 auto F.3.2.3 function void uvm_process_report_message(uvm_report_message report_message); uvm_root top; uvm_coreservice_t cs; process p; p = process::self(); cs = uvm_coreservice_t::get(); top = cs.get_root(); top.uvm_process_report_message(report_message); endfunction // TODO merge with uvm_enum_wrapper#(uvm_severity) function bit uvm_string_to_severity (string sev_str, output uvm_severity sev); case (sev_str) "UVM_INFO": sev = UVM_INFO; "UVM_WARNING": sev = UVM_WARNING; "UVM_ERROR": sev = UVM_ERROR; "UVM_FATAL": sev = UVM_FATAL; default: return 0; endcase return 1; endfunction function automatic bit uvm_string_to_action (string action_str, output uvm_action action); string actions[$]; uvm_string_split(action_str,"|",actions); uvm_string_to_action = 1; action = 0; foreach(actions[i]) begin case (actions[i]) "UVM_NO_ACTION": action |= UVM_NO_ACTION; "UVM_DISPLAY": action |= UVM_DISPLAY; "UVM_LOG": action |= UVM_LOG; "UVM_COUNT": action |= UVM_COUNT; "UVM_EXIT": action |= UVM_EXIT; "UVM_CALL_HOOK": action |= UVM_CALL_HOOK; "UVM_STOP": action |= UVM_STOP; "UVM_RM_RECORD": action |= UVM_RM_RECORD; default: uvm_string_to_action = 0; endcase end endfunction function automatic bit uvm_string_to_verbosity(string verb_str, output uvm_verbosity verb_enum); case (verb_str) "NONE" : begin verb_enum = UVM_NONE; return 1; end "UVM_NONE" : begin verb_enum = UVM_NONE; return 1; end "LOW" : begin verb_enum = UVM_LOW; return 1; end "UVM_LOW" : begin verb_enum = UVM_LOW; return 1; end "MEDIUM" : begin verb_enum = UVM_MEDIUM; return 1; end "UVM_MEDIUM" : begin verb_enum = UVM_MEDIUM; return 1; end "HIGH" : begin verb_enum = UVM_HIGH; return 1; end "UVM_HIGH" : begin verb_enum = UVM_HIGH; return 1; end "FULL" : begin verb_enum = UVM_FULL; return 1; end "UVM_FULL" : begin verb_enum = UVM_FULL; return 1; end "DEBUG" : begin verb_enum = UVM_DEBUG; return 1; end "UVM_DEBUG" : begin verb_enum = UVM_DEBUG; return 1; end default : begin return 0; end endcase endfunction //---------------------------------------------------------------------------- // // Group: Miscellaneous // // The library implements the following public API at the package level beyond // what is documented in IEEE 1800.2. //---------------------------------------------------------------------------- // @uvm-ieee 1800.2-2020 auto F.3.3.1 function bit uvm_is_match (string expr, string str); string s; s = uvm_glob_to_re(expr); return (uvm_re_match(s, str) == 0); endfunction parameter UVM_LINE_WIDTH = `UVM_LINE_WIDTH; parameter UVM_NUM_LINES = `UVM_NUM_LINES; parameter UVM_SMALL_STRING = UVM_LINE_WIDTH*8-1; parameter UVM_LARGE_STRING = UVM_LINE_WIDTH*UVM_NUM_LINES*8-1; //---------------------------------------------------------------------------- // // Function -- NODOCS -- uvm_string_to_bits // // Converts an input string to its bit-vector equivalent. Max bit-vector // length is approximately 14000 characters. //---------------------------------------------------------------------------- function logic[UVM_LARGE_STRING:0] uvm_string_to_bits(string str); $swrite(uvm_string_to_bits, "%0s", str); endfunction // @uvm-ieee 1800.2-2020 auto F.3.1.1 function uvm_core_state get_core_state(); return m_uvm_core_state; endfunction // Function: uvm_init // Implementation of uvm_init, as defined in section // F.3.1.3 in 1800.2-2020. // // *Note:* The LRM states that subsequent calls to after // the first are silently ignored, however there are scenarios wherein // the implementation breaks this requirement. // // If the core state (see ) is ~UVM_CORE_PRE_INIT~ when , // is called, then the library can not determine the appropriate core service. As // such, the default core service will be constructed and a fatal message // shall be generated. // // If the core state is past ~UVM_CORE_PRE_INIT~, and ~cs~ is a non-null core // service instance different than the value passed to the first call, // then the library will generate a warning message to alert the user that this // call to is being ignored. // // @uvm-contrib This API represents a potential contribution to IEEE 1800.2 // @uvm-ieee 1800.2-2020 auto F.3.1.3 function void uvm_init(uvm_coreservice_t cs=null); uvm_default_coreservice_t dcs; if(get_core_state()!=UVM_CORE_UNINITIALIZED) begin if (get_core_state() == UVM_CORE_PRE_INIT) begin // If we're in this state, something very strange has happened. // We've called uvm_init, and it is actively assigning the // core service, but the core service isn't actually set yet. // This means that either the library messed something up, or // we have a race occurring between two threads. Either way, // this is non-recoverable. We're going to setup using the default // core service, and immediately fatal out. dcs = new(); uvm_coreservice_t::set(dcs); `uvm_fatal("UVM/INIT/MULTI", "Non-recoverable race during uvm_init") end else begin // After PRE_INIT, we can check to see if this is worth reporting // as a warning. We only report it if the value for ~cs~ is _not_ // the current core service, and ~cs~ is not null. uvm_coreservice_t actual; actual = uvm_coreservice_t::get(); if ((cs != actual) && (cs != null)) `uvm_warning("UVM/INIT/MULTI", "uvm_init() called after library has already completed initialization, subsequent calls are ignored!") end return; end m_uvm_core_state=UVM_CORE_PRE_INIT; // We control the implementation of uvm_default_coreservice_t::new // and uvm_coreservice_t::set (which is undocumented). As such, // we guarantee that they will not trigger any calls to uvm_init. if(cs == null) begin dcs = new(); cs = dcs; end uvm_coreservice_t::set(cs); // After this point, it should be safe to query the // corservice for anything. We're not done with // initialization, but the coreservice (and the // various elements it controls) are 'stable'. // // Note that a user could have something silly // in their own space, like a specialization of // uvm_root with a constructor that relies on a // specialization of uvm_factory with a // constructor that relies on the specialized // root being constructed... but there's not // really anything that can be done about that. m_uvm_core_state=UVM_CORE_INITIALIZING; foreach(uvm_deferred_init[idx]) begin uvm_deferred_init[idx].initialize(); end uvm_deferred_init.delete(); begin uvm_root top; top = uvm_root::get(); // These next calls were moved to uvm_init from uvm_root, // because they could emit messages, resulting in the // report server being queried, which causes uvm_init. top.report_header(); top.m_check_uvm_field_flag_size(); // This sets up the global verbosity. Other command line args may // change individual component verbosity. top.m_check_verbosity(); end m_uvm_core_state=UVM_CORE_INITIALIZED; endfunction //---------------------------------------------------------------------------- // // Function -- NODOCS -- uvm_bits_to_string // // Converts an input bit-vector to its string equivalent. Max bit-vector // length is approximately 14000 characters. //---------------------------------------------------------------------------- function string uvm_bits_to_string(logic [UVM_LARGE_STRING:0] str); $swrite(uvm_bits_to_string, "%0s", str); endfunction //---------------------------------------------------------------------------- // // Task: uvm_wait_for_nba_region // // This task will block until SystemVerilog's NBA region (or Re-NBA region if // called from a program context). The purpose is to continue the calling // process only after allowing other processes any number of delta cycles (#0) // to settle out. // // @uvm-accellera The details of this API are specific to the Accellera implementation, and are not being considered for contribution to 1800.2 //---------------------------------------------------------------------------- task uvm_wait_for_nba_region; int nba; int next_nba; //If `included directly in a program block, can't use a non-blocking assign, //but it isn't needed since program blocks are in a separate region. `ifndef UVM_NO_WAIT_FOR_NBA next_nba++; nba <= next_nba; @(nba); `else repeat(`UVM_POUND_ZERO_COUNT) #0; `endif endtask `ifdef UVM_ENABLE_DEPRECATED_API //---------------------------------------------------------------------------- // // Function -- NODOCS -- uvm_split_string // // Returns a queue of strings, ~values~, that is the result of the ~str~ split // based on the ~sep~. For example: // //| uvm_split_string("1,on,false", ",", splits); // // Results in the 'splits' queue containing the three elements: 1, on and // false. //---------------------------------------------------------------------------- function automatic void uvm_split_string (string str, byte sep, ref string values[$]); int s = 0, e = 0; values.delete(); while(e < str.len()) begin for(s=e; e // method which is the logical inverse of the System Verilog ~name~ // method which is built into all enumerations. // @uvm-ieee 1800.2-2020 auto F.3.4.1 class uvm_enum_wrapper#(type T=uvm_active_passive_enum); protected static T map[string]; // @uvm-ieee 1800.2-2020 auto F.3.4.2 static function bit from_name(string name, ref T value); if (map.size() == 0) m_init_map(); if (map.exists(name)) begin value = map[name]; return 1; end else begin return 0; end endfunction : from_name // Function- m_init_map // Initializes the name map, only needs to be performed once protected static function void m_init_map(); T e = e.first(); do begin map[e.name()] = e; e = e.next(); end while (e != e.first()); endfunction : m_init_map // Function- new // Prevents accidental instantiations protected function new(); endfunction : new endclass : uvm_enum_wrapper