Hi. Just tried to use individual access in UVM and encountered something weird.
Please tell me if you have ever encountered something like this or if it’s just my own mistake.
So, I’m defining some register with multiple fields…
class axi_signals_reg extends uvm_reg;
`uvm_object_utils(axi_signals_reg)
function new (string name = "axi_signals_reg");
super.new(name, 32, UVM_NO_COVERAGE);
endfunction : new
rand uvm_reg_field field0, field1, field2;
virtual function void build();
field2 = uvm_reg_field::type_id::create("field2");
field1 = uvm_reg_field::type_id::create("field1");
field0 = uvm_reg_field::type_id::create("field0");
// access has_reset
// lsb_pos | reset|indv_acc
// size | |volatile| |rand |
// | | | | | | | |
field2.configure(this, 8, 24, "RW", 0, 0, 1, 1, 1);
field1.configure(this,16, 8, "RW", 0, 0, 1, 1, 1);
field0.configure(this, 8, 0, "RW", 0, 0, 1, 1, 1);
endfunction: build
endclass
Then I added it to the reg block (and then connect it in some way). There’s a reg adapter that supports byte enable (no warnings about it).
Regmap is set to n_butes=1 for the example.
reg_map = create_map(
.name ( "reg_map" ),
.base_addr ( 0 ),
.n_bytes ( 1 ),
.endian ( UVM_LITTLE_ENDIAN ),
.byte_addressing ( 1 )
);
axi_signals = axi_signals_reg::type_id::create("axi_signals");
axi_signals.configure(this);
axi_signals.build();
reg_map.add_reg(axi_signals, base_addr + 4*15, "RW");
In the test, I’m trying to read the fields separately. field.
uvm_status_e st;
uvm_reg_data_t dt;
REGS.axi_signals.field0.read(st, dt);
REGS.axi_signals.field1.read(st, dt);
REGS.axi_signals.field2.read(st, dt);
Then, something happens.
field0 reads as the following.
UVM_INFO <...>/UVM/CDNS-1.2/sv/src/reg/uvm_reg_map.svh(2037) @ 54 ns: reporter [uvm_reg_map] Reading address 'h3c via map "reg_block.reg_map"...
UVM_INFO <...>/UVM/CDNS-1.2/sv/src/reg/uvm_reg_map.svh(2037) @ 54 ns: reporter [uvm_reg_map] Reading address 'h3d via map "reg_block.reg_map"...
field1 also, gets an extra read
<...> Reading address 'h3d via map "reg_block.reg_map"...
<...> Reading address 'h3e via map "reg_block.reg_map"...
<...> Reading address 'h3f via map "reg_block.reg_map"...
But field2 is okay, because it’s the last?
<...> Reading address 'h3f via map "reg_block.reg_map"...
Originally I noticed it with 64-bit register split into 2 32-bit fields - the first field got 5 reads, while the second got 4 (which is expected). And switching to num_bytes=4 caused the lower field to read the entire register, which wasn’t expected.
I checked - reg adapter gets these extra reads. “Correct” reads are received with correct num_bits (8 or 32, depending on regmap num_bytes), but the “extra” read gets num_bits = 0 (with byte_en still high, by the way). But I can’t just ignore it since reg2bus should produce something…
The bus doesn’t matter since “reading address” are printed from regmap - so that means that it WANTS to read extra, for some reason.
What could be wrong here? How to make a workaround, considering that I can’t edit UVM code?