'UVM RAL: Randomizing registers in a register model
I have a large register map modelled with RAL and I would like to randomize some of the registers. If I want to constrain the registers seperately then this is simple:
reg_model.register_a.randomize() with {value > 5;}
reg_model.register_b.randomize() with {value < 2;}
reg_model.update(status);
However, if I want a relationship between the two values written I think I have to add a constraint to the whole register model:
reg_model.randomize() with {register_a.value > register_b.value;}
reg_model.register_a.update(status);
reg_model.register_b.update(status);
The problem here is that the other 254 registers in the model will also get randomized. I could just update the two registers that I want randomized, but then the mirror will not match the hardware. If I had backdoor access working I could refresh the mirror, but I don't and I certainly don't want to read back 254 registers through the front door.
Is there a way to randomize just those two registers yet still have the constraint solver maintain a relationship between them?
Solution 1:[1]
You could do
reg_model.randomize(register_a,register_b) with {register_a.value > register_b.value;}
Then only registers a and b will get randomized.
Solution 2:[2]
This can't possibly work because registers don't have a "value" variable, only fields have the "value" member variable.
This should work:
reg_model.randomize(register_a,register_b) with {register_a.get() > register_b.get();}
Solution 3:[3]
Here my two cents, Here all registers and all fields are constrained to zero.
top_regm.get_registers(regs, UVM_HIER); //NOW take ALL registers (regs) inside the block
regs.sort with (item.get_address()); //sort ascending by address
for (int unsigned r=0; r<regs.size(); r++) begin
assert(regs[r].randomize with {
regs[r].get() == 0; //constraint with function is heavy consumming
} );
reg_value_q.push_back(regs[r].get()); //store all the constrained values in a queue
end
Solution 4:[4]
I don't think
reg_model.randomize(register_a,register_b) with {register_a.get() > register_b.get();}
will work, becasue regmodel.randomize will only randomize the class member 'value' whose value will be copied to m_desired only in post_randomization.
If you want to randomize whole register, I believe you should randomize two intermediate variabls, then pass the variabls into regmodel.
int a_value,b_value;
std::randomize(a_value,b_value) with {a_value > b_value};
regmodel.register_a.set(a_value);
regmodel.register_b.set(b_value);
regmodel.register_a.update(status);
regmodel.register_b.update(status);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | dave_59 |
| Solution 2 | David Larson |
| Solution 3 | Joniale |
| Solution 4 |
