Reputation: 43
`define REG_WIDTH 48
`define FIELD_WIDTH 32
typedef enum bit [`REG_WIDTH-1:0]
{
BIN_MIN = 'h0,
BIN_MID = BIN_MIN + `REG_WIDTH'(((1<<`FIELD_WIDTH)+2)/3),
BIN_MAX = BIN_MID + `REG_WIDTH'(((1<<`FIELD_WIDTH)+2)/3),
}reg_cover;
In the above code I am getting compilation error of enum duplicate because BIN_MID is also taking value '48{0}. But when I do $display for "BIN_MIN + `REG_WIDTH'(((1<<`FIELD_WIDTH)+2)/3)"
, I don't get zero.
Since I have typecast each enum field by 48 , why I am getting zero ? I am new to system verilog.
Upvotes: 3
Views: 543
Reputation: 5098
Typically, integer constants like 1
are treated as 32-bit values (SystemVerilog LRM specifies them to be at least 32 bits but most simulators/synthesis tools use exactly 32 bits). As such, since you are preforming a shift of 32 first, you are shifting out the one completely and left with 0 during compilation (32'd1<<32
is zero). By extending the size of the integer constant first to 48 bits, you will not lose the value due to the shift:
`define REG_WIDTH 48
`define FIELD_WIDTH 32
typedef enum bit [`REG_WIDTH-1:0] {
BIN_MIN = 'h0,
BIN_MID = BIN_MIN + (((`REG_WIDTH'(1))<<`FIELD_WIDTH)+2)/3,
BIN_MAX = BIN_MID + (((`REG_WIDTH'(1))<<`FIELD_WIDTH)+2)/3
} reg_cover;
As to why when put in a $display
prints a non-zero value, I'm not sure. Some simulators I tried did print non-zero values, others printed 0. There's might be some differences in compile-time optimizations and how they run the code, but casting first is the best thing to do.
Upvotes: 4