system-veriloguvm

How to get register model in uvm_sequence task in UVM?


I'm trying to get registers in a sequence. I declared the register model and made queue to put registers into the queue. I thought that it works:

    uvm_reg_map     maps[$];
    uvm_reg         regs[$];
    uvm_reg_field   fields[$];
    string          mode[`UVM_REG_DATA_WIDTH];
    uvm_reg_data_t  dc_mask;
    uvm_reg_data_t  reset_val;
    int             n_bits;
    string          field_access;

    regmodel.get_map(maps);
    regmodel.get_registers(regs);
    regmodel.get_fields(fields);

I can check the registers:

foreach(regs[i]) begin
    `uvm_info("regs", $sformatf(" regisger = %s", regs[i].get_full_name()), UVM);

I would like to write with some randomized value by the write() method in a task.

task all_wr_pattern(uvm_reg_map  map,bit  pat);
       uvm_status_e status;
       uvm_reg_data_t val;  
      
      if(pat == 0)
         val = '1; 
      if(pat == 1) 
         void'(std::randomize(val));  
      else if(pat == 2)
          val = '0;
       regs.write(status, val, UVM_FRONTDOOR, map, this); 
   endtask

then I got this error message:

    regs.write(status, val, UVM_FRONTDOOR, map, this); 
          |
xmelab: *E,CUVUNF (./dma_reg_sequence.sv,137|16): Hierarchical name component lookup failed for 'regs' at '$unit_0x67f934e9'.

How do I correctly use the write method in a task?

I elaborate https://edaplayground.com/x/Dymm to help your understand.


Solution

  • Here are some of the relevant lines of your code:

    uvm_reg         regs[$];
    regmodel.get_registers(regs);
       regs.write(status, val, UVM_FRONTDOOR, map, this); 
    

    The 1st line declares a variable which represents a queue of registers (type uvm_reg).

    The 2nd line populates the queue variable with a set of registers from your register model.

    The error occurs in the 3rd line because you are attempting to call the write method on a queue of registers, which is illegal. You can only call write on a single register. For example, the 1st register in the queue is denoted by regs[0]:

       regs[0].write(status, val, UVM_FRONTDOOR, map, this); 
    

    You can use foreach to loop through all registers, as you did when you checked them: regs[i]