Computed verilog parameter in Yosys

937 views Asked by At

I am learning Verilog at the moment by using Yosys to synthesize code to an iCE40 development board. I am stuck at using parameters in verilog. I have the following code:

module tst;

    parameter clkspd=12000000;
    parameter baudrate=115200;
    localparam bitperiod=$floor(clkspd/baudrate-0.5);
    localparam bittmrwidth=$clog2(bitperiod);
    //localparam bittmrwidth=$clog2(103);

    initial begin
     $display("Hello World!");
     $display("width=%d",bittmrwidth);
    end

endmodule

When I compile the code with :

yosys -p 'synth_ice40 -top tst -blif tst.blif' tst.v

I get an error:

ERROR: Failed to evaluate system function `\$clog2' with non-constant value at tst.v:5.

However if I use the commented out line, everything work as expected.

How can I calculate "bittmrwidth" with the given parameters ?

1

There are 1 answers

1
toolic On BEST ANSWER

I don't have yosys installed, but when I run your code on another simulator, I get this error:

System function call $clog2 must have an integral argument.

This is consistent with the IEEE Std 1800-2012, section 20.8.1 Integer math functions, which states for $clog2:

The argument can be an integer or an arbitrary sized vector value.

The $floor function returns a real result type, according to section 20.8.2 Real math functions. Simply cast the $floor output to an integer type with $rtoi. The following code runs without errors for me:

module tst;

    parameter clkspd=12000000;
    parameter baudrate=115200;
    localparam bitperiod = $rtoi($floor(clkspd/baudrate-0.5));
    localparam bittmrwidth=$clog2(bitperiod);

    initial begin
     $display("Hello World!");
     $display("width=%d",bittmrwidth);
    end

endmodule

/*

Output:

Hello World!
width=          7

*/

My original code used a cast operator, but apparently yosys does not yet support it, according to the Comment below. Here was my original line:

localparam bitperiod = int'($floor(clkspd/baudrate-0.5));