0

I want to declare a counter reg in function of some parameters. I did it in this way :

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;

This work well in simulation with icarus but ISE 14.7 don't want to synthesize it. That give this error:

WARNING:HDLCompiler:1499 - "/src/button_deb.v" Line 4: Empty module <button_deb> remains a black box.

If I define the count like this :

reg [22:0] count;

ISE synthesize it well. If someone have a clue ?

shA.t
  • 16,580
  • 5
  • 54
  • 111
FabienM
  • 3,421
  • 23
  • 45
  • Have you tried adding another localparam that holds the result of $ln(MAX_COUNT)/$ln(2) and then use that param to define the upper bond of your register? You might need to use $floor() or $ceil() as well to make sure your number is integer – mcleod_ideafix Mar 14 '15 at 13:20
  • AFAIK ISE doesn't support `$ln` function. – Qiu Mar 14 '15 at 13:53

1 Answers1

1

This worked for me, although I'd swear I used functions like $log, $log10, $ceil and the like in the past with no problems.

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 seems to have a problem with using constant functions: they only can be at the right side of a parameter declaration expression (as I suggested in my first comment). Credits and more information here: http://www.beyond-circuits.com/wordpress/2008/11/constant-functions/

Notice too that UPPER is declared as localparam integer so we can use it inside a register definition upper bound expression. Credits go to the owner of this post: http://forums.xilinx.com/t5/Synthesis/XST-and-clog2/m-p/244440/highlight/true#M6609

(the module is just a phony module to have something that I can symthesize without the fear that the synthesizer will wipe all my code. It doesn't perform any kind of debouncing)

mcleod_ideafix
  • 11,128
  • 2
  • 24
  • 32
  • That work well for synthesis in ISE :) But doesn't work in simulation with Icarus Verilog :( ``src/button_deb.v:28: sorry: constant user functions are not currently supported: log2().`` – FabienM Mar 14 '15 at 15:28
  • That work with parameter integer : ``parameter integer MAX_COUNT_UPPER = $floor($log10(MAX_COUNT)/$log10(2));`` But I still have some ise warning : ``WARNING:HDLCompiler:413 - src/button_deb.v" Line 20: Result of 64-bit expression is truncated to fit in 32-bit target.`` – FabienM Mar 14 '15 at 16:00