5

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?

nguthrie
  • 2,615
  • 6
  • 26
  • 43

4 Answers4

7

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.

dave_59
  • 39,096
  • 3
  • 24
  • 63
  • 1
    Here is the work-around that I found since this results in a compile error for me: Use 'rand_mode' to disable randomization for the whole register model, then use it again to enable randomization for just the registers that need to be randomized. – nguthrie Jan 13 '14 at 14:54
  • 1
    2.5 years later and my work around is broken with a new version of my simulator. But now the real answer works! – nguthrie Sep 15 '16 at 19:17
  • For me a direct constraint of registers is not working since registers don't have "value" variable. I had to go up to a field. See below assert(seq_h.reg_m.randomize(* solvefaildebug *) with { info_registers.BLK_PKG_STORAGE_START_ADDR_REG_BYTE.BLK_PKG_STORAGE_START_ADDR_REG_BYTE_F.value == 32'h0; info_registers.BLK_PKG_STORAGE_SIZE_REG_BYTE.BLK_PKG_STORAGE_SIZE_REG_BYTE_F.value == 32'h1000;//4096 }) else $fatal (0, "Randomization of seq_h.reg_m failed"); //end assert – Joniale May 23 '17 at 12:06
  • A shorter example: For me a direct constraint of registers is not working since registers don't have "value" variable. I had to go up to a field. See below: -- assert(handler_mng.register_model.randomize(* solvefaildebug *) with { registerblock.register1.fieldx.value == 32'h0; registerblock.register2.fieldy.value == 32'h1000;//4096 }) else $fatal (0, "Randomization of seq_h.reg_m failed"); //end assert Can you really randomize the "value" variable from a register directly? – Joniale May 23 '17 at 12:20
  • try asking as a separate question and add declarations for the variables involved. – dave_59 May 23 '17 at 15:04
3

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();}
  • Sorry, my original question was an oversimplification: I was really talking about bitfields, not registers. But your answer is useful info too. – nguthrie Jun 08 '18 at 17:00
2

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
Joniale
  • 515
  • 4
  • 17
1

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);
一天王
  • 11
  • 2