In reply to mitesh.patel:
There are two basic differences:
- uvm_mem has no shadow (mirror or desired) storage. Only the RTL holds state. This means access is via read/write/peek/poke API methods. uvm_reg has additional get/set/update/mirror/predict.
- A register occupies one address. A memory occupies a range of addresses.
You could model a memory with uvm_reg by declaring one register and then declaring a block of multiple register instances, but that would create too much overhead. uvm_mem gives you access to the same bus abstraction layer and address mapping as uvm_reg without the overhead.
See https://verificationacademy.com/cookbook/registers/modelstructure for more details.