I am trying to make a simple testbench where I create a class that takes a 32-bit address constrainted to all zeroes and then constraint the first 7 bits to 0110011.
This was my attempt:
class bit32_address;
rand bit [31:0] addr;
constraint all_zero {addr inside {0};}
constraint setADD {addr[6:0] == 7'b0110011;}
endclass : bit32_address
Now when I use this class, terminal would say the following:
Error-[CNST-CIF] Constraints inconsistency failure
Constraints are inconsistent and cannot be solved.
Please check the inconsistent constraints being printed above and rewrite
them.
Is there a way I could use multiple constraint blocks? Or is one constraint block optimal?
Actually I fixed the problem - I made a task that helps me designate how much bits I would like to be constrained. Then once I randomize the entire 32 bits of address, I then concatenate parts of the 32-bit address with the designated bits that I have “set” beforehand in the constrained block using the task I have made.
By default, both constraint blocks are active. The problem is that the 2 constraints conflict with each other for some bits of address.
For example, consider bit address[0]. The all_zero constraint tells the simulator to set this bit to 0. The setADD constraint tells the simulator to set this bit to 1. This is a conflict, and the simulator correctly generates an error message.
A constraint block contains a set of constraint expressions. A class may contain zero or more constraint blocks. All of the constraint expressions get treated as if they are logically ANDed together.
The purpose of having multiple constraint blocks is so you can control them as a group with block_name.constraint_mode() to turn them on or off, or override them when you extend the class.
It is possible to do what you are looking for with a soft constraint. A soft constraint turns itself off when faced with a conflict.
Note that I had to apply an individual soft constraint on each bit of addr. If had soft addr == 0, then the entire constraint would be turned off by the setADD constraint conflict. The upper bits would become random.
With the code you just showed, addr [31:25], [14:12], and [6:0] are never randomized, regardless of calling hardcode() They always get the current values stored in opcode, funct3, last_7bit. If you have a more complex set of constraints with different fields you want set, this strategy will not work. Otherwise, why not just set the addr fields you want after calling randomize()
BTW, use functions, not tasks for routines that do not consume time (have no blocking delays).