# Quartus Error (12051): Project too complex: hierarchy path is too long

Status
Not open for further replies.

#### shaiko

Hello,

I've been trying to synthesize a design with no success.
Quartus (Prime 16.0) fails with the following error message:
Quartus Error (12051): Project too complex: hierarchy path is too long
The error points to the label marked in red below.

Code:
-- This is a design of a 2d_convolution filter.
-- So no fabric logic (outside the DSP block) is used for the filter calculations.
-- The design is parameterized by defining a KERNEL_SIZE and bits per pixel.
-- KERNEL_SIZE must be an odd number >= 3.

-- Example 1: KERNEL_SIZE = 3. The pixel in the center (P4) will be replaced with a new value.
-- P0 P1 P2
-- P3 P4 P5
-- P6 P7 P8
-- NEW_P4 = P0*C0 + P1*C1 + ... + P8*C8

-- Example 2: KERNEL_SIZE = 5. The pixel in the center (P4) will be replaced with a new value.
-- P0  P1  P2  P3  P4
-- P5  P6  P7  P8  P9
-- P10 P11 P12 P13 P14
-- P15 P16 P17 P18 P19
-- P20 P21 P22 P23 P24
-- NEW_P12 = P0*C0 + P1*C1 ... P24*C24

-- The value of the coefficients (C0, C1, etc...) are internal to the DSP blocks.

-- With every clock, a box of pixels arrive. The number of pixels in a box = KERNEL_SIZE * KERNEL_SIZE.

library ieee ;
use ieee.std_logic_1164.all ;
use ieee.numeric_std.all ;
use ieee.math_real.all ;

library work ;
use work.package_definitions_arrays.all ;

LIBRARY altera_mf; USE altera_mf.altera_mf_components.all;
--LIBRARY altera_lnsim;
--USE altera_lnsim.altera_lnsim_components.all;

entity convolution is

generic
(
BITS_PER_PIXEL 	:	positive := 18 ;
KERNEL_SIZE 	:	positive := 3
) ;

port
(
IN_CLOCK		:	in	std_logic ;																						-- Global clock.
IN_GLOBAL_RESET	:	in	std_logic ;																						-- Asynchronous Reset.
IN_LOCAL_RESET	:	in	std_logic ;																						-- Synchronous Reset.
IN_ENABLE 		:	in	std_logic ;																						-- Indicates that IN_BOX is valid.
IN_BOX 			:	in	generic_1d_slv_array ( 0 to KERNEL_SIZE * KERNEL_SIZE - 1 ) ( BITS_PER_PIXEL - 1 downto 0 ) ;	-- The input data is a box of adjacent pixels ( each array element is a pixel ). The "area" of the box is the number of pixels and equals "KERNEL_SIZE * KERNEL_SIZE".

OUT_RESULT		:	out	std_logic_vector ( BITS_PER_PIXEL - 1 downto 0 )
) ;

end entity ;

architecture rtl_convolution of convolution is

constant 	pixels_per_box			:	positive := KERNEL_SIZE * KERNEL_SIZE ;
signal 		registered_box 			: 	generic_1d_1d_slv_array ( 0 to pixels_per_box - 1 ) ( 0 to pixels_per_box - 1 ) ( BITS_PER_PIXEL - 1 downto 0 ) ;
signal 		input_to_dsp_multiply 	: 	generic_1d_slv_array ( 0 to pixels_per_box - 1 ) ( BITS_PER_PIXEL - 1 downto 0 ) ;
signal		input_to_dsp_add		:	generic_1d_slv_array ( 0 to pixels_per_box - 1 ) ( BITS_PER_PIXEL - 1 downto 0 ) ;
signal 		output_from_dsp 		: 	generic_1d_slv_array ( 0 to pixels_per_box - 1 ) ( BITS_PER_PIXEL - 1 downto 0 ) ;

component ALTERA_MULT_ADD is -- generated by Quartus
port (
result  : out std_logic_vector(17 downto 0);                    --  result.result
dataa_0 : in  std_logic_vector(17 downto 0) := (others => '0'); -- dataa_0.dataa_0
datab_0 : in  std_logic_vector(17 downto 0) := (others => '0'); -- datab_0.datab_0
clock0  : in  std_logic                     := '0';             --  clock0.clock0
ena0    : in  std_logic                     := '0';             --    ena0.ena0
aclr0   : in  std_logic                     := '0';             --   aclr0.aclr0
chainin : in  std_logic_vector(17 downto 0) := (others => '0')  -- chainin.chainin
);

begin

-- "registered_box" is a array in which each element is a box.
-- Our goal is to create delayed copies of IN_BOX.
-- The number of copies equals KERNEL_SIZE * KERNEL_SIZE - 1.
-- For example if KERNEL_SIZE = 3. We create 8 delayed copies.

registered_box ( 0 ) <= IN_BOX ;

create_delayed_copies_of_box : process ( IN_CLOCK , IN_GLOBAL_RESET ) is
begin
if IN_GLOBAL_RESET = '1' then
registered_box ( 1 to pixels_per_box - 1 ) <= ( others => ( others => ( others => '0' ) ) ) ;
elsif rising_edge ( IN_CLOCK ) then
for index in 0 to pixels_per_box - 2
loop
registered_box ( index + 1 ) <= registered_box ( index ) ;
end loop ;
end if ;
end process create_delayed_copies_of_box ;

-- From the delayed copies, we choose the required pixels ( not all pixels will be used ).
-- To do this we define "input_to_dsp_multiply".
-- The number of elements in "input_to_dsp_multiply" equals the number of pixels per box.
-- We map the pixels of "registered_box" into the correct location in "input_to_dsp_multiply" such that the pixel delayed the highest number of times will be connected to the last DSP block.

--		Here is an example for a KERNEL_SIZE = 3
--		input_to_dsp_multiply ( 0 ) <= registered_box ( 0 ) ( 0 ) ; -- The pixel that hasn't been delayed will be connected to the first.
--		input_to_dsp_multiply ( 1 ) <= registered_box ( 1 ) ( 1 ) ;
--		input_to_dsp_multiply ( 2 ) <= registered_box ( 2 ) ( 2 ) ;
--		input_to_dsp_multiply ( 3 ) <= registered_box ( 3 ) ( 3 ) ;
--		input_to_dsp_multiply ( 4 ) <= registered_box ( 4 ) ( 4 ) ;
--		input_to_dsp_multiply ( 5 ) <= registered_box ( 5 ) ( 5 ) ;
--		input_to_dsp_multiply ( 6 ) <= registered_box ( 6 ) ( 6 ) ;
--		input_to_dsp_multiply ( 7 ) <= registered_box ( 7 ) ( 7 ) ;
--		input_to_dsp_multiply ( 8 ) <= registered_box ( 8 ) ( 8 ) ; -- The pixel that has been delayed the highest number of times will be connected to the last DSP block.

[COLOR="#FF0000"]connecting_pixels_to_dsp[/COLOR] : for index in 0 to pixels_per_box - 1
generate

PORT MAP
(
aclr0 => IN_GLOBAL_RESET ,
chainin => input_to_dsp_add ( index ) ,
clock0 => IN_CLOCK ,
ena0 => IN_ENABLE ,
dataa_0 => input_to_dsp_multiply ( index ) ,
datab_0 => ( others => '1' ) ,
result => output_from_dsp ( index )
);

end generate ;

input_to_dsp_add ( 0 ) <= ( others => '0' ) ;
------------------------------------------------------
connecting_between_dsp : for index in 0 to pixels_per_box - 2
generate
input_to_dsp_add ( index + 1 ) <= output_from_dsp ( index ) ;
end generate ;
------------------------------------------------------
choosing_pixels_to_connect : for index in 0 to pixels_per_box - 1
generate
input_to_dsp_multiply ( index ) <= registered_box ( index ) ( index ) ;
end generate ;
------------------------------------------------------
OUT_RESULT <= output_from_dsp ( pixels_per_box - 1 ) ;

end architecture rtl_convolution ;

Last edited:

#### TrickyDicky

I assume you have this entity isnt the top level? Id go with the error - your project is too complex with paths that are too long...

#### shaiko

I assume you have this entity isnt the top level? Id go with the error - your project is too complex with paths that are too long...
For now, this is the top entity. Just wanted to synthesize it and review the RTL...

After posting I've seen this:
http://quartushelp.altera.com/14.0/mergedProjects/msgs/msgs/esgn_project_too_complex.htm
This could also be due to an undetected recursion.
I think this is more likely. But unfortunately I won't have the in front of me soon - so I can't verify.

Status
Not open for further replies.