Readmemh, hierarchical path of instance and strings

Hi,
I have a UVM environment and inside the DUT (deep inside) I have a rom. I want to use the readmemh to preload the rom before run_phase.
According to readmemh the format is readmemh(file, mem_instance).
While I don’t have problem to pass the file (including the path) using defines but my problem is the path of the instance.
The path of the rom instance is something like dut_shell.xxx.dut.u_inst1.u_inst2.u_rom and the actual array inside the rom is being declared as

reg [7:0] rom[0:127];

At the same time the vendor has a task to access the rom as

task readRom;
input [((256*8)-1):0] path;
begin 
  readmemh(path, rom.otp);
end
endtask

My questions here are
a) Is there a way to access the rom task and pass the filename from i.e any uvm phase i.e pre_reset
b) It seems I can not use the readmhem from the pre_reset phase using the above hierarchical path. Questa does like instance paths.
I converted those paths into string (also the path before the array) and Questa was complaining that the 2nd arg is not a memory
How do I put a hierarchical instance path

Thanks

In reply to prince7273:

You can do a variation of what I describe in my Missing Link paper.

What I suggest is similar to what you do with a virtual interface, except I’m going to use an interface class.

Put this interface class definition in a package that’s actable to both your UVM component and the top-level test bench module where you setup your uvm_config_db::set()s before calling run_test. (You can also put this into an existing configuration object instead of creating a separate one.

interface class memory_abstract;
  pure virtual task readmem(string path);
endclass

Then in your test bench module, you will create a “concrete” class, an put a

module tb_top;

class memory_concrete implements memory_abstract;
  task readmem(string path);
   dut_shell.xxx.dut.u_inst1.u_inst2.u_rom.readrom({>>{path}});
  endtask
endclass

memory_concrete mc = new;

initial begin
   ...
   umm_config_db#(memory_abstract)::set(null,"","mc",mc);
   ...
   run_test();
end
...

In your testbench component:

memory_abstract ma;
task pre_reset(uvm_phase phase);
  uvm_config_db#(memory_abstract)::get(this,"","mc", ma);
  ma.readmem(mypath);

In reply to dave_59:
can you please explain what will below line do?
dut_shell.xxx.dut.u_inst1.u_inst2.u_rom.readrom({{>>{path}});

Hi Dave.
For your first solution is a bit hard to implement it right now but I will.
In the meantime I came up with the following solution

`define OTP_ROM_FILE_PATH “…/src/rcf/”

task load_otp_rom_from_file (input string file_name);

static reg    [7:0] otp_buffer[0:127];
string file = file_name;
string path = `OTP_ROM_FILE_PATH;
string otp_file = {path,file};
string idx;
string full_path_of_otp;    
string otp_path = `STRING(`PRJ_DIG_TOP(0).otp_0.slp_tsmc180g33_128x8_cm4d_ak_0.slp);
 
$readmemh(otp_file, otp_buffer);
 
foreach (otp_buffer[i]) begin
     idx.itoa(i);
     full_path_of_otp = {otp_path,".otp[","idx]"};           
     void'(uvm_hdl_deposit({otp_path,".otp[",idx,"]"}, otp_buffer[i]));          
end
 
`uvm_info(get_type_name(), $sformatf("The OTP ROM was programmed from file..."), UVM_LOW)
 

endtask : load_otp_rom_from_file

and from the reset_phase you just call the task

static reg [7:0] otp[0:127];
$readmemh(`OTP_ROM_FILE(test_otp_differential_read_controller.rcf), otp);

I used the uvm_hdl_deposit to access the rom and I was converting the idx as string
It works.

I will implement your second solution and let you know

In reply to juhi_880:

I had a typo with an extra {.

{>>{path}} converts the string to the fixed sized vactor reg [((256*8)-1):0] path;, which is how Verilog represented strings before SystemVerilog came along with the string datatype.