In reply to irshad_mansur123:
Below is the simplest approach. The paper shows how you could use bind to insert many of these if the concrete class needs to go in many places in the hierarchy.
package test;
import uvm_pkg::*;
`include "uvm_macros.svh"
interface class backdoor_api;
pure virtual function void do_backdoor_wr();
// pure virtual function void do_backdoor_rd();
// ...
endclass
class test extends uvm_test;
`uvm_component_utils(test)
backdoor_api api_h;
function new(string name, uvm_component parent);
super.new(name,parent);
endfunction
function void connect_phase(uvm_phase phase);
if (!uvm_config_db#(backdoor_api)::get(this,"","api",api_h))
`uvm_fatal("NOAPI","API handle not set")
endfunction
task run_phase(uvm_phase phase);
api_h.do_backdoor_wr();
endtask
endclass
endpackage
module testbench_top;
import test::backdoor_api;
import uvm_pkg::*;
class concrete extends uvm_object implements backdoor_api;
function new(string name);
super.new(name);
endfunction
virtual function void do_backdoor_wr();
top.dut.block_a.mem.do_backdoor_wr();
endfunction
endclass
concrete api_h = new("api_h");
initial begin
uvm_config_db#(backdoor_api)::set(null,"*","api",api_h);
run_test("test");
end
endmodule
module top;
dut dut();
endmodule
module dut;
block block_a();
endmodule
module block;
memory mem();
endmodule
module memory;
function void do_backdoor_wr();
$display("%m doing backdoor write");
endfunction
endmodule