Hi all,
I’m trying to access a verilog hierarchy which was generated by a generate block - but I’m having some problems with it. for example:
verilog file: (let’s assume it is located at “testbench” hierarchy, and an interface named “some_interface” is already defined)
genvar i;
generate
for (i=0;i<3;i++)
begin : GENERATE_HEADER
some_interface some_interface_inst(clk);
assign some_interface_inst.x=1’b0;
assign some_interface_inst.y=1’b1;
end
systemverilog file:
virtual some_interface some_interface_arr[0:2];
for (int i=0;i<3;i++)
some_interface_arr[i]=testbench.GENERATE_HEADER[i].some_interface_inst;
I believe I can’t access a generated verilog hierarchy with a system-verilog for loop (variable i). Am I correct? and if so - is there a way to pass this obstacle?
Thanks in advance,
Eyal.
P.s - What I’m generally trying to do is to get handles to the instantiated interfaces (some_interface) and pass them to system verilog objects in my testbench, using the virtual interface array.
In order to reference an instance created inside a generate-for loop, you must use a constant or another genvar variable. That is because GENERATE_HEADER is not an array, it is part of a hierarchical scope name. So you could do
virtual some_interface some_interface_arr[0:2];
generate
for (i=0;i<3;i++)
initial some_interface_arr[i]=testbench.GENERATE_HEADER[i].some_interface_inst;
end
endgenerate
If you are using UVM/OVM you should be setting these interfaces in the config_db directly instead of assigning them to a local virtual interface array.
I am using UVM, and the reason for assigning the interfaces to a local virtual array is to
have the ability of using uvm_config_db::set with a for - loop. I’m pretty sure I can’t use
generate inside a system verilog file (as for the solution suggested). Am I wrong?
What makes you think you cannot use a generate block in SystemVerilog? If it was in Verilog–it is in SystemVerilog. You can put your uvm_config_db::set in the initial block that is inside the generate-for loop.
When we set the instantiated interfaces into uvm_config_db# from within the initial block which is inside the generate-for loop, there could be potential race condition between when the run_test() call and these interfaces are set in config_db# because they will be in different initial blocks . I have my bench structure where these interfaces are instantiated in a nested module within the top level module . I’m calling run_test() from initial block of top level module.
module tb_top
master m();
initial begin
m.set_rtl_interfaces();
run_test();
end
endmodule
function void set_rtl_interfaces();
for(int i=0;i<PORT_NUM;i=i+1) begin uvm_resource_db #(virtual vbus_mgt_interface.TB_PWR_CONNECT)::set_anonymous($psprintf({TOP_USB_ENV,“.drd_env[%0d].vbus_agent[%0d].driver”},i,i),vbus_mgt_if_array[i].TB_PWR_CONNECT);
end
endfunction : set_rtl_interfaces
endmodule
If we want to avoid the initial block in module master , we need direct access of the different instances of interface instantiated within the generate for loop.
Hi Dave,
I’m trying to something similar but for binding my assertions.
Below is my bind statement in my bind assert module:
define NUM_BLKS 4; genvar asrt_inst; generate for (asrt_inst = 0;asrt_inst < NUM_BLKS;asrt_inst = asrt_inst+1)
begin
bind top.u_dut.u_blk_gen[asrt_inst] my_assert u_my_assert (
.
);
end
endgenerate*
Here, the RTL is under gen block of u_blk_gen[gen_var], and I’m trying to bind my assertion to each instance of the generated instance.
The path instances of the RTL, generated using the generate block are :
top.u_dut.u_blk_gen[0]
top.u_dut.u_blk_gen[1]
top.u_dut.u_blk_gen[2]
top.u_dut.u_blk_gen[3]
And with the bind statement, I get the below compile error:
*
bind top.u_dut.u_blk_gen[gpt_asrt_inst] my_assert u_my_assert (
|
ncvlog: E,ILLGVR (/home/user/assertion_bind.v,165|72): This genvar cannot be used in this context [12.1.3(IEEE 2001)].
In reply to suhas.ns:
It would help to show the generate block in your RTL, but I think you are missing an instance name in your bind statement. It should be
even with the instname, I face same compilation issue.
If you are binding to all instances of a module, then you do not need an instance specific bind. You could do
bind targetname my_assert u_my_assert (
Here, I’m binding to all instances, but issue is that each RTL instance is with different parameters and the my assertion has to be binded to the RTL instance with the same set of parameters which I’ll be passing while binding. And that is the reason I’m trying to bind for each instance.
For the above RTL, I’m trying to bind my assertion as below in a similar fashion wherein even by assertion module has the same parameters:
localparam [5:0]ASRT_PARAM1_ARY[3:0] = '{16,16,32,40};
localparam [1:0]ASRT_PARAM2_ARY[3:0] = '{1,2,2,3};
genvar asrt_inst;
generate
for (asrt_inst = 0;asrt_inst < `NUM_BLKS;asrt_inst = asrt_inst+1)
begin
bind top.u_dut.u_blk_gen[asrt_inst].u_blk my_assert #(
.PARAM1(ASRT_PARAM1_ARY[asrt_inst]),
.PARAM2(ASRT_PARAM2_ARY[asrt_inst])
)
u_my_assert
(
.*//ports mapping done here
);
end
endgenerate
And below is the compilation error I get:
file: /home/user/assertion_bind.v
bind top.u_dut.u_blk_gen[asrt_inst].u_blk my_assert #(
|
ncvlog: *E,ILLGVR (/home/user/assertion_bind.v,167|68): This genvar cannot be used in this context [12.1.3(IEEE 2001)].
module worklib.assertion_bind:v