Rishi Jaiswal
Rishi Jaiswal

Reputation: 43

How to use Arithmetic expression in Enum in system verilog?

`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

Answers (1)

Unn
Unn

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

Related Questions