In reply to dave_59:
Hi,
Thanks a lot for you patience and writing to help me.
Here is my simple DUT, Interface and SV-UVM TB example where I try to study the uvm_config_db implementation.
But for me this testbench looks highly complex only because of uvm_config_db usage. I wonder that is it really benefiting to create a clear SV TB code.
My idea is to simply connect the driver to the interface.
Physically I want to connect the
1.DRIVER vif port with AGENT vif port then,
2.AGENT vif port with ENV vif port then,
3.ENV vif port with the TEST vif port then
4.TEST vif port with $TOP vif instantation
this is my objective on connecting the vif using a resuable hierarchical fashion.
In order to store the vif object at each component Build_phase, created configuration objects
- my_driver_config
-contains the “virtual bus_if vif;” object declration
-instiated at AGENT component using the type_id::create()
- my_agent_config
-contains the “virtual bus_if vif;” object declration
-instantiated at ENV component using the type_id::create()
- my_env_config
-contains the “virtual bus_if vif;” object declration
-instantiated at TEST component using the type_id::create()
In order to establish the vif physical connection at different component levels, created connection at the each component connect_phase
- At AGENT
-connected the vif of AGENT to the vif of DRIVER
- At ENV
-connected the vif of ENV of the vif of AGENT
- At TEST
-do i need to connect the vif of TEST to vif of ENV ???
-I am not sure, this may not be needed, but i think that is necessary to establish physical vif connection between TEST and ENV
After all taking above cares to create a reusable, easily configurable and hierarchical TB configuration database, the simulation failed with following error
######################################################################################
UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(215) @ 0: reporter [Questa UVM] QUESTA_UVM-1.2
UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(217) @ 0: reporter [Questa UVM] questa_uvm::init(+struct)
UVM_INFO @ 0: reporter [RNTST] Running test my_test…
UVM_ERROR my_pkg.sv(144) @ 0: uvm_test_top.env_inst.agt_inst [@Agent] Virtual Interface not Configured
UVM_ERROR my_pkg.sv(87) @ 0: uvm_test_top.env_inst.agt_inst.drv [@Driver] Virtul interface not configured!
UVM_FATAL @ 0: reporter [BUILDERR] stopping due to build errors
— UVM Report Summary —
** Report counts by severity
UVM_INFO : 3
UVM_WARNING : 0
UVM_ERROR : 2
UVM_FATAL : 1
** Report counts by id
[@Agent] 1
[@Driver] 1
[BUILDERR] 1
[Questa UVM] 2
[RNTST] 1
** Note: $finish : /applics/mentor/questa10.1c/questa_sim/linux/…/verilog_src/uvm-1.1b/src/base/uvm_report_object.svh(277)
Time: 0 ns Iteration: 21 Region: /uvm_pkg::uvm_phase::m_run_phases
#######################################################################################
Now this is beyond my SV-UVM knowledge to fix this error and I hope I had followed the uvm_config_db principles. But finally failed
Please help. !!!
Copying here my source code for your reference…
package my_pkg;
import uvm_pkg::*;
include "uvm_macros.svh" //------------------------------------------------------------------------// class my_seq_item extends uvm_sequence_item;
uvm_object_utils(my_seq_item)
rand logic [31:0] opA;
rand logic [31:0] opB;
rand logic [1:0] cmd;
logic [31:0] result;
function new(string name = “my_seq_item”);
super.new(name);
endfunction: new
endclass: my_seq_item
class my_seq extends uvm_sequence #(my_seq_item);
`uvm_object_utils(my_seq)
function new(string name = “my_seq”);
super.new(name);
endfunction: new
task body();
my_seq_item tx;
repeat(5)
begin
start_item(tx);
tx = my_seq_item::type_id::create(“tx”);
if (!tx.randomize) begin
uvm_error("@Body Task", "Failed to randominze the seq item") end finish_item(tx); end endtask endclass //------------------------------------------------------------------------// class my_driver_config extends uvm_object;
uvm_object_utils(my_driver_config)
virtual bus_if vif;
function new(string name = “my_driver_config”);
super.new(name);
endfunction: new
endclass: my_driver_config
//------------------------------------------------------------------------//
class my_agent_config extends uvm_object;
`uvm_object_utils(my_agent_config)
virtual bus_if vif;
bit has_driver;
function new(string name = “my_agent_config”);
super.new(name);
endfunction: new
endclass: my_agent_config
//------------------------------------------------------------------------//
class my_env_config extends uvm_object;
`uvm_object_utils(my_env_config)
virtual bus_if vif;
//my_agent_config agt_cfg;
function new(string name = “my_env_config”);
super.new(name);
endfunction: new
endclass: my_env_config
//------------------------------------------------------------------------//
class my_driver extends uvm_driver #(my_seq_item);
`uvm_component_utils(my_driver)
virtual bus_if vif;
my_driver_config drv_cfg;
function new(string name = “my_driver”, uvm_component parent = null);
super.new(name, parent);
endfunction: new
function void build_phase (uvm_phase phase);
super.build_phase(phase);
drv_cfg = my_driver_config::type_id::create("drv_cfg");
if (!uvm_config_db #(virtual bus_if)::get(this, "", "vif_cfg_drv", drv_cfg.vif)) begin
`uvm_error("@Driver","Virtul interface not configured!")
end
endfunction: build_phase
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
vif = drv_cfg.vif;
endfunction : connect_phase
task run_phase (uvm_phase phase);
my_seq_item tx;
tx = my_seq_item::type_id::create(“tx”);
forever begin
seq_item_port.get_next_item(tx);
vif.opA <= tx.opA;
vif.opB <= tx.opB;
vif.cmd <= tx.cmd;
tx.result = vif.res;
seq_item_port.item_done(tx);
end
endtask: run_phase
endclass: my_driver
//------------------------------------------------------------------------//
class my_monitor extends uvm_monitor;
`uvm_component_utils(my_monitor)
uvm_analysis_port #(my_seq_item) mon_ap;
function new(string name = “my_monitor”, uvm_component parent = null);
super.new(name, parent);
endfunction: new
endclass: my_monitor
//------------------------------------------------------------------------//
typedef uvm_sequencer #(my_seq_item) my_sequencer;
//------------------------------------------------------------------------//
class my_agent extends uvm_agent;
`uvm_component_utils(my_agent)
my_driver drv;
my_sequencer sqr;
my_monitor mon;
my_agent_config agt_cfg;
my_driver_config drv_cfg;
//virtual bus_if vif;
function new(string name = “my_agent”, uvm_component parent = null);
super.new(name, parent);
endfunction: new
function void build_phase(uvm_phase phase);
agt_cfg = my_agent_config::type_id::create("agt_cfg");
drv_cfg = my_driver_config::type_id::create("drv_cfg");
if (!uvm_config_db #(my_agent_config)::get(this, "", "my_agent_config", agt_cfg)) begin
`uvm_error("@Agent","Virtual Interface not Configured")
end
uvm_config_db #(my_driver_config)::set(null,"drv","vif_cfg_drv", drv_cfg);
drv = my_driver::type_id::create("drv", this);
sqr = my_sequencer::type_id::create("sqr", this);
mon = my_monitor::type_id::create("mon", this);
endfunction: build_phase
function void connect_phase(uvm_phase phase);
drv.seq_item_port.connect(sqr.seq_item_export);
drv_cfg.vif = agt_cfg.vif;
endfunction : connect_phase
endclass: my_agent
//------------------------------------------------------------------------//
class my_env extends uvm_env;
`uvm_component_utils(my_env)
my_env_config env_cfg;
my_agent_config agt_cfg;
my_agent agt_inst;
function new(string name = “my_env”, uvm_component parent = null);
super.new(name, parent);
endfunction: new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
agt_inst = my_agent::type_id::create(“agt_inst”, this);
env_cfg = my_env_config::type_id::create(“env_cfg”);
agt_cfg = my_agent_config::type_id::create(“agt_cfg”);
if (!uvm_config_db #(my_env_config)::get(this,“”,“my_env_config”,env_cfg)) begin
`uvm_fatal(“@Env”,“Unable to get Environment Configuration!”)
end
uvm_config_db #(my_agent_config)::set(null,"agt_inst","my_agent_config",agt_cfg);
endfunction: build_phase
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
agt_cfg.vif = env_cfg.vif;
endfunction : connect_phase
endclass: my_env
//------------------------------------------------------------------------//
class my_test extends uvm_test;
`uvm_component_utils(my_test)
my_env env_inst;
my_env_config env_cfg;
virtual bus_if vif;
function new(string name = “my_test”, uvm_component parent = null);
super.new(name, parent);
endfunction : new
function void build_phase (uvm_phase phase);
super.build_phase(phase);
env_inst = my_env::type_id::create("env_inst", this);
env_cfg = my_env_config::type_id::create("env_cfg");
if (!uvm_config_db #(virtual bus_if)::get(this,"","vif_cfg_top",vif)) begin
`uvm_error("My_TEST","Cannot find VIF configuration!")
end
env_cfg.vif = vif;
uvm_config_db #(my_env_config)::set(this,"env_inst","my_env_config",env_cfg);
endfunction: build_phase
task run_phase (uvm_phase phase);
my_seq seq_inst;
phase.raise_objection(this, "Starting Test");
seq_inst = my_seq::type_id::create("seq_inst", this);
if (!seq_inst.randomize) begin
`uvm_error("@Test Run Phase","Randomization Failed")
end
seq_inst.start(env_inst.agt_inst.sqr);
phase.drop_objection(this, "Finised Test");
endtask : run_phase
endclass: my_test
endpackage: my_pkg
//------------------------------------------------------------------------//
interface bus_if;
logic [31:0] opA;
logic [31:0] opB;
logic [31:0] res;
logic [1:0] cmd;
endinterface: bus_if
//------------------------------------------------------------------------//
module top_tb();
import uvm_pkg::;
import my_pkg::;
bus_if vif();
my_dut dut (.bus(vif));
initial
begin
//uvm_config_db #(virtual bus_if)::set(null, “uvm_test_top”,“vif_cfg_top”, vif) ;
uvm_config_db #(virtual bus_if)::set(uvm_root::get(), “*”,“vif_cfg_top”, vif) ;
run_test();
end
endmodule: top_tb
//------------------------------------------------------------------------//
module my_dut(interface bus);
logic [31:0] out;
always_comb
case(bus.cmd)
2’b00 : bus.res = bus.opA + bus.opB;
2’b01 : bus.res = bus.opA - bus.opB;
2’b10 : bus.res = bus.opA * bus.opB;
2’b11 : bus.res = bus.opA + bus.res;
endcase
endmodule: my_dut
//------------------------------------------------------------------------//