Как ограничить размер счетчика reg в verilog для синтеза ise?

Я хочу объявить счетчик reg в функции некоторых параметров. Я сделал это следующим образом:

parameter clk_freq = 95000; // clock frequency in kHz
parameter debounce_per_ms = 20;
localparam MAX_COUNT = ((debounce_per_ms * clk_freq)) + 1;
reg [$ln(MAX_COUNT)/$ln(2):0] count;

Это хорошо работает в моделировании с icarus, но ISE 14.7 не хочет его синтезировать. Это дает эту ошибку:

ВНИМАНИЕ: HDLCompiler: 1499 - "/src/button_deb.v" Строка 4: Пустой модуль <button_deb> остается черным ящиком.

Если я определяю счет следующим образом:

reg [22:0] count;

ISE хорошо его синтезировать. Если у кого-то есть ключ?


person FabienM    schedule 14.03.2015    source источник
comment
Пробовали ли вы добавить еще один локальный параметр, который содержит результат $ln(MAX_COUNT)/$ln(2), а затем использовать этот параметр для определения верхней связи вашего регистра? Возможно, вам придется использовать $floor() или $ceil(), чтобы убедиться, что ваше число является целым числом.   -  person mcleod_ideafix    schedule 14.03.2015
comment
AFAIK ISE не поддерживает функцию $ln.   -  person Qiu    schedule 14.03.2015


Ответы (1)


Это сработало для меня, хотя я готов поклясться, что раньше без проблем использовал такие функции, как $log, $log10, $ceil и им подобные.

module param_with_log2 (
    input wire clk,
    output wire d
    );

    function integer log2;
        input integer value;
        begin
            value = value-1;
            for (log2=0; value>0; log2=log2+1)
                value = value>>1;
        end
    endfunction

    parameter clk_freq = 95000; // clock frequency in kHz
    parameter debounce_per_ms = 20;
    localparam MAX_COUNT = ((debounce_per_ms * clk_freq)) + 1;
    localparam integer UPPER = log2(MAX_COUNT);

    reg [UPPER:0] count;
    always @(posedge clk)
        count <= count + 1;
    assign d = count[UPPER];
endmodule

Кажется, у XST есть проблема с использованием константных функций: они могут быть только справа от выражения объявления параметра (как я предложил в своем первом комментарии). Авторы и дополнительная информация здесь: http://www.beyond-circuits.com/wordpress/2008/11/constant-functions/

Заметьте также, что UPPER объявлено как localparam integer, поэтому мы можем использовать его внутри выражения верхней границы определения регистра. Кредиты принадлежат владельцу этого сообщения: http://forums.xilinx.com/t5/Synthesis/XST-and-clog2/m-p/244440/highlight/true#M6609

(модуль - это просто фальшивый модуль, чтобы иметь что-то, что я могу синтезировать, не опасаясь, что синтезатор сотрет весь мой код. Он не выполняет никакого устранения дребезга)

person mcleod_ideafix    schedule 14.03.2015
comment
Это хорошо работает для синтеза в ISE :) Но не работает в моделировании с Icarus Verilog :( src/button_deb.v:28: sorry: constant user functions are not currently supported: log2(). - person FabienM; 14.03.2015
comment
Это работает с целочисленным параметром: parameter integer MAX_COUNT_UPPER = $floor($log10(MAX_COUNT)/$log10(2)); Но у меня все еще есть предупреждение ise: WARNING:HDLCompiler:413 - src/button_deb.v" Line 20: Result of 64-bit expression is truncated to fit in 32-bit target. - person FabienM; 14.03.2015