RAM DEPTHがパラメータである場合、構成可能なDPRAMを実装しています。
RAM DEPTHからアドレス幅を決定する方法は?
私は関係RAM DEPTH = 2 ^(ADDRESS WIDTH)を知っています
つまり、住所の幅=ログ(底2)RAM深さ。
ログ(ベース2)関数をVerilogに実装する方法
$clog2
システムタスクが、VerilogのSystemVerilog拡張機能に追加されました(IEEE Std 1800-2005)。これは、2を底とする対数の上限の値を持つ整数を返します。深さは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
を使用することは、合成可能なコードよりも厄介です。デザインフローの他のツール(リンター、等価チェッカーなど)に問題が発生しました。
$ 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」が不正な値を生成するために使用される場合、シミュレーターはフラグを立てるべきです。
(編集後:おっと、私の1つずれたエラーを修正!)