Saturday, 30 April 2016

Override in UVM using factory with Example

One of the main advantage of UVM is Creating each components using factory enables them to be overridden in different tests or environments without changing underlying code base.

uvm_factory provides four different methods to override particular instance or all instances of particular class.
set_inst_override_by_type
set_inst_override_by_name
set_type_override_by_type
set_type_override_by_name


Let's go through example of each one of above four ways.

set_inst_override_by_type
-------------------------------------------------------
// set_inst_override_by_type
`include "uvm.svh"
import uvm_pkg::*;
//--------------------uvm_component------------------------------
class A extends uvm_agent;
`uvm_component_utils(A)
function new (string name="A", uvm_component parent);
super.new(name, parent);
`uvm_info(get_full_name, $sformatf("A new"), UVM_LOW);
endfunction : new
virtual function hello();
`uvm_info(get_full_name, $sformatf("HELLO from Original class 'A'"), UVM_LOW);
endfunction : hello
endclass : A
class A_ovr extends A;
`uvm_component_utils(A_ovr)
function new (string name="A_ovr", uvm_component parent);
super.new(name, parent);
`uvm_info(get_full_name, $sformatf("A_ovr new"), UVM_LOW);
endfunction : new
function hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'A_ovr'"), UVM_LOW);
endfunction : hello
endclass : A_ovr
//--------------------uvm_object------------------------------
class B extends uvm_object;
`uvm_object_utils(B)
function new (string name="B");
super.new(name);
`uvm_info(get_full_name, $sformatf("B new"), UVM_LOW);
endfunction : new
virtual function hello();
`uvm_info(get_full_name, $sformatf("HELLO from Original class 'B'"), UVM_LOW);
endfunction : hello
endclass : B
class B_ovr extends B;
`uvm_object_utils(B_ovr)
function new (string name="B_ovr");
super.new(name);
`uvm_info(get_full_name, $sformatf("B_ovr new"), UVM_LOW);
endfunction : new
function hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'B_ovr'"), UVM_LOW);
endfunction : hello
endclass : B_ovr
class B_override extends B_ovr;
`uvm_object_utils(B_override)
function new (string name="B_override");
super.new(name);
`uvm_info(get_full_name, $sformatf("B_override new"), UVM_LOW);
endfunction : new
function hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'B_override'"), UVM_LOW);
endfunction : hello
endclass : B_override
//--------------------env class--------------------
class environment extends uvm_env;
`uvm_component_utils(environment)
A a1;
B b1, b2;
function new(string name="environment", uvm_component parent);
super.new(name, parent);
endfunction : new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
// arguments of create method:
// 1. string name = ""
// 2. uvm_component parent = null
// 3. string contxt = ""
// The contxt argument, if supplied, supercedes the parent's context.
a1 = A::type_id::create("a1", this);
b1 = B::type_id::create("b1", , "path1");
b2 = B::type_id::create("b2", , "path2");
a1.hello(); // This will print from overridden class A_ovr
b1.hello(); // This will print from overridden class B_ovr
b2.hello(); // This will print from overridden class B_override
endfunction : build_phase
endclass : environment
//-------------------test class--------------------------
class test extends uvm_test;
`uvm_component_utils(test)
environment env;
function new(string name = "test", uvm_component parent = null);
super.new(name, parent);
endfunction : new
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = environment::type_id::create("env", this);
`uvm_info(get_full_name, $sformatf("TEST set_inst_override_by_type"), UVM_LOW);
factory.set_inst_override_by_type(A::get_type(), A_ovr::get_type(), {get_full_name, ".", "env.a1"}); // Working
//factory.set_inst_override_by_type(B::get_type(), B_ovr::get_type(), {get_full_name, ".", "env.b1"}); // Not working
factory.set_inst_override_by_type(B::get_type(), B_ovr::get_type(), "path1.b1"); // Working
//factory.set_inst_override_by_type(B::get_type(), B_override::get_type(), {get_full_name, ".", "env.b2"}); // Not working
factory.set_inst_override_by_type(B::get_type(), B_override::get_type(), "path2.b2"); // Working
factory.print(); // This will print info about overridden classes.
endfunction : build_phase
endclass : test
module top();
initial begin
run_test("test");
end
endmodule : top

-------------------------------------------------------

-------------------------------------------------------
//Output:
// UVM_INFO @ 0: reporter [RNTST] Running test test...
// UVM_INFO top.sv(118) @ 0: uvm_test_top [uvm_test_top] TEST set_inst_override_by_type
//
// #### Factory Configuration (*)
// Instance Overrides:
// Requested Type Override Path Override Type
// -------------- ------------------- -------------
// A uvm_test_top.env.a1 A_ovr
// B path1.b1 B_ovr
// B path2.b2 B_override
//
// No type overrides are registered with this factory
//
// All types registered with the factory: 45 total
// (types without type names will not be printed)
// Type Name
// ---------
// A
// A_ovr
// B
// B_override
// B_ovr
// environment
// test
// (*) Types with no associated type name will be printed as <unknown>
// ####
//
// UVM_INFO top.sv(15) @ 0: uvm_test_top.env.a1 [uvm_test_top.env.a1] A new
// UVM_INFO top.sv(28) @ 0: uvm_test_top.env.a1 [uvm_test_top.env.a1] A_ovr new
// UVM_INFO top.sv(42) @ 0: reporter [B_ovr] B new
// UVM_INFO top.sv(55) @ 0: reporter [B_ovr] B_ovr new
// UVM_INFO top.sv(42) @ 0: reporter [B_override] B new
// UVM_INFO top.sv(55) @ 0: reporter [B_override] B_ovr new
// UVM_INFO top.sv(68) @ 0: reporter [B_override] B_override new
// UVM_INFO top.sv(32) @ 0: uvm_test_top.env.a1 [uvm_test_top.env.a1] HELLO from override class 'A_ovr'
// UVM_INFO top.sv(59) @ 0: reporter [b1] HELLO from override class 'B_ovr'
// UVM_INFO top.sv(72) @ 0: reporter [b2] HELLO from override class 'B_override'

-------------------------------------------------------


set_inst_override_by_name

-------------------------------------------------------
// set_inst_override_by_name
`include "uvm.svh"
import uvm_pkg::*;
//--------------------uvm_component------------------------------
class A extends uvm_agent;
`uvm_component_utils(A)
function new (string name="A", uvm_component parent);
super.new(name, parent);
`uvm_info(get_full_name, $sformatf("A new"), UVM_LOW);
endfunction : new
virtual function hello();
`uvm_info(get_full_name, $sformatf("HELLO from Original class 'A'"), UVM_LOW);
endfunction : hello
endclass : A
class A_ovr extends A;
`uvm_component_utils(A_ovr)
function new (string name="A_ovr", uvm_component parent);
super.new(name, parent);
`uvm_info(get_full_name, $sformatf("A_ovr new"), UVM_LOW);
endfunction : new
function hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'A_ovr'"), UVM_LOW);
endfunction : hello
endclass : A_ovr
//--------------------uvm_object------------------------------
class B extends uvm_object;
`uvm_object_utils(B)
function new (string name="B");
super.new(name);
`uvm_info(get_full_name, $sformatf("B new"), UVM_LOW);
endfunction : new
virtual function hello();
`uvm_info(get_full_name, $sformatf("HELLO from Original class 'B'"), UVM_LOW);
endfunction : hello
endclass : B
class B_ovr extends B;
`uvm_object_utils(B_ovr)
function new (string name="B_ovr");
super.new(name);
`uvm_info(get_full_name, $sformatf("B_ovr new"), UVM_LOW);
endfunction : new
function hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'B_ovr'"), UVM_LOW);
endfunction : hello
endclass : B_ovr
class B_override extends B_ovr;
`uvm_object_utils(B_override)
function new (string name="B_override");
super.new(name);
`uvm_info(get_full_name, $sformatf("B_override new"), UVM_LOW);
endfunction : new
function hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'B_override'"), UVM_LOW);
endfunction : hello
endclass : B_override
//--------------------env class--------------------
class environment extends uvm_env;
`uvm_component_utils(environment)
A a1;
B b1, b2;
function new(string name="environment", uvm_component parent);
super.new(name, parent);
endfunction : new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
// arguments of create method:
// 1. string name = ""
// 2. uvm_component parent = null
// 3. string contxt = ""
// The contxt argument, if supplied, supercedes the parent's context.
a1 = A::type_id::create("a1", this);
b1 = B::type_id::create("b1", , "path1");
b2 = B::type_id::create("b2", , "path2");
a1.hello(); // This will print from overridden class A_ovr
b1.hello(); // This will print from overridden class B_ovr
b2.hello(); // This will print from overridden class B_override
endfunction : build_phase
endclass : environment
//-------------------test class--------------------------
class test extends uvm_test;
`uvm_component_utils(test)
environment env;
function new(string name = "test", uvm_component parent = null);
super.new(name, parent);
endfunction : new
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = environment::type_id::create("env", this);
`uvm_info(get_full_name, $sformatf("TEST set_inst_override_by_name"), UVM_LOW);
factory.set_inst_override_by_name("A", "A_ovr", {get_full_name, ".", "env.a1"}); // Working
//factory.set_inst_override_by_name("B", "B_ovr", {get_full_name, ".", "env.b1"}); // Not working
factory.set_inst_override_by_name("B", "B_ovr", "path1.b1"); // Working
//factory.set_inst_override_by_name("B", "B_override", {get_full_name, ".", "env.b2"}); // Not working
factory.set_inst_override_by_name("B", "B_override", "path2.b2"); // Working
factory.print(); // This will print info about overridden classes.
endfunction : build_phase
endclass : test
module top();
initial begin
run_test("test");
end
endmodule : top

-------------------------------------------------------

-------------------------------------------------------
//Output:
// UVM_INFO @ 0: reporter [RNTST] Running test test...
// UVM_INFO top.sv(118) @ 0: uvm_test_top [uvm_test_top] TEST set_inst_override_by_name
//
// #### Factory Configuration (*)
// Instance Overrides:
// Requested Type Override Path Override Type
// -------------- ------------------- -------------
// A uvm_test_top.env.a1 A_ovr
// B path1.b1 B_ovr
// B path2.b2 B_override
//
// No type overrides are registered with this factory
//
// All types registered with the factory: 45 total
// (types without type names will not be printed)
// Type Name
// ---------
// A
// A_ovr
// B
// B_override
// B_ovr
// environment
// test
// (*) Types with no associated type name will be printed as <unknown>
// ####
//
// UVM_INFO top.sv(15) @ 0: uvm_test_top.env.a1 [uvm_test_top.env.a1] A new
// UVM_INFO top.sv(28) @ 0: uvm_test_top.env.a1 [uvm_test_top.env.a1] A_ovr new
// UVM_INFO top.sv(42) @ 0: reporter [B_ovr] B new
// UVM_INFO top.sv(55) @ 0: reporter [B_ovr] B_ovr new
// UVM_INFO top.sv(42) @ 0: reporter [B_override] B new
// UVM_INFO top.sv(55) @ 0: reporter [B_override] B_ovr new
// UVM_INFO top.sv(68) @ 0: reporter [B_override] B_override new
// UVM_INFO top.sv(32) @ 0: uvm_test_top.env.a1 [uvm_test_top.env.a1] HELLO from override class 'A_ovr'
// UVM_INFO top.sv(59) @ 0: reporter [b1] HELLO from override class 'B_ovr'
// UVM_INFO top.sv(72) @ 0: reporter [b2] HELLO from override class 'B_override'

-------------------------------------------------------


set_type_override_by_type
-------------------------------------------------------
// set_type_override_by_type
`include "uvm.svh"
import uvm_pkg::*;
//--------------------uvm_component------------------------------
class A extends uvm_agent;
`uvm_component_utils(A)
function new (string name="A", uvm_component parent);
super.new(name, parent);
`uvm_info(get_full_name, $sformatf("A new"), UVM_LOW);
endfunction : new
virtual function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from Original class 'A'"), UVM_LOW);
endfunction : hello
endclass : A
class A_ovr extends A;
`uvm_component_utils(A_ovr)
function new (string name="A_ovr", uvm_component parent);
super.new(name, parent);
`uvm_info(get_full_name, $sformatf("A_ovr new"), UVM_LOW);
endfunction : new
function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'A_ovr'"), UVM_LOW);
endfunction : hello
endclass : A_ovr
//--------------------uvm_object------------------------------
class B extends uvm_object;
`uvm_object_utils(B)
function new (string name="B");
super.new(name);
`uvm_info(get_full_name, $sformatf("B new"), UVM_LOW);
endfunction : new
virtual function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from Original class 'B'"), UVM_LOW);
endfunction : hello
endclass : B
class B_ovr extends B;
`uvm_object_utils(B_ovr)
function new (string name="B_ovr");
super.new(name);
`uvm_info(get_full_name, $sformatf("B_ovr new"), UVM_LOW);
endfunction : new
function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'B_ovr'"), UVM_LOW);
endfunction : hello
endclass : B_ovr
class B_override extends B_ovr;
`uvm_object_utils(B_override)
function new (string name="B_override");
super.new(name);
`uvm_info(get_full_name, $sformatf("B_override new"), UVM_LOW);
endfunction : new
function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'B_override'"), UVM_LOW);
endfunction : hello
endclass : B_override
//--------------------env class--------------------
class environment extends uvm_env;
`uvm_component_utils(environment)
A a1;
B b1, b2;
function new(string name="environment", uvm_component parent);
super.new(name, parent);
endfunction : new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
// arguments of create method:
// 1. string name = ""
// 2. uvm_component parent = null
// 3. string contxt = ""
// The contxt argument, if supplied, supercedes the parent's context.
a1 = A::type_id::create("a1", this);
b1 = B::type_id::create("b1", , "path1");
b2 = B::type_id::create("b2", , "path2");
void'(a1.hello()); // This will print from overridden class A_ovr
void'(b1.hello()); // This will print from overridden class B_override
void'(b2.hello()); // This will print from overridden class B_override
endfunction : build_phase
endclass : environment
//-------------------test class--------------------------
class test extends uvm_test;
`uvm_component_utils(test)
environment env;
function new(string name = "test", uvm_component parent = null);
super.new(name, parent);
endfunction : new
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = environment::type_id::create("env", this);
`uvm_info(get_full_name, $sformatf("TEST set_inst_override_by_name"), UVM_LOW);
factory.set_type_override_by_type(A::get_type(), A_ovr::get_type()); // Working
factory.set_type_override_by_type(B::get_type(), B_override::get_type()); // Working
factory.print(); // This will print info about overridden classes.
endfunction : build_phase
endclass : test
module top();
initial begin
run_test("test");
end
endmodule : top

-------------------------------------------------------

-------------------------------------------------------
//Output:
UVM_INFO @ 0: reporter [RNTST] Running test test...
UVM_INFO testbench.sv(109) @ 0: uvm_test_top [uvm_test_top] TEST set_inst_override_by_name
#### Factory Configuration (*)
No instance overrides are registered with this factory
Type Overrides:
Requested Type Override Type
-------------- -------------
A A_ovr
B B_override
All types registered with the factory: 45 total
(types without type names will not be printed)
Type Name
---------
A
A_ovr
B
B_override
B_ovr
environment
snps_uvm_reg_bank_group
snps_uvm_reg_map
test
(*) Types with no associated type name will be printed as <unknown>
####
UVM_INFO testbench.sv(9) @ 0: uvm_test_top.env.a1 [uvm_test_top.env.a1] A new
UVM_INFO testbench.sv(22) @ 0: uvm_test_top.env.a1 [uvm_test_top.env.a1] A_ovr new
UVM_INFO testbench.sv(36) @ 0: reporter [B_override] B new
UVM_INFO testbench.sv(49) @ 0: reporter [B_override] B_ovr new
UVM_INFO testbench.sv(62) @ 0: reporter [B_override] B_override new
UVM_INFO testbench.sv(36) @ 0: reporter [B_override] B new
UVM_INFO testbench.sv(49) @ 0: reporter [B_override] B_ovr new
UVM_INFO testbench.sv(62) @ 0: reporter [B_override] B_override new
UVM_INFO testbench.sv(26) @ 0: uvm_test_top.env.a1 [uvm_test_top.env.a1] HELLO from override class 'A_ovr'
UVM_INFO testbench.sv(66) @ 0: reporter [b1] HELLO from override class 'B_override'
UVM_INFO testbench.sv(66) @ 0: reporter [b2] HELLO from override class 'B_override'

-------------------------------------------------------


set_type_override_by_name
-------------------------------------------------------
// set_type_override_by_name
`include "uvm.svh"
import uvm_pkg::*;
//--------------------uvm_component------------------------------
class A extends uvm_agent;
`uvm_component_utils(A)
function new (string name="A", uvm_component parent);
super.new(name, parent);
`uvm_info(get_full_name, $sformatf("A new"), UVM_LOW);
endfunction : new
virtual function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from Original class 'A'"), UVM_LOW);
endfunction : hello
endclass : A
class A_ovr extends A;
`uvm_component_utils(A_ovr)
function new (string name="A_ovr", uvm_component parent);
super.new(name, parent);
`uvm_info(get_full_name, $sformatf("A_ovr new"), UVM_LOW);
endfunction : new
function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'A_ovr'"), UVM_LOW);
endfunction : hello
endclass : A_ovr
//--------------------uvm_object------------------------------
class B extends uvm_object;
`uvm_object_utils(B)
function new (string name="B");
super.new(name);
`uvm_info(get_full_name, $sformatf("B new"), UVM_LOW);
endfunction : new
virtual function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from Original class 'B'"), UVM_LOW);
endfunction : hello
endclass : B
class B_ovr extends B;
`uvm_object_utils(B_ovr)
function new (string name="B_ovr");
super.new(name);
`uvm_info(get_full_name, $sformatf("B_ovr new"), UVM_LOW);
endfunction : new
function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'B_ovr'"), UVM_LOW);
endfunction : hello
endclass : B_ovr
class B_override extends B_ovr;
`uvm_object_utils(B_override)
function new (string name="B_override");
super.new(name);
`uvm_info(get_full_name, $sformatf("B_override new"), UVM_LOW);
endfunction : new
function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'B_override'"), UVM_LOW);
endfunction : hello
endclass : B_override
//--------------------env class--------------------
class environment extends uvm_env;
`uvm_component_utils(environment)
A a1;
B b1, b2;
B_ovr b3;
function new(string name="environment", uvm_component parent);
super.new(name, parent);
endfunction : new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
// arguments of create method:
// 1. string name = ""
// 2. uvm_component parent = null
// 3. string contxt = ""
// The contxt argument, if supplied, supercedes the parent's context.
// contxt argument is not required for set_type_override_*,
// It is only required for set_inst_override_* to locate
// instance of uvm_object which is not part of uvm hierarchy.
a1 = A::type_id::create("a1", this);
b1 = B::type_id::create("b1", , "path1");
b2 = B::type_id::create("b2");
b3 = B_ovr::type_id::create("b3");
void'(a1.hello()); // This will print from overridden class A_ovr
void'(b1.hello()); // This will print from overridden class B_override
void'(b2.hello()); // This will print from overridden class B_override
void'(b3.hello()); // This will print from overridden class B_ovr
endfunction : build_phase
endclass : environment
//-------------------test class--------------------------
class test extends uvm_test;
`uvm_component_utils(test)
environment env;
function new(string name = "test", uvm_component parent = null);
super.new(name, parent);
endfunction : new
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = environment::type_id::create("env", this);
`uvm_info(get_full_name, $sformatf("TEST set_inst_override_by_name"), UVM_LOW);
factory.set_type_override_by_name("A", "A_ovr"); // Working
factory.set_type_override_by_name("B", "B_override"); // Working
factory.print(); // This will print info about overridden classes.
endfunction : build_phase
endclass : test
module top();
initial begin
run_test("test");
end
endmodule : top

-------------------------------------------------------

-------------------------------------------------------
//Output:
UVM_INFO @ 0: reporter [RNTST] Running test test...
UVM_INFO testbench.sv(117) @ 0: uvm_test_top [uvm_test_top] TEST set_inst_override_by_name
#### Factory Configuration (*)
No instance overrides are registered with this factory
Type Overrides:
Requested Type Override Type
-------------- -------------
A A_ovr
B B_override
All types registered with the factory: 45 total
(types without type names will not be printed)
Type Name
---------
A
A_ovr
B
B_override
B_ovr
environment
snps_uvm_reg_bank_group
snps_uvm_reg_map
test
(*) Types with no associated type name will be printed as <unknown>
####
UVM_INFO testbench.sv(11) @ 0: uvm_test_top.env.a1 [uvm_test_top.env.a1] A new
UVM_INFO testbench.sv(24) @ 0: uvm_test_top.env.a1 [uvm_test_top.env.a1] A_ovr new
UVM_INFO testbench.sv(38) @ 0: reporter [B_override] B new
UVM_INFO testbench.sv(51) @ 0: reporter [B_override] B_ovr new
UVM_INFO testbench.sv(64) @ 0: reporter [B_override] B_override new
UVM_INFO testbench.sv(38) @ 0: reporter [B_override] B new
UVM_INFO testbench.sv(51) @ 0: reporter [B_override] B_ovr new
UVM_INFO testbench.sv(64) @ 0: reporter [B_override] B_override new
UVM_INFO testbench.sv(38) @ 0: reporter [B_ovr] B new
UVM_INFO testbench.sv(51) @ 0: reporter [B_ovr] B_ovr new
UVM_INFO testbench.sv(28) @ 0: uvm_test_top.env.a1 [uvm_test_top.env.a1] HELLO from override class 'A_ovr'
UVM_INFO testbench.sv(68) @ 0: reporter [b1] HELLO from override class 'B_override'
UVM_INFO testbench.sv(68) @ 0: reporter [b2] HELLO from override class 'B_override'
UVM_INFO testbench.sv(55) @ 0: reporter [b3] HELLO from override class 'B_ovr'

-------------------------------------------------------

set_inst_override_* has high precedence than set_type_override_*.
i.e. If any particular instance of class is override by using set_inst_override_* and type of same class is overridden by using set_type_override_* then that particular instance of class is overridden by set_inst_override_* and rest other instances are overridden by set_type_override_*

-------------------------------------------------------
// set_inst_override_* hase high priority than set_type_override_*
`include "uvm.svh"
import uvm_pkg::*;
//--------------------uvm_component------------------------------
class A extends uvm_agent;
`uvm_component_utils(A)
function new (string name="A", uvm_component parent);
super.new(name, parent);
`uvm_info(get_full_name, $sformatf("A new"), UVM_LOW);
endfunction : new
virtual function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from Original class 'A'"), UVM_LOW);
endfunction : hello
endclass : A
class A_ovr extends A;
`uvm_component_utils(A_ovr)
function new (string name="A_ovr", uvm_component parent);
super.new(name, parent);
`uvm_info(get_full_name, $sformatf("A_ovr new"), UVM_LOW);
endfunction : new
function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'A_ovr'"), UVM_LOW);
endfunction : hello
endclass : A_ovr
class A_override extends A;
`uvm_component_utils(A_override)
function new (string name="A_override", uvm_component parent);
super.new(name, parent);
`uvm_info(get_full_name, $sformatf("A_override new"), UVM_LOW);
endfunction : new
function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'A_override'"), UVM_LOW);
endfunction : hello
endclass : A_override
//--------------------uvm_object------------------------------
class B extends uvm_object;
`uvm_object_utils(B)
function new (string name="B");
super.new(name);
`uvm_info(get_full_name, $sformatf("B new"), UVM_LOW);
endfunction : new
virtual function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from Original class 'B'"), UVM_LOW);
endfunction : hello
endclass : B
class B_ovr extends B;
`uvm_object_utils(B_ovr)
function new (string name="B_ovr");
super.new(name);
`uvm_info(get_full_name, $sformatf("B_ovr new"), UVM_LOW);
endfunction : new
function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'B_ovr'"), UVM_LOW);
endfunction : hello
endclass : B_ovr
class B_override extends B_ovr;
`uvm_object_utils(B_override)
function new (string name="B_override");
super.new(name);
`uvm_info(get_full_name, $sformatf("B_override new"), UVM_LOW);
endfunction : new
function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'B_override'"), UVM_LOW);
endfunction : hello
endclass : B_override
//--------------------env class--------------------
class environment extends uvm_env;
`uvm_component_utils(environment)
A a1, a2, a3;
B b1, b2, b3;
function new(string name="environment", uvm_component parent);
super.new(name, parent);
endfunction : new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
a1 = A::type_id::create("a1", this);
a2 = A::type_id::create("a2", this);
a3 = A::type_id::create("a3", this);
b1 = B::type_id::create("b1", , "path1");
b2 = B::type_id::create("b2", , "path2");
b3 = B::type_id::create("b3", , "path3");
void'(a1.hello()); // This will print from overridden class A_ovr
void'(a2.hello()); // This will print from overridden class A_ovr
void'(a3.hello()); // This will print from overridden class A_override
void'(b1.hello()); // This will print from overridden class B_ovr
void'(b2.hello()); // This will print from overridden class B_override
void'(b3.hello()); // This will print from overridden class B_override
endfunction : build_phase
endclass : environment
//-------------------test class--------------------------
class test extends uvm_test;
`uvm_component_utils(test)
environment env;
function new(string name = "test", uvm_component parent = null);
super.new(name, parent);
endfunction : new
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = environment::type_id::create("env", this);
`uvm_info(get_full_name, $sformatf("TEST set_inst_override_by_name"), UVM_LOW);
factory.set_type_override_by_type(A::get_type(), A_ovr::get_type()); // Working
factory.set_type_override_by_name("B", "B_override"); // Working
factory.set_inst_override_by_type(A::get_type(), A_override::get_type(), {get_full_name, ".", "env.a3"});
factory.set_inst_override_by_name("B", "B_ovr", "path1.b1");
factory.print(); // This will print info about overridden classes.
endfunction : build_phase
endclass : test
module top();
initial begin
run_test("test");
end
endmodule : top

-------------------------------------------------------

-------------------------------------------------------
//Output:
UVM_INFO @ 0: reporter [RNTST] Running test test...
UVM_INFO testbench.sv(122) @ 0: uvm_test_top [uvm_test_top] TEST set_inst_override_by_name
#### Factory Configuration (*)
Instance Overrides:
Requested Type Override Path Override Type
-------------- ------------------- -------------
A uvm_test_top.env.a3 A_override
B path1.b1 B_ovr
Type Overrides:
Requested Type Override Type
-------------- -------------------
A A_ovr
B B_override
All types registered with the factory: 46 total
(types without type names will not be printed)
Type Name
---------
A
A_override
A_ovr
B
B_override
B_ovr
environment
snps_uvm_reg_bank_group
snps_uvm_reg_map
test
(*) Types with no associated type name will be printed as <unknown>
####
UVM_INFO testbench.sv(7) @ 0: uvm_test_top.env.a1 [uvm_test_top.env.a1] A new
UVM_INFO testbench.sv(20) @ 0: uvm_test_top.env.a1 [uvm_test_top.env.a1] A_ovr new
UVM_INFO testbench.sv(7) @ 0: uvm_test_top.env.a2 [uvm_test_top.env.a2] A new
UVM_INFO testbench.sv(20) @ 0: uvm_test_top.env.a2 [uvm_test_top.env.a2] A_ovr new
UVM_INFO testbench.sv(7) @ 0: uvm_test_top.env.a3 [uvm_test_top.env.a3] A new
UVM_INFO testbench.sv(33) @ 0: uvm_test_top.env.a3 [uvm_test_top.env.a3] A_override new
UVM_INFO testbench.sv(47) @ 0: reporter [B_ovr] B new
UVM_INFO testbench.sv(60) @ 0: reporter [B_ovr] B_ovr new
UVM_INFO testbench.sv(47) @ 0: reporter [B_override] B new
UVM_INFO testbench.sv(60) @ 0: reporter [B_override] B_ovr new
UVM_INFO testbench.sv(73) @ 0: reporter [B_override] B_override new
UVM_INFO testbench.sv(47) @ 0: reporter [B_override] B new
UVM_INFO testbench.sv(60) @ 0: reporter [B_override] B_ovr new
UVM_INFO testbench.sv(73) @ 0: reporter [B_override] B_override new
UVM_INFO testbench.sv(24) @ 0: uvm_test_top.env.a1 [uvm_test_top.env.a1] HELLO from override class 'A_ovr'
UVM_INFO testbench.sv(24) @ 0: uvm_test_top.env.a2 [uvm_test_top.env.a2] HELLO from override class 'A_ovr'
UVM_INFO testbench.sv(37) @ 0: uvm_test_top.env.a3 [uvm_test_top.env.a3] HELLO from override class 'A_override'
UVM_INFO testbench.sv(64) @ 0: reporter [b1] HELLO from override class 'B_ovr'
UVM_INFO testbench.sv(77) @ 0: reporter [b2] HELLO from override class 'B_override'
UVM_INFO testbench.sv(77) @ 0: reporter [b3] HELLO from override class 'B_override'

-------------------------------------------------------



UVM also support override through command line,
+uvm_set_inst_override=,,
+uvm_set_type_override=,[,]

work like the name based overrides in the factory--factory.set_inst_override_by_name() and factory.set_type_override_by_name().

Let's implement same example as above using command line arguments.
-------------------------------------------------------
//--------------------uvm_component------------------------------
class A extends uvm_agent;
`uvm_component_utils(A)
function new (string name="A", uvm_component parent);
super.new(name, parent);
`uvm_info(get_full_name, $sformatf("A new"), UVM_LOW);
endfunction : new
virtual function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from Original class 'A'"), UVM_LOW);
endfunction : hello
endclass : A
class A_ovr extends A;
`uvm_component_utils(A_ovr)
function new (string name="A_ovr", uvm_component parent);
super.new(name, parent);
`uvm_info(get_full_name, $sformatf("A_ovr new"), UVM_LOW);
endfunction : new
function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'A_ovr'"), UVM_LOW);
endfunction : hello
endclass : A_ovr
class A_override extends A;
`uvm_component_utils(A_override)
function new (string name="A_override", uvm_component parent);
super.new(name, parent);
`uvm_info(get_full_name, $sformatf("A_override new"), UVM_LOW);
endfunction : new
function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'A_override'"), UVM_LOW);
endfunction : hello
endclass : A_override
//--------------------uvm_object------------------------------
class B extends uvm_object;
`uvm_object_utils(B)
function new (string name="B");
super.new(name);
`uvm_info(get_full_name, $sformatf("B new"), UVM_LOW);
endfunction : new
virtual function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from Original class 'B'"), UVM_LOW);
endfunction : hello
endclass : B
class B_ovr extends B;
`uvm_object_utils(B_ovr)
function new (string name="B_ovr");
super.new(name);
`uvm_info(get_full_name, $sformatf("B_ovr new"), UVM_LOW);
endfunction : new
function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'B_ovr'"), UVM_LOW);
endfunction : hello
endclass : B_ovr
class B_override extends B_ovr;
`uvm_object_utils(B_override)
function new (string name="B_override");
super.new(name);
`uvm_info(get_full_name, $sformatf("B_override new"), UVM_LOW);
endfunction : new
function void hello();
`uvm_info(get_full_name, $sformatf("HELLO from override class 'B_override'"), UVM_LOW);
endfunction : hello
endclass : B_override
//--------------------env class--------------------
class environment extends uvm_env;
`uvm_component_utils(environment)
A a1, a2, a3;
B b1, b2, b3;
function new(string name="environment", uvm_component parent);
super.new(name, parent);
endfunction : new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
a1 = A::type_id::create("a1", this);
a2 = A::type_id::create("a2", this);
a3 = A::type_id::create("a3", this);
b1 = B::type_id::create("b1", , "path1");
b2 = B::type_id::create("b2", , "path2");
b3 = B::type_id::create("b3", , "path3");
void'(a1.hello()); // This will print from overridden class A_ovr
void'(a2.hello()); // This will print from overridden class A_ovr
void'(a3.hello()); // This will print from overridden class A_override
void'(b1.hello()); // This will print from overridden class B_ovr
void'(b2.hello()); // This will print from overridden class B_override
void'(b3.hello()); // This will print from overridden class B_override
endfunction : build_phase
endclass : environment
//-------------------test class--------------------------
class test extends uvm_test;
`uvm_component_utils(test)
environment env;
function new(string name = "test", uvm_component parent = null);
super.new(name, parent);
endfunction : new
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = environment::type_id::create("env", this);
`uvm_info(get_full_name, $sformatf("TEST set_inst_override_by_name"), UVM_LOW);
//factory.set_type_override_by_type(A::get_type(), A_ovr::get_type()); // Working
//factory.set_type_override_by_name("B", "B_override"); // Working
//factory.set_inst_override_by_type(A::get_type(), A_override::get_type(), {get_full_name, ".", "env.a3"});
//factory.set_inst_override_by_name("B", "B_ovr", "path1.b1");
factory.print(); // This will print info about overridden classes.
endfunction : build_phase
endclass : test
module top();
initial begin
run_test("test");
end
endmodule : top

-------------------------------------------------------

Simulation time argument:
+uvm_set_inst_override=A,A_override,uvm_test_top.env.a3 \
+uvm_set_inst_override=B,B_ovr,path1.b1 \
+uvm_set_type_override=A,A_ovr \
+uvm_set_type_override=B,B_override
-------------------------------------------------------
UVM_INFO @ 0: reporter [RNTST] Running test test...
UVM_INFO @ 0: reporter [INSTOVR] Applying instance override from the command line: +uvm_set_inst_override=A,A_override,uvm_test_top.env.a3
UVM_INFO @ 0: reporter [INSTOVR] Applying instance override from the command line: +uvm_set_inst_override=B,B_ovr,path1.b1
UVM_INFO @ 0: reporter [UVM_CMDLINE_PROC] Applying type override from the command line: +uvm_set_type_override=A,A_ovr
UVM_INFO @ 0: reporter [UVM_CMDLINE_PROC] Applying type override from the command line: +uvm_set_type_override=B,B_override
UVM_INFO testbench.sv(122) @ 0: uvm_test_top [uvm_test_top] TEST set_inst_override_by_name
#### Factory Configuration (*)
Instance Overrides:
Requested Type Override Path Override Type
-------------- ------------------- -------------
A uvm_test_top.env.a3 A_override
B path1.b1 B_ovr
Type Overrides:
Requested Type Override Type
-------------- -------------------
A A_ovr
B B_override
All types registered with the factory: 46 total
(types without type names will not be printed)
Type Name
---------
A
A_override
A_ovr
B
B_override
B_ovr
environment
snps_uvm_reg_bank_group
snps_uvm_reg_map
test
(*) Types with no associated type name will be printed as <unknown>
####
UVM_INFO testbench.sv(7) @ 0: uvm_test_top.env.a1 [uvm_test_top.env.a1] A new
UVM_INFO testbench.sv(20) @ 0: uvm_test_top.env.a1 [uvm_test_top.env.a1] A_ovr new
UVM_INFO testbench.sv(7) @ 0: uvm_test_top.env.a2 [uvm_test_top.env.a2] A new
UVM_INFO testbench.sv(20) @ 0: uvm_test_top.env.a2 [uvm_test_top.env.a2] A_ovr new
UVM_INFO testbench.sv(7) @ 0: uvm_test_top.env.a3 [uvm_test_top.env.a3] A new
UVM_INFO testbench.sv(33) @ 0: uvm_test_top.env.a3 [uvm_test_top.env.a3] A_override new
UVM_INFO testbench.sv(47) @ 0: reporter [B_ovr] B new
UVM_INFO testbench.sv(60) @ 0: reporter [B_ovr] B_ovr new
UVM_INFO testbench.sv(47) @ 0: reporter [B_override] B new
UVM_INFO testbench.sv(60) @ 0: reporter [B_override] B_ovr new
UVM_INFO testbench.sv(73) @ 0: reporter [B_override] B_override new
UVM_INFO testbench.sv(47) @ 0: reporter [B_override] B new
UVM_INFO testbench.sv(60) @ 0: reporter [B_override] B_ovr new
UVM_INFO testbench.sv(73) @ 0: reporter [B_override] B_override new
UVM_INFO testbench.sv(24) @ 0: uvm_test_top.env.a1 [uvm_test_top.env.a1] HELLO from override class 'A_ovr'
UVM_INFO testbench.sv(24) @ 0: uvm_test_top.env.a2 [uvm_test_top.env.a2] HELLO from override class 'A_ovr'
UVM_INFO testbench.sv(37) @ 0: uvm_test_top.env.a3 [uvm_test_top.env.a3] HELLO from override class 'A_override'
UVM_INFO testbench.sv(64) @ 0: reporter [b1] HELLO from override class 'B_ovr'
UVM_INFO testbench.sv(77) @ 0: reporter [b2] HELLO from override class 'B_override'
UVM_INFO testbench.sv(77) @ 0: reporter [b3] HELLO from override class 'B_override'

-------------------------------------------------------

11 comments:

  1. Great post. I see some of the code is commented and for some you said not working. Is that something you tried before coming out with a working example.

    On a related note, can you add examples for parameterized class overrides ?

    ReplyDelete
    Replies
    1. Thanks :)
      Yes, I have tried commented code where I have mentioned not working.
      As of now I don't have example ready for parameterized class. I will try to do it.

      Delete
  2. Also, running the examples as it is gives error as uvm.svh is not inside package or module ?

    ReplyDelete
    Replies
    1. To Run examples, you explicitly need to give $UVM_HOME (path of UVM library) in compilation command.

      Delete
  3. Very nice article. many many thanks

    ReplyDelete
  4. you should not call set_override function , after creating environment.
    you should call it before.

    ReplyDelete
  5. Hi Sagar,
    Just wanted to know. if by any chance you tried the above overriding example for parameterized class

    ReplyDelete
  6. One more way :

    B_driver::type_id::set_type_override(D_driver::get_type());

    ReplyDelete
  7. Thank You Sagar...these are nice articles to understanding UVM fundamentals.as per your examples what ever content is not working might be a tool problem.I have tested not working code from your examples with latest version of VCS and I can see it is working after adding below code.
    uvm_factory factory; //declaration in test class
    //in build_phase function just call below line to resolve factory object
    factory = uvm_factory::get();

    also Anonymous mentioned in above chat.That would be UVM coding guide line.once we do required object overriding,then we can construct env based on new overridden objects(at least from this example).

    ReplyDelete
  8. i am facing error in set_int_override_type example

    Error (suppressible): (vsim-13215) factory_type_override.sv(121): Cannot assign an unpacked type 'class work.uvm_pkg::uvm_object_registry #(class work.factory_type_override_sv_unit::B_ovr, "B_ovr")' to a packed type 'reg'.

    Unresolved reference to 'factory' in $root.factory.print.

    i am not able to resole

    ReplyDelete
    Replies
    1. declare uvm_factory factory and write factory= uvm_factory::get(), this will work.

      Delete