Article ID: 000083380 Content Type: Troubleshooting Last Reviewed: 12/15/2012

FIR Filters may Fail to Use DSP Block Input Registers

Environment

    Quartus® II Subscription Edition
BUILT IN - ARTICLE INTRO SECOND COMPONENT

Critical Issue

Description

Some FIR filters, which the FIR Compiler II produces, fail to use all the appropriate DSP block input registers. TimeQuest does not correctly analyze these FIR filters, and they appear to meet timing. In reality, the timing on the unregistered paths are not analyzed and these FIR filters are likely to cause timing-related errors when implemented in hardware.The issue affects Stratix V, Arria V (both GX and GZ), and Cyclone V devices. The problem affects FIR filters that:Use systolic modeNeed an odd number of multipliersThis problem does not affect FIR filters that need an even number of multipliers.Odd and even refer to the number of physical multipliers that implement the FIR filter, not the number of taps that you originally specify. A FIR filter with an even number of taps may need an odd number of physical multipliers and vice versa.To determine whether my FIR filter is affected, follow these steps:Examine the generated VHDL code to determine whether it contains a dummy multiplier. A systolic FIR filter contains a number of CHAINMULTADD comments. If your FIR filter does not contain any comments similar to the following comments, your FIR filter is not a systolic FIR filter and is not affected: --u0_m0_wo0_cma0(CHAINMULTADD,33)@13

If your FIR contains one or more CHAINMULTADD comments, examine the VHDL code that follows each such comment. A few lines after the CHAINMULTADD comment, find a chainmultadd process similar to the following code:u0_m0_wo0_cma0_chainmultadd: PROCESS (clk, areset) BEGIN IF (areset = '1') THEN u0_m0_wo0_cma0_a <= (others => (others => '0')); u0_m0_wo0_cma0_b <= (others => (others => '0')); u0_m0_wo0_cma0_c <= (others => (others => '0')); u0_m0_wo0_cma0_anl <= '0'; u0_m0_wo0_cma0_s <= (others => (others => '0')); ELSIF(clk'EVENT AND clk = '1') THEN IF (d_u0_m0_wo0_compute_q_13_q = "1") THEN u0_m0_wo0_cma0_a(0) <= SIGNED(RESIZE(SIGNED(u0_m0_wo0_wi0_delayr0_q),17)); u0_m0_wo0_cma0_a(1) <= SIGNED(RESIZE(SIGNED(u0_m0_wo0_wi0_split1_b),17)); u0_m0_wo0_cma0_a(2) <= SIGNED(RESIZE(SIGNED(u0_m0_wo0_wi0_split1_c),17)); u0_m0_wo0_cma0_a(3) <= (others => '0'); u0_m0_wo0_cma0_b(0) <= SIGNED(RESIZE(SIGNED(u0_m0_wo0_wi0_split4_c),17)); u0_m0_wo0_cma0_b(1) <= SIGNED(RESIZE(SIGNED(u0_m0_wo0_wi0_split4_b),17)); u0_m0_wo0_cma0_b(2) <= SIGNED(RESIZE(SIGNED(u0_m0_wo0_cma0_mux_2_q),17)); u0_m0_wo0_cma0_b(3) <= (others => '0'); u0_m0_wo0_cma0_c(0) <= UNSIGNED(RESIZE(UNSIGNED(u0_m0_wo0_ca2_q),3)); u0_m0_wo0_cma0_c(1) <= UNSIGNED(RESIZE(UNSIGNED(u0_m0_wo0_ca2_q),3)); u0_m0_wo0_cma0_c(2) <= UNSIGNED(RESIZE(UNSIGNED(u0_m0_wo0_ca2_q),3)); u0_m0_wo0_cma0_c(3) <= (others => '0'); u0_m0_wo0_cma0_anl <= not(u0_m0_wo0_aseq_q(0)); END IF; IF (d_u0_m0_wo0_compute_q_14_q = "1") THEN u0_m0_wo0_cma0_s(0) <= u0_m0_wo0_cma0_z(0) u0_m0_wo0_cma0_y(0); u0_m0_wo0_cma0_s(1) <= u0_m0_wo0_cma0_y(1); u0_m0_wo0_cma0_s(2) <= u0_m0_wo0_cma0_y(2); u0_m0_wo0_cma0_s(3) <= u0_m0_wo0_cma0_y(3); END IF; END IF; END PROCESS;The lines in bold set both inputs of the same multiplier to zero, which is a dummy multiplier, and your FIR filter is affected. If none of the chainmultadd processes contains a dummy multiplier, your FIR is not affected.

Resolution

To workaround this problem, increase the length that you specify for the FIR filter. If you choose the right length, the implementation does not need any dummy multipliers.Alternatively, manually edit the VHDL generated by FIR Compiler II to add the Quartus II preserve attribute to the DSP input registers. The Quartus II synthesis does not remove the dummy multiplier input registers and the Quartus II fitter packs all the DSP block input registers correctly. To manually edit the VHDL, follow these steps:Find the declarations of the input registers, which look similar to the following code: type u0_m0_wo0_cma0_a_type is array(0 to 3) of SIGNED(16 downto 0); signal u0_m0_wo0_cma0_a : u0_m0_wo0_cma0_a_type; type u0_m0_wo0_cma0_b_type is array(0 to 3) of SIGNED(16 downto 0); signal u0_m0_wo0_cma0_b : u0_m0_wo0_cma0_b_type; type u0_m0_wo0_cma0_c_type is array(0 to 3) of UNSIGNED(2 downto 0); signal u0_m0_wo0_cma0_c : u0_m0_wo0_cma0_c_type;If the FIR filter does not use the DSP block\'s preadders, the \'b\' signal is not present. Add the following code: attribute preserve : boolean; attribute preserve of u0_m0_wo0_cma0_a : signal is true; attribute preserve of u0_m0_wo0_cma0_b : signal is true; attribute preserve of u0_m0_wo0_cma0_c : signal is true;Only add the preserve attribute should be declared only once.

This problem is fixed in DSP Builder v13.1.

Related Products

This article applies to 1 products

Intel® Programmable Devices

1