I want to access some memory part of these models so I am trying by below mentioned way
// Write randome data from backdoor of memory
for(int i= 0 ; i < `WIDTH ; i++) begin
top.dram_model.GEN_MEM_MODEL.MEM_MODEL_INST[i].i_dram0.task_name;
end
It’s not allow to use me ‘i’ variable.
It will give me error as
** Error: (vsim-3745) /home/niyati/projects/DRACO/sv_ve/verif/scripts/…/…/…//sv_ve/tests/sib_ddr3_base_test.sv(472): A variable index into the generate block ‘ddr_tb_top.dram_model.GEN_MEM_MODEL.MEM_MODEL_INST’ is illegal.
verror 3745 :
vsim Message # 3745:
A variable index was detected in a reference to the specified generate
hierarchy. The index must be an integer literal, a parameter, a localparam,
or an expression made up of them (constant expression).
It allow to use as
top.dram_model.GEN_MEM_MODEL.MEM_MODEL_INST[0].i_dram0.task_name;
top.dram_model.GEN_MEM_MODEL.MEM_MODEL_INST[1].i_dram0.task_name;
top.dram_model.GEN_MEM_MODEL.MEM_MODEL_INST[2].i_dram0.task_name;
Can you please suggest me some way by which I can use or call it in for loop inplace of writing / calling one by one
The index created by a generate loop or array if instances cannot be accessed via a dynamic variable. This restriction is mainly because of Verilog parametrization and a few other features that has the potential to make each instance unique. In a regular array, every element is the exact same type and has the exact same sub-components. The compiler must check at elaboration, not at run-time if the full path is valid.
There are several ways to get around this limitation. If you need to call all instances at once, you can create a generated loop of always blocks that wait for a trigger when you want to call all the tasks
event call_task1_name;
event call_function2_name;
genvar index;
for(index = 0; i < `WIDTH; i++) begin
always @call_task1_name
top.dram_model.GEN_MEM_MODEL.MEM_MODEL_INST[ index].i_dram0.task1_name;
always @call_function2_name
top.dram_model.GEN_MEM_MODEL.MEM_MODEL_INST[ index].i_dram0.function2_name;
end
When you trigger call_task_name, all the tasks will be called in parallel.
If you need to selectively call the tasks, then the best thing to do is wrap the calls in methods of a class
virtual class mem_model_array_c;
pure virtual task task1_name;
pure virtual function void function2_name;
endclass
mem_model_array_c mem_model_array_h[`WIDTH];
genvar index;
for(index = 0; i < `WIDTH; i++) begin :class_decl_loop
class mem_model_element_c extends mem_model_array_c;
task task1_name;
top.dram_model.GEN_MEM_MODEL.MEM_MODEL_INST[ index].i_dram0.task1_name;
endtask
function void function2_name;
top.dram_model.GEN_MEM_MODEL.MEM_MODEL_INST[ index].i_dram0.function2_name;
endfunction
endclass
mem_model_element_C mem_model_element_h = new();
initial mem_model_array_h[ index] = mem_model_element_h;
end : class_decl_loop
Now you can individually call the task or function with
mem_model_array_h[ expr].function2_name;
P.S. Please try to use parameters in packages instead of `defines for WIDTH
Please use function void for routines that do not consume time. Tasks can call other functions, but functions cannot call other tasks.
By this syntax I want to go for back door write. So I need to define one task in base test(base test is call extended from uvm_test) [I am using SV + UVM environment]. So How can use this in task or suggest me some another way.
The generate loop is to define and construct the concrete class. Instead of storing the class handle in an array, use uvm_config_db to pass it to your UVM classes
The abstract class mem_model_array_c from my original post should be defined in a package, and you will call uvm_config_db#(mem_model_array_c)::get from your UVM class. (You might want to change its name to mem_model_abstract_c)
In the same manner you would have passed a interface instance to a virtual interface variable, you are now passing a concrete class handle to an abstract class variable. That object can now be used inside your class-based UVM testbench, but because that was constructed in your module-based testbench, it will call the task/function inside the module.