RAM DEPTH的地址宽度

Ash*_*ini 23 verilog system-verilog

我正在实现一个可配置的DPRAM,其中RAM DEPTH是参数.

如何从RAM DEPTH确定ADDRESS WIDTH?

我知道关系RAM DEPTH = 2 ^(ADDRESS WIDTH)

即ADDRESS WIDTH = log(base 2)RAM DEPTH.

如何在Verilog中实现log(base 2)函数?

too*_*lic 30

$clog2系统任务添加到SystemVerilog的扩展的Verilog(IEEE标准1800-2005).这将返回一个整数,该整数具有日志基数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
Run Code Online (Sandbox Code Playgroud)

运行模拟将显示以下内容:

d=5, w=3
Run Code Online (Sandbox Code Playgroud)

但是,我不知道支持的综合工具$clog2.如果您需要综合代码,可以使用function.这是从IEEE 1364-2001标准版复制的,但网上还有其他版本:

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
Run Code Online (Sandbox Code Playgroud)

我的经验是使用function它比合成代码更值得麻烦.它给设计流程中的其他工具(短路,等效检查器等)带来了问题.

  • 由于这个答案发布已经有几年了,我想指出(至少一些)综合工具现在确实支持 $clog2。如果您的工具不支持它,我会看看您是否可以请求它,因为它是一个非常有用的功能。 (2认同)
  • 验证了icestorm可以合成`$ clog2`. (2认同)

Jon*_*yer 23

虽然$ 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);
Run Code Online (Sandbox Code Playgroud)

如果最后的"-1"用于产生非法值,则模拟器应该标记.

(后期编辑:哎呀,修复了我的一对一错误!)