Ravi Teja , ASIC Design-Verification Engineer @ www.cvcblr.com &
TeamCVC (Nikhil, Satish, Srini et al.)
SystemVerilog is a massive language with several surprises under its belt. Every time you encounter some unexpected result, the first reaction is “Oh! I know System Verilog, this is incorrect behavior of the tool”. Voila! EDA developers get paid *really well* and read the LRM thoroughly before committing their code in. This is not to say that there are no bugs in EDA tools (“bug free EDA tool” is more or less an OXYMORON). But with System Verilog tools becoming more and more stable and advanced, it is very likely the case that you fall under the famous John Cooley’s signature (www.deepchip.com):
So was our recent experience with Aldec’s Riviera-Pro simulator with SystemVerilog constraints.
Let the code speak for itself:
class xactn;
rand int var1;
rand int var2;
constraint c_var1 { var1 inside {[1:10]};}
constraint c_var2 { var2 inside {[1:10]};}
endclass:xactn
Now var1 & var2 are non-state variables. Whenever I randomize an object of this class, the solver should obey the constraints – no ground breaking stuff, is it? Consider turning the non-state variables to “inactive” state. SystemVerilog supports rand_mode(0/1) for this, a quick explanation for the same is below:
Now the real fun starts when you delve into corner cases (a la “the devil lies in the detail”). Even though the rand variable is turned inactive, its value MUST be within the values as demanded by the constraints – in other words the “constraints” are still ACTIVE. This has obvious but overlooked results when used with a rand_mode(ON/OFF). The results after randomization are tabulated below:
So why is the 2nd & 3rd case don’t result in random values for var2, var1 respectively? Isn’t that a bug in the EDA tool? Shouldn’t we be calling their support@aldec.com staff? Hold on.. Let’s believe the tool, after all – some of the best minds in comp-science write these geeky solvers, they must have had something in their mind while writing this piece of code inside :-)
A little bit of RTFM (Read The Fine Manual) reveals the “hidden” secrets of “Art of Debug” with Riviera-Pro. It supports a rc_verbose flag which, when set to a magic value of “2” throws out messages to the log file.
set rc_verbose 2
# RCKERNEL: Error: ../src/test.sv(1): The condition 'c_var1()&&c_var2()&&rc_ext_constraint' is overconstrained.
# KERNEL: 1 (0,0) Var1 = 0 , Var2 = 0
# RCKERNEL: Error: ../src/test.sv(1): The condition 'c_var1()&&c_var2()&&rc_ext_constraint' is overconstrained.
# KERNEL: 2 (0,1) Var1 = 0 , Var2 = 0
# RCKERNEL: Error: ../src/test.sv(1): The condition 'c_var1()&&c_var2()&&rc_ext_constraint' is overconstrained.
# KERNEL: 3 (1,0) Var1 = 0 , Var2 = 0
# KERNEL: 4 (1,1) Var1 = 3 , Var2 = 9
# KERNEL: 5 (0,0) Var1 = 3 , Var2 = 9
# KERNEL: 6 (0,1) Var1 = 3 , Var2 = 4
So the first 3 randomize() calls were failing – important that you handle the return value from object.randomize() (Guideline-1).
First three cases gave a constraint violation. We observed that for cases 1,2,3 atleast one of the constraints is not fulfilled.Hence the randomize method returns zero. What? I turned the rand_mode to OFF, yet it tries randomizing and failing? Crazy Friday Phenomenon Huh?
Oh Dear, wait..let’s peel the onion and see why..
This is because each call to randomize involves two steps:
1)solve
In this step all the constraints are solved (as they are still active). The solver must keep the values of var1 and var2
between 1 to 10. Their default values are however 0. (i.e var1=0 & var2=0) . This violates the constraints, hence the solver failed.
2)assign
If the solver passed (i.e no constraint violation) and rand_mode is ON then the randomized value is assigned to the variables
Now in case 2 & 3 wherein only one of the variables is set to rand_mode(OFF), the AND operation means that – since the solver ahs failed, no assignment of potential random value to the other variable is performed, hence retaining the value 0f “0”.
Now, the constraint debugger with Riviera-Pro is good to start with, wish it had pin-pointed it to the exact constraint that caused the violation, instead of combining both into single equation as:
# RCKERNEL: Error: ../src/test.sv(1): The condition 'c_var1()&&c_var2()&&rc_ext_constraint' is overconstrained.
Oh, let’s leave some room for improvement :-)
Now, as a closing remark and 2nd coding guideline – if you are changing the rand_mode, see if you can isolate related constraint on that variable and make constraint_mode(OFF) as well. Once again as John Colley puts it:
No comments:
Post a Comment