Search code examples
verilogsystem-veriloguvm

Register Abstraction Layer Difference Access Type


I am writing a set of register models using uvm_reg class. Individual register size is 8-bit. Register block is created to contains those registers:

class my_reg_block extends uvm_reg_block;
  my_byte_reg reg_00;
  my_byte_reg reg_01;
  my_byte_reg reg_10;
  my_byte_reg reg_11;
  ...
  // build()
  my_map.add_reg(reg_00, 32'h0000 /*offset*/, ""RW");
  my_map.add_reg(reg_01, 32'h0001 /*offset*/, ""RW");
  my_map.add_reg(reg_10, 32'h0002 /*offset*/, ""RW");
  my_map.add_reg(reg_11, 32'h0003 /*offset*/, ""RW");
  ...

I have a register adapter that will translate read/write into bus transaction. So, I am able to do this inside my sequence:

reg_00.write(status, 'hff, .parent(this));

The bus transaction will do write to that specific register: reg_00.

My problem is that the bus has byte_enable that allow it to write accross 4 register in double-word access. Using the existing register model above, is it possible to write/read in 4 register at the same time? Or do I need to create another set of registers (with 32-bit size)? It would be something like this pseudo-code:

{reg_11,reg_10,reg_01,reg_00}.write(status, 'hffffffff, .parent(this));

Any suggestion?


Solution

  • you could try passing additional information like byte_enable to the adapter using the extension argument in the write function. Then the adapter can decide accordingly if this is a legal double word transaction and assign the bus transaction fields accordingly. see partial example below

    virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);
    bus_trans            trans;
    uvm_reg_item            item;
    regtrans_params         params;
    
    
    item                    = get_item();
    trans                   = bus_trans::type_id::create("trans");
    
    if(item.extension == null) 
      `uvm_fatal("", "item.extension==null !!")
    if(!$cast(params, item.extension))
      `uvm_fatal("", "FAILED $cast(params, item.extension) !!")
    
    trans.dst_chip_addr              = params.chip_addr;
    

    in the sequence:

    block.reg_00.write(status, 32'hfffffffff .extension(params));