Hi all,
I am working on the validation of backdoor access method and for a design having structure of register. I need to use backdoor accessing support routines i.e. uvm_hdl_deposit and uvm_hdl_read. I am able to read and write the register on the RTL side. However, when I am reading their corresponding values from the register model of Testbench their values returned is 0 always what could be the reason for this. Also, If possible please help me in clarifying how to access the multidimensional array of register through register backdoor access.
Thanks in advance for the help.
The corresponding design code of seq is specified below:
RTL code:
module slave(apb_dut_if apb,
input bit rst);
reg [31:0] pr_data;
assign apb.prdata = (apb.psel && apb.penable && !apb.pwrite) ? pr_data : 'z;
typedef struct {
reg [63:0] SRC;
reg [63:0] DST;
} socket_t;
Top level Module
module tb_top;
…//other lines
slave dut(dapb, rst);
…//other lines
endmodule: tb_top
My used seq code (snippet)
// Implemanting uvm_hdl_deposit and uvm_hdl_read method on a packed struct.
#100;
begin
string path=“tb_top.dut.SESSION[%0d].SRC”;
burst_data = 64’hABCD_ABCD_ABCD_ABCD;
begin
uvm_hdl_deposit($sformatf(path,10),burst_data);
assert(status == UVM_IS_OK);
end
begin
uvm_hdl_read($sformatf(path,10),read_data);
assert(status == UVM_IS_OK);
end
assert(read_data == burst_data) $info("SRC variable data = %0h SRC variable expected = %0h", read_data,burst_data);
else $warning("data = %0h expected = %0h", read_data,burst_data);
end
`uvm_info(get_type_name(), $sformatf("At READ desired=0x%0h mirrored=0x%0h", model.SESSION[10].SRC.get(), model.SESSION[10].SRC.get_mirrored_value()), UVM_MEDIUM)
#100;
begin
string path=“tb_top.dut.SESSION[%0d].DST”;
burst_data = 64’hFAFA_FAFA_FAFA_FAFA;
begin
uvm_hdl_deposit($sformatf(path,10),burst_data);
assert(status == UVM_IS_OK);
end
begin
uvm_hdl_read($sformatf(path,10),read_data);
assert(status == UVM_IS_OK);
end
assert(read_data == burst_data) $info(“DST variable data = %0h DST variable expected = %0h”, read_data,burst_data);
else $warning(“data = %0h expected = %0h”, read_data,burst_data);
end
`uvm_info(get_type_name(), $sformatf(“At READ desired=0x%0h mirrored=0x%0h”, model.SESSION[10].DST.get(), model.SESSION[10].DST.get_mirrored_value()), UVM_MEDIUM) //getting value 0
Snippet of RAL model related sub codes
class ral_reg_SOCKET extends uvm_reg;
rand uvm_reg_field IP;
rand uvm_reg_field PORT;
function new(string name = "SOCKET");
super.new(name, 64,build_coverage(UVM_NO_COVERAGE));
endfunction: new
virtual function void build();
this.IP = uvm_reg_field::type_id::create(“IP”,get_full_name());
this.IP.configure(this, 48, 0, “RW”, 0, 48’h0, 1, 0, 1);
this.PORT = uvm_reg_field::type_id::create(“PORT”,get_full_name());
this.PORT.configure(this, 16, 48, “RW”, 0, 16’h0, 1, 0, 1);
add_hdl_path_slice(.name(“socket_t.SRC”), .offset(0), .size(64),.first(1));//Is it correct to add hdl path like this for backdoor access?
add_hdl_path_slice(.name(“socket_t.DST”), .offset(8), .size(64),.first(1));//Is it correct to add hdl path like this for backdoor access?
endfunction: build
`uvm_object_utils(ral_reg_SOCKET)
endclass : ral_reg_SOCKET
class ral_regfile_SESSION extends uvm_reg_file;
uvm_reg regs[$];
rand ral_reg_SOCKET SRC;
rand ral_reg_SOCKET DST;
rand uvm_reg_field SRC_IP;
rand uvm_reg_field SRC_PORT;
rand uvm_reg_field DST_IP;
rand uvm_reg_field DST_PORT;
function new(string name = "SESSION");
super.new(name);
endfunction : new
virtual function void build();
this.SRC = ral_reg_SOCKET::type_id::create("SRC",,get_full_name());
this.SRC.configure(get_block(), this, "");
this.SRC.build();
this.SRC.add_hdl_path_slice("SESSION.SRC",0,64);**//Is it correct to add hdl path like this for backdoor access?**
this.SRC_IP = this.SRC.IP;
this.SRC_PORT = this.SRC.PORT;
this.regs.push_back(SRC);
this.DST = ral_reg_SOCKET::type_id::create("DST",,get_full_name());
this.DST.configure(get_block(), this, "");
this.DST.build();
this.DST.add_hdl_path_slice("SESSION.DST",0,64);**//Is it correct to add hdl path like this for backdoor access?**
this.DST_IP = this.DST.IP;
this.DST_PORT = this.DST.PORT;
this.regs.push_back(DST);
endfunction : build
virtual function void map(uvm_reg_map mp,
uvm_reg_addr_t offset);
mp.add_reg(SRC, offset+`UVM_REG_ADDR_WIDTH'h0);
mp.add_reg(DST, offset+`UVM_REG_ADDR_WIDTH'h2);
endfunction
virtual function void set_offset(uvm_reg_map mp,
uvm_reg_addr_t offset);
SRC.set_offset(mp, offset+`UVM_REG_ADDR_WIDTH'h0);
DST.set_offset(mp, offset+`UVM_REG_ADDR_WIDTH'h2);
endfunction
`uvm_object_utils(ral_regfile_SESSION)
endclass : ral_regfile_SESSION
foreach (this.SESSION[i]) begin
int J = i;
this.SESSION[J] = ral_regfile_SESSION::type_id::create($psprintf("SESSION[%0d]",J),,get_full_name());
this.SESSION[J].configure(this, null, "");
this.SESSION[J].build();
this.SESSION[J].add_hdl_path("SESSION[J]");
this.SESSION[J].map(default_map, `UVM_REG_ADDR_WIDTH'h1000+`UVM_REG_ADDR_WIDTH'h4 * J);**// AM I doing something wrong here ?**
end