Jump to content
Sign in to follow this  
mea1201

IES 10.2 -- Using config_db to set array of interfaces

Recommended Posts

AARGH!!!

It shouldn't be this difficult, but it apparently is for me.

In my top module, I am trying to support a parametric design where the number of interfaces is determined by a parameter (let's call it num_ifs). So, I declared an array of interfaces:

my_if_type`params_map my_if[0:num_ifs-1](.*);

Later, I would like to set the UVM config DB with these interfaces, so that each agent instance gets the right virtual interface to play with. So, I tried the following:

string inst_name;
initial begin : SET_CFG_DB
  foreach(my_if[i]) begin
    $sformat(inst_name, "MY_IF[%0d]", i);
    uvm_config_db#(virtual my_if_type`params_map)::set(uvm_root::get(), "*", inst_name, my_if[i]);
end : SET_CFG_DB

IES (10.20-s105) fails at compile-time with the following:

ncvlog: *E,NOTPAR (my_top.sv,line_no|col): Illegal operand for constant expression [4(IEEE)].

The error points to the i index in the config set method call.

WTF???!!! I am at a loss here. I don't see anything wrong with what I'm trying to do. Since I have no access to other simulators (Questa, VCS), I cannot say if this problem is Cadence-specific, or a broader UVM issue.

The funny part is that I actually have several arrays of interfaces, so the initial block would have several foreach loops. I initially got an INTERNAL EXCEPTION (MESSAGE: cetpfunc unknown wad struct id 'ifs_vst') and an ncvlog.err dump. As I commented each loop out, I could bypass the INTERNAL EXCEPTION and get to the NOTPAR error described earlier.

The only work-around I can think of is to do something stupid like this:

initial begin : SET_CFG_DB
  uvm_config_db#(virtual my_if_type`params_map)::set(uvm_root::get(), "*", "MY_IF[0]", my_if[0]);
  // and so on...
end : SET_CFG_DB

Clearly, that is not an acceptable work-around for a parametric design.

Ideas? Any help? Please?

Share this post


Link to post
Share on other sites

Hello,

How about something like this:

module top #(parameter int numif=1) ();
...
generate
genvar i;
 for (i=0; i<numif; i++) begin : blk
 apb_if apbif (clock, reset);
 memctldut dut (.clock, .reset, .apbif(apbif));
 initial
   uvm_config_db#(virtual apb_if)::set(uvm_root::get(), "*",
               $sformatf("MY_IF[%0d]",i), blk[i].apbif);
 end
endgenerate
...
endmodule

It uses a generate block but could do the trick...

Kathleen

-------------------------------------------

Kathleen Meade

Verification Solutions Architect

Cadence Design Systems

--------------------------------------------

Share this post


Link to post
Share on other sites

I also had to use the genvar for assignment of the dynamic array of interfaces in the top_tb. This was VMM 1.1.1a code though and I didn't have the config database and I was using an older version of the Questa (the 6.6 series -- so it could be different now with 10). So this may be across compilers. We had to go through push-ups to get this to work. (Not the top_tb, but the assignment of physical interfaces to the vif -- because we didn't have a config_db).

The other thing you can do to be more generic -- is don't paramterize your top.

You can actually use the command line parameter set_config_int and then you can have a configuration knob to change the number of interfaces on the fly. This is really useful if you have your on internal library of IP and need to test across different configurations. IE a channel based environment that can support 3 to 10 channels depending on what product the IP is going into.

It really depends on how flexible you need your knobs and configurations to be.

Edited by lisakb1963

Share this post


Link to post
Share on other sites

Hello,

module top #(parameter int numif=1) ();
...
generate
genvar i;
for (i=0; i<numif; i++) begin : blk
apb_if apbif (clock, reset);
memctldut dut (.clock, .reset, .apbif(apbif));
initial
uvm_config_db#(virtual apb_if)::set(uvm_root::get(), "*",
$sformatf("MY_IF[%0d]",i), blk[i].apbif);
end
endgenerate
...
endmodule

Is it safe ? I mean, I use the same trick. However, I am wondering, whether it is fine, that somewhere else in top I have:

initial

Share this post


Link to post
Share on other sites

Hello,

module top #(parameter int numif=1) ();
...
generate
genvar i;
for (i=0; i<numif; i++) begin : blk
apb_if apbif (clock, reset);
memctldut dut (.clock, .reset, .apbif(apbif));
initial
uvm_config_db#(virtual apb_if)::set(uvm_root::get(), "*",
$sformatf("MY_IF[%0d]",i), blk[i].apbif);
end
endgenerate
...
endmodule

Is it safe ? I mean, I use the same trick. However, I am wondering, whether it is fine, that somewhere else in the top module I have:

initial
  run_test("My_Test")
Does it not introduce a race hazard of initial processes ? Of course, one could put start of the test as a condition in the last iteration of the generate loop, but in my opinion is not a clean solution... Edited by drianf0

Share this post


Link to post
Share on other sites

You can set a bit in each generated initial after putting the VIF into the config DB. Then, the initial that launches run_test can block until all bits have been set (wait on bitwise AND). That can ensure the build phases run after all VIF's have been put into the config DB.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×