Backdoor acess through user defined maps

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.

In reply to usnath:

Yes chr_sue is right? Your implementation is so weird.
Two thing I don’t understand:
1.


this.field1.configure.add_hdl_path_slice("abc");

In uvm_reg_field class doesn’t has attribute ‘configure’.


reg1.add_hdl_path("xyz");

In uvm_reg class, we only have add_hdl_path with following prototype:


function void uvm_reg::add_hdl_path(uvm_hdl_path_slice slices[],
                                    string kind = "RTL");

Please follow chr_sue example to implement.

In reply to cuonghl:

Hi cuonghl,
You’re correct, the correct implementation is


this.field1.add_hdl_path_slice("abc");

The usage you said,


function void uvm_reg::add_hdl_path(uvm_hdl_path_slice slices[],
                                    string kind = "RTL");

is used within the register implementation, outside the implementation for example inside a register block we can do the same as below


this.reg1.add_hdl_path("xyz");

P.S. Please do not consider the code completely, its just for the concept, the real code is very complex and huge.

In reply to usnath:

Hi chr_sue and cuonghl,

The problem was basically due to wrong hdl_path being used in the register level(reg.add_hdl_path). I assumed that the compiler will give a error if hdl path does not exist. Seems like it gives error only when there is a error in hdl slices(because I used to get "hdl path not found " errors). Thank you very much for your suggestions.

Hi Sirs,

Sorry for appending my question to this thread, since it is related to above discussions.
I am pretty new in UVM and now I am exploring RAL.

I have few things needed to be clarified/confirmed. Thank you in advance for your kind answers…

  1. add_hdl_path is the path to the register block in my DUT?
    So if I have this DUT hierarchy : DUT->CORE->SUBBLOCK->REGBLOCK
    Then my add_hdl_path usage should be below?

    add_hdl_path(“TBTOP.DUT.CORE.SUBBLOCK.REGBLOCK”, “RTL”);

  2. add_hdl_path_slice points to the actual declared register inside the REGBLOCK?
    reg0.add_hdl_path_slice(“REG0”, 0, 8);

  3. I have an auto-generated REGBLOCK, and there is no actual REG0 signal declared.
    The register fields signals are the ones declared directly. How do I add
    add_hdl_path_slice in this case?

P.S. I am trying the built-in sequence like uvm_reg_hw_reset_seq, and getting below:
RegModel : Register “reg_block.REG1*” value read from DUT (0x0000000000000000) does not match mirrored value (0x0000000000010103
This mismatch occur because my add_hdl_path_slice is not set correctly, right?

Thank you!