How to setup a backdoor access within UVM RAL model?

Dear All,

For understanding UVM RAL MODEL Especially BACKDOOR ACCESS, I was make a simple example as the below link.

Here is class ral_control_reg
I 'd like to setup and want to access parity_en, dbg_en and mod_en register field by using BACKDOOR access.

class ral_control_reg extends uvm_reg;
  rand uvm_reg_field rsvd;
  rand uvm_reg_field parity_en;
  rand uvm_reg_field dbg_en;
  rand uvm_reg_field mod_en;
  
  `uvm_object_utils(ral_control_reg)
  function new(string name = "ral_control_reg");
    super.new(name, 32, build_coverage(UVM_NO_COVERAGE));
  endfunction
  
  virtual function void build();
    rsvd = uvm_reg_field::type_id::create("rsvd");
    parity_en = uvm_reg_field::type_id::create("parity_en");
    dbg_en = uvm_reg_field::type_id::create("dbg_en");
    mod_en = uvm_reg_field::type_id::create("mod_en");
    
    rsvd.configure     (this, 29, 3, "RO", 0, 1'b0, 1, 1, 0);
    parity_en.configure(this,  1, 2, "RW", 0, 1'b1, 1, 1, 0);
    dbg_en.configure   (this,  1, 1, "RW", 0, 1'b0, 1, 1, 0);
    mod_en.configure   (this,  1, 0, "RW", 0, 1'b1, 1, 1, 0);
    //To access BACKDOOR
    add_hdl_path_slice( .name("parity_en"), .offset(2), .size(1));
    add_hdl_path_slice( .name("dbg_en"	 ), .offset(1), .size(1));
    add_hdl_path_slice( .name("mod_en"   ), .offset(0), .size(1));
      
  endfunction
endclass

To access Backdoor I’ve added with

     //To access BACKDOOR
    //[RegModel] No backdoor access available for register 'reg_model.mod_reg.control_reg' . Using frontdoor instead.
    reg_model.mod_reg.control_reg.write(status, 32'h1234_1234, UVM_BACKDOOR, .parent(this));
    reg_model.mod_reg.control_reg.read(status, read_data, UVM_BACKDOOR, .parent(this));
  //To access BACKDOOR
    add_hdl_path_slice( .name("parity_en"), .offset(2), .size(1));
    add_hdl_path_slice( .name("dbg_en"	 ), .offset(1), .size(1));
    add_hdl_path_slice( .name("mod_en"   ), .offset(0), .size(1));
//To access BACKDOOR
add_hdl_path( .path("tb_top.DUT"));

But I got the error message as below

# UVM_ERROR verilog_src/uvm-1.2/src/reg/uvm_reg_block.svh(2049) @ 14: reporter [RegModel] Block does not have hdl path defined for abstraction 'RTL'
# ** Error (suppressible): (vsim-16132) Unable to read value from 'tb_top.DUT.parity_en' Either the path is incorrect, or you may not have PLI/ACC visibility to that object.
# ** Error (suppressible): (vsim-16132) Unable to read value from 'tb_top.DUT.dbg_en' Either the path is incorrect, or you may not have PLI/ACC visibility to that object.
# ** Error (suppressible): (vsim-16132) Unable to read value from 'tb_top.DUT.mod_en' Either the path is incorrect, or you may not have PLI/ACC visibility to that object.
# UVM_ERROR verilog_src/uvm-1.2/src/reg/uvm_reg_block.svh(2049) @ 14: reporter [RegModel] Block does not have hdl path defined for abstraction 'RTL'
# ** Error (suppressible): (vsim-16132) Unable to read value from 'tb_top.DUT.parity_en' Either the path is incorrect, or you may not have PLI/ACC visibility to that object.
# ** Error (suppressible): (vsim-16132) Unable to read value from 'tb_top.DUT.dbg_en' Either the path is incorrect, or you may not have PLI/ACC visibility to that object.
# ** Error (suppressible): (vsim-16132) Unable to read value from 'tb_top.DUT.mod_en' Either the path is incorrect, or you may not have PLI/ACC visibility to that object.

Could you guide me What am I supposed to do?

In reply to UVM_LOVE:

When calling ‘add_hdl_path_slice’, you need to provide the name of the RTL register. The three fields that you are defining are in the RTL register ‘control_reg’


//To access BACKDOOR
add_hdl_path_slice( .name("control_reg"), .offset(2), .size(1));
add_hdl_path_slice( .name("control_reg"), .offset(1), .size(1));
add_hdl_path_slice( .name("control_reg"), .offset(0), .size(1));

In reply to cgales:

THANK YOU really. cgales.

To check Backdoor access, I added UVM_INFO as the below,

    `uvm_info(get_type_name(), "BACKDOOR ACCESS START", UVM_LOW);
    reg_model.mod_reg.control_reg.write(status, 32'h9876_5432, UVM_BACKDOOR, .parent(this));
    reg_model.mod_reg.control_reg.read(status, read_data, UVM_BACKDOOR, .parent(this));
    `uvm_info(get_type_name(), "BACKDOOR ACCESS FINISH", UVM_LOW);

But this BACKDOOR ACCESS doesn’t work. it seems like to skip.
There is no any message inside START to FINISH.

# UVM_INFO base_seq.sv(35) @ 14: uvm_test_top.env_o.agt.seqr@@rseq [reg_seq] BACKDOOR ACCESS START
# UVM_INFO base_seq.sv(38) @ 14: uvm_test_top.env_o.agt.seqr@@rseq [reg_seq] BACKDOOR ACCESS FINISH

What am I supposed to do to resolve skip problem?
I linked to RAL example(3) - EDA Playground

In reply to UVM_LOVE:

What messages do you expect to see? The accesses via backdoor are silent.

I wonder that the read_data have 0 value after add the below

        add_hdl_path_slice( .name("control_reg"), .offset(3), .size(29));
	add_hdl_path_slice( .name("control_reg"), .offset(2), .size(1));
	add_hdl_path_slice( .name("control_reg"), .offset(1), .size(1));
	add_hdl_path_slice( .name("control_reg"), .offset(0), .size(1));

I expected that I could be got the read data from BACKDOOR per fields.
But, I got the simulation report as the bloew,

UVM_INFO @ 14: reporter [RegModel] Wrote register via DPI backdoor: reg_model.mod_reg.control_reg=0x91a091a2
UVM_INFO @ 14: reporter [RegModel] Read  register via DPI backdoor: reg_model.mod_reg.control_reg=0

By using the below in base_seq.sv

  `uvm_info(get_type_name(), "BACKDOOR ACCESS START", UVM_LOW);
    reg_model.mod_reg.control_reg.write(status, 32'h9876_5432, UVM_BACKDOOR, .parent(this));
    reg_model.mod_reg.control_reg.read(status, read_data, UVM_BACKDOOR, .parent(this));
    `uvm_info(get_type_name(), "BACKDOOR ACCESS FINISH", UVM_LOW);