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?
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));