Как использовать выражение Arithmeti c в Enum в системном Verilog? - PullRequest
3 голосов
/ 13 июля 2020
`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;

В приведенном выше коде я получаю ошибку компиляции enum duplicate, потому что BIN_MID также принимает значение '48 {0}. Но когда я делаю $ display для "BIN_MIN + `REG_WIDTH'(((1<<`FIELD_WIDTH)+2)/3)", я не получаю ноль. Поскольку у меня есть тип каждого поля перечисления на 48, почему я получаю ноль? Я новичок в системе Verilog.

1 Ответ

4 голосов
/ 13 июля 2020

Обычно целочисленные константы, такие как 1, обрабатываются как 32-битные значения (SystemVerilog LRM указывает, что они должны быть как минимум 32-битными, но большинство симуляторов / инструментов синтеза используют ровно 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. Могут быть некоторые различия в оптимизации во время компиляции и в том, как они запускают код, но сначала приведение типов - это лучше всего.

...