АДРЕСНАЯ ШИРИНА из RAM DEPTH

Я реализую конфигурируемый DPRAM, где RAM DEPTH является параметром.

Как определить ADDRESS WIDTH из RAM DEPTH?

Я знаю отношение RAM DEPTH = 2 ^ (ADDRESS WIDTH)

i.e ADDRESS WIDTH = log (base 2) RAM DEPTH.

Как реализовать функцию журнала (база 2) в Verilog?

Ответ 1

Системная задача $clog2 была добавлена ​​в расширение SystemVerilog для Verilog (IEEE Std 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

Запуск моделирования покажет это:

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 - это больше проблем, чем для синтезируемого кода. Это вызвало проблемы для других инструментов в потоке проектирования (литеры, проверки эквивалентности и т.д.).

Ответ 2

В то время как $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" используется для создания недопустимого значения, которое должен обозначить симулятор.

(позднее редактирование: oops, исправлена ​​ошибка "один за другим"!)