Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17255 Discussions

Newbie question about long control signal

Altera_Forum
Honored Contributor II
2,344 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
941 Views

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

0 Kudos
Altera_Forum
Honored Contributor II
941 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
941 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
941 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
941 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
941 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