What is the correct way to read/write an individual field using the UVM register model?

I can’t seem to figure out the ‘correct’ way to read an individual field using the UVM register model. I know that reading and writing the fields directly is not recommended (and produces warning messages):


my_block.my_reg.my_field.write( ... );
my_block.my_reg.my_field.read( ... );

It seems the correct way to write an individual field is:


my_block.my_reg.my_field.set( ... );
my_block.my_reg.update( ... );

I was expecting something similar to work for reads, but the ‘get’ call does not return the correct value:


my_block.my_reg.read( ... );
my_block.my_reg.my_field.get( ... );

I think I had this working at some point with Auto-Prediction mode enabled, but I need it now with that mode disabled. This seems like something that should be really easy to do…

In reply to laarens:

If you had it working with auto-prediction enabled and it doesn’t work now, this suggests that you didn’t implement the explicit prediction path (monitor → predictor → reg-model).

Also, what you’ve implemented in there using set() and get() isn’t physically writing and reading only one field (i.e. doing narrow accesses). You’re just writing and reading the whole register and selecting what you need from it. If you want to start narrow bus accesses, you need to do my_block.my_reg.my_field.write( … )/read(…), but the underlying bus needs to support that and the register field must be alone in the byte lane(s) it occupies.