Forum Discussion

FPGA_Newbie's avatar
FPGA_Newbie
Icon for New Contributor rankNew Contributor
2 years ago

Pipeline parameter issues for LPM_Divide

Hey everyone,

im new to VHDL and Quatus Prime. Im working with ADC data and i need to calculate the RMS for it using LPM_Mult, LPM_Divide and ALTSQRT, but im having problems with pipeline values only for divide. the LPM_Divide has the following parameters:

lpm_drepresentation => "UNSIGNED",
lpm_hint => "LPM_REMAINDERPOSITIVE=TRUE",
lpm_nrepresentation => "UNSIGNED",
lpm_pipeline => 24,
lpm_type => "LPM_DIVIDE",
lpm_widthd => 22,
lpm_widthn => 24

I have read in the user guide that we cannot specify a calue for the LPM_PIPLINE parameter that is higher than LPM_WIDTHN => 24 .. and im still getting a lot of negative slacks (Please refer to the photo below for details). Any ideas and help will be appreciated

Im using Quartus Prime 18.1.
FPGA Cyclone IV.


16 Replies

  • Hi,

    I don't know if it makes sense to make a new case for a simaler problem, so im going to right it here

    Im facing timing issues like before with "LPM_Divide" but im now using the average (similare to RMS). I have a sample design for adding the data with a PLL output of 250MHz and a register for dividing that PLL output to 125MHz called "clk_2".

    "clk_2" is connected to a "valid_register" (for a faster clock domain (PLL output) to another slower clock domain (clk_2)) and LPM_Divide where im facing timing errors.

    Here some Infos about my design:

    RTL Viewer this Desgin and Timing report attached.


    LPM_Divide Parameters:
    lpm_drepresentation => "UNSIGNED",
    lpm_hint => "MAXIMIZE_SPEED=6,LPM_REMAINDERPOSITIVE=TRUE",
    lpm_nrepresentation => "SIGNED",
    lpm_pipeline => 12,
    lpm_type => "LPM_DIVIDE",
    lpm_widthd => 22,
    lpm_widthn => 12

    SDC file:

    set_time_format -unit ns -decimal_places 3

    create_clock -name {clk} -period 20.000 -waveform { 0.000 10.000 } [get_ports {clk}]


    create_generated_clock -name {DUT0|altpll_component|auto_generated|pll1|clk[0]} -source [get_pins {DUT0|altpll_component|auto_generated|pll1|inclk[0]}] -duty_cycle 50/1 -multiply_by 5 -master_clock {clk} [get_pins {DUT0|altpll_component|auto_generated|pll1|clk[0]}]
    create_generated_clock -name clk_2 -source [get_pins {DUT0|altpll_component|auto_generated|pll1|clk[0]}] -divide_by 2 [get_pins {clk_2|q}]

    set_clock_uncertainty -rise_from [get_clocks {DUT0|altpll_component|auto_generated|pll1|clk[0]}] -rise_to [get_clocks {DUT0|altpll_component|auto_generated|pll1|clk[0]}] 0.020
    set_clock_uncertainty -rise_from [get_clocks {DUT0|altpll_component|auto_generated|pll1|clk[0]}] -fall_to [get_clocks {DUT0|altpll_component|auto_generated|pll1|clk[0]}] 0.020
    set_clock_uncertainty -fall_from [get_clocks {DUT0|altpll_component|auto_generated|pll1|clk[0]}] -rise_to [get_clocks {DUT0|altpll_component|auto_generated|pll1|clk[0]}] 0.020
    set_clock_uncertainty -fall_from [get_clocks {DUT0|altpll_component|auto_generated|pll1|clk[0]}] -fall_to [get_clocks {DUT0|altpll_component|auto_generated|pll1|clk[0]}] 0.020

    set_clock_uncertainty -rise_from [get_clocks {clk}] -rise_to [get_clocks {clk}] 0.020
    set_clock_uncertainty -rise_from [get_clocks {DUT0|altpll_component|auto_generated|pll1|clk[0]}] -rise_to [get_clocks {clk}] 0.020
    set_clock_uncertainty -rise_from [get_clocks {clk}] -rise_to [get_clocks {DUT0|altpll_component|auto_generated|pll1|clk[0]}] 0.020

    set_clock_uncertainty -rise_from clk_2 -rise_to DUT0|altpll_component|auto_generated|pll1|clk[0] 0.020
    set_clock_uncertainty -fall_from clk_2 -rise_to DUT0|altpll_component|auto_generated|pll1|clk[0] 0.020
    set_clock_uncertainty -rise_from DUT0|altpll_component|auto_generated|pll1|clk[0] -fall_to clk_2 0.020
    set_clock_uncertainty -fall_from clk_2 -rise_to clk_2 0.020
    set_clock_uncertainty -fall_from clk_2 -fall_to clk_2 0.020

    set_input_delay -add_delay -clock [get_clocks {DUT0|altpll_component|auto_generated|pll1|clk[0]}] 0.020 [get_ports {ADC_data*}]
    set_input_delay -add_delay -clock [get_clocks {DUT0|altpll_component|auto_generated|pll1|clk[0]}] 0.020 [get_ports {num_adc_data*}]

    set_output_delay -add_delay -clock [get_clocks {DUT0|altpll_component|auto_generated|pll1|clk[0]}] 0.020 [get_ports {fifo_wrreq}]
    set_output_delay -add_delay -clock [get_clocks {clk_2}] 0.020 [get_ports {mean_result*}]


    set_false_path -from [get_ports {reset}]

    set_multicycle_path -setup -end -from [get_registers {ADD_res:DUT6|fifo_valid_s}] -to [get_ports {fifo_wrreq}] 2
    set_multicycle_path -hold -end -from [get_registers {ADD_res:DUT6|fifo_valid_s}] -to [get_ports {fifo_wrreq}] 1


    Any thoughts on how we can manage to control the timing error, I'd appreciate it.
    thanks in advance

  • sstrell's avatar
    sstrell
    Icon for Super Contributor rankSuper Contributor

    It's really not clear what you are trying to do here. You're launching on a falling edge and latching an output (to a downstream device I presume) on the following launch edge, so you only have 4 ns between launch and latch. Is that intended?

    You also have a huge clock skew. I'm not really sure what is going on here.

  • Hey sstrell,

    i didn't understand what you meant with the launching and latching edge, but i got it now, i should initialise "clk_2" with '0' not '1'.
    where can i see that i have a clock skew ?

  • sstrell's avatar
    sstrell
    Icon for Super Contributor rankSuper Contributor

    This info is all in the timing reports you posted. The waveform view clearly shows that you are analyzing timing with the launch edge as the falling edge. The setup slack report shows a clock skew of over 2.2 ns for all the failing paths listed in red. I'm also not sure what you are trying to accomplish with the multicycle timing exceptions in your SDC.