What is the solution space for the following union?
typedef enum logic[1:0]{SMALL_SIZE=0, MEDIUM=1, BIG=2} size_t;
typedef enum logic[1:0]{SMALL=0,LARGE=3} size_1_t;
typedef union packed {
size_t size;
size_1_t size_1;
logic[1:0] bit_val;
} sample_union;
Constraining size_1 to value LARGE results in constraint solver error
Solver failed when solving following set of constraints
rand bit[1:0] s1; // rand_mode = ON
constraint INTERNAL_0 // (constraint_mode = ON)
{
((s1 inside {2’h0, 2’h3}) && (s1 inside {[2’h0:2’h2]}));
}
constraint WITH_CONSTRAINT // (from this) (constraint_mode = ON) (testbench.sv:58)
{
(s1 == my_package::size_1_t::LARGE);
}
=======================================================
How can I get the constraint to work and why is the internal constraint ANDing the two enums?
Full code is below
package my_package;
typedef enum logic[1:0]{SMALL_SIZE=0, MEDIUM=1, BIG=2} size_t;
typedef enum logic[1:0]{SMALL=0,LARGE=3} size_1_t;
typedef union packed {
size_t size;
size_1_t size_1;
logic[1:0] bit_val;
} sample_union;
class Base;
// Properties
rand bit test_result;
rand sample_union s1;
endclass
endpackage
module GRG_constraint;
import my_package::*;
Base B_h;
bit result;
initial begin
B_h = new;
if(B_h.randomize() with {
s1.size_1 == LARGE;
})
$display("B_h.s1.size_1 = %0s",B_h.s1.size_1.name());
else
$error("Failed to randomize Base");
#10;
end
endmodule
In reply to prang:
This is one of the clarifications made to the recent 1800-2017 LRM. The solver is not allowed to choose a value that lies outside the set of named values of the enum type. This is something constraint solvers were already doing, just not documented.
In your union, 0 is the only value common to the two enum types.
I’m not sure what you are trying to accomplish with the packed union; there might be alternatives like created lists of values with queues or associative arrays.
In reply to dave_59:
The packed union containing enums is part of an interface struct, we ran into this issue while randomizing input values.
I looked at 2017 LRM and found this section. Is this the clarification you referred to?
If a rand variable of packed structure or packed untagged union type has a member of enum type,
the rules in 18.3 restricting the random values of an enum variable shall not apply to that member.
For example:
typedef enum bit [1:0] { A=2'b00, B=2'b11 } ab_e;
typedef struct packed {
ab_e ValidAB;
} VStructEnum;
typedef union packed {
ab_e ValidAB;
} VUnionEnum;
When randomizing a variable of type ab_e, the solver can only select a random value of 2’b00 or
2’b11 (A or B, respectively). However, when randomizing a variable of type VStructEnum or
VUnionEnum, the solver can select 2’b00, 2’b01, 2’b10 or 2’b11.
To me, this implies my standalone testcase should work. If I extend the definition of VUnionEnum as follows
typedef enum bit [1:0] { C=2'b01, D=2'b10 } cd_e;
typedef union packed {
ab_e ValidAB;
cd_e ValidCD;
} VUnionEnum;
when randomizing ValidCD, I have values b01 and b10 available. While randomizing ValidAB, I have values b00 and b11 available. While Randomizing VUnionEnum, I have all 4 values available. Is this right?
In reply to prang:
Sorry I missed the “packed” in your union declaration. This is yet another clarification in the LRM that many not be implemented in your tool. Please contact your tool vendor.