来自RAM深度的地址宽度是什么意思?

26

我正在实现一个可配置的DPRAM,其中RAM深度是参数。

如何从RAM深度确定地址宽度?

我知道RAM深度和地址宽度之间的关系是RAM深度 = 2 ^ (地址宽度)

即地址宽度 = log (以2为底) RAM深度。

如何在Verilog中实现以2为底的对数函数?

2个回答

40

$clog2 系统任务是被添加到 SystemVerilog 扩展的 Verilog(IEEE 标准 1800-2005)中的。它返回一个整数,该整数的值为以2为底的对数向上取整的结果。DEPT可以不是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会带来比它所值得的更多的麻烦。这可能会影响设计流程中的其他工具(如linters、等价性检查器等)。


2
由于这个答案发布已经有几年了,我想指出现在(至少一些)综合工具已经支持 $clog2。如果你的工具不支持它,我建议你尝试请求支持,因为它是一个非常有用的函数。 - nguthrie
4
确认了 icestorm 可以综合 $clog2 - Jonathan Schneider
最近的Quartus版本支持这个功能。但是我发现像Incisive IUS这样的模拟器存在问题。 - sebs

25

虽然 $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"被用于产生一个非法值时,模拟器应该发出警报。

(晚期编辑:哎呀,我修复了我的偏移错误!)


它能工作...但是它很粗糙和杂乱无章;这让我想起了我曾经看过的一个C代码片段,其中程序员需要知道一个数字是否为偶数,因此他将其与0到100之间的所有偶数进行比较。 - Kaiser Keister
1
微妙的差别在于,你的第一个版本计算了位宽;而你的修改计算了以2为底的对数的上限。因此,这两个算法都很有用。也许你可以编辑你的帖子来展示它们,即CLOG2(x)和BIT_WIDTH(x)。 - tim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接