blob: 005cb63561631fdcdbdb0890c9e4de61754dac19 [file] [log] [blame]
// $Id: //dvt/vtech/dev/main/ovm/src/base/ovm_component.sv#85 $
//------------------------------------------------------------------------------
// Copyright 2007-2009 Mentor Graphics Corporation
// Copyright 2007-2009 Cadence Design Systems, Inc.
// All Rights Reserved Worldwide
//
// Licensed under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in
// writing, software distributed under the License is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See
// the License for the specific language governing
// permissions and limitations under the License.
//------------------------------------------------------------------------------
`include "base/ovm_component.svh"
`include "base/ovm_root.svh"
ovm_component ovm_top_levels[$]; // don't use
//------------------------------------------------------------------------------
//
// CLASS- ovm_component
//
//------------------------------------------------------------------------------
// new
// ---
function ovm_component::new (string name, ovm_component parent);
string error_str;
super.new(name);
// If ovm_top, reset name to "" so it doesn't show in full paths then return
if (parent==null && name == "__top__") begin
set_name("");
return;
end
// Check that we're not in or past end_of_elaboration
if (end_of_elaboration_ph.is_in_progress() ||
end_of_elaboration_ph.is_done() ) begin
ovm_phase curr_phase;
curr_phase = ovm_top.get_current_phase();
ovm_report_fatal("ILLCRT", {"It is illegal to create a component once",
" phasing reaches end_of_elaboration. The current phase is ",
curr_phase.get_name()}, OVM_NONE);
end
if (name == "") begin
name.itoa(m_inst_count);
name = {"COMP_", name};
end
if(parent == this) begin
ovm_report_fatal("THISPARENT", "cannot set the parent of a component to itself", OVM_NONE);
end
if (parent == null)
parent = ovm_top;
if(ovm_report_enabled(OVM_MEDIUM+1, OVM_INFO, "NEWCOMP"))
ovm_report_info("NEWCOMP",$psprintf("this=%0s, parent=%0s, name=%s",
this.get_full_name(),parent.get_full_name(),name),OVM_MEDIUM+1);
if (parent.has_child(name) && this != parent.get_child(name)) begin
if (parent == ovm_top) begin
error_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: $psprintf(\"\%m.\%s\",\"",name,"\")."};
ovm_report_fatal("CLDEXT",error_str, OVM_NONE);
end
else
ovm_report_fatal("CLDEXT",
$psprintf("Cannot set '%s' as a child of '%s', %s",
name, parent.get_full_name(),
"which already has a child by that name."), OVM_NONE);
return;
end
m_parent = parent;
set_name(name);
if (!m_parent.m_add_child(this))
m_parent = null;
event_pool = new("event_pool");
// Now that inst name is established, reseed (if use_ovm_seeding is set)
reseed();
// Do local configuration settings (URM backward compatibility)
void'(get_config_int("recording_detail", recording_detail));
// Deprecated container of top-levels (replaced by ovm_top)
if (parent == ovm_top)
ovm_top_levels.push_back(this);
set_report_verbosity_level(ovm_top.get_report_verbosity_level());
set_report_id_action("CFGOVR", OVM_NO_ACTION);
set_report_id_action("CFGSET", OVM_NO_ACTION);
//Not sure what ovm_top isn't taking the setting... these two lines should be removed.
ovm_top.set_report_id_action("CFGOVR", OVM_NO_ACTION);
ovm_top.set_report_id_action("CFGSET", OVM_NO_ACTION);
endfunction
// m_add_child
// -----------
function bit ovm_component::m_add_child(ovm_component child);
if (m_children.exists(child.get_name()) &&
m_children[child.get_name()] != child) begin
ovm_report_warning("BDCLD",
$psprintf("A child with the name '%0s' (type=%0s) already exists.",
child.get_name(), m_children[child.get_name()].get_type_name()), OVM_NONE);
return 0;
end
if (m_children_by_handle.exists(child)) begin
ovm_report_warning("BDCHLD",
$psprintf("A child with the name '%0s' %0s %0s'",
child.get_name(),
"already exists in parent under name '",
m_children_by_handle[child].get_name()), OVM_NONE);
return 0;
end
m_children[child.get_name()] = child;
m_children_by_handle[child] = child;
return 1;
endfunction
//------------------------------------------------------------------------------
//
// Hierarchy Methods
//
//------------------------------------------------------------------------------
// get_first_child
// ---------------
function int ovm_component::get_first_child(ref string name);
return m_children.first(name);
endfunction
// get_next_child
// --------------
function int ovm_component::get_next_child(ref string name);
return m_children.next(name);
endfunction
// get_child
// ---------
function ovm_component ovm_component::get_child(string name);
if (m_children.exists(name))
return m_children[name];
ovm_report_warning("NOCHILD",{"Component with name '",name,
"' is not a child of component '",get_full_name(),"'"}, OVM_NONE);
return null;
endfunction
// has_child
// ---------
function int ovm_component::has_child(string name);
return m_children.exists(name);
endfunction
// get_num_children
// ----------------
function int ovm_component::get_num_children();
return m_children.num();
endfunction
// get_full_name
// -------------
function string ovm_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();
else
return m_name;
endfunction
// get_parent
// ----------
function ovm_component ovm_component::get_parent ();
return m_parent;
endfunction
// set_name
// --------
function void ovm_component::set_name (string name);
super.set_name(name);
m_set_full_name();
endfunction
// m_set_full_name
// ---------------
function void ovm_component::m_set_full_name();
if (m_parent == ovm_top || m_parent==null)
m_name = get_name();
else
m_name = {m_parent.get_full_name(), ".", get_name()};
foreach (m_children[c]) begin
ovm_component tmp;
tmp = m_children[c];
tmp.m_set_full_name();
end
endfunction
// lookup
// ------
function ovm_component ovm_component::lookup( string name );
string leaf , remainder;
ovm_component comp;
comp = this;
m_extract_name(name, leaf, remainder);
if (leaf == "") begin
comp = ovm_top; // absolute lookup
m_extract_name(remainder, leaf, remainder);
end
if (!comp.has_child(leaf)) begin
ovm_report_warning("Lookup Error",
$psprintf("Cannot find child %0s",leaf), OVM_NONE);
return null;
end
if( remainder != "" )
return comp.m_children[leaf].lookup(remainder);
return comp.m_children[leaf];
endfunction
// m_extract_name
// --------------
function void ovm_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++ ) begin
if( name[i] == "." ) begin
break;
end
end
if( i == len ) begin
leaf = name;
remainder = "";
return;
end
leaf = name.substr( 0 , i - 1 );
remainder = name.substr( i + 1 , len - 1 );
return;
endfunction
// flush
// -----
function void ovm_component::flush();
return;
endfunction
// do_flush (flush_hier?)
// --------
function void ovm_component::do_flush();
foreach( m_children[s] )
m_children[s].do_flush();
flush();
endfunction
//------------------------------------------------------------------------------
//
// Factory Methods
//
//------------------------------------------------------------------------------
// create
// ------
function ovm_object ovm_component::create (string name ="");
ovm_report_error("ILLCRT",
"create cannot be called on a ovm_component. Use create_component instead.", OVM_NONE);
return null;
endfunction
// clone
// ------
function ovm_object ovm_component::clone ();
ovm_report_error("ILLCLN","clone cannot be called on a ovm_component. ", OVM_NONE);
return null;
endfunction
// print_override_info
// -------------------
function void ovm_component::print_override_info (string requested_type_name,
string name="");
factory.debug_create_by_name(requested_type_name, get_full_name(), name);
endfunction
// create_component
// ----------------
function ovm_component ovm_component::create_component (string requested_type_name,
string name);
return factory.create_component_by_name(requested_type_name, get_full_name(),
name, this);
endfunction
// create_object
// -------------
function ovm_object ovm_component::create_object (string requested_type_name,
string name="");
return factory.create_object_by_name(requested_type_name,
get_full_name(), name);
endfunction
// set_type_override (static)
// -----------------
function void ovm_component::set_type_override (string original_type_name,
string override_type_name,
bit replace=1);
factory.set_type_override_by_name(original_type_name,
override_type_name, replace);
endfunction
// set_type_override_by_type (static)
// -------------------------
function void ovm_component::set_type_override_by_type (ovm_object_wrapper original_type,
ovm_object_wrapper override_type,
bit replace=1);
factory.set_type_override_by_type(original_type, override_type, replace);
endfunction
// set_inst_override
// -----------------
function void ovm_component::set_inst_override (string relative_inst_path,
string original_type_name,
string override_type_name);
string full_inst_path;
if (relative_inst_path == "")
full_inst_path = get_full_name();
else
full_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 ovm_component::set_inst_override_by_type (string relative_inst_path,
ovm_object_wrapper original_type,
ovm_object_wrapper override_type);
string full_inst_path;
if (relative_inst_path == "")
full_inst_path = get_full_name();
else
full_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_severity_action_hier
// -------------------------------
function void ovm_component::set_report_severity_action_hier( ovm_severity severity,
ovm_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 ovm_component::set_report_id_action_hier( string id, ovm_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 ovm_component::set_report_severity_id_action_hier( ovm_severity severity,
string id,
ovm_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 ovm_component::set_report_severity_file_hier( ovm_severity severity,
OVM_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 ovm_component::set_report_default_file_hier( OVM_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 ovm_component::set_report_id_file_hier( string id, OVM_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 ovm_component::set_report_severity_id_file_hier ( ovm_severity severity,
string id,
OVM_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 ovm_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
//
//------------------------------------------------------------------------------
// do_func_phase
// -------------
function void ovm_component::do_func_phase (ovm_phase phase);
// If in build_ph, don't build if already done
m_curr_phase = phase;
if (!(phase == build_ph && m_build_done))
phase.call_func(this);
endfunction
// do_task_phase
// -------------
task ovm_component::do_task_phase (ovm_phase phase);
m_curr_phase = phase;
`ifndef INCA
//fork
//begin
m_phase_process = process::self();
phase.call_task(this);
@m_kill_request;
//end
//join
`else
// don't use fine grained process control
fork begin // isolate inner fork so can safely kill via disable fork
fork : task_phase
// process 1 - call task; if returns, keep alive until kill request
begin
phase.call_task(this);
@m_kill_request;
end
// process 2 - any kill request will preempt process 1
@m_kill_request;
join_any
disable fork;
end
join
`endif
endtask
// do_kill_all
// -----------
function void ovm_component::do_kill_all();
foreach(m_children[c])
m_children[c].do_kill_all();
kill();
endfunction
// kill
// ----
function void ovm_component::kill();
`ifndef INCA
if (m_phase_process != null) begin
m_phase_process.kill;
m_phase_process = null;
end
`else
->m_kill_request;
`endif
endfunction
// suspend
// -------
task ovm_component::suspend();
`ifndef INCA
if(m_phase_process != null)
m_phase_process.suspend;
`else
ovm_report_error("UNIMP", "suspend not implemented", OVM_NONE);
`endif
endtask
// resume
// ------
task ovm_component::resume();
`ifndef INCA
if(m_phase_process!=null)
m_phase_process.resume;
`else
ovm_report_error("UNIMP", "resume not implemented", OVM_NONE);
`endif
endtask
// restart
// -------
task ovm_component::restart();
ovm_report_warning("UNIMP",
$psprintf("%0s: restart not implemented",this.get_name()), OVM_NONE);
endtask
// status
//-------
function string ovm_component::status();
`ifndef INCA
process::state ps;
if(m_phase_process == null)
return "<unknown>";
ps = m_phase_process.status();
return ps.name();
`else
ovm_report_error("UNIMP", "status not implemented", OVM_NONE);
`endif
endfunction
// build
// -----
function void ovm_component::build();
m_build_done = 1;
apply_config_settings(print_config_matches);
endfunction
// connect
// -------
function void ovm_component::connect();
return;
endfunction
// start_of_simulation
// -------------------
function void ovm_component::start_of_simulation();
return;
endfunction
// end_of_elaboration
// ------------------
function void ovm_component::end_of_elaboration();
return;
endfunction
// run
// ---
task ovm_component::run();
return;
endtask
// extract
// -------
function void ovm_component::extract();
return;
endfunction
// check
// -----
function void ovm_component::check();
return;
endfunction
// report
// ------
function void ovm_component::report();
return;
endfunction
// stop
// ----
task ovm_component::stop(string ph_name);
return;
endtask
// resolve_bindings
// ----------------
function void ovm_component::resolve_bindings();
return;
endfunction
// do_resolve_bindings
// -------------------
function void ovm_component::do_resolve_bindings();
foreach( m_children[s] )
m_children[s].do_resolve_bindings();
resolve_bindings();
endfunction
//------------------------------------------------------------------------------
//
// Recording interface
//
//------------------------------------------------------------------------------
// accept_tr
// ---------
function void ovm_component::accept_tr (ovm_transaction tr,
time accept_time=0);
ovm_event 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 ovm_component::begin_tr (ovm_transaction tr,
string stream_name ="main",
string label="",
string desc="",
time begin_time=0);
return m_begin_tr(tr, 0, 0, stream_name, label, desc, begin_time);
endfunction
// begin_child_tr
// --------------
function integer ovm_component::begin_child_tr (ovm_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, 1, stream_name, label, desc, begin_time);
endfunction
// m_begin_tr
// ----------
function integer ovm_component::m_begin_tr (ovm_transaction tr,
integer parent_handle=0,
bit has_parent=0,
string stream_name="main",
string label="",
string desc="",
time begin_time=0);
ovm_event e;
integer stream_h;
integer tr_h;
integer link_tr_h;
string name;
tr_h = 0;
if(has_parent)
link_tr_h = tr.begin_child_tr(begin_time, parent_handle);
else
link_tr_h = tr.begin_tr(begin_time);
if (tr.get_name() != "")
name = tr.get_name();
else
name = tr.get_type_name();
if(stream_name == "") stream_name="main";
if (ovm_verbosity'(recording_detail) != OVM_NONE) begin
if(m_stream_handle.exists(stream_name))
stream_h = m_stream_handle[stream_name];
if (ovm_check_handle_kind("Fiber", stream_h) != 1)
begin
stream_h = ovm_create_fiber(stream_name, "TVM", get_full_name());
m_stream_handle[stream_name] = stream_h;
end
if(has_parent == 0)
tr_h = ovm_begin_transaction("Begin_No_Parent, Link",
stream_h,
name,
label,
desc,
begin_time);
else begin
tr_h = ovm_begin_transaction("Begin_End, Link",
stream_h,
name,
label,
desc,
begin_time);
if(parent_handle!=0)
ovm_link_transaction(parent_handle, tr_h, "child");
end
m_tr_h[tr] = tr_h;
if (ovm_check_handle_kind("Transaction", link_tr_h) == 1)
ovm_link_transaction(tr_h,link_tr_h);
do_begin_tr(tr,stream_name,tr_h);
end
e = event_pool.get("begin_tr");
if (e!=null)
e.trigger(tr);
return tr_h;
endfunction
// end_tr
// ------
function void ovm_component::end_tr (ovm_transaction tr,
time end_time=0,
bit free_handle=1);
ovm_event e;
integer tr_h;
tr_h = 0;
tr.end_tr(end_time,free_handle);
if (ovm_verbosity'(recording_detail) != OVM_NONE) begin
if (m_tr_h.exists(tr)) begin
tr_h = m_tr_h[tr];
do_end_tr(tr, tr_h); // callback
m_tr_h.delete(tr);
if (ovm_check_handle_kind("Transaction", tr_h) == 1) begin
ovm_default_recorder.tr_handle = tr_h;
tr.record(ovm_default_recorder);
ovm_end_transaction(tr_h,end_time);
if (free_handle)
ovm_free_transaction_handle(tr_h);
end
end
else begin
do_end_tr(tr, tr_h); // callback
end
end
e = event_pool.get("end_tr");
if(e!=null)
e.trigger();
endfunction
// record_error_tr
// ---------------
function integer ovm_component::record_error_tr (string stream_name="main",
ovm_object info=null,
string label="error_tr",
string desc="",
time error_time=0,
bit keep_active=0);
string etype;
integer stream_h;
if(keep_active) etype = "Error, Link";
else etype = "Error";
if(error_time == 0) error_time = $time;
stream_h = m_stream_handle[stream_name];
if (ovm_check_handle_kind("Fiber", stream_h) != 1) begin
stream_h = ovm_create_fiber(stream_name, "TVM", get_full_name());
m_stream_handle[stream_name] = stream_h;
end
record_error_tr = ovm_begin_transaction(etype, stream_h, label,
label, desc, error_time);
if(info!=null) begin
ovm_default_recorder.tr_handle = record_error_tr;
info.record(ovm_default_recorder);
end
ovm_end_transaction(record_error_tr,error_time);
endfunction
// record_event_tr
// ---------------
function integer ovm_component::record_event_tr (string stream_name="main",
ovm_object info=null,
string label="event_tr",
string desc="",
time event_time=0,
bit keep_active=0);
string etype;
integer stream_h;
if(keep_active) etype = "Event, Link";
else etype = "Event";
if(event_time == 0) event_time = $time;
stream_h = m_stream_handle[stream_name];
if (ovm_check_handle_kind("Fiber", stream_h) != 1) begin
stream_h = ovm_create_fiber(stream_name, "TVM", get_full_name());
m_stream_handle[stream_name] = stream_h;
end
record_event_tr = ovm_begin_transaction(etype, stream_h, label,
label, desc, event_time);
if(info!=null) begin
ovm_default_recorder.tr_handle = record_event_tr;
info.record(ovm_default_recorder);
end
ovm_end_transaction(record_event_tr,event_time);
endfunction
// do_accept_tr
// ------------
function void ovm_component::do_accept_tr (ovm_transaction tr);
return;
endfunction
// do_begin_tr
// -----------
function void ovm_component::do_begin_tr (ovm_transaction tr,
string stream_name,
integer tr_handle);
return;
endfunction
// do_end_tr
// ---------
function void ovm_component::do_end_tr (ovm_transaction tr,
integer tr_handle);
return;
endfunction
//------------------------------------------------------------------------------
//
// Configuration interface
//
//------------------------------------------------------------------------------
// set_config_int
// --------------
function void ovm_component::set_config_int (string inst_name,
string field_name,
ovm_bitstream_t value);
ovm_int_config_setting cfg;
cfg = new(inst_name, field_name, value, this);
m_config_set = 1;
m_configuration_table.push_front(cfg);
endfunction
// set_config_string
// -----------------
function void ovm_component::set_config_string (string inst_name,
string field_name,
string value);
ovm_string_config_setting cfg;
cfg = new(inst_name, field_name, value, this);
m_config_set = 1;
m_configuration_table.push_front(cfg);
endfunction
// set_config_object
// -----------------
function void ovm_component::set_config_object (string inst_name,
string field_name,
ovm_object value,
bit clone=1);
ovm_object_config_setting cfg;
if(clone && (value != null)) begin
ovm_object tmp;
tmp = value.clone();
// If create not implemented, or clone is attempted on objects that
// do not t allow cloning (e.g. components) clone will return null.
if(tmp == null) begin
ovm_component comp;
if ($cast(comp,value)) begin
ovm_report_error("INVCLNC", {"Clone failed during set_config_object ",
"with an object that is an ovm_component. Components cannot be cloned."}, OVM_NONE);
return;
end
else begin
ovm_report_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."}, OVM_NONE);
end
end
else
value = tmp;
end
cfg = new(inst_name, field_name, value, this, clone);
m_config_set = 1;
m_configuration_table.push_front(cfg);
endfunction
// m_component_path
// ----------------
function void ovm_component::m_component_path(ref ovm_component path[$]);
ovm_component comp;
comp = this;
`ifdef INCA
path.delete();
`else
path = '{};
`endif
while(comp != null) begin
path.push_front(comp);
comp = comp.get_parent();
end
endfunction
// m_get_config_matches
// --------------------
function void ovm_component::m_get_config_matches(
ref ovm_config_setting cfg_matches[$],
input ovm_config_setting::ovm_config_type cfgtype, string field_name);
ovm_component comp;
static ovm_component stack[$];
static ovm_config_setting comp_matches[$];
comp = this;
`ifdef INCA
cfg_matches.delete();
`else
cfg_matches = '{};
`endif
//Get the path up to the root. Since configs are done in groups for a comp,
//cache the set of config matches from the last check to reduce searching.
if((stack.size() == 0) || (stack[stack.size()-1] != this) || (m_config_set == 1)) begin
m_config_set = 0;
m_component_path(stack);
`ovm_clear_queue(comp_matches);
foreach(stack[i]) begin
for(int j=0; j<stack[i].m_configuration_table.size(); ++j) begin
if(stack[i].m_configuration_table[j].component_match(this))
comp_matches.push_back(stack[i].m_configuration_table[j]);
end
end
end
foreach(comp_matches[i]) begin
if(comp_matches[i].field_match(field_name) &&
((comp_matches[i].get_value_type() == cfgtype) ||
(cfgtype == ovm_config_setting::OVM_UNDEFINED_TYPE)))
begin
cfg_matches.push_back(comp_matches[i]);
end
end
endfunction
// check_config_usage
// ------------------
function void ovm_component::check_config_usage ( bit recurse=1 );
ovm_config_setting cfg;
bit found;
string fstr, applied_str, cfg_type;
found=0;
if(recurse)
foreach(m_children[i]) begin
m_children[i].check_config_usage(recurse);
end
if(m_configuration_table.size() == 0) return;
if(this == ovm_top)
fstr = "from the GLOBAL scope";
else
fstr = {"from component ", get_full_name(), "(",
get_type_name(), ")"};
foreach(m_configuration_table[i]) begin
cfg = m_configuration_table[i];
if(cfg.m_used_list.size() == 0 &&
cfg.m_override_list.size() == 0 )
begin
if(cfg.get_value_type() == ovm_config_setting::OVM_INT_TYPE)
cfg_type = "int";
else if(cfg.get_value_type() == ovm_config_setting::OVM_STRING_TYPE)
cfg_type = "string";
else
cfg_type = "object";
ovm_report_warning("CFGNTS", {"No get_config_",cfg_type,
"() call ever matched the following set_config_", cfg_type, "() call ", fstr,
": ", cfg.convert2string()}, OVM_NONE);
end
end
//Do not do the lookup work if the CFGOVR action is off
if(ovm_report_enabled(OVM_LOW, OVM_INFO, "CFGOVR"))
foreach(m_configuration_table[i]) begin
cfg = m_configuration_table[i];
if(cfg.m_override_list.size() != 0)
begin
ovm_report_info("CFGOVR", {"The configuration setting ", cfg.convert2string(), " ", fstr, " was overridden by config setting ", cfg.m_override_list[0].convert2string(), " from component ", cfg.m_override_list[0].m_from.get_full_name(), "(", cfg.m_override_list[0].m_from.get_type_name(), ")"}, OVM_NONE);
end
end
//Do not do the lookup work if the CFGSET action is off
if(ovm_report_enabled(OVM_LOW, OVM_INFO, "CFGSET"))
foreach(m_configuration_table[i]) begin
string cfgstr;
cfg = m_configuration_table[i];
if(cfg.m_used_list.size() != 0)
begin
cfgstr = cfg.convert2string();
applied_str = "";
for(int j=0; j<cfg.m_used_list.size(); ++j) begin
ovm_report_info("CFGSET", {"The configuration setting ", cfgstr, " ", fstr, " was applied to component: ", cfg.m_used_list[j].get_full_name(), " (", cfg.m_used_list[j].get_type_name(), ")"}, OVM_NONE);
end
end
end
endfunction
// get_config_int
// --------------
function bit ovm_component::get_config_int (string field_name,
inout ovm_bitstream_t value);
static ovm_config_setting cfg_matches[$];
ovm_int_config_setting cfg;
ovm_component c;
//Scan the config tables of each component in the path
m_get_config_matches(cfg_matches, ovm_config_setting::OVM_INT_TYPE, field_name);
//The first match is the override
if(cfg_matches.size()) begin
$cast(cfg, cfg_matches[0]);
if(print_config_matches)
cfg_matches[0].print_match(this, cfg_matches[0].get_from_component(), field_name);
cfg_matches[0].set_used(this);
for(int i=1; i<cfg_matches.size(); ++i) begin
cfg_matches[i].set_override(cfg_matches[0]);
end
value = cfg.m_value;
return 1;
end
return 0;
endfunction
// get_config_string
// -----------------
function bit ovm_component::get_config_string (string field_name,
inout string value);
static ovm_config_setting cfg_matches[$];
ovm_string_config_setting cfg;
ovm_component c;
//Scan the config tables of each component in the path
m_get_config_matches(cfg_matches, ovm_config_setting::OVM_STRING_TYPE, field_name);
//The first match is the override
if(cfg_matches.size()) begin
$cast(cfg, cfg_matches[0]);
if(print_config_matches)
cfg_matches[0].print_match(this, cfg_matches[0].get_from_component(), field_name);
cfg_matches[0].set_used(this);
for(int i=1; i<cfg_matches.size(); ++i)
cfg_matches[i].set_override(cfg_matches[0]);
value = cfg.m_value;
return 1;
end
return 0;
endfunction
// get_config_object
// -----------------
function bit ovm_component::get_config_object (string field_name,
inout ovm_object value,
input bit clone=1);
static ovm_config_setting cfg_matches[$];
ovm_object_config_setting cfg;
ovm_component c;
//Scan the config tables of each component in the path
m_get_config_matches(cfg_matches, ovm_config_setting::OVM_OBJECT_TYPE, field_name);
//The first match is the override
if(cfg_matches.size()) begin
$cast(cfg, cfg_matches[0]);
if(print_config_matches)
cfg_matches[0].print_match(this, cfg_matches[0].get_from_component(), field_name);
cfg_matches[0].set_used(this);
for(int i=1; i<cfg_matches.size(); ++i)
cfg_matches[i].set_override(cfg_matches[0]);
if((clone && cfg.m_clone) && (cfg.m_value != null))
value = cfg.m_value.clone();
else
value = cfg.m_value;
return 1;
end
return 0;
endfunction
// apply_config_settings
// ---------------------
function void ovm_component::apply_config_settings (bit verbose=0);
static ovm_component stack[$];
static ovm_config_setting overrides[string];
ovm_config_setting cfg;
ovm_int_config_setting cfg_int;
ovm_string_config_setting cfg_str;
ovm_object_config_setting cfg_obj;
ovm_component comp;
string match_str;
string matched="";
bit has_match=0;
if(stack.size() == 0 || stack[stack.size()-1] != this) begin
m_component_path(stack);
end
//apply any override that matches this component. Go bottom up and then back
//to front so the last override in the global scope has precedence to the
//first override in the parent scope.
if (verbose) begin
match_str = {"Auto-configuration matches for component ",
this.get_full_name()," (",get_type_name(),"). Last entry for a given field takes precedence.\n\n",
" Config set from Instance Path Field name Type Value\n",
" ------------------------------------------------------------------------------\n"};
end
for(int i=stack.size()-1; i>=0; --i) begin
comp = stack[i];
if(comp == null) comp = ovm_top;
if(comp!=null) begin
for(int j=comp.m_configuration_table.size()-1; j>=0; --j) begin
cfg = comp.m_configuration_table[j];
if(cfg.component_match(this)) begin
if(verbose)
matched = cfg.matches_string(this,comp);
if($cast(cfg_int, cfg))
set_int_local(cfg_int.m_field, cfg_int.m_value);
else if($cast(cfg_str, cfg))
set_string_local(cfg_str.m_field, cfg_str.m_value);
else if($cast(cfg_obj, cfg)) begin
set_object_local(cfg_obj.m_field, cfg_obj.m_value, cfg_obj.m_clone);
if(verbose)
matched = {matched, " clone=",(cfg_obj.m_clone==1)?"1":"0"};
end
if(verbose)
match_str = {match_str, " ", matched,"\n"};
has_match = 1;
if(m_sc.status)
cfg.m_used_list.push_back(this);
end
end
end
end
if (verbose && has_match)
if(ovm_report_enabled(OVM_MEDIUM, OVM_INFO, "auto-configuration"))
ovm_report_info("auto-configuration", {match_str,"\n"}, OVM_MEDIUM);
endfunction
// print_config_settings
// ---------------------
function void ovm_component::print_config_settings (string field="",
ovm_component comp=null,
bit recurse=0);
static int depth;
static ovm_component stack[$];
ovm_component cc;
string all_matches;
string v,r;
all_matches = "";
if(comp==null)
comp = this;
comp.m_component_path(stack);
while(stack.size() && (stack[stack.size()-1] != comp))
void'(stack.pop_back());
cc = comp;
$swrite(v, "%s", cc.get_full_name());
while(v.len()<17) v = {v," "};
foreach(stack[s]) begin
comp = stack[s];
for(int i=0; i<comp.m_configuration_table.size(); ++i) begin
r = comp.m_configuration_table[i].matches_string(cc, comp);
if(r != "")
all_matches = {all_matches, v, r, "\n"};
end
end
// Note- should use ovm_printer for formatting
if(((all_matches != "") || (recurse == 1)) && depth == 0) begin
$display("Configuration settings for component %s (recurse = %0d)",
cc.get_full_name(), recurse);
$display("Set to Set from Component match Field name Type Value");
$display("-------------------------------------------------------------------------------");
end
if(all_matches == "")
$display("%s NONE", v);
else
$write("%s", all_matches);
if(recurse) begin
depth++;
if(cc.m_children.first(v))
do this.print_config_settings(field, cc.m_children[v], recurse);
while(cc.m_children.next(v));
depth--;
end
endfunction
//------------------------------------------------------------------------------
//
// DEPRECATED - DO NOT USE
//
//------------------------------------------------------------------------------
// global_stop_request (static, deprecated)
// -------------------
function void ovm_component::global_stop_request();
ovm_root top;
top = ovm_root::get();
top.stop_request();
endfunction
// post_new (deprecated)
// --------
function void ovm_component::post_new();
return;
endfunction
// export_connections (deprecated)
// ------------------
function void ovm_component::export_connections();
return;
endfunction
// import_connections (deprecated)
// ------------------
function void ovm_component::import_connections();
return;
endfunction
// configure (deprecated)
// ---------
function void ovm_component::configure();
return;
endfunction
// pre_run (deprecated)
// -------
function void ovm_component::pre_run();
return;
endfunction
// find_component (deprecated)
// --------------
function ovm_component ovm_component::find_component (string comp_match);
static bit issued=0;
if (!issued) begin
issued=1;
ovm_top.ovm_report_warning("deprecated",
{"ovm_component::find_component() is deprecated and replaced by ",
"ovm_top.find()"}, OVM_NONE);
end
return ovm_top.find(comp_match);
endfunction
// find_components (deprecated)
// ---------------
function void ovm_component::find_components (string comp_match,
ref ovm_component comps[$]);
static bit issued=0;
if (!issued) begin
issued=1;
ovm_top.ovm_report_warning("deprecated",
{"ovm_component::find_components() is deprecated and replaced by ",
"ovm_top.find_all()"}, OVM_NONE);
end
ovm_top.find_all(comp_match,comps);
endfunction
// get_component (deprecated)
// -------------
function ovm_component ovm_component::get_component (int ele);
ovm_component m__comps[$];
static bit issued=0;
if (!issued) begin
issued=1;
ovm_top.ovm_report_warning("deprecated",
{"ovm_component::get_component() is an internal method that has been ",
"deprecated. ovm_top's find, find_all, and ovm_component's lookup ",
"method provide similar functionality."}, OVM_NONE);
end
if (m__comps.size()==0)
ovm_top.find_all("*",m__comps);
if (ele < m__comps.size())
return m__comps[ele];
return null;
endfunction
// get_num_components (deprecated)
// ------------------
function int ovm_component::get_num_components ();
ovm_component m__comps[$];
static bit issued=0;
if (!issued) begin
issued=1;
ovm_top.ovm_report_warning("deprecated",
{"ovm_component::get_num_components() is an internal method that has ",
"been deprecated. The number of components in the testbench can be ",
"obtained using the ovm_top.find_all() method."}, OVM_NONE);
end
while (m__comps.size()!=0)
m__comps.delete(0);
ovm_top.find_all("*",m__comps);
get_num_components = m__comps.size();
endfunction