URL
https://opencores.org/ocsvn/uart2bus_testbench/uart2bus_testbench/trunk
Subversion Repositories uart2bus_testbench
[/] [uart2bus_testbench/] [trunk/] [tb/] [uvm_src/] [base/] [uvm_component.svh] - Rev 16
Compare with Previous | Blame | View Log
////------------------------------------------------------------------------------// Copyright 2007-2011 Mentor Graphics Corporation// Copyright 2007-2011 Cadence Design Systems, Inc.// Copyright 2010-2011 Synopsys, Inc.// Copyright 2013 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.//------------------------------------------------------------------------------typedef class uvm_objection;typedef class uvm_sequence_base;typedef class uvm_sequence_item;//------------------------------------------------------------------------------//// CLASS: uvm_component//// The uvm_component class is the root base class for UVM components. In// addition to the features inherited from <uvm_object> and <uvm_report_object>,// uvm_component provides the following interfaces://// Hierarchy - provides methods for searching and traversing the component// hierarchy.//// Phasing - defines a phased test flow that all components follow, with a// group of standard phase methods and an API for custom phases and// multiple independent phasing domains to mirror DUT behavior e.g. power//// Reporting - provides a convenience interface to the <uvm_report_handler>. All// messages, warnings, and errors are processed through this interface.//// Transaction recording - provides methods for recording the transactions// produced or consumed by the component to a transaction database (vendor// specific).//// Factory - provides a convenience interface to the <uvm_factory>. The factory// is used to create new components and other objects based on type-wide and// instance-specific configuration.//// The uvm_component is automatically seeded during construction using UVM// seeding, if enabled. All other objects must be manually reseeded, if// appropriate. See <uvm_object::reseed> for more information.////------------------------------------------------------------------------------virtual class uvm_component extends uvm_report_object;// Function: new//// Creates a new component with the given leaf instance ~name~ and handle// to its ~parent~. If the component is a top-level component (i.e. it is// created in a static module or interface), ~parent~ should be ~null~.//// The component will be inserted as a child of the ~parent~ object, if any.// If ~parent~ already has a child by the given ~name~, an error is produced.//// If ~parent~ is ~null~, then the component will become a child of the// implicit top-level component, ~uvm_top~.//// All classes derived from uvm_component must call super.new(name,parent).extern function new (string name, uvm_component parent);//----------------------------------------------------------------------------// Group: Hierarchy Interface//----------------------------------------------------------------------------//// These methods provide user access to information about the component// hierarchy, i.e., topology.////----------------------------------------------------------------------------// Function: get_parent//// Returns a handle to this component's parent, or ~null~ if it has no parent.extern virtual function uvm_component get_parent ();// Function: get_full_name//// Returns the full hierarchical name of this object. The default// implementation concatenates the hierarchical name of the parent, if any,// with the leaf name of this object, as given by <uvm_object::get_name>.extern virtual function string get_full_name ();// Function: get_children//// This function populates the end of the ~children~ array with the// list of this component's children.////| uvm_component array[$];//| my_comp.get_children(array);//| foreach(array[i])//| do_something(array[i]);extern function void get_children(ref uvm_component children[$]);// Function: get_childextern function uvm_component get_child (string name);// Function: get_next_childextern function int get_next_child (ref string name);// Function: get_first_child//// These methods are used to iterate through this component's children, if// any. For example, given a component with an object handle, ~comp~, the// following code calls <uvm_object::print> for each child:////| string name;//| uvm_component child;//| if (comp.get_first_child(name))//| do begin//| child = comp.get_child(name);//| child.print();//| end while (comp.get_next_child(name));extern function int get_first_child (ref string name);// Function: get_num_children//// Returns the number of this component's children.extern function int get_num_children ();// Function: has_child//// Returns 1 if this component has a child with the given ~name~, 0 otherwise.extern function int has_child (string name);// Function - set_name//// Renames this component to ~name~ and recalculates all descendants'// full names. This is an internal function for now.extern virtual function void set_name (string name);// Function: lookup//// Looks for a component with the given hierarchical ~name~ relative to this// component. If the given ~name~ is preceded with a '.' (dot), then the search// begins relative to the top level (absolute lookup). The handle of the// matching component is returned, else ~null~. The name must not contain// wildcards.extern function uvm_component lookup (string name);// Function: get_depth//// Returns the component's depth from the root level. uvm_top has a// depth of 0. The test and any other top level components have a depth// of 1, and so on.extern function int unsigned get_depth();//----------------------------------------------------------------------------// Group: Phasing Interface//----------------------------------------------------------------------------//// These methods implement an interface which allows all components to step// through a standard schedule of phases, or a customized schedule, and// also an API to allow independent phase domains which can jump like state// machines to reflect behavior e.g. power domains on the DUT in different// portions of the testbench. The phase tasks and functions are the phase// name with the _phase suffix. For example, the build phase function is// <build_phase>.//// All processes associated with a task-based phase are killed when the phase// ends. See <uvm_task_phase> for more details.//----------------------------------------------------------------------------// Function: build_phase//// The <uvm_build_phase> phase implementation method.//// Any override should call super.build_phase(phase) to execute the automatic// configuration of fields registered in the component by calling// <apply_config_settings>.// To turn off automatic configuration for a component,// do not call super.build_phase(phase).//// This method should never be called directly.extern virtual function void build_phase(uvm_phase phase);// For backward compatibility the base <build_phase> method calls <build>.extern virtual function void build();// Function: connect_phase//// The <uvm_connect_phase> phase implementation method.//// This method should never be called directly.extern virtual function void connect_phase(uvm_phase phase);// For backward compatibility the base connect_phase method calls connect.extern virtual function void connect();// Function: end_of_elaboration_phase//// The <uvm_end_of_elaboration_phase> phase implementation method.//// This method should never be called directly.extern virtual function void end_of_elaboration_phase(uvm_phase phase);// For backward compatibility the base <end_of_elaboration_phase> method calls <end_of_elaboration>.extern virtual function void end_of_elaboration();// Function: start_of_simulation_phase//// The <uvm_start_of_simulation_phase> phase implementation method.//// This method should never be called directly.extern virtual function void start_of_simulation_phase(uvm_phase phase);// For backward compatibility the base <start_of_simulation_phase> method calls <start_of_simulation>.extern virtual function void start_of_simulation();// Task: run_phase//// The <uvm_run_phase> phase implementation method.//// This task returning or not does not indicate the end// or persistence of this phase.// Thus the phase will automatically// end once all objections are dropped using ~phase.drop_objection()~.//// Any processes forked by this task continue to run// after the task returns,// but they will be killed once the phase ends.//// The run_phase task should never be called directly.extern virtual task run_phase(uvm_phase phase);// For backward compatibility the base <run_phase> method calls <run>.extern virtual task run();// Task: pre_reset_phase//// The <uvm_pre_reset_phase> phase implementation method.//// This task returning or not does not indicate the end// or persistence of this phase.// It is necessary to raise an objection// using ~phase.raise_objection()~ to cause the phase to persist.// Once all components have dropped their respective objection// using ~phase.drop_objection()~, or if no components raises an// objection, the phase is ended.//// Any processes forked by this task continue to run// after the task returns,// but they will be killed once the phase ends.//// This method should not be called directly.extern virtual task pre_reset_phase(uvm_phase phase);// Task: reset_phase//// The <uvm_reset_phase> phase implementation method.//// This task returning or not does not indicate the end// or persistence of this phase.// It is necessary to raise an objection// using ~phase.raise_objection()~ to cause the phase to persist.// Once all components have dropped their respective objection// using ~phase.drop_objection()~, or if no components raises an// objection, the phase is ended.//// Any processes forked by this task continue to run// after the task returns,// but they will be killed once the phase ends.//// This method should not be called directly.extern virtual task reset_phase(uvm_phase phase);// Task: post_reset_phase//// The <uvm_post_reset_phase> phase implementation method.//// This task returning or not does not indicate the end// or persistence of this phase.// It is necessary to raise an objection// using ~phase.raise_objection()~ to cause the phase to persist.// Once all components have dropped their respective objection// using ~phase.drop_objection()~, or if no components raises an// objection, the phase is ended.//// Any processes forked by this task continue to run// after the task returns,// but they will be killed once the phase ends.//// This method should not be called directly.extern virtual task post_reset_phase(uvm_phase phase);// Task: pre_configure_phase//// The <uvm_pre_configure_phase> phase implementation method.//// This task returning or not does not indicate the end// or persistence of this phase.// It is necessary to raise an objection// using ~phase.raise_objection()~ to cause the phase to persist.// Once all components have dropped their respective objection// using ~phase.drop_objection()~, or if no components raises an// objection, the phase is ended.//// Any processes forked by this task continue to run// after the task returns,// but they will be killed once the phase ends.//// This method should not be called directly.extern virtual task pre_configure_phase(uvm_phase phase);// Task: configure_phase//// The <uvm_configure_phase> phase implementation method.//// This task returning or not does not indicate the end// or persistence of this phase.// It is necessary to raise an objection// using ~phase.raise_objection()~ to cause the phase to persist.// Once all components have dropped their respective objection// using ~phase.drop_objection()~, or if no components raises an// objection, the phase is ended.//// Any processes forked by this task continue to run// after the task returns,// but they will be killed once the phase ends.//// This method should not be called directly.extern virtual task configure_phase(uvm_phase phase);// Task: post_configure_phase//// The <uvm_post_configure_phase> phase implementation method.//// This task returning or not does not indicate the end// or persistence of this phase.// It is necessary to raise an objection// using ~phase.raise_objection()~ to cause the phase to persist.// Once all components have dropped their respective objection// using ~phase.drop_objection()~, or if no components raises an// objection, the phase is ended.//// Any processes forked by this task continue to run// after the task returns,// but they will be killed once the phase ends.//// This method should not be called directly.extern virtual task post_configure_phase(uvm_phase phase);// Task: pre_main_phase//// The <uvm_pre_main_phase> phase implementation method.//// This task returning or not does not indicate the end// or persistence of this phase.// It is necessary to raise an objection// using ~phase.raise_objection()~ to cause the phase to persist.// Once all components have dropped their respective objection// using ~phase.drop_objection()~, or if no components raises an// objection, the phase is ended.//// Any processes forked by this task continue to run// after the task returns,// but they will be killed once the phase ends.//// This method should not be called directly.extern virtual task pre_main_phase(uvm_phase phase);// Task: main_phase//// The <uvm_main_phase> phase implementation method.//// This task returning or not does not indicate the end// or persistence of this phase.// It is necessary to raise an objection// using ~phase.raise_objection()~ to cause the phase to persist.// Once all components have dropped their respective objection// using ~phase.drop_objection()~, or if no components raises an// objection, the phase is ended.//// Any processes forked by this task continue to run// after the task returns,// but they will be killed once the phase ends.//// This method should not be called directly.extern virtual task main_phase(uvm_phase phase);// Task: post_main_phase//// The <uvm_post_main_phase> phase implementation method.//// This task returning or not does not indicate the end// or persistence of this phase.// It is necessary to raise an objection// using ~phase.raise_objection()~ to cause the phase to persist.// Once all components have dropped their respective objection// using ~phase.drop_objection()~, or if no components raises an// objection, the phase is ended.//// Any processes forked by this task continue to run// after the task returns,// but they will be killed once the phase ends.//// This method should not be called directly.extern virtual task post_main_phase(uvm_phase phase);// Task: pre_shutdown_phase//// The <uvm_pre_shutdown_phase> phase implementation method.//// This task returning or not does not indicate the end// or persistence of this phase.// It is necessary to raise an objection// using ~phase.raise_objection()~ to cause the phase to persist.// Once all components have dropped their respective objection// using ~phase.drop_objection()~, or if no components raises an// objection, the phase is ended.//// Any processes forked by this task continue to run// after the task returns,// but they will be killed once the phase ends.//// This method should not be called directly.extern virtual task pre_shutdown_phase(uvm_phase phase);// Task: shutdown_phase//// The <uvm_shutdown_phase> phase implementation method.//// This task returning or not does not indicate the end// or persistence of this phase.// It is necessary to raise an objection// using ~phase.raise_objection()~ to cause the phase to persist.// Once all components have dropped their respective objection// using ~phase.drop_objection()~, or if no components raises an// objection, the phase is ended.//// Any processes forked by this task continue to run// after the task returns,// but they will be killed once the phase ends.//// This method should not be called directly.extern virtual task shutdown_phase(uvm_phase phase);// Task: post_shutdown_phase//// The <uvm_post_shutdown_phase> phase implementation method.//// This task returning or not does not indicate the end// or persistence of this phase.// It is necessary to raise an objection// using ~phase.raise_objection()~ to cause the phase to persist.// Once all components have dropped their respective objection// using ~phase.drop_objection()~, or if no components raises an// objection, the phase is ended.//// Any processes forked by this task continue to run// after the task returns,// but they will be killed once the phase ends.//// This method should not be called directly.extern virtual task post_shutdown_phase(uvm_phase phase);// Function: extract_phase//// The <uvm_extract_phase> phase implementation method.//// This method should never be called directly.extern virtual function void extract_phase(uvm_phase phase);// For backward compatibility the base extract_phase method calls extract.extern virtual function void extract();// Function: check_phase//// The <uvm_check_phase> phase implementation method.//// This method should never be called directly.extern virtual function void check_phase(uvm_phase phase);// For backward compatibility the base check_phase method calls check.extern virtual function void check();// Function: report_phase//// The <uvm_report_phase> phase implementation method.//// This method should never be called directly.extern virtual function void report_phase(uvm_phase phase);// For backward compatibility the base report_phase method calls report.extern virtual function void report();// Function: final_phase//// The <uvm_final_phase> phase implementation method.//// This method should never be called directly.extern virtual function void final_phase(uvm_phase phase);// Function: phase_started//// Invoked at the start of each phase. The ~phase~ argument specifies// the phase being started. Any threads spawned in this callback are// not affected when the phase ends.extern virtual function void phase_started (uvm_phase phase);// Function: phase_ready_to_end//// Invoked when all objections to ending the given ~phase~ and all// sibling phases have been dropped, thus indicating that ~phase~ is// ready to begin a clean exit. Sibling phases are any phases that// have a common successor phase in the schedule plus any phases that// sync'd to the current phase. Components needing to consume delta// cycles or advance time to perform a clean exit from the phase// may raise the phase's objection.//// |phase.raise_objection(this,"Reason");//// It is the responsibility of this component to drop the objection// once it is ready for this phase to end (and processes killed).// If no objection to the given ~phase~ or sibling phases are raised,// then phase_ended() is called after a delta cycle. If any objection// is raised, then when all objections to ending the given ~phase~// and siblings are dropped, another iteration of phase_ready_to_end// is called. To prevent endless iterations due to coding error,// after 20 iterations, phase_ended() is called regardless of whether// previous iteration had any objections raised.extern virtual function void phase_ready_to_end (uvm_phase phase);// Function: phase_ended//// Invoked at the end of each phase. The ~phase~ argument specifies// the phase that is ending. Any threads spawned in this callback are// not affected when the phase ends.extern virtual function void phase_ended (uvm_phase phase);//--------------------------------------------------------------------// phase / schedule / domain API//--------------------------------------------------------------------// Function: set_domain//// Apply a phase domain to this component and, if ~hier~ is set,// recursively to all its children.//// Calls the virtual <define_domain> method, which derived components can// override to augment or replace the domain definition of its base class.//extern function void set_domain(uvm_domain domain, int hier=1);// Function: get_domain//// Return handle to the phase domain set on this componentextern function uvm_domain get_domain();// Function: define_domain//// Builds custom phase schedules into the provided ~domain~ handle.//// This method is called by <set_domain>, which integrators use to specify// this component belongs in a domain apart from the default 'uvm' domain.//// Custom component base classes requiring a custom phasing schedule can// augment or replace the domain definition they inherit by overriding// their ~defined_domain~. To augment, overrides would call super.define_domain().// To replace, overrides would not call super.define_domain().//// The default implementation adds a copy of the ~uvm~ phasing schedule to// the given ~domain~, if one doesn't already exist, and only if the domain// is currently empty.//// Calling <set_domain>// with the default ~uvm~ domain (i.e. <uvm_domain::get_uvm_domain> ) on// a component with no ~define_domain~ override effectively reverts the// that component to using the default ~uvm~ domain. This may be useful// if a branch of the testbench hierarchy defines a custom domain, but// some child sub-branch should remain in the default ~uvm~ domain,// call <set_domain> with a new domain instance handle with ~hier~ set.// Then, in the sub-branch, call <set_domain> with the default ~uvm~ domain handle,// obtained via <uvm_domain::get_uvm_domain>.//// Alternatively, the integrator may define the graph in a new domain externally,// then call <set_domain> to apply it to a component.extern virtual protected function void define_domain(uvm_domain domain);// Function: set_phase_imp//// Override the default implementation for a phase on this component (tree) with a// custom one, which must be created as a singleton object extending the default// one and implementing required behavior in exec and traverse methods//// The ~hier~ specifies whether to apply the custom functor to the whole tree or// just this component.extern function void set_phase_imp(uvm_phase phase, uvm_phase imp, int hier=1);// Task: suspend//// Suspend this component.//// This method must be implemented by the user to suspend the// component according to the protocol and functionality it implements.// A suspended component can be subsequently resumed using <resume()>.extern virtual task suspend ();// Task: resume//// Resume this component.//// This method must be implemented by the user to resume a component// that was previously suspended using <suspend()>.// Some component may start in the suspended state and// may need to be explicitly resumed.extern virtual task resume ();`ifndef UVM_NO_DEPRECATED// Function- status - DEPRECATED//// Returns the status of this component.//// Returns a string that describes the current status of the// components. Possible values include, but are not limited to//// "<unknown>" - Status is unknown (default)// "FINISHED" - Component has stopped on its own accord. May be resumed.// "RUNNING" - Component is running.// May be suspended after normal completion// of operation in progress.// "WAITING" - Component is waiting. May be suspended immediately.// "SUSPENDED" - Component is suspended. May be resumed.// "KILLED" - Component has been killed and is unable to operate// any further. It cannot be resumed.extern function string status ();// Function- kill - DEPRECATED//// Kills the process tree associated with this component's currently running// task-based phase, e.g., run.extern virtual function void kill ();// Function- do_kill_all - DEPRECATED//// Recursively calls <kill> on this component and all its descendants,// which abruptly ends the currently running task-based phase, e.g., run.// See <run_phase> for better options to ending a task-based phase.extern virtual function void do_kill_all ();// Task- stop_phase -- DEPRECATED//// The stop_phase task is called when this component's <enable_stop_interrupt>// bit is set and <global_stop_request> is called during a task-based phase,// e.g., run.//// Before a phase is abruptly ended, e.g., when a test deems the simulation// complete, some components may need extra time to shut down cleanly. Such// components may implement stop_phase to finish the currently executing// transaction, flush the queue, or perform other cleanup. Upon return from// stop_phase, a component signals it is ready to be stopped.//// The ~stop_phase~ method will not be called if <enable_stop_interrupt> is 0.//// The default implementation is empty, i.e., it will return immediately.//// This method should never be called directly.extern virtual task stop_phase(uvm_phase phase);// backward compatextern virtual task stop (string ph_name);// Variable- enable_stop_interrupt - DEPRECATED//// This bit allows a component to raise an objection to the stopping of the// current phase. It affects only time consuming phases (such as the run// phase).//// When this bit is set, the <stop> task in the component is called as a result// of a call to <global_stop_request>. Components that are sensitive to an// immediate killing of its run-time processes should set this bit and// implement the stop task to prepare for shutdown.int enable_stop_interrupt;`endif// Function: resolve_bindings//// Processes all port, export, and imp connections. Checks whether each port's// min and max connection requirements are met.//// It is called just before the end_of_elaboration phase.//// Users should not call directly.extern virtual function void resolve_bindings ();extern function string massage_scope(string scope);//----------------------------------------------------------------------------// Group: Configuration Interface//----------------------------------------------------------------------------//// Components can be designed to be user-configurable in terms of its// topology (the type and number of children it has), mode of operation, and// run-time parameters (knobs). The configuration interface accommodates// this common need, allowing component composition and state to be modified// without having to derive new classes or new class hierarchies for// every configuration scenario.////----------------------------------------------------------------------------`ifndef UVM_NO_DEPRECATEDstatic bit m_config_deprecated_warned;// Used for caching config settingsstatic bit m_config_set = 1;// Function- set_config_intextern virtual function void set_config_int (string inst_name,string field_name,uvm_bitstream_t value);// Function- set_config_stringextern virtual function void set_config_string (string inst_name,string field_name,string value);// Function- set_config_object//// Calling set_config_* causes configuration settings to be created and// placed in a table internal to this component. There are similar global// methods that store settings in a global table. Each setting stores the// supplied ~inst_name~, ~field_name~, and ~value~ for later use by descendent// components during their construction. (The global table applies to// all components and takes precedence over the component tables.)//// When a descendant component calls a get_config_* method, the ~inst_name~// and ~field_name~ provided in the get call are matched against all the// configuration settings stored in the global table and then in each// component in the parent hierarchy, top-down. Upon the first match, the// value stored in the configuration setting is returned. Thus, precedence is// global, following by the top-level component, and so on down to the// descendent component's parent.//// These methods work in conjunction with the get_config_* methods to// provide a configuration setting mechanism for integral, string, and// uvm_object-based types. Settings of other types, such as virtual interfaces// and arrays, can be indirectly supported by defining a class that contains// them.//// Both ~inst_name~ and ~field_name~ may contain wildcards.//// - For set_config_int, ~value~ is an integral value that can be anything// from 1 bit to 4096 bits.//// - For set_config_string, ~value~ is a string.//// - For set_config_object, ~value~ must be an <uvm_object>-based object or// ~null~. Its clone argument specifies whether the object should be cloned.// If set, the object is cloned both going into the table (during the set)// and coming out of the table (during the get), so that multiple components// matched to the same setting (by way of wildcards) do not end up sharing// the same object.////// See <get_config_int>, <get_config_string>, and <get_config_object> for// information on getting the configurations set by these methods.extern virtual function void set_config_object (string inst_name,string field_name,uvm_object value,bit clone=1);// Function- get_config_intextern virtual function bit get_config_int (string field_name,inout uvm_bitstream_t value);// Function- get_config_stringextern virtual function bit get_config_string (string field_name,inout string value);// Function- get_config_object//// These methods retrieve configuration settings made by previous calls to// their set_config_* counterparts. As the methods' names suggest, there is// direct support for integral types, strings, and objects. Settings of other// types can be indirectly supported by defining an object to contain them.//// Configuration settings are stored in a global table and in each component// instance. With each call to a get_config_* method, a top-down search is// made for a setting that matches this component's full name and the given// ~field_name~. For example, say this component's full instance name is// top.u1.u2. First, the global configuration table is searched. If that// fails, then it searches the configuration table in component 'top',// followed by top.u1.//// The first instance/field that matches causes ~value~ to be written with the// value of the configuration setting and 1 is returned. If no match// is found, then ~value~ is unchanged and the 0 returned.//// Calling the get_config_object method requires special handling. Because// ~value~ is an output of type <uvm_object>, you must provide a uvm_object// handle to assign to (_not_ a derived class handle). After the call, you can// then $cast to the actual type.//// For example, the following code illustrates how a component designer might// call upon the configuration mechanism to assign its ~data~ object property,// whose type myobj_t derives from uvm_object.////| class mycomponent extends uvm_component;//|//| local myobj_t data;//|//| function void build_phase(uvm_phase phase);//| uvm_object tmp;//| super.build_phase(phase);//| if(get_config_object("data", tmp))//| if (!$cast(data, tmp))//| `uvm_error("CFGERR","error! config setting for 'data' not of type myobj_t")//| endfunction//| ...//// The above example overrides the <build_phase> method. If you want to retain// any base functionality, you must call super.build_phase(uvm_phase phase).//// The ~clone~ bit clones the data inbound. The get_config_object method can// also clone the data outbound.//// See Members for information on setting the global configuration table.extern virtual function bit get_config_object (string field_name,inout uvm_object value,input bit clone=1);`endif// Function: check_config_usage//// Check all configuration settings in a components configuration table// to determine if the setting has been used, overridden or not used.// When ~recurse~ is 1 (default), configuration for this and all child// components are recursively checked. This function is automatically// called in the check phase, but can be manually called at any time.//// To get all configuration information prior to the run phase, do something// like this in your top object://| function void start_of_simulation_phase(uvm_phase phase);//| check_config_usage();//| endfunctionextern function void check_config_usage (bit recurse=1);// Function: apply_config_settings//// Searches for all config settings matching this component's instance path.// For each match, the appropriate set_*_local method is called using the// matching config setting's field_name and value. Provided the set_*_local// method is implemented, the component property associated with the// field_name is assigned the given value.//// This function is called by <uvm_component::build_phase>.//// The apply_config_settings method determines all the configuration// settings targeting this component and calls the appropriate set_*_local// method to set each one. To work, you must override one or more set_*_local// methods to accommodate setting of your component's specific properties.// Any properties registered with the optional `uvm_*_field macros do not// require special handling by the set_*_local methods; the macros provide// the set_*_local functionality for you.//// If you do not want apply_config_settings to be called for a component,// then the build_phase() method should be overloaded and you should not call// super.build_phase(phase). Likewise, apply_config_settings can be overloaded to// customize automated configuration.//// When the ~verbose~ bit is set, all overrides are printed as they are// applied. If the component's <print_config_matches> property is set, then// apply_config_settings is automatically called with ~verbose~ = 1.extern virtual function void apply_config_settings (bit verbose = 0);// Function: print_config_settings//// Called without arguments, print_config_settings prints all configuration// information for this component, as set by previous calls to <uvm_config_db::set()>.// The settings are printing in the order of their precedence.//// If ~field~ is specified and non-empty, then only configuration settings// matching that field, if any, are printed. The field may not contain// wildcards.//// If ~comp~ is specified and non-~null~, then the configuration for that// component is printed.//// If ~recurse~ is set, then configuration information for all ~comp~'s// children and below are printed as well.//// This function has been deprecated. Use print_config instead.extern function void print_config_settings (string field="",uvm_component comp=null,bit recurse=0);// Function: print_config//// Print_config_settings prints all configuration information for this// component, as set by previous calls to <uvm_config_db::set()> and exports to// the resources pool. The settings are printing in the order of// their precedence.//// If ~recurse~ is set, then configuration information for all// children and below are printed as well.//// if ~audit~ is set then the audit trail for each resource is printed// along with the resource name and valueextern function void print_config(bit recurse = 0, bit audit = 0);// Function: print_config_with_audit//// Operates the same as print_config except that the audit bit is// forced to 1. This interface makes user code a bit more readable as// it avoids multiple arbitrary bit settings in the argument list.//// If ~recurse~ is set, then configuration information for all// children and below are printed as well.extern function void print_config_with_audit(bit recurse = 0);// Variable: print_config_matches//// Setting this static variable causes uvm_config_db::get() to print info about// matching configuration settings as they are being applied.static bit print_config_matches;//----------------------------------------------------------------------------// Group: Objection Interface//----------------------------------------------------------------------------//// These methods provide object level hooks into the <uvm_objection>// mechanism.////----------------------------------------------------------------------------// Function: raised//// The ~raised~ callback is called when this or a descendant of this component// instance raises the specified ~objection~. The ~source_obj~ is the object// that originally raised the objection.// The ~description~ is optionally provided by the ~source_obj~ to give a// reason for raising the objection. The ~count~ indicates the number of// objections raised by the ~source_obj~.virtual function void raised (uvm_objection objection, uvm_object source_obj,string description, int count);endfunction// Function: dropped//// The ~dropped~ callback is called when this or a descendant of this component// instance drops the specified ~objection~. The ~source_obj~ is the object// that originally dropped the objection.// The ~description~ is optionally provided by the ~source_obj~ to give a// reason for dropping the objection. The ~count~ indicates the number of// objections dropped by the ~source_obj~.virtual function void dropped (uvm_objection objection, uvm_object source_obj,string description, int count);endfunction// Task: all_dropped//// The ~all_droppped~ callback is called when all objections have been// dropped by this component and all its descendants. The ~source_obj~ is the// object that dropped the last objection.// The ~description~ is optionally provided by the ~source_obj~ to give a// reason for raising the objection. The ~count~ indicates the number of// objections dropped by the ~source_obj~.virtual task all_dropped (uvm_objection objection, uvm_object source_obj,string description, int count);endtask//----------------------------------------------------------------------------// Group: Factory Interface//----------------------------------------------------------------------------//// The factory interface provides convenient access to a portion of UVM's// <uvm_factory> interface. For creating new objects and components, the// preferred method of accessing the factory is via the object or component// wrapper (see <uvm_component_registry #(T,Tname)> and// <uvm_object_registry #(T,Tname)>). The wrapper also provides functions// for setting type and instance overrides.////----------------------------------------------------------------------------// Function: create_component//// A convenience function for <uvm_factory::create_component_by_name>,// this method calls upon the factory to create a new child component// whose type corresponds to the preregistered type name, ~requested_type_name~,// and instance name, ~name~. This method is equivalent to:////| factory.create_component_by_name(requested_type_name,//| get_full_name(), name, this);//// If the factory determines that a type or instance override exists, the type// of the component created may be different than the requested type. See// <set_type_override> and <set_inst_override>. See also <uvm_factory> for// details on factory operation.extern function uvm_component create_component (string requested_type_name,string name);// Function: create_object//// A convenience function for <uvm_factory::create_object_by_name>,// this method calls upon the factory to create a new object// whose type corresponds to the preregistered type name,// ~requested_type_name~, and instance name, ~name~. This method is// equivalent to:////| factory.create_object_by_name(requested_type_name,//| get_full_name(), name);//// If the factory determines that a type or instance override exists, the// type of the object created may be different than the requested type. See// <uvm_factory> for details on factory operation.extern function uvm_object create_object (string requested_type_name,string name="");// Function: set_type_override_by_type//// A convenience function for <uvm_factory::set_type_override_by_type>, this// method registers a factory override for components and objects created at// this level of hierarchy or below. This method is equivalent to:////| factory.set_type_override_by_type(original_type, override_type,replace);//// The ~relative_inst_path~ is relative to this component and may include// wildcards. The ~original_type~ represents the type that is being overridden.// In subsequent calls to <uvm_factory::create_object_by_type> or// <uvm_factory::create_component_by_type>, if the requested_type matches the// ~original_type~ and the instance paths match, the factory will produce// the ~override_type~.//// The original and override type arguments are lightweight proxies to the// types they represent. See <set_inst_override_by_type> for information// on usage.extern static function void set_type_override_by_type(uvm_object_wrapper original_type,uvm_object_wrapper override_type,bit replace=1);// Function: set_inst_override_by_type//// A convenience function for <uvm_factory::set_inst_override_by_type>, this// method registers a factory override for components and objects created at// this level of hierarchy or below. In typical usage, this method is// equivalent to:////| factory.set_inst_override_by_type( original_type,//| override_type,//| {get_full_name(),".",//| relative_inst_path});//// The ~relative_inst_path~ is relative to this component and may include// wildcards. The ~original_type~ represents the type that is being overridden.// In subsequent calls to <uvm_factory::create_object_by_type> or// <uvm_factory::create_component_by_type>, if the requested_type matches the// ~original_type~ and the instance paths match, the factory will produce the// ~override_type~.//// The original and override types are lightweight proxies to the types they// represent. They can be obtained by calling ~type::get_type()~, if// implemented by ~type~, or by directly calling ~type::type_id::get()~, where// ~type~ is the user type and ~type_id~ is the name of the typedef to// <uvm_object_registry #(T,Tname)> or <uvm_component_registry #(T,Tname)>.//// If you are employing the `uvm_*_utils macros, the typedef and the get_type// method will be implemented for you. For details on the utils macros// refer to <Utility and Field Macros for Components and Objects>.//// The following example shows `uvm_*_utils usage:////| class comp extends uvm_component;//| `uvm_component_utils(comp)//| ...//| endclass//|//| class mycomp extends uvm_component;//| `uvm_component_utils(mycomp)//| ...//| endclass//|//| class block extends uvm_component;//| `uvm_component_utils(block)//| comp c_inst;//| virtual function void build_phase(uvm_phase phase);//| set_inst_override_by_type("c_inst",comp::get_type(),//| mycomp::get_type());//| endfunction//| ...//| endclassextern function void set_inst_override_by_type(string relative_inst_path,uvm_object_wrapper original_type,uvm_object_wrapper override_type);// Function: set_type_override//// A convenience function for <uvm_factory::set_type_override_by_name>,// this method configures the factory to create an object of type// ~override_type_name~ whenever the factory is asked to produce a type// represented by ~original_type_name~. This method is equivalent to:////| factory.set_type_override_by_name(original_type_name,//| override_type_name, replace);//// The ~original_type_name~ typically refers to a preregistered type in the// factory. It may, however, be any arbitrary string. Subsequent calls to// create_component or create_object with the same string and matching// instance path will produce the type represented by override_type_name.// The ~override_type_name~ must refer to a preregistered type in the factory.extern static function void set_type_override(string original_type_name,string override_type_name,bit replace=1);// Function: set_inst_override//// A convenience function for <uvm_factory::set_inst_override_by_name>, this// method registers a factory override for components created at this level// of hierarchy or below. In typical usage, this method is equivalent to:////| factory.set_inst_override_by_name(original_type_name,//| override_type_name,//| {get_full_name(),".",//| relative_inst_path}//| );//// The ~relative_inst_path~ is relative to this component and may include// wildcards. The ~original_type_name~ typically refers to a preregistered type// in the factory. It may, however, be any arbitrary string. Subsequent calls// to create_component or create_object with the same string and matching// instance path will produce the type represented by ~override_type_name~.// The ~override_type_name~ must refer to a preregistered type in the factory.extern function void set_inst_override(string relative_inst_path,string original_type_name,string override_type_name);// Function: print_override_info//// This factory debug method performs the same lookup process as create_object// and create_component, but instead of creating an object, it prints// information about what type of object would be created given the// provided arguments.extern function void print_override_info(string requested_type_name,string name="");//----------------------------------------------------------------------------// Group: Hierarchical Reporting Interface//----------------------------------------------------------------------------//// This interface provides versions of the set_report_* methods in the// <uvm_report_object> base class that are applied recursively to this// component and all its children.//// When a report is issued and its associated action has the LOG bit set, the// report will be sent to its associated FILE descriptor.//----------------------------------------------------------------------------// Function: set_report_id_verbosity_hierextern function void set_report_id_verbosity_hier (string id,int verbosity);// Function: set_report_severity_id_verbosity_hier//// These methods recursively associate the specified verbosity with reports of// the given ~severity~, ~id~, or ~severity-id~ pair. A verbosity associated// with a particular severity-id pair takes precedence over a verbosity// associated with id, which takes precedence over a verbosity associated// with a severity.//// For a list of severities and their default verbosities, refer to// <uvm_report_handler>.extern function void set_report_severity_id_verbosity_hier(uvm_severity severity,string id,int verbosity);// Function: set_report_severity_action_hierextern function void set_report_severity_action_hier (uvm_severity severity,uvm_action action);// Function: set_report_id_action_hierextern function void set_report_id_action_hier (string id,uvm_action action);// Function: set_report_severity_id_action_hier//// These methods recursively associate the specified action with reports of// the given ~severity~, ~id~, or ~severity-id~ pair. An action associated// with a particular severity-id pair takes precedence over an action// associated with id, which takes precedence over an action associated// with a severity.//// For a list of severities and their default actions, refer to// <uvm_report_handler>.extern function void set_report_severity_id_action_hier(uvm_severity severity,string id,uvm_action action);// Function: set_report_default_file_hierextern function void set_report_default_file_hier (UVM_FILE file);// Function: set_report_severity_file_hierextern function void set_report_severity_file_hier (uvm_severity severity,UVM_FILE file);// Function: set_report_id_file_hierextern function void set_report_id_file_hier (string id,UVM_FILE file);// Function: set_report_severity_id_file_hier//// These methods recursively associate the specified FILE descriptor with// reports of the given ~severity~, ~id~, or ~severity-id~ pair. A FILE// associated with a particular severity-id pair takes precedence over a FILE// associated with id, which take precedence over an a FILE associated with a// severity, which takes precedence over the default FILE descriptor.//// For a list of severities and other information related to the report// mechanism, refer to <uvm_report_handler>.extern function void set_report_severity_id_file_hier(uvm_severity severity,string id,UVM_FILE file);// Function: set_report_verbosity_level_hier//// This method recursively sets the maximum verbosity level for reports for// this component and all those below it. Any report from this component// subtree whose verbosity exceeds this maximum will be ignored.//// See <uvm_report_handler> for a list of predefined message verbosity levels// and their meaning.extern function void set_report_verbosity_level_hier (int verbosity);// Function: pre_abort//// This callback is executed when the message system is executing a// <UVM_EXIT> action. The exit action causes an immediate termination of// the simulation, but the pre_abort callback hook gives components an// opportunity to provide additional information to the user before// the termination happens. For example, a test may want to executed// the report function of a particular component even when an error// condition has happened to force a premature termination you would// write a function like:////| function void mycomponent::pre_abort();//| report();//| endfunction//// The pre_abort() callback hooks are called in a bottom-up fashion.virtual function void pre_abort;endfunction//----------------------------------------------------------------------------// Group: Recording Interface//----------------------------------------------------------------------------// These methods comprise the component-based transaction recording// interface. The methods can be used to record the transactions that// this component "sees", i.e. produces or consumes.//// The API and implementation are subject to change once a vendor-independent// use-model is determined.//----------------------------------------------------------------------------// Function: accept_tr//// This function marks the acceptance of a transaction, ~tr~, by this// component. Specifically, it performs the following actions://// - Calls the ~tr~'s <uvm_transaction::accept_tr> method, passing to it the// ~accept_time~ argument.//// - Calls this component's <do_accept_tr> method to allow for any post-begin// action in derived classes.//// - Triggers the component's internal accept_tr event. Any processes waiting// on this event will resume in the next delta cycle.extern function void accept_tr (uvm_transaction tr, time accept_time = 0);// Function: do_accept_tr//// The <accept_tr> method calls this function to accommodate any user-defined// post-accept action. Implementations should call super.do_accept_tr to// ensure correct operation.extern virtual protected function void do_accept_tr (uvm_transaction tr);// Function: begin_tr//// This function marks the start of a transaction, ~tr~, by this component.// Specifically, it performs the following actions://// - Calls ~tr~'s <uvm_transaction::begin_tr> method, passing to it the// ~begin_time~ argument. The ~begin_time~ should be greater than or equal// to the accept time. By default, when ~begin_time~ = 0, the current// simulation time is used.//// If recording is enabled (recording_detail != UVM_OFF), then a new// database-transaction is started on the component's transaction stream// given by the stream argument. No transaction properties are recorded at// this time.//// - Calls the component's <do_begin_tr> method to allow for any post-begin// action in derived classes.//// - Triggers the component's internal begin_tr event. Any processes waiting// on this event will resume in the next delta cycle.//// A handle to the transaction is returned. The meaning of this handle, as// well as the interpretation of the arguments ~stream_name~, ~label~, and// ~desc~ are vendor specific.extern function integer begin_tr (uvm_transaction tr,string stream_name="main",string label="",string desc="",time begin_time=0,integer parent_handle=0);// Function: begin_child_tr//// This function marks the start of a child transaction, ~tr~, by this// component. Its operation is identical to that of <begin_tr>, except that// an association is made between this transaction and the provided parent// transaction. This association is vendor-specific.extern function integer begin_child_tr (uvm_transaction tr,integer parent_handle=0,string stream_name="main",string label="",string desc="",time begin_time=0);// Function: do_begin_tr//// The <begin_tr> and <begin_child_tr> methods call this function to// accommodate any user-defined post-begin action. Implementations should call// super.do_begin_tr to ensure correct operation.extern virtual protectedfunction void do_begin_tr (uvm_transaction tr,string stream_name,integer tr_handle);// Function: end_tr//// This function marks the end of a transaction, ~tr~, by this component.// Specifically, it performs the following actions://// - Calls ~tr~'s <uvm_transaction::end_tr> method, passing to it the// ~end_time~ argument. The ~end_time~ must at least be greater than the// begin time. By default, when ~end_time~ = 0, the current simulation time// is used.//// The transaction's properties are recorded to the database-transaction on// which it was started, and then the transaction is ended. Only those// properties handled by the transaction's do_record method (and optional// `uvm_*_field macros) are recorded.//// - Calls the component's <do_end_tr> method to accommodate any post-end// action in derived classes.//// - Triggers the component's internal end_tr event. Any processes waiting on// this event will resume in the next delta cycle.//// The ~free_handle~ bit indicates that this transaction is no longer needed.// The implementation of free_handle is vendor-specific.extern function void end_tr (uvm_transaction tr,time end_time=0,bit free_handle=1);// Function: do_end_tr//// The <end_tr> method calls this function to accommodate any user-defined// post-end action. Implementations should call super.do_end_tr to ensure// correct operation.extern virtual protected function void do_end_tr (uvm_transaction tr,integer tr_handle);// Function: record_error_tr//// This function marks an error transaction by a component. Properties of the// given uvm_object, ~info~, as implemented in its <uvm_object::do_record> method,// are recorded to the transaction database.//// An ~error_time~ of 0 indicates to use the current simulation time. The// ~keep_active~ bit determines if the handle should remain active. If 0,// then a zero-length error transaction is recorded. A handle to the// database-transaction is returned.//// Interpretation of this handle, as well as the strings ~stream_name~,// ~label~, and ~desc~, are vendor-specific.extern function integer record_error_tr (string stream_name="main",uvm_object info=null,string label="error_tr",string desc="",time error_time=0,bit keep_active=0);// Function: record_event_tr//// This function marks an event transaction by a component.//// An ~event_time~ of 0 indicates to use the current simulation time.//// A handle to the transaction is returned. The ~keep_active~ bit determines// if the handle may be used for other vendor-specific purposes.//// The strings for ~stream_name~, ~label~, and ~desc~ are vendor-specific// identifiers for the transaction.extern function integer record_event_tr (string stream_name="main",uvm_object info=null,string label="event_tr",string desc="",time event_time=0,bit keep_active=0);// Function: get_tr_stream// Returns a tr stream with ~this~ component's full name as a scope.//// Streams which are retrieved via this method will be stored internally,// such that later calls to ~get_tr_stream~ will return the same stream// reference.//// The stream can be removed from the internal storage via a call// to <free_tr_stream>.//// Parameters:// name - Name for the stream// stream_type_name - Type name for the stream (Default = "")extern virtual function uvm_tr_stream get_tr_stream(string name,string stream_type_name="");// Function: free_tr_stream// Frees the internal references associated with ~stream~.//// The next call to <get_tr_stream> will result in a newly created// <uvm_tr_stream>. If the current stream is open (or closed),// then it will be freed.extern virtual function void free_tr_stream(uvm_tr_stream stream);// Variable: print_enabled//// This bit determines if this component should automatically be printed as a// child of its parent object.//// By default, all children are printed. However, this bit allows a parent// component to disable the printing of specific children.bit print_enabled = 1;// Variable: tr_database//// Specifies the <uvm_tr_database> object to use for <begin_tr>// and other methods in the <Recording Interface>.// Default is <uvm_coreservice_t::get_default_tr_database>.uvm_tr_database tr_database;extern virtual function uvm_tr_database m_get_tr_database();//----------------------------------------------------------------------------// PRIVATE or PSUEDO-PRIVATE members// *** Do not call directly ***// Implementation and even existence are subject to change.//----------------------------------------------------------------------------// Most local methods are prefixed with m_, indicating they are not// user-level methods. SystemVerilog does not support friend classes,// which forces some otherwise internal methods to be exposed (i.e. not// be protected via 'local' keyword). These methods are also prefixed// with m_ to indicate they are not intended for public use.//// Internal methods will not be documented, although their implementa-// tions are freely available via the open-source license.//----------------------------------------------------------------------------protected uvm_domain m_domain; // set_domain stores our domain handle/*protected*/ uvm_phase m_phase_imps[uvm_phase]; // functors to override ovm_root defaults//TND review protected, provide read-only accessor.uvm_phase m_current_phase; // the most recently executed phaseprotected process m_phase_process;/*protected*/ bit m_build_done;/*protected*/ int m_phasing_active;extern function void set_int_local(string field_name,uvm_bitstream_t value,bit recurse=1);/*protected*/ uvm_component m_parent;protected uvm_component m_children[string];protected uvm_component m_children_by_handle[uvm_component];extern protected virtual function bit m_add_child(uvm_component child);extern local virtual function void m_set_full_name();extern function void do_resolve_bindings();extern function void do_flush();extern virtual function void flush ();extern local function void m_extract_name(string name ,output string leaf ,output string remainder );// overridden to disableextern virtual function uvm_object create (string name="");extern virtual function uvm_object clone ();local uvm_tr_stream m_main_stream;local uvm_tr_stream m_streams[string][string];local uvm_recorder m_tr_h[uvm_transaction];extern protected function integer m_begin_tr (uvm_transaction tr,integer parent_handle=0,string stream_name="main", string label="",string desc="", time begin_time=0);string m_name;const static string type_name = "uvm_component";virtual function string get_type_name();return type_name;endfunctionprotected uvm_event_pool event_pool;int unsigned recording_detail = UVM_NONE;extern function void do_print(uvm_printer printer);// Internal methods for setting up command line messaging stuffextern function void m_set_cl_msg_args;extern function void m_set_cl_verb;extern function void m_set_cl_action;extern function void m_set_cl_sev;extern function void m_apply_verbosity_settings(uvm_phase phase);// The verbosity settings may have a specific phase to start at.// We will do this work in the phase_started callback.typedef struct {string comp;string phase;time offset;uvm_verbosity verbosity;string id;} m_verbosity_setting;m_verbosity_setting m_verbosity_settings[$];static m_verbosity_setting m_time_settings[$];// does the pre abort callback hierarchicallyextern /*local*/ function void m_do_pre_abort;typedef struct {string arg;string args[$];int unsigned used;} uvm_cmdline_parsed_arg_t;static uvm_cmdline_parsed_arg_t m_uvm_applied_cl_action[$];static uvm_cmdline_parsed_arg_t m_uvm_applied_cl_sev[$];endclass : uvm_component`include "base/uvm_root.svh"//------------------------------------------------------------------------------// IMPLEMENTATION//------------------------------------------------------------------------------//------------------------------------------------------------------------------//// CLASS- uvm_component////------------------------------------------------------------------------------// new// ---function uvm_component::new (string name, uvm_component parent);string error_str;uvm_root top;uvm_coreservice_t cs;super.new(name);// If uvm_top, reset name to "" so it doesn't show in full paths then returnif (parent==null && name == "__top__") beginset_name(""); // *** VIRTUALreturn;endcs = uvm_coreservice_t::get();top = cs.get_root();// Check that we're not in or past end_of_elaborationbeginuvm_phase bld;uvm_domain common;common = uvm_domain::get_common_domain();bld = common.find(uvm_build_phase::get());if (bld == null)uvm_report_fatal("COMP/INTERNAL","attempt to find build phase object failed",UVM_NONE);if (bld.get_state() == UVM_PHASE_DONE) beginuvm_report_fatal("ILLCRT", {"It is illegal to create a component ('",name,"' under '",(parent == null ? top.get_full_name() : parent.get_full_name()),"') after the build phase has ended."},UVM_NONE);endendif (name == "") beginname.itoa(m_inst_count);name = {"COMP_", name};endif(parent == this) begin`uvm_fatal("THISPARENT", "cannot set the parent of a component to itself")endif (parent == null)parent = top;if(uvm_report_enabled(UVM_MEDIUM+1, UVM_INFO, "NEWCOMP"))`uvm_info("NEWCOMP", {"Creating ",(parent==top?"uvm_top":parent.get_full_name()),".",name},UVM_MEDIUM+1)if (parent.has_child(name) && this != parent.get_child(name)) beginif (parent == top) beginerror_str = {"Name '",name,"' is not unique to other top-level ","instances. If parent is a module, build a unique name by combining the ","the module name and component name: $sformatf(\"\%m.\%s\",\"",name,"\")."};`uvm_fatal("CLDEXT",error_str)endelse`uvm_fatal("CLDEXT",$sformatf("Cannot set '%s' as a child of '%s', %s",name, parent.get_full_name(),"which already has a child by that name."))return;endm_parent = parent;set_name(name); // *** VIRTUALif (!m_parent.m_add_child(this))m_parent = null;event_pool = new("event_pool");m_domain = parent.m_domain; // by default, inherit domains from parents// Now that inst name is established, reseed (if use_uvm_seeding is set)reseed();// Do local configuration settingsif (!uvm_config_db #(uvm_bitstream_t)::get(this, "", "recording_detail", recording_detail))void'(uvm_config_db #(int)::get(this, "", "recording_detail", recording_detail));m_rh.set_name(get_full_name());set_report_verbosity_level(parent.get_report_verbosity_level());m_set_cl_msg_args();endfunction// m_add_child// -----------function bit uvm_component::m_add_child(uvm_component child);if (m_children.exists(child.get_name()) &&m_children[child.get_name()] != child) begin`uvm_warning("BDCLD",$sformatf("A child with the name '%0s' (type=%0s) already exists.",child.get_name(), m_children[child.get_name()].get_type_name()))return 0;endif (m_children_by_handle.exists(child)) begin`uvm_warning("BDCHLD",$sformatf("A child with the name '%0s' %0s %0s'",child.get_name(),"already exists in parent under name '",m_children_by_handle[child].get_name()))return 0;endm_children[child.get_name()] = child;m_children_by_handle[child] = child;return 1;endfunction//------------------------------------------------------------------------------//// Hierarchy Methods////------------------------------------------------------------------------------// get_children// ------------function void uvm_component::get_children(ref uvm_component children[$]);foreach(m_children[i])children.push_back(m_children[i]);endfunction// get_first_child// ---------------function int uvm_component::get_first_child(ref string name);return m_children.first(name);endfunction// get_next_child// --------------function int uvm_component::get_next_child(ref string name);return m_children.next(name);endfunction// get_child// ---------function uvm_component uvm_component::get_child(string name);if (m_children.exists(name))return m_children[name];`uvm_warning("NOCHILD",{"Component with name '",name,"' is not a child of component '",get_full_name(),"'"})return null;endfunction// has_child// ---------function int uvm_component::has_child(string name);return m_children.exists(name);endfunction// get_num_children// ----------------function int uvm_component::get_num_children();return m_children.num();endfunction// get_full_name// -------------function string uvm_component::get_full_name ();// Note- Implementation choice to construct full name once since the// full name may be used often for lookups.if(m_name == "")return get_name();elsereturn m_name;endfunction// get_parent// ----------function uvm_component uvm_component::get_parent ();return m_parent;endfunction// set_name// --------function void uvm_component::set_name (string name);if(m_name != "") begin`uvm_error("INVSTNM", $sformatf("It is illegal to change the name of a component. The component name will not be changed to \"%s\"", name))return;endsuper.set_name(name);m_set_full_name();endfunction// m_set_full_name// ---------------function void uvm_component::m_set_full_name();uvm_root top;top = uvm_top;if (m_parent == top || m_parent==null)m_name = get_name();elsem_name = {m_parent.get_full_name(), ".", get_name()};foreach (m_children[c]) beginuvm_component tmp;tmp = m_children[c];tmp.m_set_full_name();endendfunction// lookup// ------function uvm_component uvm_component::lookup( string name );string leaf , remainder;uvm_component comp;uvm_root top;uvm_coreservice_t cs;cs = uvm_coreservice_t::get();top = cs.get_root();comp = this;m_extract_name(name, leaf, remainder);if (leaf == "") begincomp = top; // absolute lookupm_extract_name(remainder, leaf, remainder);endif (!comp.has_child(leaf)) begin`uvm_warning("Lookup Error",$sformatf("Cannot find child %0s",leaf))return null;endif( remainder != "" )return comp.m_children[leaf].lookup(remainder);return comp.m_children[leaf];endfunction// get_depth// ---------function int unsigned uvm_component::get_depth();if(m_name == "") return 0;get_depth = 1;foreach(m_name[i])if(m_name[i] == ".") ++get_depth;endfunction// m_extract_name// --------------function void uvm_component::m_extract_name(input string name ,output string leaf ,output string remainder );int i , len;string extract_str;len = name.len();for( i = 0; i < name.len(); i++ ) beginif( name[i] == "." ) beginbreak;endendif( i == len ) beginleaf = name;remainder = "";return;endleaf = name.substr( 0 , i - 1 );remainder = name.substr( i + 1 , len - 1 );return;endfunction// flush// -----function void uvm_component::flush();return;endfunction// do_flush (flush_hier?)// --------function void uvm_component::do_flush();foreach( m_children[s] )m_children[s].do_flush();flush();endfunction//------------------------------------------------------------------------------//// Factory Methods////------------------------------------------------------------------------------// create// ------function uvm_object uvm_component::create (string name ="");`uvm_error("ILLCRT","create cannot be called on a uvm_component. Use create_component instead.")return null;endfunction// clone// ------function uvm_object uvm_component::clone ();`uvm_error("ILLCLN", $sformatf("Attempting to clone '%s'. Clone cannot be called on a uvm_component. The clone target variable will be set to null.", get_full_name()))return null;endfunction// print_override_info// -------------------function void uvm_component::print_override_info (string requested_type_name,string name="");uvm_coreservice_t cs = uvm_coreservice_t::get();uvm_factory factory=cs.get_factory();factory.debug_create_by_name(requested_type_name, get_full_name(), name);endfunction// create_component// ----------------function uvm_component uvm_component::create_component (string requested_type_name,string name);uvm_coreservice_t cs = uvm_coreservice_t::get();uvm_factory factory=cs.get_factory();return factory.create_component_by_name(requested_type_name, get_full_name(),name, this);endfunction// create_object// -------------function uvm_object uvm_component::create_object (string requested_type_name,string name="");uvm_coreservice_t cs = uvm_coreservice_t::get();uvm_factory factory=cs.get_factory();return factory.create_object_by_name(requested_type_name,get_full_name(), name);endfunction// set_type_override (static)// -----------------function void uvm_component::set_type_override (string original_type_name,string override_type_name,bit replace=1);uvm_coreservice_t cs = uvm_coreservice_t::get();uvm_factory factory=cs.get_factory();factory.set_type_override_by_name(original_type_name,override_type_name, replace);endfunction// set_type_override_by_type (static)// -------------------------function void uvm_component::set_type_override_by_type (uvm_object_wrapper original_type,uvm_object_wrapper override_type,bit replace=1);uvm_coreservice_t cs = uvm_coreservice_t::get();uvm_factory factory=cs.get_factory();factory.set_type_override_by_type(original_type, override_type, replace);endfunction// set_inst_override// -----------------function void uvm_component::set_inst_override (string relative_inst_path,string original_type_name,string override_type_name);string full_inst_path;uvm_coreservice_t cs = uvm_coreservice_t::get();uvm_factory factory=cs.get_factory();if (relative_inst_path == "")full_inst_path = get_full_name();elsefull_inst_path = {get_full_name(), ".", relative_inst_path};factory.set_inst_override_by_name(original_type_name,override_type_name,full_inst_path);endfunction// set_inst_override_by_type// -------------------------function void uvm_component::set_inst_override_by_type (string relative_inst_path,uvm_object_wrapper original_type,uvm_object_wrapper override_type);string full_inst_path;uvm_coreservice_t cs = uvm_coreservice_t::get();uvm_factory factory=cs.get_factory();if (relative_inst_path == "")full_inst_path = get_full_name();elsefull_inst_path = {get_full_name(), ".", relative_inst_path};factory.set_inst_override_by_type(original_type, override_type, full_inst_path);endfunction//------------------------------------------------------------------------------//// Hierarchical report configuration interface////------------------------------------------------------------------------------// set_report_id_verbosity_hier// -------------------------function void uvm_component::set_report_id_verbosity_hier( string id, int verbosity);set_report_id_verbosity(id, verbosity);foreach( m_children[c] )m_children[c].set_report_id_verbosity_hier(id, verbosity);endfunction// set_report_severity_id_verbosity_hier// ----------------------------------function void uvm_component::set_report_severity_id_verbosity_hier( uvm_severity severity,string id,int verbosity);set_report_severity_id_verbosity(severity, id, verbosity);foreach( m_children[c] )m_children[c].set_report_severity_id_verbosity_hier(severity, id, verbosity);endfunction// set_report_severity_action_hier// -------------------------function void uvm_component::set_report_severity_action_hier( uvm_severity severity,uvm_action action);set_report_severity_action(severity, action);foreach( m_children[c] )m_children[c].set_report_severity_action_hier(severity, action);endfunction// set_report_id_action_hier// -------------------------function void uvm_component::set_report_id_action_hier( string id, uvm_action action);set_report_id_action(id, action);foreach( m_children[c] )m_children[c].set_report_id_action_hier(id, action);endfunction// set_report_severity_id_action_hier// ----------------------------------function void uvm_component::set_report_severity_id_action_hier( uvm_severity severity,string id,uvm_action action);set_report_severity_id_action(severity, id, action);foreach( m_children[c] )m_children[c].set_report_severity_id_action_hier(severity, id, action);endfunction// set_report_severity_file_hier// -----------------------------function void uvm_component::set_report_severity_file_hier( uvm_severity severity,UVM_FILE file);set_report_severity_file(severity, file);foreach( m_children[c] )m_children[c].set_report_severity_file_hier(severity, file);endfunction// set_report_default_file_hier// ----------------------------function void uvm_component::set_report_default_file_hier( UVM_FILE file);set_report_default_file(file);foreach( m_children[c] )m_children[c].set_report_default_file_hier(file);endfunction// set_report_id_file_hier// -----------------------function void uvm_component::set_report_id_file_hier( string id, UVM_FILE file);set_report_id_file(id, file);foreach( m_children[c] )m_children[c].set_report_id_file_hier(id, file);endfunction// set_report_severity_id_file_hier// --------------------------------function void uvm_component::set_report_severity_id_file_hier ( uvm_severity severity,string id,UVM_FILE file);set_report_severity_id_file(severity, id, file);foreach( m_children[c] )m_children[c].set_report_severity_id_file_hier(severity, id, file);endfunction// set_report_verbosity_level_hier// -------------------------------function void uvm_component::set_report_verbosity_level_hier(int verbosity);set_report_verbosity_level(verbosity);foreach( m_children[c] )m_children[c].set_report_verbosity_level_hier(verbosity);endfunction//------------------------------------------------------------------------------//// Phase interface////------------------------------------------------------------------------------// phase methods//--------------// these are prototypes for the methods to be implemented in user components// build_phase() has a default implementation, the others have an empty defaultfunction void uvm_component::build_phase(uvm_phase phase);m_build_done = 1;build();endfunction// Backward compatibility build functionfunction void uvm_component::build();m_build_done = 1;apply_config_settings(print_config_matches);if(m_phasing_active == 0) beginuvm_report_warning("UVM_DEPRECATED", "build()/build_phase() has been called explicitly, outside of the phasing system. This usage of build is deprecated and may lead to unexpected behavior.");endendfunction// these phase methods are common to all components in UVM. For backward// compatibility, they call the old style name (without the _phse)function void uvm_component::connect_phase(uvm_phase phase);connect();return;endfunctionfunction void uvm_component::start_of_simulation_phase(uvm_phase phase);start_of_simulation();return;endfunctionfunction void uvm_component::end_of_elaboration_phase(uvm_phase phase);end_of_elaboration();return;endfunctiontask uvm_component::run_phase(uvm_phase phase);run();return;endtaskfunction void uvm_component::extract_phase(uvm_phase phase);extract();return;endfunctionfunction void uvm_component::check_phase(uvm_phase phase);check();return;endfunctionfunction void uvm_component::report_phase(uvm_phase phase);report();return;endfunction// These are the old style phase names. In order for runtime phase names// to not conflict with user names, the _phase postfix was added.function void uvm_component::connect(); return; endfunctionfunction void uvm_component::start_of_simulation(); return; endfunctionfunction void uvm_component::end_of_elaboration(); return; endfunctiontask uvm_component::run(); return; endtaskfunction void uvm_component::extract(); return; endfunctionfunction void uvm_component::check(); return; endfunctionfunction void uvm_component::report(); return; endfunctionfunction void uvm_component::final_phase(uvm_phase phase); return; endfunction// these runtime phase methods are only called if a set_domain() is donetask uvm_component::pre_reset_phase(uvm_phase phase); return; endtasktask uvm_component::reset_phase(uvm_phase phase); return; endtasktask uvm_component::post_reset_phase(uvm_phase phase); return; endtasktask uvm_component::pre_configure_phase(uvm_phase phase); return; endtasktask uvm_component::configure_phase(uvm_phase phase); return; endtasktask uvm_component::post_configure_phase(uvm_phase phase); return; endtasktask uvm_component::pre_main_phase(uvm_phase phase); return; endtasktask uvm_component::main_phase(uvm_phase phase); return; endtasktask uvm_component::post_main_phase(uvm_phase phase); return; endtasktask uvm_component::pre_shutdown_phase(uvm_phase phase); return; endtasktask uvm_component::shutdown_phase(uvm_phase phase); return; endtasktask uvm_component::post_shutdown_phase(uvm_phase phase); return; endtask//------------------------------// current phase convenience API//------------------------------// phase_started// -------------// phase_started() and phase_ended() are extra callbacks called at the// beginning and end of each phase, respectively. Since they are// called for all phases the phase is passed in as an argument so the// extender can decide what to do, if anything, for each phase.function void uvm_component::phase_started(uvm_phase phase);endfunction// phase_ended// -----------function void uvm_component::phase_ended(uvm_phase phase);endfunction// phase_ready_to_end// ------------------function void uvm_component::phase_ready_to_end (uvm_phase phase);endfunction//------------------------------// phase / schedule / domain API//------------------------------// methods for VIP creators and integrators to use to set up schedule domains// - a schedule is a named, organized group of phases for a component base type// - a domain is a named instance of a schedule in the master phasing schedule// define_domain// -------------function void uvm_component::define_domain(uvm_domain domain);uvm_phase schedule;//schedule = domain.find(uvm_domain::get_uvm_schedule());schedule = domain.find_by_name("uvm_sched");if (schedule == null) beginuvm_domain common;schedule = new("uvm_sched", UVM_PHASE_SCHEDULE);uvm_domain::add_uvm_phases(schedule);domain.add(schedule);common = uvm_domain::get_common_domain();if (common.find(domain,0) == null)common.add(domain,.with_phase(uvm_run_phase::get()));endendfunction// set_domain// ----------// assigns this component [tree] to a domain. adds required schedules into graph// If called from build, ~hier~ won't recurse into all chilren (which don't exist yet)// If we have components inherit their parent's domain by default, then ~hier~// isn't needed and we need a way to prevent children from inheriting this component's domainfunction void uvm_component::set_domain(uvm_domain domain, int hier=1);// build and store the custom domainm_domain = domain;define_domain(domain);if (hier)foreach (m_children[c])m_children[c].set_domain(domain);endfunction// get_domain// ----------//function uvm_domain uvm_component::get_domain();return m_domain;endfunction// set_phase_imp// -------------function void uvm_component::set_phase_imp(uvm_phase phase, uvm_phase imp, int hier=1);m_phase_imps[phase] = imp;if (hier)foreach (m_children[c])m_children[c].set_phase_imp(phase,imp,hier);endfunction//--------------------------// phase runtime control API//--------------------------`ifndef UVM_NO_DEPRECATED// do_kill_all// -----------function void uvm_component::do_kill_all();foreach(m_children[c])m_children[c].do_kill_all();kill();endfunction// kill// ----function void uvm_component::kill();if (m_phase_process != null) beginm_phase_process.kill;m_phase_process = null;endendfunction`endif// suspend// -------task uvm_component::suspend();`uvm_warning("COMP/SPND/UNIMP", "suspend() not implemented")endtask// resume// ------task uvm_component::resume();`uvm_warning("COMP/RSUM/UNIMP", "resume() not implemented")endtask// status//-------`ifndef UVM_NO_DEPRECATEDfunction string uvm_component::status();`ifdef UVM_USE_SUSPEND_RESUME`ifdef UVM_USE_PROCESS_STATEprocess::state ps;if(m_phase_process == null)return "<unknown>";ps = m_phase_process.status();return ps.name();`elseif(m_phase_process == null)return "<unknown>";case(m_phase_process.status())0: return "FINISHED";1: return "RUNNING";2: return "WAITING";3: return "SUSPENDED";4: return "KILLED";default: return "<unknown>";endcase`endif`endifreturn "<unknown>";endfunction// stop// ----task uvm_component::stop(string ph_name);return;endtask// stop_phase// ----------task uvm_component::stop_phase(uvm_phase phase);stop(phase.get_name());return;endtask`endif// resolve_bindings// ----------------function void uvm_component::resolve_bindings();return;endfunction// do_resolve_bindings// -------------------function void uvm_component::do_resolve_bindings();foreach( m_children[s] )m_children[s].do_resolve_bindings();resolve_bindings();endfunction//------------------------------------------------------------------------------//// Recording interface////------------------------------------------------------------------------------// accept_tr// ---------function void uvm_component::accept_tr (uvm_transaction tr,time accept_time=0);uvm_event#(uvm_object) e;tr.accept_tr(accept_time);do_accept_tr(tr);e = event_pool.get("accept_tr");if(e!=null)e.trigger();endfunction// begin_tr// --------function integer uvm_component::begin_tr (uvm_transaction tr,string stream_name="main",string label="",string desc="",time begin_time=0,integer parent_handle=0);return m_begin_tr(tr, parent_handle, stream_name, label, desc, begin_time);endfunction// begin_child_tr// --------------function integer uvm_component::begin_child_tr (uvm_transaction tr,integer parent_handle=0,string stream_name="main",string label="",string desc="",time begin_time=0);return m_begin_tr(tr, parent_handle, stream_name, label, desc, begin_time);endfunction// m_get_tr_database// ---------------------function uvm_tr_database uvm_component::m_get_tr_database();if (tr_database == null) beginuvm_coreservice_t cs = uvm_coreservice_t::get();tr_database = cs.get_default_tr_database();endreturn tr_database;endfunction : m_get_tr_database// get_tr_stream// ------------function uvm_tr_stream uvm_component::get_tr_stream( string name,string stream_type_name="" );uvm_tr_database db = m_get_tr_database();if (!m_streams.exists(name) || !m_streams[name].exists(stream_type_name))m_streams[name][stream_type_name] = db.open_stream(name, this.get_full_name(), stream_type_name);return m_streams[name][stream_type_name];endfunction : get_tr_stream// free_tr_stream// --------------function void uvm_component::free_tr_stream(uvm_tr_stream stream);// Check the null case...if (stream == null)return;// Then make sure this name/type_name combo existsif (!m_streams.exists(stream.get_name()) ||!m_streams[stream.get_name()].exists(stream.get_stream_type_name()))return;// Then make sure this name/type_name combo is THIS streamif (m_streams[stream.get_name()][stream.get_stream_type_name()] != stream)return;// Then delete it from the arraysm_streams[stream.get_name()].delete(stream.get_type_name());if (m_streams[stream.get_name()].size() == 0)m_streams.delete(stream.get_name());// Finally, free the stream if necessaryif (stream.is_open() || stream.is_closed()) beginstream.free();endendfunction : free_tr_stream// m_begin_tr// ----------function integer uvm_component::m_begin_tr (uvm_transaction tr,integer parent_handle=0,string stream_name="main",string label="",string desc="",time begin_time=0);uvm_event#(uvm_object) e;string name;string kind;uvm_tr_database db;integer handle, link_handle;uvm_tr_stream stream;uvm_recorder recorder, parent_recorder, link_recorder;if (tr == null)return 0;db = m_get_tr_database();if (parent_handle != 0)parent_recorder = uvm_recorder::get_recorder_from_handle(parent_handle);if (parent_recorder == null) beginuvm_sequence_item seq;if ($cast(seq,tr)) beginuvm_sequence_base parent_seq = seq.get_parent_sequence();if (parent_seq != null) beginparent_recorder = parent_seq.m_tr_recorder;endendendif(parent_recorder != null) beginlink_handle = tr.begin_child_tr(begin_time, parent_recorder.get_handle());endelse beginlink_handle = tr.begin_tr(begin_time);endif (link_handle != 0)link_recorder = uvm_recorder::get_recorder_from_handle(link_handle);if (tr.get_name() != "")name = tr.get_name();elsename = tr.get_type_name();if (uvm_verbosity'(recording_detail) != UVM_NONE) beginif ((stream_name == "") || (stream_name == "main")) beginif (m_main_stream == null)m_main_stream = db.open_stream("main", this.get_full_name(), "TVM");stream = m_main_stream;endelsestream = get_tr_stream(stream_name);if (stream != null ) beginkind = (parent_recorder == null) ? "Begin_No_Parent, Link" : "Begin_End, Link";recorder = stream.open_recorder(name, begin_time, kind);if (recorder != null) beginif (label != "")recorder.record_string("label", label);if (desc != "")recorder.record_string("desc", desc);if (parent_recorder != null) begintr_database.establish_link(uvm_parent_child_link::get_link(parent_recorder,recorder));endif (link_recorder != null) begintr_database.establish_link(uvm_related_link::get_link(recorder,link_recorder));endm_tr_h[tr] = recorder;endendhandle = (recorder == null) ? 0 : recorder.get_handle();do_begin_tr(tr, stream_name, handle);ende = event_pool.get("begin_tr");if (e!=null)e.trigger(tr);return handle;endfunction// end_tr// ------function void uvm_component::end_tr (uvm_transaction tr,time end_time=0,bit free_handle=1);uvm_event#(uvm_object) e;uvm_recorder recorder;uvm_tr_database db = m_get_tr_database();if (tr == null)return;tr.end_tr(end_time,free_handle);if (uvm_verbosity'(recording_detail) != UVM_NONE) beginif (m_tr_h.exists(tr)) beginrecorder = m_tr_h[tr];do_end_tr(tr, recorder.get_handle()); // callbackm_tr_h.delete(tr);tr.record(recorder);recorder.close(end_time);if (free_handle)recorder.free();endelse begindo_end_tr(tr, 0); // callbackendende = event_pool.get("end_tr");if(e!=null)e.trigger();endfunction// record_error_tr// ---------------function integer uvm_component::record_error_tr (string stream_name="main",uvm_object info=null,string label="error_tr",string desc="",time error_time=0,bit keep_active=0);uvm_recorder recorder;string etype;uvm_tr_stream stream;uvm_tr_database db = m_get_tr_database();integer handle;if(keep_active) etype = "Error, Link";else etype = "Error";if(error_time == 0) error_time = $realtime;if ((stream_name=="") || (stream_name=="main")) beginif (m_main_stream == null)m_main_stream = tr_database.open_stream("main", this.get_full_name(), "TVM");stream = m_main_stream;endelsestream = get_tr_stream(stream_name);handle = 0;if (stream != null) beginrecorder = stream.open_recorder(label,error_time,etype);if (recorder != null) beginif (label != "")recorder.record_string("label", label);if (desc != "")recorder.record_string("desc", desc);if (info!=null)info.record(recorder);recorder.close(error_time);if (keep_active == 0) beginrecorder.free();endelse beginhandle = recorder.get_handle();endend // if (recorder != null)end // if (stream != null)return handle;endfunction// record_event_tr// ---------------function integer uvm_component::record_event_tr (string stream_name="main",uvm_object info=null,string label="event_tr",string desc="",time event_time=0,bit keep_active=0);uvm_recorder recorder;string etype;integer handle;uvm_tr_stream stream;uvm_tr_database db = m_get_tr_database();if(keep_active) etype = "Event, Link";else etype = "Event";if(event_time == 0) event_time = $realtime;if ((stream_name=="") || (stream_name=="main")) beginif (m_main_stream == null)m_main_stream = tr_database.open_stream("main", this.get_full_name(), "TVM");stream = m_main_stream;endelsestream = get_tr_stream(stream_name);handle = 0;if (stream != null) beginrecorder = stream.open_recorder(label,event_time,etype);if (recorder != null) beginif (label != "")recorder.record_string("label", label);if (desc != "")recorder.record_string("desc", desc);if (info!=null)info.record(recorder);recorder.close(event_time);if (keep_active == 0) beginrecorder.free();endelse beginhandle = recorder.get_handle();endend // if (recorder != null)end // if (stream != null)return handle;endfunction// do_accept_tr// ------------function void uvm_component::do_accept_tr (uvm_transaction tr);return;endfunction// do_begin_tr// -----------function void uvm_component::do_begin_tr (uvm_transaction tr,string stream_name,integer tr_handle);return;endfunction// do_end_tr// ---------function void uvm_component::do_end_tr (uvm_transaction tr,integer tr_handle);return;endfunction//------------------------------------------------------------------------------//// Configuration interface////------------------------------------------------------------------------------function string uvm_component::massage_scope(string scope);// uvm_topif(scope == "")return "^$";if(scope == "*")return {get_full_name(), ".*"};// absolute path to the top-level testif(scope == "uvm_test_top")return "uvm_test_top";// absolute path to uvm_rootif(scope[0] == ".")return {get_full_name(), scope};return {get_full_name(), ".", scope};endfunction// Undocumented struct for storing clone bit along w/// object on set_config_object(...) callsclass uvm_config_object_wrapper;uvm_object obj;bit clone;endclass : uvm_config_object_wrapper`ifndef UVM_NO_DEPRECATED//// set_config_int//function void uvm_component::set_config_int(string inst_name,string field_name,uvm_bitstream_t value);if (!m_config_deprecated_warned) begin`uvm_warning("UVM/CFG/SET/DPR", "get/set_config_* API has been deprecated. Use uvm_config_db instead.")m_config_deprecated_warned = 1;enduvm_config_int::set(this, inst_name, field_name, value);endfunction//// set_config_string//function void uvm_component::set_config_string(string inst_name,string field_name,string value);if (!m_config_deprecated_warned) begin`uvm_warning("UVM/CFG/SET/DPR", "get/set_config_* API has been deprecated. Use uvm_config_db instead.")m_config_deprecated_warned = 1;enduvm_config_string::set(this, inst_name, field_name, value);endfunction//// set_config_object//function void uvm_component::set_config_object(string inst_name,string field_name,uvm_object value,bit clone = 1);uvm_object tmp;uvm_config_object_wrapper wrapper;if (!m_config_deprecated_warned) begin`uvm_warning("UVM/CFG/SET/DPR", "get/set_config_* API has been deprecated. Use uvm_config_db instead.")m_config_deprecated_warned = 1;endif(value == null)`uvm_warning("NULLCFG", {"A null object was provided as a ",$sformatf("configuration object for set_config_object(\"%s\",\"%s\")",inst_name, field_name), ". Verify that this is intended."})if(clone && (value != null)) begintmp = value.clone();if(tmp == null) beginuvm_component comp;if ($cast(comp,value)) begin`uvm_error("INVCLNC", {"Clone failed during set_config_object ","with an object that is a uvm_component. Components cannot be cloned."})return;endelse begin`uvm_warning("INVCLN", {"Clone failed during set_config_object, ","the original reference will be used for configuration. Check that ","the create method for the object type is defined properly."})endendelsevalue = tmp;enduvm_config_object::set(this, inst_name, field_name, value);wrapper = new;wrapper.obj = value;wrapper.clone = clone;uvm_config_db#(uvm_config_object_wrapper)::set(this, inst_name, field_name, wrapper);endfunction//// get_config_int//function bit uvm_component::get_config_int (string field_name,inout uvm_bitstream_t value);if (!m_config_deprecated_warned) begin`uvm_warning("UVM/CFG/GET/DPR", "get/set_config_* API has been deprecated. Use uvm_config_db instead.")m_config_deprecated_warned = 1;endreturn uvm_config_int::get(this, "", field_name, value);endfunction//// get_config_string//function bit uvm_component::get_config_string(string field_name,inout string value);if (!m_config_deprecated_warned) begin`uvm_warning("UVM/CFG/GET/DPR", "get/set_config_* API has been deprecated. Use uvm_config_db instead.")m_config_deprecated_warned = 1;endreturn uvm_config_string::get(this, "", field_name, value);endfunction//// get_config_object////// Note that this does not honor the set_config_object clone bitfunction bit uvm_component::get_config_object (string field_name,inout uvm_object value,input bit clone=1);if (!m_config_deprecated_warned) begin`uvm_warning("UVM/CFG/GET/DPR", "get/set_config_* API has been deprecated. Use uvm_config_db instead.")m_config_deprecated_warned = 1;endif(!uvm_config_object::get(this, "", field_name, value)) beginreturn 0;endif(clone && value != null) beginvalue = value.clone();endreturn 1;endfunction`endif// check_config_usage// ------------------function void uvm_component::check_config_usage ( bit recurse=1 );uvm_resource_pool rp = uvm_resource_pool::get();uvm_queue#(uvm_resource_base) rq;rq = rp.find_unused_resources();if(rq.size() == 0)return;uvm_report_info("CFGNRD"," ::: The following resources have at least one write and no reads :::",UVM_INFO);rp.print_resources(rq, 1);endfunction// apply_config_settings// ---------------------function void uvm_component::apply_config_settings (bit verbose=0);uvm_resource_pool rp = uvm_resource_pool::get();uvm_queue#(uvm_resource_base) rq;uvm_resource_base r;string name;string search_name;int unsigned i;int unsigned j;// populate an internal 'field_array' with list of// fields declared with `uvm_field macros (checking// that there aren't any duplicates along the way)__m_uvm_field_automation (null, UVM_CHECK_FIELDS, "");// if no declared fields, nothing to do.if (__m_uvm_status_container.field_array.size() == 0)return;if(verbose)uvm_report_info("CFGAPL","applying configuration settings", UVM_NONE);// The following is VERY expensive. Needs refactoring. Should// get config only for the specific field names in 'field_array'.// That's because the resource pool is organized first by field name.// Can further optimize by encoding the value for each 'field_array'// entry to indicate string, uvm_bitstream_t, or object. That way,// we call 'get' for specific fields of specific types rather than// the search-and-cast approach here.rq = rp.lookup_scope(get_full_name());rp.sort_by_precedence(rq);// rq is in precedence order now, so we have to go through in reverse// order to do the settings.for(int i=rq.size()-1; i>=0; --i) beginr = rq.get(i);name = r.get_name();// does name have brackets [] in it?for(j = 0; j < name.len(); j++)if(name[j] == "[" || name[j] == ".")break;// If it does have brackets then we'll use the name// up to the brackets to search __m_uvm_status_container.field_arrayif(j < name.len())search_name = name.substr(0, j-1);elsesearch_name = name;if(!__m_uvm_status_container.field_array.exists(search_name) &&search_name != "recording_detail")continue;if(verbose)uvm_report_info("CFGAPL",$sformatf("applying configuration to field %s", name),UVM_NONE);beginuvm_resource#(uvm_integral_t) rit;if ($cast(rit, r))set_int_local(name, rit.read(this));else beginuvm_resource#(uvm_bitstream_t) rbs;if($cast(rbs, r))set_int_local(name, rbs.read(this));else beginuvm_resource#(int) ri;if($cast(ri, r))set_int_local(name, ri.read(this));else beginuvm_resource#(int unsigned) riu;if($cast(riu, r))set_int_local(name, riu.read(this));else beginuvm_resource#(uvm_active_passive_enum) rap;if ($cast(rap, r))set_int_local(name, rap.read(this));else beginuvm_resource#(string) rs;if($cast(rs, r))set_string_local(name, rs.read(this));else beginuvm_resource#(uvm_config_object_wrapper) rcow;if ($cast(rcow, r)) beginuvm_config_object_wrapper cow = rcow.read();set_object_local(name, cow.obj, cow.clone);endelse beginuvm_resource#(uvm_object) ro;if($cast(ro, r)) beginset_object_local(name, ro.read(this), 0);endelse if (verbose) beginuvm_report_info("CFGAPL", $sformatf("field %s has an unsupported type", name), UVM_NONE);endend // else: !if($cast(rcow, r))end // else: !if($cast(rs, r))end // else: !if($cast(rap, r))end // else: !if($cast(riu, r))end // else: !if($cast(ri, r))end // else: !if($cast(rbs, r))end // else: !if($cast(rit, r))endend__m_uvm_status_container.field_array.delete();endfunction// print_config// ------------function void uvm_component::print_config(bit recurse = 0, audit = 0);uvm_resource_pool rp = uvm_resource_pool::get();uvm_report_info("CFGPRT","visible resources:",UVM_INFO);rp.print_resources(rp.lookup_scope(get_full_name()), audit);if(recurse) beginuvm_component c;foreach(m_children[name]) beginc = m_children[name];c.print_config(recurse, audit);endendendfunction// print_config_settings// ---------------------function void uvm_component::print_config_settings (string field="",uvm_component comp=null,bit recurse=0);static bit have_been_warned;if(!have_been_warned) beginuvm_report_warning("deprecated", "uvm_component::print_config_settings has been deprecated. Use print_config() instead");have_been_warned = 1;endprint_config(recurse, 1);endfunction// print_config_with_audit// -----------------------function void uvm_component::print_config_with_audit(bit recurse = 0);print_config(recurse, 1);endfunction// do_print (override)// --------function void uvm_component::do_print(uvm_printer printer);string v;super.do_print(printer);// It is printed only if its value is other than the default (UVM_NONE)if(uvm_verbosity'(recording_detail) != UVM_NONE)case (recording_detail)UVM_LOW : printer.print_generic("recording_detail", "uvm_verbosity",$bits(recording_detail), "UVM_LOW");UVM_MEDIUM : printer.print_generic("recording_detail", "uvm_verbosity",$bits(recording_detail), "UVM_MEDIUM");UVM_HIGH : printer.print_generic("recording_detail", "uvm_verbosity",$bits(recording_detail), "UVM_HIGH");UVM_FULL : printer.print_generic("recording_detail", "uvm_verbosity",$bits(recording_detail), "UVM_FULL");default : printer.print_field_int("recording_detail", recording_detail,$bits(recording_detail), UVM_DEC, , "integral");endcase`ifndef UVM_NO_DEPRECATEDif (enable_stop_interrupt != 0) beginprinter.print_field_int("enable_stop_interrupt", enable_stop_interrupt,$bits(enable_stop_interrupt), UVM_BIN, ".", "bit");end`endifendfunction// set_int_local (override)// -------------function void uvm_component::set_int_local (string field_name,uvm_bitstream_t value,bit recurse=1);//call the super function to get child recursion and any registered fieldssuper.set_int_local(field_name, value, recurse);//set the local propertiesif(uvm_is_match(field_name, "recording_detail"))recording_detail = value;endfunction// Internal methods for setting messagin parameters from command line switchestypedef class uvm_cmdline_processor;// m_set_cl_msg_args// -----------------function void uvm_component::m_set_cl_msg_args;m_set_cl_verb();m_set_cl_action();m_set_cl_sev();endfunction// m_set_cl_verb// -------------function void uvm_component::m_set_cl_verb;// _ALL_ can be used for ids// +uvm_set_verbosity=<comp>,<id>,<verbosity>,<phase|time>,<offset>// +uvm_set_verbosity=uvm_test_top.env0.agent1.*,_ALL_,UVM_FULL,time,800static string values[$];static bit first = 1;string args[$];uvm_cmdline_processor clp = uvm_cmdline_processor::get_inst();uvm_root top;uvm_coreservice_t cs;cs = uvm_coreservice_t::get();top = cs.get_root();if(!values.size())void'(uvm_cmdline_proc.get_arg_values("+uvm_set_verbosity=",values));foreach(values[i]) beginm_verbosity_setting setting;args.delete();uvm_split_string(values[i], ",", args);// Warning is already issued in uvm_root, so just don't keep itif(first && ( ((args.size() != 4) && (args.size() != 5)) ||(clp.m_convert_verb(args[2], setting.verbosity) == 0)) )beginvalues.delete(i);endelse beginsetting.comp = args[0];setting.id = args[1];void'(clp.m_convert_verb(args[2],setting.verbosity));setting.phase = args[3];setting.offset = 0;if(args.size() == 5) setting.offset = args[4].atoi();if((setting.phase == "time") && (this == top)) beginm_time_settings.push_back(setting);endif (uvm_is_match(setting.comp, get_full_name()) ) beginif((setting.phase == "" || setting.phase == "build" || setting.phase == "time") &&(setting.offset == 0) )beginif(setting.id == "_ALL_")set_report_verbosity_level(setting.verbosity);elseset_report_id_verbosity(setting.id, setting.verbosity);endelse beginif(setting.phase != "time") beginm_verbosity_settings.push_back(setting);endendendendend// do time based settingsif(this == top) beginfork begintime last_time = 0;if (m_time_settings.size() > 0)m_time_settings.sort() with ( item.offset );foreach(m_time_settings[i]) beginuvm_component comps[$];top.find_all(m_time_settings[i].comp,comps);#(m_time_settings[i].offset - last_time);last_time = m_time_settings[i].offset;if(m_time_settings[i].id == "_ALL_") beginforeach(comps[j]) begincomps[j].set_report_verbosity_level(m_time_settings[i].verbosity);endendelse beginforeach(comps[j]) begincomps[j].set_report_id_verbosity(m_time_settings[i].id, m_time_settings[i].verbosity);endendendend join_none // fork beginendfirst = 0;endfunction// m_set_cl_action// ---------------function void uvm_component::m_set_cl_action;// _ALL_ can be used for ids or severities// +uvm_set_action=<comp>,<id>,<severity>,<action[|action]>// +uvm_set_action=uvm_test_top.env0.*,_ALL_,UVM_ERROR,UVM_NO_ACTIONstatic bit initialized = 0;uvm_severity sev;uvm_action action;if(!initialized) beginstring values[$];void'(uvm_cmdline_proc.get_arg_values("+uvm_set_action=",values));foreach(values[idx]) beginuvm_cmdline_parsed_arg_t t;string args[$];uvm_split_string(values[idx], ",", args);if(args.size() != 4) begin`uvm_warning("INVLCMDARGS", $sformatf("+uvm_set_action requires 4 arguments, but %0d given for command +uvm_set_action=%s, Usage: +uvm_set_action=<comp>,<id>,<severity>,<action[|action]>", args.size(), values[idx]))continue;endif((args[2] != "_ALL_") && !uvm_string_to_severity(args[2], sev)) begin`uvm_warning("INVLCMDARGS", $sformatf("Bad severity argument \"%s\" given to command +uvm_set_action=%s, Usage: +uvm_set_action=<comp>,<id>,<severity>,<action[|action]>", args[2], values[idx]))continue;endif(!uvm_string_to_action(args[3], action)) begin`uvm_warning("INVLCMDARGS", $sformatf("Bad action argument \"%s\" given to command +uvm_set_action=%s, Usage: +uvm_set_action=<comp>,<id>,<severity>,<action[|action]>", args[3], values[idx]))continue;endt.args=args;t.arg=values[idx];m_uvm_applied_cl_action.push_back(t);endinitialized=1;endforeach(m_uvm_applied_cl_action[i]) beginstring args[$] = m_uvm_applied_cl_action[i].args;if (!uvm_is_match(args[0], get_full_name()) ) continue;void'(uvm_string_to_severity(args[2], sev));void'(uvm_string_to_action(args[3], action));m_uvm_applied_cl_action[i].used++;if(args[1] == "_ALL_") beginif(args[2] == "_ALL_") beginset_report_severity_action(UVM_INFO, action);set_report_severity_action(UVM_WARNING, action);set_report_severity_action(UVM_ERROR, action);set_report_severity_action(UVM_FATAL, action);endelse beginset_report_severity_action(sev, action);endendelse beginif(args[2] == "_ALL_") beginset_report_id_action(args[1], action);endelse beginset_report_severity_id_action(sev, args[1], action);endendendendfunction// m_set_cl_sev// ------------function void uvm_component::m_set_cl_sev;// _ALL_ can be used for ids or severities// +uvm_set_severity=<comp>,<id>,<orig_severity>,<new_severity>// +uvm_set_severity=uvm_test_top.env0.*,BAD_CRC,UVM_ERROR,UVM_WARNINGstatic bit initialized;uvm_severity orig_sev, sev;if(!initialized) beginstring values[$];void'(uvm_cmdline_proc.get_arg_values("+uvm_set_severity=",values));foreach(values[idx]) beginuvm_cmdline_parsed_arg_t t;string args[$];uvm_split_string(values[idx], ",", args);if(args.size() != 4) begin`uvm_warning("INVLCMDARGS", $sformatf("+uvm_set_severity requires 4 arguments, but %0d given for command +uvm_set_severity=%s, Usage: +uvm_set_severity=<comp>,<id>,<orig_severity>,<new_severity>", args.size(), values[idx]))continue;endif(args[2] != "_ALL_" && !uvm_string_to_severity(args[2], orig_sev)) begin`uvm_warning("INVLCMDARGS", $sformatf("Bad severity argument \"%s\" given to command +uvm_set_severity=%s, Usage: +uvm_set_severity=<comp>,<id>,<orig_severity>,<new_severity>", args[2], values[idx]))continue;endif(!uvm_string_to_severity(args[3], sev)) begin`uvm_warning("INVLCMDARGS", $sformatf("Bad severity argument \"%s\" given to command +uvm_set_severity=%s, Usage: +uvm_set_severity=<comp>,<id>,<orig_severity>,<new_severity>", args[3], values[idx]))continue;endt.args=args;t.arg=values[idx];m_uvm_applied_cl_sev.push_back(t);endinitialized=1;endforeach(m_uvm_applied_cl_sev[i]) beginstring args[$]=m_uvm_applied_cl_sev[i].args;if (!uvm_is_match(args[0], get_full_name()) ) continue;void'(uvm_string_to_severity(args[2], orig_sev));void'(uvm_string_to_severity(args[3], sev));m_uvm_applied_cl_sev[i].used++;if(args[1] == "_ALL_" && args[2] == "_ALL_") beginset_report_severity_override(UVM_INFO,sev);set_report_severity_override(UVM_WARNING,sev);set_report_severity_override(UVM_ERROR,sev);set_report_severity_override(UVM_FATAL,sev);endelse if(args[1] == "_ALL_") beginset_report_severity_override(orig_sev,sev);endelse if(args[2] == "_ALL_") beginset_report_severity_id_override(UVM_INFO,args[1],sev);set_report_severity_id_override(UVM_WARNING,args[1],sev);set_report_severity_id_override(UVM_ERROR,args[1],sev);set_report_severity_id_override(UVM_FATAL,args[1],sev);endelse beginset_report_severity_id_override(orig_sev,args[1],sev);endendendfunction// m_apply_verbosity_settings// --------------------------function void uvm_component::m_apply_verbosity_settings(uvm_phase phase);foreach(m_verbosity_settings[i]) beginif(phase.get_name() == m_verbosity_settings[i].phase) beginif( m_verbosity_settings[i].offset == 0 ) beginif(m_verbosity_settings[i].id == "_ALL_")set_report_verbosity_level(m_verbosity_settings[i].verbosity);elseset_report_id_verbosity(m_verbosity_settings[i].id, m_verbosity_settings[i].verbosity);endelse beginprocess p = process::self();string p_rand = p.get_randstate();fork beginm_verbosity_setting setting = m_verbosity_settings[i];#setting.offset;if(setting.id == "_ALL_")set_report_verbosity_level(setting.verbosity);elseset_report_id_verbosity(setting.id, setting.verbosity);end join_none;p.set_randstate(p_rand);end// Remove after usem_verbosity_settings.delete(i);endendendfunction// m_do_pre_abort// --------------function void uvm_component::m_do_pre_abort;foreach(m_children[i])m_children[i].m_do_pre_abort();pre_abort();endfunction
