How can I set/ get a struct using uvm_config_db

I’m trying to generalize my virtual sequence for different kinds of good, corner and error scenarios. Hence I’ve declared a struct in my test and declared the fields that I want to exercise in that struct. Now, from the build_phase of my test I’m setting this struct and trying to get it in the body task of my virtual sequence(as shown in the below code).

The print after setting the struct to config_db is printing the values that I’m passing, but I’m ending up with the fatal error from my sequence saying that my_s not available in data base. I tried to parameterize config db with ‘struct’ and also ‘struct my_struct’ keyword but in vain.
Please let me know how can I get a struct successfully from config_db.


//-------- TEST CASE CODE-------//
class my_test extends test_base;

typedef struct {
  bit [3:0] addr;
  string msg;
  int value;
} my_struct;

my_struct my_s;

virtual function void build_phase(uvm_phase phase);
  super.build_phase(phase);
  my_s.addr = 4'ha;
  my_s.msg = "GOOD";
  my_s.value = 1;
  uvm_config_db #(my_struct)::set(null, "*", "my_s", my_s);
  `uvm_info("build_phase", $sformatf("Set the struct in config db through build_phase of my_test and the struct looks as follows %p", my_s), UVM_LOW)
endfunction
endclass

//-------- SEQ CODE-------//
class my_vir_sequence extends virtual_seq_base;

typedef struct {
  bit [3:0] addr;
  string msg;
  int value;
} my_struct;

my_struct test_ctrls;

virtual task body();
my_sequence_item seq_item;
super.body();
if(!uvm_config_db#(my_struct)::get(null, "*", "my_s", test_ctrls))
  `uvm_fatal("body", "Coudln't get my_struct from config db")

`uvm_do_on_with(seq_item, p_sequencer, {
                  addr == test_ctrls.addr;
                  value == test_ctrls.value;
                  msg == test_ctrls.msg;
               })
endtask
endclass


Below is the print I’m getting after ‘set’ of struct in the config_db


UVM_INFO ./tb/my_test.sv(83) @ 0.00 ps: uvm_test_top [build_phase] Set the struct in config db through build_phase of my_test and the struct looks as follows '{addr:'ha, msg:"GOOD", value:1}

Below is the fatal msg printing from my sequence:


UVM_FATAL ./env/my_sequence_collection.sv(358) @ 25029958.10 ps: uvm_test_top.env.test_env_seqr@ [body] Coudln't get my_struct from config db

In reply to Shadow:

Here, there are two definitions of structure “my_struct. One definition is in the scope “my_vir_sequence::my_struct” and the other is in “my_test::my_struct”. The config db set is done for test structure type and get is done for sequence structure type. Eventhough the type names of test and sequence are same, they are in different scopes and treated differently. Henceforth the config db get is failing.

You can declare my_struct globally in your package and use it in both test and sequence.

package my_test_suite_pkg;
typedef struct {
  bit [3:0] addr;
  string msg;
  int value;
} my_struct; // single definition of my_struct
`include "my_vir_sequence.sv" // definition of my_vir_sequence class
`include "my_test.sv"  // definition of my_test class
endpackage

Or you can declare it in a separate global package and import that package in your test suite.

package my_pkg;
  typedef struct {
  bit [3:0] addr;
  string msg;
  int value;
} my_struct;
endpackage

package my_test_suite_pkg;
import my_pkg::*;
`include "my_vir_sequence.sv" // definition of my_vir_sequence class
`include "my_test.sv"  // dtion of my_test class
endpackage

Or if you don’t want to play with packages, one can use scope resolution wile getting the structure “my_test::my_struct”. But I would not prefer this option due to dependency issues.

// In sequence class:
my_test::my_struct test_ctrls;
if(!uvm_config_db#(my_test::my_struct)::get(null, "*", "my_s", test_ctrls))

Please refer to this post by Dave for more information about packages.

In reply to sharvil111:

For struct type [set & get ]Can’t we use uvm_config_db??

Thank you.

In reply to gani:

You can pass any data type to the config db. But your structs have a different space and this generates your error message.
BTW the better solution for your problem is to use configuration object (class object).

In reply to gani:

Yes you can use set/get. Here, its just that the structure is defined twice in different scopes.

In reply to sharvil111:

In reply to Shadow:
Here, there are two definitions of structure “my_struct. One definition is in the scope “my_vir_sequence::my_struct” and the other is in “my_test::my_struct”. The config db set is done for test structure type and get is done for sequence structure type. Eventhough the type names of test and sequence are same, they are in different scopes and treated differently. Henceforth the config db get is failing.
You can declare my_struct globally in your package and use it in both test and sequence.

package my_test_suite_pkg;
typedef struct {
bit [3:0] addr;
string msg;
int value;
} my_struct; // single definition of my_struct
`include "my_vir_sequence.sv" // definition of my_vir_sequence class
`include "my_test.sv"  // definition of my_test class
endpackage

Or you can declare it in a separate global package and import that package in your test suite.

package my_pkg;
typedef struct {
bit [3:0] addr;
string msg;
int value;
} my_struct;
endpackage
package my_test_suite_pkg;
import my_pkg::*;
`include "my_vir_sequence.sv" // definition of my_vir_sequence class
`include "my_test.sv"  // dtion of my_test class
endpackage

Or if you don’t want to play with packages, one can use scope resolution wile getting the structure “my_test::my_struct”. But I would not prefer this option due to dependency issues.

// In sequence class:
my_test::my_struct test_ctrls;
if(!uvm_config_db#(my_test::my_struct)::get(null, "*", "my_s", test_ctrls))

Please refer to this post by Dave for more information about packages.

Thank You sharvil111.
As this requirement is solely for my test case, I would not go with package but would get my work done using scope resolution operator. But, if I rely on scope resolution operator, then actually I don’t need to use config_db in first place, and the whole purpose of posting this question is missed :P .

In reply to Shadow:

If this is just for a small test case, then move the typedef struct outside the classes into the space . The problem not just with the uvm_config_db, but with assignment compatibility between my_s and test_ctrls. You will not be able to make assignments from one to the other except by assignments by individual members if the types are not the same.

But for any real work, please put your classes in a package