Académique Documents
Professionnel Documents
Culture Documents
//------------------------------------------------------------------------------
//
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//------------------------------------------------------------------------------
uvm_factory_override queue[$];
endclass
//------------------------------------------------------------------------------
//
// This page covers the classes that define the UVM factory facility.
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
// CLASS: uvm_factory
//
//------------------------------------------------------------------------------
//
// with the factory using lightweight proxies to the actual objects and
// and <uvm_components>.
//
//
// by string arguments that can be misspelled and provided in the wrong order.
// Errors in name-based requests might only be caught at the time of the call,
//
// See <Usage> section for details on configuring and using the factory.
//
class uvm_factory;
// Function: get()
//
// Function: register
//
// Registers the given proxy object, ~obj~, with the factory. The proxy object
// the factory needs to create an object of a given type, it calls the proxy's
//
// Function: set_inst_override_by_type
extern function
uvm_object_wrapper override_type,
string full_inst_path);
// Function: set_inst_override_by_name
//
//
//
//
//
extern function
string override_type_name,
string full_inst_path);
// Function: set_type_override_by_type
extern function
uvm_object_wrapper override_type,
bit replace=1);
// Function: set_type_override_by_name
//
//
//
// string. Future calls to any of the create_* methods with the same string
//
extern function
string override_type_name,
bit replace=1);
// Group: Creation
// Function: create_object_by_type
extern function
uvm_object create_object_by_type (uvm_object_wrapper requested_type,
string parent_inst_path="",
string name="");
// Function: create_component_by_type
extern function
string parent_inst_path="",
string name,
uvm_component parent);
// Function: create_object_by_name
extern function
string parent_inst_path="",
string name="");
// Function: create_component_by_name
//
// Creates and returns a component or object of the requested type, which may
// from the <uvm_component> base class, and a requested object must be derived
//
//
// When requesting by name, the ~request_type_name~ is a string representing
// the requested type, which must have been registered with the factory with
// that name prior to the request. If the factory does not recognize the
//
// parent.
//
// override.
//
// is returned in place of the requested type. New components will have the
// given ~name~ and ~parent~. New objects will have the given ~name~, if
// provided.
//
// overrides ~foo~, then a request for ~bar~ will produce ~xyz~. Recursive
// loops will result in an error, in which case the type returned will be
// that which formed the loop. Using the previous example, if ~bar~
extern function
string parent_inst_path="",
string name,
uvm_component parent);
// Group: Debug
// Function: debug_create_by_type
extern function
string parent_inst_path="",
string name="");
// Function: debug_create_by_name
//
// These methods perform the same search algorithm as the create_* methods,
// but they do not create new objects. Instead, they provide detailed
extern function
string parent_inst_path="",
string name="");
// Function: find_override_by_type
extern function
uvm_object_wrapper find_override_by_type (uvm_object_wrapper requested_type,
string full_inst_path);
// Function: find_override_by_name
//
// These methods return the proxy to the object that would be created given
// instance path and the leaf name of the object to be created, i.e.
extern function
string full_inst_path);
extern
// Function: print
//
//
// When ~all_types~ is 0, only type and instance overrides are displayed. When
// well, provided they have names associated with them. When ~all_types~ is 2,
// the UVM types (prefixed with uvm_) are included in the list of registered
// types.
// PRIVATE MEMBERS
extern protected
uvm_object_wrapper requested_type,
string parent_inst_path,
string name);
extern protected
uvm_object_wrapper result,
string full_inst_path);
(uvm_object_wrapper original_type,
uvm_object_wrapper override_type,
string full_inst_path);
endclass
//------------------------------------------------------------------------------
//
// Group: Usage
//
//
// 3 - Configuring the factory with type and instance overrides, both within and
// outside components
//
// We'll briefly cover each of these steps here. More reference information can
//
//
//
//
//| `uvm_object_utils(packet)
//| endclass
//|
//| `uvm_object_utils(packetD)
//| endclass
//
//
//| endclass
//
//
//| `uvm_component_utils(comp)
//| endclass
//
//
//
// the type with the factory and define the get_type, get_type_name, and create
// type_name variable in the class, which will allow you to determine the type
//
//
// - The get_type_name method and static type_name variable are not defined. You
//
// - A type name is not associated with the type when registeriing with the
// parameterized classes.
//
//
// type-based methods will register the types involved "on the fly," when first
//
//
// 2 -- Designing components that defer creation to the factory:
//
// Having registered your objects and components with the factory, you can now
// make requests for new objects and components via the factory. Using the factory
// substituted for the original without modifying the requesting class. The
//
//|
//|
//| // our packet type; this can be overridden via the factory
//| T pkt;
//|
//| super.new(name,parent);
//| endfunction
//|
//| endfunction
//|
//| // using the factory allows pkt overrides from outside the class
//| endfunction
//|
//| // print the packet so we can confirm its type when printing
//| printer.print_object("pkt",pkt);
//| endfunction
//|
//| endclass
//
//
//|
//|
//| super.new(name,parent);
//| endfunction
//|
//| endfunction
//|
//| endclass
//|
//|
//|
//| super.new(name,parent);
//| endfunction
//|
//| endfunction
//|
//| endclass
//|
//
// Next, we'll define a agent component, which requires a utils macro for
//
//|
//| `uvm_component_utils(agent)
//| ...
//| B_driver driver0;
//|
//| super.new(name,parent);
//| endfunction
//|
//|
//| packet::type_id::set_inst_override(packetD::get_type(),"driver0.*");
//|
//| // create using the factory; actual driver types may be different
//|
//| endfunction
//|
//| endclass
//
//
//|
//| `uvm_component_utils(env)
//|
//|
//| super.new(name,parent);
//| endfunction
//|
//|
//| set_inst_override_by_type("agent1.driver1",
//| B_driver::get_type(),
//| D2_driver::get_type());
//|
//| B_driver::type_id::set_inst_override(D2_driver::get_type(),
//| "agent1.driver1",this);
//|
//| factory.set_inst_override_by_type(B_driver::get_type(),
//| D2_driver::get_type(),
//| {get_full_name(),".agent1.driver1"});
//|
//| // create agents using the factory; actual agent types may be different
//|
//| endfunction
//|
//| // at end_of_elaboration, print topology and factory state to verify
//| uvm_top.print_topology();
//| endfunction
//|
//| endfunction
//|
//| endclass
//
//
//
//
//|
//|
//|
//| // over any overrides made within env0's construction & build.
//|
//|
//|
//| B_driver::type_id::set_inst_override(B_driver::get_type(),
//| "env0.agent0.driver0");
//|
//| factory.set_inst_override_by_type(B_driver::get_type(),
//| B_driver::get_type(),
//| {get_full_name(),"env0.agent0.driver0"});
//|
//|
//| run_test();
//|
//| end
//|
//| endmodule
//
// When the above example is run, the resulting topology (displayed via a call to
//
//| # UVM_INFO @ 0 [RNTST] Running test ...
//| # ----------------------------------------------------------------------
//| # ----------------------------------------------------------------------
//| # ----------------------------------------------------------------------
//
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
// CLASS: uvm_object_wrapper
//
//
//------------------------------------------------------------------------------
// Function: create_object
//
return null;
endfunction
// Function: create_component
//
// Creates a new component, passing to its constructor the given ~name~ and
uvm_component parent);
return null;
endfunction
// Function: get_type_name
//
// Derived classes implement this method to return the type name of the object
endclass
//------------------------------------------------------------------------------
//
// CLASS- uvm_factory_override
//
// Internal class.
//------------------------------------------------------------------------------
class uvm_factory_override;
string full_inst_path;
string orig_type_name;
string ovrd_type_name;
bit selected;
uvm_object_wrapper orig_type;
uvm_object_wrapper ovrd_type;
string orig_type_name="",
uvm_object_wrapper orig_type=null,
uvm_object_wrapper ovrd_type);
uvm_report_fatal ("NULLWR", "Attempting to register a null override object with the factory",
UVM_NONE);
end
this.full_inst_path= full_inst_path;
this.orig_type = orig_type;
this.ovrd_type_name = ovrd_type.get_type_name();
this.ovrd_type = ovrd_type;
endfunction
endclass
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// IMPLEMENTATION
//-----------------------------------------------------------------------------
// get
// ---
function uvm_factory uvm_factory::get();
m_inst = new();
end
return m_inst;
endfunction
// new
// ---
endfunction
// register
// --------
uvm_report_fatal ("NULLWR", "Attempting to register a null object with the factory", UVM_NONE);
end
if (m_type_names.exists(obj.get_type_name()))
"support for multiple types with the same type name."}, UVM_NONE);
else
m_type_names[obj.get_type_name()] = obj;
end
if (m_types.exists(obj)) begin
end
else begin
m_types[obj] = 1;
// procedural (e.g. initial) blocks. There should not be any preexisting overrides.
if(m_inst_override_name_queues.exists(obj.get_type_name())) begin
m_inst_override_queues[obj] = new;
m_inst_override_queues[obj].queue =
m_inst_override_name_queues[obj.get_type_name()].queue;
m_inst_override_name_queues.delete(obj.get_type_name());
end
if(m_wildcard_inst_overrides.size()) begin
if(! m_inst_override_queues.exists(obj))
m_inst_override_queues[obj] = new;
m_inst_override_queues[obj].queue.push_back(m_wildcard_inst_overrides[i]);
end
end
end
endfunction
// set_type_override_by_type
// -------------------------
uvm_object_wrapper override_type,
bit replace=1);
bit replaced;
else
original_type.get_type_name()}, UVM_NONE);
return;
end
// register the types if not already done so, for the benefit of string-based lookup
if (!m_types.exists(original_type))
register(original_type);
if (!m_types.exists(override_type))
register(override_type);
if (m_type_overrides[index].orig_type == original_type ||
string msg;
m_type_overrides[index].ovrd_type_name,"'"};
if (!replace) begin
msg = {msg, ". Set 'replace' argument to replace the existing entry."};
return;
end
override_type.get_type_name(),"'."};
replaced = 1;
m_type_overrides[index].orig_type = original_type;
m_type_overrides[index].orig_type_name = original_type.get_type_name();
m_type_overrides[index].ovrd_type = override_type;
m_type_overrides[index].ovrd_type_name = override_type.get_type_name();
end
end
// make a new entry
if (!replaced) begin
uvm_factory_override override;
override = new(.orig_type(original_type),
.orig_type_name(original_type.get_type_name()),
.full_inst_path("*"),
.ovrd_type(override_type));
m_type_overrides.push_back(override);
end
endfunction
// set_type_override_by_name
// -------------------------
string override_type_name,
bit replace=1);
bit replaced;
uvm_object_wrapper original_type;
uvm_object_wrapper override_type;
if(m_type_names.exists(original_type_name))
original_type = m_type_names[original_type_name];
if(m_type_names.exists(override_type_name))
override_type = m_type_names[override_type_name];
return;
end
return;
end
if (!replace) begin
return;
end
replaced = 1;
m_type_overrides[index].ovrd_type = override_type;
m_type_overrides[index].ovrd_type_name = override_type_name;
end
end
if (original_type == null)
m_lookup_strs[original_type_name] = 1;
if (!replaced) begin
uvm_factory_override override;
override = new(.orig_type(original_type),
.orig_type_name(original_type_name),
.full_inst_path("*"),
.ovrd_type(override_type));
m_type_overrides.push_back(override);
// m_type_names[original_type_name] = override.ovrd_type;
end
endfunction
// check_inst_override_exists
// --------------------------
uvm_object_wrapper override_type,
string full_inst_path);
uvm_factory_override override;
uvm_factory_queue_class qc;
if (m_inst_override_queues.exists(original_type))
qc = m_inst_override_queues[original_type];
else
return 0;
override = qc.queue[index];
full_inst_path,"'"},UVM_HIGH);
return 1;
end
end
return 0;
endfunction
// set_inst_override_by_type
// -------------------------
uvm_object_wrapper override_type,
string full_inst_path);
uvm_factory_override override;
if (!m_types.exists(original_type))
register(original_type);
if (!m_types.exists(override_type))
register(override_type);
if (check_inst_override_exists(original_type,override_type,full_inst_path))
return;
if(!m_inst_override_queues.exists(original_type))
m_inst_override_queues[original_type] = new;
override = new(.full_inst_path(full_inst_path),
.orig_type(original_type),
.orig_type_name(original_type.get_type_name()),
.ovrd_type(override_type));
m_inst_override_queues[original_type].queue.push_back(override);
endfunction
// set_inst_override_by_name
// -------------------------
function void uvm_factory::set_inst_override_by_name (string original_type_name,
string override_type_name,
string full_inst_path);
uvm_factory_override override;
uvm_object_wrapper original_type;
uvm_object_wrapper override_type;
if(m_type_names.exists(original_type_name))
original_type = m_type_names[original_type_name];
if(m_type_names.exists(override_type_name))
override_type = m_type_names[override_type_name];
original_type_name,"' and instance path '",full_inst_path,"' because the type it's supposed ",
return;
end
if (original_type == null)
m_lookup_strs[original_type_name] = 1;
override = new(.full_inst_path(full_inst_path),
.orig_type(original_type),
.orig_type_name(original_type_name),
.ovrd_type(override_type));
if (check_inst_override_exists(original_type,override_type,full_inst_path))
return;
if(!m_inst_override_queues.exists(original_type))
m_inst_override_queues[original_type] = new;
m_inst_override_queues[original_type].queue.push_back(override);
end
else begin
if(m_has_wildcard(original_type_name)) begin
foreach(m_type_names[i]) begin
if(uvm_is_match(original_type_name,i)) begin
end
end
m_wildcard_inst_overrides.push_back(override);
end
else begin
if(!m_inst_override_name_queues.exists(original_type_name))
m_inst_override_name_queues[original_type_name] = new;
m_inst_override_name_queues[original_type_name].queue.push_back(override);
end
end
endfunction
foreach (nm[i])
if(nm[i] == "*" || nm[i] == "?") return 1;
return 0;
endfunction
// create_object_by_name
// ---------------------
string parent_inst_path="",
string name="");
uvm_object_wrapper wrapper;
string inst_path;
if (parent_inst_path == "")
inst_path = name;
inst_path = {parent_inst_path,".",name};
else
inst_path = parent_inst_path;
m_override_info.delete();
if (wrapper==null) begin
if(!m_type_names.exists(requested_type_name)) begin
uvm_report_warning("BDTYP",{"Cannot create an object of type '",
return null;
end
wrapper = m_type_names[requested_type_name];
end
return wrapper.create_object(name);
endfunction
// create_object_by_type
// ---------------------
string parent_inst_path="",
string name="");
string full_inst_path;
if (parent_inst_path == "")
full_inst_path = name;
full_inst_path = {parent_inst_path,".",name};
else
full_inst_path = parent_inst_path;
m_override_info.delete();
requested_type = find_override_by_type(requested_type, full_inst_path);
return requested_type.create_object(name);
endfunction
// create_component_by_name
// ------------------------
string parent_inst_path="",
string name,
uvm_component parent);
uvm_object_wrapper wrapper;
string inst_path;
if (parent_inst_path == "")
inst_path = name;
inst_path = {parent_inst_path,".",name};
else
inst_path = parent_inst_path;
m_override_info.delete();
if(!m_type_names.exists(requested_type_name)) begin
return null;
end
wrapper = m_type_names[requested_type_name];
end
endfunction
// create_component_by_type
// ------------------------
string parent_inst_path="",
string name,
uvm_component parent);
string full_inst_path;
if (parent_inst_path == "")
full_inst_path = name;
full_inst_path = {parent_inst_path,".",name};
else
full_inst_path = parent_inst_path;
m_override_info.delete();
endfunction
// find_by_name
// ------------
if (m_type_names.exists(type_name))
return m_type_names[type_name];
endfunction
// find_override_by_name
// ---------------------
function uvm_object_wrapper uvm_factory::find_override_by_name (string requested_type_name,
string full_inst_path);
uvm_object_wrapper rtype;
uvm_factory_queue_class qc;
uvm_object_wrapper override;
if (m_type_names.exists(requested_type_name))
rtype = m_type_names[requested_type_name];
/***
requested_type_name, " is not registered with the factory. The instance override to ",
end
m_lookup_strs[requested_type_name] = 1;
return null;
end
***/
if(m_inst_override_name_queues.exists(requested_type_name))
qc = m_inst_override_name_queues[requested_type_name];
end
else begin
if(m_inst_override_queues.exists(rtype))
qc = m_inst_override_queues[rtype];
end
if(qc != null)
m_override_info.push_back(qc.queue[index]);
if (m_debug_pass) begin
override = qc.queue[index].ovrd_type;
qc.queue[index].selected = 1;
end
end
else begin
if (qc.queue[index].ovrd_type.get_type_name() == requested_type_name)
return qc.queue[index].ovrd_type;
else
return find_override_by_type(qc.queue[index].ovrd_type,full_inst_path);
end
end
end
end
m_inst_override_queues[rtype] = new;
if(uvm_is_match(m_wildcard_inst_overrides[i].orig_type_name, requested_type_name))
m_inst_override_queues[rtype].queue.push_back(m_wildcard_inst_overrides[i]);
end
end
foreach (m_type_overrides[index])
m_override_info.push_back(m_type_overrides[index]);
if (m_debug_pass) begin
override = m_type_overrides[index].ovrd_type;
m_type_overrides[index].selected = 1;
end
end
else begin
return find_override_by_type(m_type_overrides[index].ovrd_type,full_inst_path);
end
end
// No override found
return null;
endfunction
// find_override_by_type
// ---------------------
string full_inst_path);
uvm_object_wrapper override;
uvm_factory_queue_class qc = null;
if (m_inst_override_queues.exists(requested_type))
qc = m_inst_override_queues[requested_type];
if (!m_debug_pass)
return requested_type;
end
end
// inst override; return first match; takes precedence over type overrides
if ((qc.queue[index].orig_type == requested_type ||
m_override_info.push_back(qc.queue[index]);
if (m_debug_pass) begin
override = qc.queue[index].ovrd_type;
qc.queue[index].selected = 1;
end
end
else begin
if (qc.queue[index].ovrd_type == requested_type)
return requested_type;
else
return find_override_by_type(qc.queue[index].ovrd_type,full_inst_path);
end
end
end
if (m_type_overrides[index].orig_type == requested_type ||
m_override_info.push_back(m_type_overrides[index]);
if (m_debug_pass) begin
override = m_type_overrides[index].ovrd_type;
m_type_overrides[index].selected = 1;
end
end
else begin
if (m_type_overrides[index].ovrd_type == requested_type)
return requested_type;
else
return find_override_by_type(m_type_overrides[index].ovrd_type,full_inst_path);
end
end
end
//foreach (m_type_overrides[index])
// if (uvm_is_match(index,requested_type.get_type_name())) begin
// m_override_info.push_back(m_inst_overrides[index]);
// return find_override_by_type(m_type_overrides[index],full_inst_path);
// end
if (override == requested_type)
return requested_type;
else
return find_override_by_type(override,full_inst_path);
return requested_type;
endfunction
// print
// -----
string key;
uvm_factory_queue_class sorted_override_queues[string];
string tmp;
int id;
uvm_object_wrapper obj;
obj = i;
tmp = obj.get_type_name();
sorted_override_queues[tmp] = m_inst_override_queues[i];
end
sorted_override_queues[i] = m_inst_override_name_queues[i];
end
else begin
int max1,max2,max3;
if(!sorted_override_queues.num())
else begin
foreach(sorted_override_queues[j]) begin
uvm_factory_queue_class qc = sorted_override_queues[j];
max1=qc.queue[i].orig_type_name.len();
max2=qc.queue[i].full_inst_path.len();
max3=qc.queue[i].ovrd_type_name.len();
end
end
$display("Instance Overrides:\n");
dash.substr(1,max2),
dash.substr(1,max3));
foreach(sorted_override_queues[j]) begin
uvm_factory_queue_class qc = sorted_override_queues[j];
$write(" %0s%0s",qc.queue[i].orig_type_name,
space.substr(1,max1-qc.queue[i].orig_type_name.len()));
space.substr(1,max2-qc.queue[i].full_inst_path.len()));
end
end
end
if (!m_type_overrides.size())
else begin
max1=m_type_overrides[i].orig_type_name.len();
end
$display("\nType Overrides:\n");
dash.substr(1,max2));
foreach (m_type_overrides[index])
m_type_overrides[index].orig_type_name,
space.substr(1,max1-m_type_overrides[index].orig_type_name.len()),
m_type_overrides[index].ovrd_type_name);
end
end
bit banner;
do begin
// filter out uvm_ classes (if all_types<2) and non-types (lookup strings)
m_type_names[key].get_type_name())) &&
if (!banner) begin
banner=1;
end
end
end while(m_type_names.next(key));
end
$display("\n####\n");
endfunction
// debug_create_by_name
// --------------------
string parent_inst_path="",
string name="");
endfunction
// debug_create_by_type
// --------------------
string name="");
endfunction
// m_debug_create
// --------------
uvm_object_wrapper requested_type,
string parent_inst_path,
string name);
string full_inst_path;
uvm_object_wrapper result;
if (parent_inst_path == "")
full_inst_path = name;
full_inst_path = {parent_inst_path,".",name};
else
full_inst_path = parent_inst_path;
m_override_info.delete();
if (!m_type_names.exists(requested_type_name) &&
!m_lookup_strs.exists(requested_type_name)) begin
uvm_report_warning("Factory Warning", {"The factory does not recognize '",
return;
end
m_debug_pass = 1;
result = find_override_by_name(requested_type_name,full_inst_path);
end
else begin
m_debug_pass = 1;
if (!m_types.exists(requested_type))
register(requested_type);
result = find_override_by_type(requested_type,full_inst_path);
if (requested_type_name == "")
requested_type_name = requested_type.get_type_name();
end
m_debug_pass = 0;
foreach (m_override_info[index])
m_override_info[index].selected = 0;
endfunction
// m_debug_display
// ---------------
function void uvm_factory::m_debug_display (string requested_type_name,
uvm_object_wrapper result,
string full_inst_path);
int max1,max2,max3;
if (m_override_info.size() == 0)
else begin
max1=m_override_info[i].orig_type_name.len();
max2=m_override_info[i].full_inst_path.len();
max3=m_override_info[i].ovrd_type_name.len();
end
if (max1 < 13) max1 = 13;
dash.substr(1,max2),
dash.substr(1,max3));
$write("%s%0s%0s",
m_override_info[i].orig_type_name,
space.substr(1,max1-m_override_info[i].orig_type_name.len()));
space.substr(1,max2-m_override_info[i].full_inst_path.len()));
space.substr(1,max3-m_override_info[i].ovrd_type_name.len()));
if (m_override_info[i].full_inst_path == "*")
else
$display();
end
$display();
end
$display("Result:\n");
$display("\n####\n");
endfunction