如何在系统verilog中使用枚举中的算术表达式?

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;

在上面的代码中,我遇到了枚举重复的编译错误,因为 BIN_MID 也取值 '48{0}。但是当我为 "BIN_MIN + `REG_WIDTH'(((1<<`FIELD_WIDTH)+2)/3)" 做 $display 时,我没有得到零。 由于我已将每个枚举字段类型转换为 48,为什么我得到零?我是系统verilog的新手。

通常,像 1 这样的整数常量被视为 32 位值(SystemVerilog LRM 指定它们至少为 32 位,但大多数 simulators/synthesis 工具恰好使用 32 位)。因此,由于您首先执行 32 的移位,因此您将完全移出一个并在编译期间留下 0(32'd1<<32 为零)。通过将整数常量的大小先扩展到48位,就不会因为移位而丢失值:

`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;

至于为什么当放入 $display 时会打印出非零值,我不确定。我尝试过的一些模拟器确实打印了非零值,其他模拟器打印了 0。编译时优化以及它们如何 运行 代码可能存在一些差异,但最好先进行转换。