Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

Help - Quartus never completes Analysis/Synthesis

Hi - I'm dead-in-the-water after 3 hours of debugging. I have a small (21K ALUT) design on a Stratix-IV FPGA. It's a DSP design, and in

several places I re-use a small parameterized module called "shft_rnd_sat". (you can guess what it does 8-}).

I recently put it in 1 additional place in the design (to replace a shift-only operation), and now the compile stalls 46% of the way in. It runs in excess of 30 minutes stuck at this point (it normally takes 2 minutes to get past this point).

I've isolated it down to a single line of code - the round. I have this unconditional line

data_in_shift_rnd <= (data_in (data_in_len -1 downto rshift)) + ((data_in_len-rshift-1 downto 1 => '0') & '1');

If I change it to

data_in_shift_rnd <= (data_in (data_in_len -1 downto rshift)) + ((data_in_len-rshift-1 downto 1 => '0') & '0');

or even

data_in_shift_rnd <= (data_in (data_in_len -1 downto rshift)) or ((data_in_len-rshift-1 downto 1 => '0') & '1');

everything works fine.

I made a copy of the module that is instantiated only in the 1 new place, and changing only that copy as noted above is sufficient to turn

on/off the problem.

ALSO - I should mention that my design has a top-level that is little more than a generate statement with 8 instantiations of a 2.6K ALUT 'main' module which (down the hierarchy a bit) contains the troubling module. If I work with the 'main' module alone it compiles fine, however, when I try to build with 2 or more main modules instantiated (either using a generate or explicit instantiation), then it hangs. It's very predictable and repeatable.

Without the problem it gets past this point in 2 minutes. With the problem it runs at least 30 minutes. (It might converge overnight but that's not a fix as it will make it hard to move forward).

I don't know how to go about debugging it. I've tried recoding the module a few different ways to no avail.

Any ideas? Anyone?

Thanks!

/j

(running 64b Quartus 11.2 SP2 on CentOS)

3 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    For anyone interested - here's the entire module. It's instantiated only ONE place in the 'main' module. There are 2 lines of code highlighted. If either one is changed from what it is to what I want, the compile hangs 2 minutes in, on "Duplicate registers merged into single register". When it doesn't hang, it generates the "duplicate registers" message 2 more times, and then begins inferring, elaborating, and instantiating megafunctions.

    help? 8-}

    /j

    library ieee;

    use IEEE.std_logic_signed.all;

    use ieee.std_logic_1164.all;

    -- saturates top sat_wid bits and then delivers next data_out_len significant bits

    entity shft_rnd_sat0 is

    generic (

    data_in_len : integer;

    data_out_len : integer;

    rshift : integer

    );

    port (

    data_in : in std_logic_vector (data_in_len -1 downto 0);

    data_out : out std_logic_vector (data_out_len -1 downto 0)

    );

    end shft_rnd_sat0;

    architecture rtl of shft_rnd_sat0 is

    constant din_shift_len : integer := data_in_len - rshift;

    -- constant sat_wid : integer := din_shift_len - data_out_len; -- GOOD

    constant sat_wid : integer := din_shift_len - data_out_len-1; -- WRONG, but permits compile

    signal data_in_shift_rnd : std_logic_vector (din_shift_len-1 downto 0);

    signal data_in_shift : std_logic_vector (din_shift_len-1 downto 0);

    signal sat_val : std_logic_vector (sat_wid downto 0);

    begin

    -- round operation

    data_in_shift_rnd <= (data_in (data_in_len -1 downto rshift)) + ((data_in_len-rshift-1 downto 1 => '0') & '0'); -- WRONG, but permits compile

    -- data_in_shift_rnd <= (data_in (data_in_len -1 downto rshift)) + ((data_in_len-rshift-1 downto 1 => '0') & '1'); -- GOOD

    process (all)

    begin

    -- if the rounding bit is 0, or if the value is

    -- max and can't be rounded, just shift into smaller container

    if ((data_in(rshift-1) = '0') or

    (data_in (data_in_len -1 downto rshift) = ('0' & (data_in_len-rshift-2 downto 0 => '1')))) then

    data_in_shift <= data_in (data_in_len -1 downto rshift);

    else

    -- otherwise shift and round into smaller container

    data_in_shift <= data_in_shift_rnd(din_shift_len-1 downto 0);

    end if;

    -- saturate smaller container downto output width

    sat_val <= data_in_shift (din_shift_len-1 downto din_shift_len - sat_wid-1);

    if (((sat_val = (sat_val'length-1 downto 0 => '0')) or

    (sat_val = (sat_val'length-1 downto 0 => '1'))) or (sat_wid = 0)) then

    data_out <= data_in_shift (data_out_len - 1 downto 0);

    elsif (sat_val(sat_val'length-1) = '1') then

    data_out <= ('1' & (data_out_len-2 downto 1 => '0') & '1'); -- symetric

    else

    data_out <= ('0' & (data_out_len-2 downto 0 => '1'));

    end if;

    end process;

    end;