Search code examples
verilogmodelsim

Verilog floating point arithmetic at compile time?


My Verilog testbench code defines a module with these parameters:

parameter PHASE_BITS = 32;
parameter real MAX_PHASE = 1 << PHASE_BITS;

I cannot get MAX_PHASE to have the expected value 4294967296 or its approximation; ModelSim shows me 0 instead. This despite the fact that MAX_PHASE is declared real.

I guess there's some integer overflow involved, because it works fine if PHASE_BITS is lowered to 31.

How do I make this parameter be equal to 2 to the power of another parameter?


Solution

  • The problem lies in the right-hand expression itself:

    1 << PHASE_BITS
    

    It is evaluated before considering the type of the variable it is stored into. Because 1 is an integer literal and integers in Verilog are signed 32 bits, the << operator (left shift operator) will output an integer of the same type, and will cause an overflow if PHASE_BITS is higher than 31.

    We could force 1 to be a real literal instead:

    1.0 << PHASE_BITS
    

    But this causes a compile time error, as << is not defined for real values.

    Let's use plain 2-power-to-N:

    2.0 ** PHASE_BITS
    

    This will yield the desired result, 4.29497e+09.