- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?Link Copied
6 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Show us what kind of code is producing that error..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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) ); 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; --- 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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page