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.