$ rtoi()不是一个恒定的系统函数

时间:2015-03-15 10:10:36

标签: verilog xilinx-ise icarus

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

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 -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兼容吗?

1 个答案:

答案 0 :(得分:2)

$log10(MAX_COUNT)/$log10(2)是一种在没有log2可用时计算log2的方法。

$log10()可用的Verilog系统中,您还应该有$log2()

floor函数是舍入为整数,这将向下舍入。更常见的是想要向上舍入以知道覆盖该数量的位置所需的位数。

为此我们有Ceiling log2 $clog2()。这不是您的功能的完全替代品,因为它会向上舍入而不是向下。

实施例

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

以下内容对您也有用(无需进行整数类型):

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