Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
17267 Discussions

Newbie question about long control signal

Altera_Forum
Honored Contributor II
2,359 Views

hey, in my design i have a very long control signal, when i try complie the code i got error message like "Cannot split carry or cascade chain crossing xxx logic cells and starting on logic cell xxx into legal LABs." so i decide to break the singal manually to fit the maximum for a entire comlomn, and then connect them up. 

 

the maximum length withour error is about 440 here, let's say i want the signal length to be 4000 and i want to break it into several 440 signal and connect them together(the next bit for the end of one column is the start one of the next comlumn), how should i write the code?
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
956 Views

Show us what kind of code is producing that error..

0 Kudos
Altera_Forum
Honored Contributor II
956 Views

library IEEE; 

use IEEE.STD_LOGIC_1164.ALL; 

USE IEEE.numeric_std.ALL; 

entity rc_adder is 

generic ( 

vsize: integer := 440 

); 

Port ( clk : in STD_LOGIC; 

a_in : in STD_LOGIC; 

b_in : in STD_LOGIC; 

r : out STD_LOGIC; 

load : in STD_LOGIC); 

end rc_adder; 

architecture Behavioral of rc_adder is 

signal a, b : STD_LOGIC_VECTOR(vsize-1 downto 0); 

signal rout : STD_LOGIC_VECTOR(vsize-1 downto 0); 

begin 

add : process 

 

begin 

 

wait until clk'event and clk = '1'; 

if (load = '1') then 

a <= a(vsize-2 downto 0) & a_in; 

b <= b(vsize-2 downto 0) & b_in; 

rout <= rout(vsize-2 downto 0) & '0'; 

r <= rout(vsize-1); 

else 

rout <= std_logic_vector(signed(a) + signed(b)); 

end if; 

end process add; 

end Behavioral;
0 Kudos
Altera_Forum
Honored Contributor II
956 Views

 

--- Quote Start ---  

Show us what kind of code is producing that error.. 

--- Quote End ---  

 

 

what i want to do here is add to very large number together, now i set generic to 440 which is ok, but i wish to have like 4000, so i think i need break the carry chain manually and connect it up, how to do that?
0 Kudos
Altera_Forum
Honored Contributor II
956 Views

I think you've come across a bug... 

Quartus should do it automatically for you. There's a synthesis setting for that and it's set to 70.  

 

A work arround is to use an LCELL primitive to break it, like this: 

 

library IEEE; 

use IEEE.STD_LOGIC_1164.ALL; 

USE IEEE.numeric_std.ALL; 

 

entity rc_adder is 

generic ( 

nblocks: integer := 40 

); 

Port ( clk : in STD_LOGIC; 

a_in : in STD_LOGIC; 

b_in : in STD_LOGIC; 

r : out STD_LOGIC; 

load : in STD_LOGIC); 

end rc_adder; 

architecture Behavioral of rc_adder is 

 

component lcell 

 

port ( 

 

a_in : in std_logic; 

 

a_out : out std_logic); 

 

end component; 

 

constant vsize : integer := nblocks * 32; 

signal a, b : STD_LOGIC_VECTOR(vsize-1 downto 0); 

signal rout : STD_LOGIC_VECTOR(vsize-1 downto 0); 

 

 

signal sum : std_logic_vector(vsize - 1 downto 0); 

 

signal carry_a : std_logic_vector(nblocks downto 0); 

signal carry_b : std_logic_vector(nblocks downto 0); 

 

begin 

 

carry_b(0) <= '0'; 

adders : for i in 1 to nblocks generate  

 

adder : entity work.adder_32  

port map( 

carry_in => carry_b(i-1), 

a => a(32*i-1 downto 32*(i-1)), 

b => b(32*i-1 downto 32*(i-1)), 

z => sum(32*i-1 downto 32*(i-1)), 

carry_out => carry_a(i) 

); 

 

lc : lcell  

port map ( 

a_in => carry_a(i), 

a_out => carry_b(i) 

); 

 

end generate; 

 

 

add : process 

begin 

wait until clk'event and clk = '1'; 

if (load = '1') then 

a <= a(vsize-2 downto 0) & a_in; 

b <= b(vsize-2 downto 0) & b_in; 

rout <= rout(vsize-2 downto 0) & '0'; 

r <= rout(vsize-1); 

else 

rout <= sum; 

end if; 

end process add; 

end Behavioral;
0 Kudos
Altera_Forum
Honored Contributor II
956 Views

 

--- Quote Start ---  

I think you've come across a bug... 

Quartus should do it automatically for you. There's a synthesis setting for that and it's set to 70.  

 

A work arround is to use an LCELL primitive to break it, like this: 

 

library IEEE; 

use IEEE.STD_LOGIC_1164.ALL; 

USE IEEE.numeric_std.ALL; 

 

entity rc_adder is 

generic ( 

nblocks: integer := 40 

); 

Port ( clk : in STD_LOGIC; 

a_in : in STD_LOGIC; 

b_in : in STD_LOGIC; 

r : out STD_LOGIC; 

load : in STD_LOGIC); 

end rc_adder; 

architecture Behavioral of rc_adder is 

 

component lcell 

 

port ( 

 

a_in : in std_logic; 

 

a_out : out std_logic); 

 

end component; 

 

constant vsize : integer := nblocks * 32; 

signal a, b : STD_LOGIC_VECTOR(vsize-1 downto 0); 

signal rout : STD_LOGIC_VECTOR(vsize-1 downto 0); 

 

 

signal sum : std_logic_vector(vsize - 1 downto 0); 

 

signal carry_a : std_logic_vector(nblocks downto 0); 

signal carry_b : std_logic_vector(nblocks downto 0); 

 

begin 

 

carry_b(0) <= '0'; 

adders : for i in 1 to nblocks generate  

 

adder : entity work.adder_32  

port map( 

carry_in => carry_b(i-1), 

a => a(32*i-1 downto 32*(i-1)), 

b => b(32*i-1 downto 32*(i-1)), 

z => sum(32*i-1 downto 32*(i-1)), 

carry_out => carry_a(i) 

&nbsp;); 

 

lc : lcell  

port map ( 

a_in => carry_a(i), 

a_out => carry_b(i) 

&nbsp;); 

 

end generate; 

 

 

add : process 

begin 

wait until clk'event and clk = '1'; 

if (load = '1') then 

a <= a(vsize-2 downto 0) & a_in; 

b <= b(vsize-2 downto 0) & b_in; 

rout <= rout(vsize-2 downto 0) & '0'; 

r <= rout(vsize-1); 

else 

rout <= sum; 

end if; 

end process add; 

end Behavioral; 

--- Quote End ---  

 

 

thank you very much rbugalho! im quite new to vhdl and im not quite understand the part you write, can you please expain it a bit?
0 Kudos
Altera_Forum
Honored Contributor II
956 Views

I broke down the big adder into a series of 40 32 bit adders, creating a 1280 bit adder -- you need to write an "adder_32" module, which is a 32 bit adder with carry in and carry out. 

 

I pass the carry signal between two adders through an LCELL primitive to break the carry chain. 

 

I used a generate statement to generate the 40 adders and 40 LCELLs, instead of repeating the code 40 times.
0 Kudos
Reply