Problems with uvm_config_db#()::get() in a class called tinyalu_agent_cfg

Hello, everybody, i’m novice in UVM SystemVerilog. I trying to understand making my own practice based on Tinyalu core that simply make operation (add,and,xor) in one cycle clock and mul in three cycles over operand in 8 bits unsigned.
The objetives is make an Agent with the next components: 1-command_monitor(receive command from interface throught write_command function and send the command(command transaction) to subscribers with a uvm_analysis_port (put)).
2-result_monitor(idem before component, but using result transaction)
3-Coverage subscriber #(command transaction).
4-Scoreboard subscriber # (coommand/result transactions)
5- tester(put_port) → fifo → (get_port)driver–> write tinyalu_bfm optionally configuration using is_active (uvm_active_passive_enum)

Basically the chapter is about understand UVM agent concept; the test instanciate two agents and two tinyalu designs, the first is_active ACTIVE, and second is_active PASSIVE because the stimulus use an module called tester_module(virtual tinyalu bfm).

tinyalu_agent_cfg:


class tinyalu_agent_cfg ;
virtual tinyalu_bfm bfm ;
protected uvm_active_passive_enum is_active;

function new(virtual tinyalu_bfm bfm, uvm_active_passive_enum is_active);
this.bfm =bfm ;
this.is_active=is_active;
endfunction

function uvm_active_passive_enum get_is_active();
return is_active;
endfunction
endclass: tinyalu_agent_cfg

class tinyalu_agent extends uvm_agent;
`uvm_component_utils(tinyalu_agent)

tinyalu_agent_cfg tinyalu_agent_cfg_h ;

scoreboard scoreboard_h ;
coverage coverage_h ;
result_monitor result_monitor_h ;
command_monitor command_monitor_h ;
tester tester_h ;
driver driver_h ;

uvm_tlm_fifo #(command_transaction) command_f ;
uvm_analysis_port #(command_transaction) cmd_ap ;
uvm_analysis_port #(result_transaction) result_ap ;

function new(string name=“”,uvm_component parent) ;
super.new(name,parent) ;
endfunction

function void build_phase(uvm_phase phase);

if(!uvm_config_db#(tinyalu_agent_cfg)::get(this,"","config",tinyalu_agent_cfg_h))
`uvm_fatal("Tinyalu agent","Failed to get agent config") 
is_active=tinyalu_agent_cfg_h.get_is_active();

if(get_is_active()==UVM_ACTIVE)
  begin:make_stimulus
    command_f=new("command_f",this)                  ;
    tester_h=tester::type_id::create("tester_h",this);
    driver_h=driver::type_id::create("driver_h",this);
  end

scoreboard_h     =scoreboard::type_id::create("scoreboard_h",this)          ;
coverage_h       =coverage::type_id::create("coverage_h",this)              ;

result_monitor_h =result_monitor::type_id::create("result_monitor_h",this)  ;
command_monitor_h=command_monitor::type_id::create("command_monitor_h",this);

cmd_ap           =new("cmd_ap",this)                                        ;
result_ap        =new("result_ap",this)                                     ;

endfunction

function void connect_phase(uvm_phase phase) ;

if(get_is_active()==UVM_ACTIVE)
  begin:make_connections
    driver_h.command_port.connect(command_f.get_export)         ;
    tester_h.command_port.connect(command_f.put_export)         ;
  end

command_monitor_h.ap.connect(cmd_ap)                            ;
result_monitor_h.ap.connect(result_ap)                          ;

command_monitor_h.ap.connect(scoreboard_h.cmd_f.analysis_export);
command_monitor_h.ap.connect(coverage_h.analysis_export)        ;
result_monitor_h.ap.connect(scoreboard_h.analysis_export)       ;

endfunction

endclass

********************Finally the Modelsim 10.6d stop the simulation **************************

End time: 12:53:09 on Oct 04,2023, Elapsed time: 0:01:24

Errors: 0, Warnings: 0

*********** IMPORTANT RELEASE NOTES ************

You are using a version of the UVM library that has been compiled

with `UVM_NO_DEPRECATED undefined.

See 404 for more details.

You are using a version of the UVM library that has been compiled

with `UVM_OBJECT_MUST_HAVE_CONSTRUCTOR undefined.

See 404 for more details.

(Specify +UVM_NO_RELNOTES to turn off this notice)

UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(215) @ 0: reporter [Questa UVM] QUESTA_UVM-1.2.3

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 dual_test…

UVM_FATAL tb_classes/tinyalu_agent.svh(25) @ 0: uvm_test_top.env_h.class_agent_h [Tinyalu agent] Failed to get agent config

I don`t no why !!!

In reply to JorgeCanadea:

Please share the code for uvm_config_db#(tinyalu_agent_cfg)::set ?
Also it would be easier for us to help if you could share an edalink of your UVM testbench.

Hello, well first put code about env_cgf

class env_cfg;

virtual tinyalu_bfm class_bfm;
virtual tinyalu_bfm module_bfm;

function new(virtual tinyalu_bfm class_bfm, virtual tinyalu_bfm module_bfm);
this.class_bfm=class_bfm;
this.module_bfm=module_bfm;
endfunction

endclass

class env extends uvm_env;

`uvm_component_utils(env)

tinyalu_agent class_tinyalu_h,module_tinyalu_h ;
tinyalu_agent_cfg class_tinyalu_cfg_h,module_tinyalu_cfg_h ;

function new(string name, uvm_component parent)             ;
  super.new(name,parent)                                    ;
endfunction :new

function void build_phase(uvm_phase phase)                  ;
  virtual tinyalu_bfm class_bfm                             ;
  virtual tinyalu_bfm module_bfm                            ;
  env_cfg env_cfg_h                                         ;
  
  if(!uvm_config_db#(env_cfg)::get(this,"","config",env_cfg_h))
  `uvm_fatal("ENVIRONMENT","Failed to get RANDOM test")

  class_tinyalu_cfg_h =new(.bfm(env_cfg_h.class_bfm),.is_active(UVM_ACTIVE))  ;
  module_tinyalu_cfg_h=new(.bfm(env_cfg_h.module_bfm),.is_active(UVM_PASSIVE));

  uvm_config_db#(tinyalu_agent_cfg)::set(this,"class_agent_config","config",class_tinyalu_cfg_h)  ;
  uvm_config_db#(tinyalu_agent_cfg)::set(this,"module_agent_config","config",module_tinyalu_cfg_h);

  class_tinyalu_h =new("class_agent_h",this) ;
  module_tinyalu_h=new("module_agent_h",this);

endfunction :build_phase

endclass

The error ModelSim reference is: " UVM_FATAL tb_classes/tinyalu_agent.svh(25) @ 0: uvm_test_top.env_h.class_agent_h [Tinyalu agent] Failed to get agent config"


class tinyalu_agent extends uvm_agent;
`uvm_component_utils(tinyalu_agent)

tinyalu_agent_cfg tinyalu_agent_cfg_h ;

scoreboard scoreboard_h ;
coverage coverage_h ;
result_monitor result_monitor_h ;
command_monitor command_monitor_h ;
tester tester_h ;
driver driver_h ;

uvm_tlm_fifo #(command_transaction) command_f ;
uvm_analysis_port #(command_transaction) cmd_ap ;
uvm_analysis_port #(result_transaction) result_ap ;

function new(string name=“”,uvm_component parent) ;
super.new(name,parent) ;
endfunction

function void build_phase(uvm_phase phase);

if(!uvm_config_db#(tinyalu_agent_cfg)::get(this,"","config",tinyalu_agent_cfg_h))
`uvm_fatal("Tinyalu agent","Failed to get agent config") 
is_active=tinyalu_agent_cfg_h.get_is_active();

if(get_is_active()==UVM_ACTIVE)
  begin:make_stimulus
    command_f=new("command_f",this)                  ;
    tester_h=tester::type_id::create("tester_h",this);
    driver_h=driver::type_id::create("driver_h",this);
  end

scoreboard_h     =scoreboard::type_id::create("scoreboard_h",this)          ;
coverage_h       =coverage::type_id::create("coverage_h",this)              ;

result_monitor_h =result_monitor::type_id::create("result_monitor_h",this)  ;
command_monitor_h=command_monitor::type_id::create("command_monitor_h",this);

cmd_ap           =new("cmd_ap",this)                                        ;
result_ap        =new("result_ap",this)                                     ;

endfunction

function void connect_phase(uvm_phase phase) ;

if(get_is_active()==UVM_ACTIVE)
  begin:make_connections
    driver_h.command_port.connect(command_f.get_export)         ;
    tester_h.command_port.connect(command_f.put_export)         ;
  end

command_monitor_h.ap.connect(cmd_ap)                            ;
result_monitor_h.ap.connect(result_ap)                          ;

command_monitor_h.ap.connect(scoreboard_h.cmd_f.analysis_export);
command_monitor_h.ap.connect(coverage_h.analysis_export)        ;
result_monitor_h.ap.connect(scoreboard_h.analysis_export)       ;

endfunction

endclass

Run this with +UVM_UVM_CONFIG_DB_TRACE and grep for tinyalu_agent_cfg.
Look for the set() and get() calls and identify the mismatch.

Transcript out is :

# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(215) @ 0: reporter [Questa UVM] QUESTA_UVM-1.2.3

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 verilog_src/uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/GET] Configuration ‘.recording_detail’ (type int) read by = null (failed lookup)

UVM_INFO verilog_src/uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/GET] Configuration ‘.recording_detail’ (type reg signed[4095:0]) read by = null (failed lookup)

UVM_INFO verilog_src/uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/SET] Configuration ‘.recording_detail’ (type int) set by = (int) 0

UVM_INFO verilog_src/uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/SET] Configuration ‘.recording_detail’ (type reg signed[4095:0]) set by = (reg signed[4095:0]) 0

UVM_INFO verilog_src/uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/SET] Configuration ‘*.class_bfm’ (type virtual tinyalu_bfm) set by = (virtual tinyalu_bfm) /top/class_bfm

UVM_INFO verilog_src/uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/SET] Configuration ‘*.module_bfm’ (type virtual tinyalu_bfm) set by = (virtual tinyalu_bfm) /top/module_bfm

UVM_INFO verilog_src/uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/GET] Configuration ‘uvm_test_top.recording_detail’ (type reg signed[4095:0]) read by uvm_test_top = (reg signed[4095:0]) 0

UVM_INFO @ 0: reporter [RNTST] Running test dual_test…

UVM_INFO verilog_src/uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/GET] Configuration ‘uvm_test_top.module_bfm’ (type virtual tinyalu_bfm) read by uvm_test_top = (virtual tinyalu_bfm) /top/module_bfm

UVM_INFO verilog_src/uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/GET] Configuration ‘uvm_test_top.class_bfm’ (type virtual tinyalu_bfm) read by uvm_test_top = (virtual tinyalu_bfm) /top/class_bfm

UVM_INFO verilog_src/uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/SET] Configuration ‘uvm_test_top.env_h*.config’ (type class tinyalu_pkg::env_cfg) set by uvm_test_top = (class tinyalu_pkg::env_cfg) /top/class_bfm /top/module_bfm

UVM_INFO verilog_src/uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/GET] Configuration ‘uvm_test_top.env_h.recording_detail’ (type reg signed[4095:0]) read by uvm_test_top.env_h = (reg signed[4095:0]) 0

UVM_INFO verilog_src/uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/GET] Configuration ‘uvm_test_top.env_h.config’ (type class tinyalu_pkg::env_cfg) read by uvm_test_top.env_h = (class tinyalu_pkg::env_cfg) /top/class_bfm /top/module_bfm

UVM_INFO verilog_src/uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/SET] Configuration ‘uvm_test_top.env_h.class_agent_config.config’ (type class tinyalu_pkg::tinyalu_agent_cfg) set by uvm_test_top.env_h = (class tinyalu_pkg::tinyalu_agent_cfg) /top/class_bfm UVM_ACTIVE

UVM_INFO verilog_src/uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/SET] Configuration ‘uvm_test_top.env_h.module_agent_config.config’ (type class tinyalu_pkg::tinyalu_agent_cfg) set by uvm_test_top.env_h = (class tinyalu_pkg::tinyalu_agent_cfg) /top/module_bfm UVM_PASSIVE

UVM_INFO verilog_src/uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/GET] Configuration ‘uvm_test_top.env_h.class_agent_h.recording_detail’ (type reg signed[4095:0]) read by uvm_test_top.env_h.class_agent_h = (reg signed[4095:0]) 0

UVM_INFO verilog_src/uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/GET] Configuration ‘uvm_test_top.env_h.module_agent_h.recording_detail’ (type reg signed[4095:0]) read by uvm_test_top.env_h.module_agent_h = (reg signed[4095:0]) 0

UVM_INFO verilog_src/uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/GET] Configuration ‘uvm_test_top.env_h.class_agent_h.config’ (type class tinyalu_pkg::tinyalu_agent_cfg) read by uvm_test_top.env_h.class_agent_h = null (failed lookup)

UVM_FATAL tb_classes/tinyalu_agent.svh(25) @ 0: uvm_test_top.env_h.class_agent_h [Tinyalu agent] Failed to get agent config

In reply to JorgeCanadea:

I’d work on these 2 lines of code:

uvm_config_db #(tinyalu_agent_cfg)::set(this,"class_agent_config","config",class_tinyalu_cfg_h);
uvm_config_db#(tinyalu_agent_cfg)::set(this,"module_agent_config","config",module_tinyalu_cfg_h);

Use as the 2nd argument a wildcard. Then you can see if something is wrong with your path where you are doing the get. It should look like this:

uvm_config_db #(tinyalu_agent_cfg)::set(this,"*","config",class_tinyalu_cfg_h);
uvm_config_db#(tinyalu_agent_cfg)::set(this,"*","config",module_tinyalu_cfg_h);

There are 3 lines with that string. Here is a shorter version. You are calling set() with “class_agent_config” UVM_ACTIVE and “module_agent_config” UVM_PASSIVE, but reading it with “config”. Wildcards won’t help as you set two different values.

SET ‘uvm_test_top.env_h.class_agent_config.config’ (type tinyalu_agent_cfg) set by uvm_test_top.env_h = (class tinyalu_agent_cfg) /top/class_bfm UVM_ACTIVE
SET ‘uvm_test_top.env_h.module_agent_config.config’ (type tinyalu_agent_cfg) set by uvm_test_top.env_h = (class tinyalu_agent_cfg) /top/module_bfm UVM_PASSIVE
GET ‘uvm_test_top.env_h.class_agent_h.config’ (type tinyalu_agent_cfg) read by uvm_test_top.env_h.class_agent_h = null (failed lookup)

Well, i have good news, when i don`t understand UVM make me feel frustrated. The problem is in the below lines in the environment uvm_component:

SOLUTION:

class env extends uvm_env;

`uvm_component_utils(env)

tinyalu_agent class_tinyalu_h,module_tinyalu_h ;
tinyalu_agent_cfg class_tinyalu_cfg_h,module_tinyalu_cfg_h ;

function new(string name, uvm_component parent) ;
super.new(name,parent) ;
endfunction :new

function void build_phase(uvm_phase phase) ;
virtual tinyalu_bfm class_bfm ;
virtual tinyalu_bfm module_bfm ;
env_cfg env_cfg_h ;

if(!uvm_config_db#(env_cfg)::get(this,“”,“config”,env_cfg_h))
`uvm_fatal(“ENVIRONMENT”,“Failed to get RANDOM test”)

class_tinyalu_cfg_h =new(.bfm(env_cfg_h.class_bfm),.is_active(UVM_ACTIVE)) ;
module_tinyalu_cfg_h=new(.bfm(env_cfg_h.module_bfm),.is_active(UVM_PASSIVE));

uvm_config_db# (tinyalu_agent_cfg)::set(this,“class_agent_config”<–(WRONG)!!REPLACE BY–>“class_tinyalu_h*”,“config”,class_tinyalu_cfg_h);
uvm_config_db#(tinyalu_agent_cfg)::set(this,“module_agent_config”<–(WRONG)!!..REPLACE BY–>“module_tinyalu_h*”,“config”,module_tinyalu_cfg_h);

class_tinyalu_h =new(“class_agent_h”,this) ;
module_tinyalu_h=new(“module_agent_h”,this);

endfunction :build_phase

endclass


thank all!! for the answers. And do you know about one book or tutorial with a complete guide of theory about UVM System Verilog pure definitions,examples,applications? Than you again.

In reply to JorgeCanadea:

Here is a paper for reference : Hierarchical Testbench Configuration using uvm_config_db

Here is the correct link for the paper Hierarchical Testbench Configuration using uvm_config_db

This is an older paper from 2014, before many companies had performance issues with the uvm_config_db. Personally, I would discourage automatic configuration as this triggers many calls to get(), which has performance issues. In your build_phase(), don’t call super.build_phase(). Instead, use configuration objects as they shrink the DB by 10-50x, and simplify passing multiple values through the testbench hierarchy.

Speaking of performance, avoid any “inst_name” (the second argument) that starts with “*” wildcard, as this regular expression will partially match with ANY scope, causing performance to plummet. One company’s build_phase() took 24 hours until they removed these wildcards and moved configuration variables into configuration classes.

Finally, set_config_int() is leftover from OVM.