Jump to content
Sign in to follow this  
Logger

Complicated Register Modeling with uvm_reg

Recommended Posts

Looking for suggestions on the best approach to modeling something akin the following.

 

data bus width: 16 bits

addr bus width: 16 bits

 

register: cfg @ 0xa000

field: value_mode @ 0 : enum { DIRECT=0, MULT=1 }

 

register: value0 @ 0xa002

field: value0[15:0] @ 0 : // On write, set value_reg[15:0]. On read, depends on value_mode

 

register: value1 @ 0xa004

field: value1[15:0] @ 0 : // On write, set value_reg[31:16]. On read, depends on value_mode

 

 

 

value1 and value0 are implemented as value_reg[31:0] in RTL. The value actually stored in this register is always whatever you wrote to it. However, what you read back, and what HW sees when it looks at this register depends on the value of value_mode.

 

When value_mode == DIRECT, you'll read back the whatever value is physically stored in value_reg[15:0] as value0 and value_reg[31:16] as value1.

 

When value_mode == MULT, you'll read back a computed value instead. Let quotient == value_reg[15:0] * value_reg[31:16]. Then you'll read back quotient[15:0] as value0 and quotient[31:16] as value1.

 

Right now I've just added tasks write_value( bit [15:0] a, bit [15:0 b ), read_value( output bit [31:0] quotient ) to the register model, which look at value_mode before accessing value_reg. In both cases, write_value() just writes parameters a and b to value0 and value1 using the register model. When value_mode == DIRECT, read_value() reads value0 and value1 multiplies them and returns the result. When value_mode == MULT, read_value() reads value0 and value1, concats them and returns the result.

 

I'm contemplating adding some kind of virtual register to the register model instead of the tasks. Then, implement the logic using either callbacks or a custom front door. It also needs to preserve support for multiple address maps.

 

The goal is to prevent multiple scoreboards and coverage classes which are referencing these registers from having to implement the same computation. The idea of a virtual register is to provide the same uvm_reg API to the user as other registers. A side benefit is the user only makes a single call to read the 32 bit value, rather than making two calls.

 

Cheers.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×