Backdoor acess through user defined maps

Hi All,

Is there a way I can use register backdoor using user defined maps. Or is it like backdoor can only be done using default map. It would also be very helpful if you could comment on the uvm_reg_field::backdoor() static function and possible ways it can be a solution to my above problem. Thank You.

In reply to usnath:

In the register model you are alwayys defining your individual reg_map. Even if it is named default_map it is the user-defined map.

In reply to usnath:

Hi All,
Is there a way I can use register backdoor using user defined maps. Or is it like backdoor can only be done using default map. It would also be very helpful if you could comment on the uvm_reg_field::backdoor() static function and possible ways it can be a solution to my above problem. Thank You.

Why do you think register backdoor access is related to register map?
The flow that you need to do to access a register value using backdoor:

  • Provide hdl_path (size and offset as well) which is pointed to RTL register using add_hdl_path/add_hdl_path_slice.
  • Use provided functions to read/write backdoor such as peek, poke, mirror, etc.

In reply to cuonghl:

In reply to usnath:
Why do you think register backdoor access is related to register map?
The flow that you need to do to access a register value using backdoor:

  • Provide hdl_path (size and offset as well) which is pointed to RTL register using add_hdl_path/add_hdl_path_slice.
  • Use provided functions to read/write backdoor such as peek, poke, mirror, etc.

My register backdoor write test failed when I added another map in the child class of the reg_top. The default map is added to the new map using add_submap.

In reply to usnath:

So, I think you use mirror to check, right? And you send here the detail flow and error log?

In reply to chr_sue:

In reply to usnath:
In the register model you are alwayys defining your individual reg_map. Even if it is named default_map it is the user-defined map.

True. What I wanted was to differentiate map that is defined in the register definition and other maps to which this default map is added(in a wrapper outside the reg_top).

In reply to cuonghl:

In reply to usnath:
So, I think you use mirror to check, right? And you send here the detail flow and error log?

I don’t get an error.It’s just that the value won’t be written to the hierarchy. The log “reporter [RegMem] backdoor_write to ” is missing.

In reply to usnath:

Did you add to reg correct hdl path using add_hdl_path_slice/add_hdl_path function? Don’t add empty string to hdl_path.

In reply to cuonghl:

In reply to usnath:
Did you add to reg correct hdl path using add_hdl_path_slice/add_hdl_path function? Don’t add empty string to hdl_path.

Yes I did…all registers have their corresponding hdl paths. I had the test passing before, only when the reg_top was changed and maps added, this anomaly started arising.

In reply to usnath:

In reply to usnath:
True. What I wanted was to differentiate map that is defined in the register definition and other maps to which this default map is added(in a wrapper outside the reg_top).

The reg_model defines the structure of your registers in the DUT. This register model might contain sub_maps as required by the structure in the DUT.
But you cannot have a reg_map outside of your top reg_block (register model).

In reply to chr_sue:

In reply to usnath:
The reg_model defines the structure of your registers in the DUT. This register model might contain sub_maps as required by the structure in the DUT.
But you cannot have a reg_map outside of your top reg_block (register model).

I created a class that extends from the real reg_model and made it my new reg_model. The other maps are defined inside the new reg_model.

In reply to usnath:

Hi All,
I found out that the failure was not due to maps, but reg.get_full_hdl_path don’t return anything. While get_hdl_path is working fine.The definition shows a parent register file that is by default null. Is that the problem. Do share your ideas. Thanks.

In reply to usnath:

Could you share your source code (just simple)? I want to analyze this case.

In reply to usnath:

get_hdl_path returns only the last hierarchy Level and get_full_hdl_path returns the full hierarchy down to your registers. If this does not exist it doesn’t retrurn anything.
You Can check the correct path to oyur registers with the function has_hdl_path.

In reply to cuonghl:[/i]


class reg1 extends uvm_reg;
  this.field1.configure.add_hdl_path_slice("abc");
  //...;
endclass

class reg_block extends uvm_reg_block;
  reg1.add_hdl_path("xyz");
  //...;
endclass

class top_regmodel extends reg_block;
  uvm_regmap spi_map;
  //.....;
ensclass

class env extends uvm_env;
  top_regmodel.set_hdl_path_root("pqr");
  //....;
endclass

class cb extends uvm_reg_cb;
  virtual task pre_write(uvm_reg_item rw);
    top_regmodel.reg_block.reg1.write(status,value,UVM_BACKDOOR); //write does not happen
  endtask
endclass

In reply to chr_sue:
has_hdl_path is 1. But write is not happening.

In reply to usnath:

Looks a Little bits complicated. The reg_model needs the information about the hdl_path_slice this has to be defined for each register. And you have to define the the hdl_path. This looks like this:

class my_reg_block extends uvm_reg_block;
      `uvm_object_utils(my_reg_block)
.....
     rand my_reg0 reg0;
     rand my_reg1 reg1;
.....
     
     function new(string name = "my_reg_block");
         super.new(name, UVM_NO_COVERAGE);
     endfunction
 
     virtual function void build();
         reg0 = my_reg0::type_id::create("reg0");
         reg0.configure(this);
         reg0.build();
	 reg0.add_hdl_path_slice("mode_reg[0]", 0, 8);
..........
       // the same for all other registers
..........
         // Assign dut to the hdl path
         add_hdl_path(<name of the toplevel mod>.dut", "RTL"); // dut is the RTL. The regs are on the toplevel of the dut.
         lock_model();
      endfunction


In reply to usnath:

In reply to chr_sue:
has_hdl_path is 1. But write is not happening.

This says you have defined a hdl_path, but it doesn’t say it’s correct.
backdoor access has specified commands for Read and write. I’d recommend to use this to be sure you are working backdoor.

The backdoor write is poke and the backdoor read is peek.

You can also use uvm_hdl_check_path to check if the hdl_path is existing.

In reply to chr_sue:
Yeah I have implemented similarly. And about the hdl_path being correct, shouldn’t the program give an error if it is not correct, like “hdl_path not found”. And for the record the write to all registers works like a charm when the top_regmodel is swapped with reg_block in set_hdl_path_root.i.e


class reg1 extends uvm_reg;
  this.field1.configure.add_hdl_path_slice("abc");
  //...;
endclass
 
class reg_block extends uvm_reg_block;
  reg1.add_hdl_path("xyz");
  //...;
endclass
 
//class top_regmodel extends reg_block;
//  uvm_regmap spi_map;
//  //.....;
//ensclass
 
class env extends uvm_env;
  reg_block.set_hdl_path_root("pqr");
  //....;
endclass
 
class cb extends uvm_reg_cb;
  virtual task pre_write(uvm_reg_item rw);
    reg_block.reg1.write(status,value,UVM_BACKDOOR); //write does not happen
  endtask
endclass

In reply to usnath:

If the hdl_path is incorrect it does not return an error. Simply it does not work. In all my projetcs I had to spend certain effort on defining the correct hdl_path.
I found uvm_hdl_check_path is a good means to double-check the correct hdl_path.