Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16621 Discussions

Quartus compiler parameter expression evaluation with power operator (A**) faulty?

Steve-Mowbray-ENL
New Contributor I
629 Views

Hi

I have encountered a discrepancy between Quartus and ModelSim compilation of parameter expressions containing a power operator (A**B):

 

module quartus_pow_op_test #(
    parameter F_S_HZ = 100000000,
    parameter F_C_HZ = 300000,
    parameter N_BITS = 34
    )
(
    input  wire clk,
    input  wire reset
);
localparam POW_2_N_BITS_INT = 2**N_BITS;        // valid for N_BITS = 0...30
localparam POW_2_N_BITS_REAL = 2.0**N_BITS;

localparam PHASE_RATE_0 = ((1.0*F_C_HZ)/(1.0*F_S_HZ)) * (2.0**N_BITS);
localparam PHASE_RATE_1 = ((1.0*F_C_HZ)/(1.0*F_S_HZ)) * (2.0**34);
localparam PHASE_RATE_2 = ((1.0*F_C_HZ)/(1.0*F_S_HZ)) * (1.0*(2.0**34));
localparam PHASE_RATE_3 = ((1.0*F_C_HZ)/(1.0*F_S_HZ)) * (1.0*(2.0**N_BITS));
localparam PHASE_RATE_4 = ((1.0*F_C_HZ)/(1.0*F_S_HZ)) * POW_2_N_BITS_REAL;

initial begin
    $display("DEBUG: F_S_HZ       = %0f", F_S_HZ);
    $display("DEBUG: F_C_HZ       = %0f", F_C_HZ);
    $display("DEBUG: N_BITS       = %0f", N_BITS);
    $display("DEBUG: 2**N_BITS    = %0f", POW_2_N_BITS_INT);
    $display("DEBUG: 2.0**N_BITS  = %0f (POW_2_N_BITS_REAL)", POW_2_N_BITS_REAL);
    $display("DEBUG: ((1.0*F_C_HZ)/(1.0*F_S_HZ)) * (2.0**N_BITS)       = %0f", PHASE_RATE_0);
    $display("DEBUG: ((1.0*F_C_HZ)/(1.0*F_S_HZ)) * (2.0**34)           = %0f", PHASE_RATE_1);
    $display("DEBUG: ((1.0*F_C_HZ)/(1.0*F_S_HZ)) * (1.0*(2.0**34))     = %0f", PHASE_RATE_2);
    $display("DEBUG: ((1.0*F_C_HZ)/(1.0*F_S_HZ)) * (1.0*(2.0**N_BITS)) = %0f", PHASE_RATE_3);
    $display("DEBUG: ((1.0*F_C_HZ)/(1.0*F_S_HZ)) * POW_2_N_BITS_REAL   = %0f", PHASE_RATE_4);
end

endmodule

 

 Result is:

 

DEBUG: F_S_HZ       = 100000000.000000
DEBUG: F_C_HZ       = 300000.000000
DEBUG: N_BITS       = 34.000000
DEBUG: 2**N_BITS    = 0.000000
DEBUG: 2.0**N_BITS  = 17179869184.000000 (POW_2_N_BITS_REAL)
DEBUG: ((1.0*F_C_HZ)/(1.0*F_S_HZ)) * (2.0**N_BITS)       = 0.000000
DEBUG: ((1.0*F_C_HZ)/(1.0*F_S_HZ)) * (2.0**34)           = 0.000000
DEBUG: ((1.0*F_C_HZ)/(1.0*F_S_HZ)) * (1.0*(2.0**34))     = 51539607.552000
DEBUG: ((1.0*F_C_HZ)/(1.0*F_S_HZ)) * (1.0*(2.0**N_BITS)) = 0.000000
DEBUG: ((1.0*F_C_HZ)/(1.0*F_S_HZ)) * POW_2_N_BITS_REAL   = 51539607.552000

 

 Note that some forms of the expression evaluate to (incorrect) zero - whereas ModelSim compiler evaluates all forms correctly.

Am I missing something here? Also is there a better way of produces info messages during Quartus compile than the above use of $display() in an initial section?

Thanks

Steve

Labels (1)
0 Kudos
1 Solution
FvM
Valued Contributor III
609 Views

Hi,

Verilog LRM says
"Implementations may limit the maximum size of integer variables, but it shall be at least 32 bits."

You see that Quartus apparently uses 32 bit integer but Modelsim most likely 64 bit. That's completely legal but must be considered.

Quartus gives an overflow  warning for line 10, by the way.

 

The rest shouldn't happen according to Verilog language reference, I think. Looks a bug in parameter calculation, ignoring type proagation rules for real parameters.

This worked for me in Quartus 19.1

localparam PHASE_RATE_5 = real'(F_C_HZ)/real'(F_S_HZ) * real'(2.0**N_BITS);

 

 

View solution in original post

0 Kudos
5 Replies
FvM
Valued Contributor III
610 Views

Hi,

Verilog LRM says
"Implementations may limit the maximum size of integer variables, but it shall be at least 32 bits."

You see that Quartus apparently uses 32 bit integer but Modelsim most likely 64 bit. That's completely legal but must be considered.

Quartus gives an overflow  warning for line 10, by the way.

 

The rest shouldn't happen according to Verilog language reference, I think. Looks a bug in parameter calculation, ignoring type proagation rules for real parameters.

This worked for me in Quartus 19.1

localparam PHASE_RATE_5 = real'(F_C_HZ)/real'(F_S_HZ) * real'(2.0**N_BITS);

 

 

0 Kudos
Steve-Mowbray-ENL
New Contributor I
606 Views

Many Thanks FvM

Noted integer variable size at 32 - I understood Verilog LRM along the lines "if any operand to the operator is real then result is real" hence my use of (2.0**B) rather than (2**B) also I somewhat imprecisely use (1.0 * C) as lazy form of real'(C) {{which is new to me}} but based on the same premise.

I agree seems like parameter expression evaluation bug when real result power operator is present...

 

Final question is of great interest to me:  Is there a better way of produces info messages during Quartus compile than the above use of $display() in an initial section?

 

Regards

Steve

0 Kudos
Nurina
Employee
542 Views

Hi Steve,


As far as I know there isn't a way to produce info messages on Quartus besides using $display.


Regards,

Nurina


0 Kudos
Steve-Mowbray-ENL
New Contributor I
454 Views

Hi Nurina

Sorry for late response I didn't receive any prompts about this thread for some reason - thanks for confirming that, I shall continue using $display() to generate console output messages as and when required

Regards

Steve

0 Kudos
Nurina
Employee
501 Views

Hi,


We have not received a reply from you. As such, I now transition this thread to community support. If you have a new question, Feel free to open a new thread or login to ‘ https://supporttickets.intel.com ’, view details of the desire request, and post a feed/response within the next 15 days to allow me to continue to support you. After 15 days, this thread will be transitioned to community support. The community users will be able to help you on your follow-up questions.

  

Have a great day!

Best regards,

Nurina W.


0 Kudos
Reply