Backdoor Access for a packed Structure of different register and an unpacked multi-dimension array of register

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

In reply to Abhishek kumar Diwakar:
uvm_hdl_deposit and uvm_hdl_read are not specific register backdoor routines. They can be used in any place also without a register model.

The uvm_hdl_read/uvm_hdl_deposit are restricte to integral data types.
See the definition of

function int uvm_hdl_deposit(string path, uvm_hdl_data_t value);
uvm_hdl_data_t

is the following

typedef logic [UVM_HDL_MAX_WIDTH-1:0] uvm_hdl_data_t;

Did you check the HDL path? Does it exist?. If the return value is 0 this ccould be an inducation it is wrong/incomplete.
You can use

uvm_hdl_check_path

to check the path

In reply to chr_sue:

Thanks for your reply as you mentioned “The uvm_hdl_read/uvm_hdl_deposit is restricted to integral data types.” I must clarify that my value data(burst_data and read_data) are of uvm_hdl_data_t. Also, as you told me to check the HDL path I have done that and that is also giving me the return value 1. So, I can say Path provided is correct. The used code to check this given below.
The problem I am facing is with the testbench environment RAL model side at the DUT side these access methods are working fine but when I am trying to check the updated value through register I am not able to get the value.

New seq code to check path provided is correct or not
#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
if(uvm_hdl_check_path($sformatf(path,10)))begin
$display(“PATH checking successful”);
end
else
$display(“PATH Provided Invalid”);

         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) 

Output:
PATH checking successful