I am running into a “Illegal operand for constant expression” when access an array of interface that was created by generate statement in testbench
Here is my code -
On the verilog side, I have
interface sub_interface;
endinterface
interface main_interface
genvar i;
generate
for (i =0;i< SUB_NUM;i++) begin :sub_vif
sub_interface sub_vif_h ();
end
endgenerate
endinterface
I then instantiate the main_interface and pass it to the UVM monitor by config_db set/get pair.
On the UVM side in the monitor, I was able to retrieve the main_interface object. However, I am not able to access the sub_interface objects by an index id. For example
class my_monitor extends uvm_collector;
virtual main_interface my_main_vif_h;
virtual sub_interface my_sub_vif_h;
function foo(int index);
my_sub_vif_h = my_main_vif_h.sub_vif[index].sub_vif_h;
endfunction
endclass
I got “Illegal operand for constant expression” error on the foo() during compile time. I can however do this
my_sub_vif_h = my_main_vif_h.sub_vif[0].sub_vif_h;
So it means my hierarchical path is correct.
So why is the compile error in the foo()? What is a solution to get the sub_interface instance by index?
You cannot select an array of instances or a generated loop of instances with a variable. Arrays of scopes are not the same as arrays of variables.
You can create an array of virtual interface variables
interface main_interface;
virtual sub_interface sub_vif_h[SUB_NUM];
for (genvar i =0;i< SUB_NUM;i++) begin :sub_vif
sub_interface sub ();
initial sub_vif_h[i] = sub;
end
endinterface
In reply to Michaelotus:
You cannot select an array of instances or a generated loop of instances with a variable. Arrays of scopes are not the same as arrays of variables.
You can create an array of virtual interface variables
interface main_interface;
virtual sub_interface sub_vif_h[SUB_NUM];
for (genvar i =0;i< SUB_NUM;i++) begin :sub_vif
sub_interface sub ();
initial sub_vif_h[i] = sub;
end
endinterface
Thank you Dave. I gave the suggestion a try. I got this error
Virtual interface declaration is not allowed here [SystemVerilog]
at the virtual declaration line. I am using xcelium. Is this a limit of Cadence or LRM?
In reply to dave_59:
Thank you Dave. I gave the suggestion a try. I got this error
Virtual interface declaration is not allowed here [SystemVerilog]
at the virtual declaration line. I am using xcelium. Is this a limit of Cadence or LRM?
OK. I figured out.
The module interface is static in nature. It does not allow the virtual dynamic concept.
However, interface can have structured data member which that has virtual dynamic concept.
So the solution is to create a struct contains virtual interface handles and cheats the interface.
Bellow code will work
interface main_interface;
sub_if_wrap my_sub_if_wrap;
for (genvar i =0;i< SUB_NUM;i++) begin :sub_vif
sub_interface sub ();
initial my_sub_if_wrap.sub_vif_h[i] = sub;
end
endinterface
[/quote]
Above creates sub interface instances and store their handles in the virtual interface array in the warp structure
This typedef MUST be defined in the package, otherwise will get an elaboration error “Disallowed virtual interface hierarchical reference object type” in the function foo()
Then in the monitor code, retrieve the sub interface
class my_monitor extends uvm_collector;
virtual main_interface my_main_vif_h;
virtual sub_interface my_sub_vif_h;
function foo(int index);
my_sub_vif_h = my_main_vif_h.my_sub_if_wrap.sub_vif_h[i];
endfunction
endclass