Hi all,
I am confused about how to properly instantiate a virtual interface within a module. I have a simple interface as follows:
`ifndef ADDSUB_INTERFACE__SV
`define ADDSUB_INTERFACE__SV
interface addsub_if();
logic clk;
logic addsub, cin, cout;
logic [7:0] a, b, sum;
endinterface: addsub_if
`endif
Then I need to be able to access this interface from both the top-level test class as well as the _env class. Note that I am following the UVM basics series of videos in this attempt to implement my own. If this thread is better located in the UVM thread just let me know and I’ll head over there, but I believe my confusion to be a matter of SV convention.
In the videos, the virtual interface is instantiated in the my_env class, and it is not referenced at all within the my_test class, even though it is required to add it to the uvm database via:
uvm_config_db #(virtual addsub_if)::set…etc.
When I attempted to compile this way (listing addsub_env prior to addsub_test in my package), I get the following errors:
Error-[IND] Identifier not declared
8bitaddsub_tb.sv, 18
Identifier ‘addsub_vi’ has not been declared yet. If this error is not
expected, please check if you have set `default_nettype to none.
Error-[IND] Identifier not declared
8bitaddsub_tb.sv, 22
Identifier ‘addsub_vi’ has not been declared yet. If this error is not
expected, please check if you have set `default_nettype to none.
I can get my code to compile by adding another declaration within the test class, but this can’t be the correct way to go about solving the issue.
Now after that long (hopefully not confusing) explanation, my question boils down to: how do I properly instantiate a virtual interface and share it between all classes? I was hoping to avoid global variables here as well. If there is not enough information here to answer my question, please let me know and I can dig deeper. Below are my env and test classes for reference:
class my_test extends uvm_test;
`uvm_component_utils(my_test)
addsub_env addsub_env_h;
virtual addsub_if addsub_vi;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction: new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
if(!uvm_resource_db#(virtual addsub_if)::read_by_name("addsub_ifs", "addsub_vi", addsub_vi))
begin
//print("\nERROR: VIRTUAL DB INTERFACE ERROR\n\n");
end
uvm_config_db #(virtual addsub_if)::set(this, "*", "addsub_vi", addsub_vi);
addsub_env_h = addsub_env::type_id::create("addsub_env_h", this);
endfunction: build_phase
endclass: my_test
class addsub_env extends uvm_env;
`uvm_component_utils(addsub_env)
virtual addsub_if addsub_vi;
function new (string name, uvm_component parent);
super.new(name, parent);
endfunction: new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
assert(uvm_config_db #(virtual addsub_if)::get(this, "*", "addsub_vi", addsub_vi));
endfunction: build_phase
task run_phase(uvm_phase phase);
phase.raise_objection(this);
addsub_vi.a = 1;
addsub_vi.b = 1;
#10;
phase.drop_objection(this);
endtask: run_phase
endclass: addsub_env
Any guidance would be greatly appreciated. I hope that all makes sense.