To answer my own question, YES, it is possible.
I figured out my problem. The default_map within my register block was created with n_bytes==4, which was incorrect. It should have been ==1, since the bus width is one byte.
Once I corrected that, I got the behavior I wanted... sort of.
Item 1: Reading/writing a 32-bit register via the model would result in 4 bus transactions
This is what I observed. Nice.
Item 2: Reading/writing a single byte of the register via the bus agent would update/predict just that one byte in the model.
The model sure surprised me on this one. It's smarter than I expected. The 32-bit register model is not updated until all bytes of the register are written. The order does not matter, and the predictor is tracking what has been written, so that if only a single byte is written I get an error like this:
[PENDING REG ITEMS] There are 1 incomplete register transactions still pending completion
My preference would be for each byte to get updated independently of the others. But I can live without that if there's no way to control it.
So, my follow-up questions are:
a) Is the behavior I described above documented anywhere? I couldn't find an explanation in the UVM HTML docs that ship with the library.
b) Is the behavior configurable, such that I could have each byte in the model update independently of the others?