我正在实现一个可配置的 DPRAM,其中 RAM DEPTH 是参数。
如何从 RAM DEPTH 确定地址宽度?
我知道关系 RAM DEPTH = 2 ^ (ADDRESS WIDTH)
即地址宽度 = log (base 2) RAM DEPTH。
Verilog中如何实现log(base 2)功能?
我正在实现一个可配置的 DPRAM,其中 RAM DEPTH 是参数。
如何从 RAM DEPTH 确定地址宽度?
我知道关系 RAM DEPTH = 2 ^ (ADDRESS WIDTH)
即地址宽度 = log (base 2) RAM DEPTH。
Verilog中如何实现log(base 2)功能?
$clog2
系统任务已添加到 Verilog (IEEE Std 1800-2005) 的 SystemVerilog 扩展中。这将返回一个整数,其值为对数基数 2 的上限。DEPTH 不必是 2 的幂。
module tb;
parameter DEPTH = 5;
parameter WIDTH = $clog2(DEPTH);
initial begin
$display("d=%0d, w=%0d", DEPTH, WIDTH);
#5 $finish;
end
endmodule
运行模拟将显示:
d=5, w=3
但是,我不知道支持$clog2
. 如果需要合成代码,可以使用function
. 这是从 IEEE 1364-2001 Std 复制的,但网上还有其他版本:
function integer clogb2;
input [31:0] value;
begin
value = value - 1;
for (clogb2 = 0; value > 0; clogb2 = clogb2 + 1) begin
value = value >> 1;
end
end
endfunction
我的经验是,function
对于可综合的代码,使用它比使用它更麻烦。它给设计流程中的其他工具(linter、等价检查器等)带来了问题。
虽然 $clog2 是正确答案,但在工具供应商赶上之前,您可以将自己的 clog2 函数实现为 verilog-2001 宏,它适用于所有综合和仿真工具。
如:
`define CLOG2(x) \
(x <= 2) ? 1 : \
(x <= 4) ? 2 : \
(x <= 8) ? 3 : \
(x <= 16) ? 4 : \
(x <= 32) ? 5 : \
(x <= 64) ? 6 : \
..etc, as far as you need to go..
(x <= 4294967296) ? 32 : \
-1
parameter FOO_MAX_VALUE = 42;
parameter FOO_WIDTH = `CLOG2(FOO_MAX_VALUE);
最后的“-1”用于产生非法值,模拟器应该标记。
(后期编辑:哎呀,修复了我的错误!)