0

我想为计数器设置一个常量的大小:

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

这适用于 XST (ise) 和验证器,但在 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 -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 兼容吗?

4

1 回答 1

2

$log10(MAX_COUNT)/$log10(2) is a way to calculate log2 when you do not have log2 available.

In Verilog systems with $log10() available you should also have $log2().

The floor function is to round to integer, this will round down. It is more common to want to round up to know the number of bits required to cover that number of locations.

For this we have Ceiling log2 $clog2(). This is not an exact replacement for your function because it rounds up, not down.

Example:

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

The following should also have worked for you (no need to make integer type):

parameter MAX_COUNT_UPPER = $floor($log10(MAX_COUNT)/$log10(2));
于 2015-03-15T11:16:09.193 回答