$rtoi() не является постоянной системной функцией.

Я хочу установить размер константы для счетчика:

localparam MAX_COUNT = ((debounce_per_ms * clk_freq)) + 1;
parameter MAX_COUNT_UPPER = $rtoi($floor($log10(MAX_COUNT)/$log10(2)));

Это хорошо работает с XST (ise) и с verilator, но в Icarus у меня есть эта ошибка:

src/button_deb.v:20: error: $rtoi() is not a constant system function.

Я могу решить это, используя "целочисленный" тип:

parameter integer MAX_COUNT_UPPER = $floor($log10(MAX_COUNT)/$log10(2));

Но это дает мне предупреждение в verilator:

$ verilator -cc src/button_deb.v
%Warning-REALCVT: src/button_deb.v:20: Implicit conversion of real to integer
%Warning-REALCVT: Use "/* verilator lint_off REALCVT */" and lint_on around source to disable this message.
%Error: Exiting due to 1 warning(s)
%Error: Command Failed /usr/local/bin/verilator_bin -cc src/button_deb.v

Как вы думаете, есть ли хороший способ сделать это и обеспечить совместимость с Icarus, verilator и Xst?


person FabienM    schedule 15.03.2015    source источник


Ответы (1)


$log10(MAX_COUNT)/$log10(2) — это способ вычисления log2, когда у вас нет доступного log2.

В системах Verilog с доступным $log10() у вас также должен быть $log2().

Функция пола состоит в том, чтобы округлить до целого числа, это округлит в меньшую сторону. Чаще всего требуется округлить, чтобы узнать количество битов, необходимых для охвата этого количества местоположений.

Для этого у нас есть Потолочное бревно2 $clog2(). Это не точная замена вашей функции, потому что она округляется вверх, а не вниз.

Пример:

parameter RAM_DEPTH      = 10;
parameter RAM_ADDR_WIDTH = $clog2(RAM_DEPTH);

Следующее также должно было сработать для вас (не нужно создавать целочисленный тип):

parameter MAX_COUNT_UPPER = $floor($log10(MAX_COUNT)/$log10(2));
person Morgan    schedule 15.03.2015
comment
$clog2() отлично работает со всеми инструментами (ise, icarus, verilator), спасибо! - person FabienM; 15.03.2015