library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; use work.cpu_pkg.all; --library UNISIM; --use UNISIM.VComponents.all; entity csa is generic ( WIDTH : natural := 32 -- adder will add WIDTH bits, should be a power of 2 ); port ( op_1 : in std_logic_vector(WIDTH-1 downto 0); op_2 : in std_logic_vector(WIDTH-1 downto 0); c_in : in std_logic; sum : out std_logic_vector(WIDTH-1 downto 0); c_out : out std_logic ); end csa; architecture csa_arch of csa is component csa is generic ( WIDTH : natural ); port ( op_1 : in std_logic_vector(WIDTH-1 downto 0); op_2 : in std_logic_vector(WIDTH-1 downto 0); c_in : in std_logic; sum : out std_logic_vector(WIDTH-1 downto 0); c_out : out std_logic ); end component; signal sum_loc_0 : std_logic_vector(WIDTH-1 downto 0); signal sum_loc_1 : std_logic_vector(WIDTH-1 downto 0); signal c_out_loc_0 : std_logic_vector(1 downto 0); signal c_out_loc_1 : std_logic_vector(1 downto 0); begin base_case : if (WIDTH = 1) generate full_adder_0 : full_adder port map ( op_1 => op_1(0), op_2 => op_2(0), c_in => '0', sum => sum_loc_0(0), c_out => c_out_loc_0(1) ); full_adder_1 : full_adder port map ( op_1 => op_1(0), op_2 => op_2(0), c_in => '1', sum => sum_loc_1(0), c_out => c_out_loc_1(1) ); end generate; common_case : if (WIDTH > 1) generate csa_first_half_0 : csa generic map ( WIDTH => WIDTH / 2 ) port map ( op_1 => op_1(WIDTH/2-1 downto 0), op_2 => op_2(WIDTH/2-1 downto 0), c_in => '0', sum => sum_loc_0(WIDTH/2-1 downto 0), c_out => c_out_loc_0(0) ); csa_second_half_0 : csa generic map ( WIDTH => WIDTH / 2 ) port map ( op_1 => op_1(WIDTH-1 downto WIDTH/2), op_2 => op_2(WIDTH-1 downto WIDTH/2), c_in => c_out_loc_0(0), sum => sum_loc_0(WIDTH-1 downto WIDTH/2), c_out => c_out_loc_0(1) ); csa_first_half_1 : csa generic map ( WIDTH => WIDTH / 2 ) port map ( op_1 => op_1(WIDTH/2-1 downto 0), op_2 => op_2(WIDTH/2-1 downto 0), c_in => '1', sum => sum_loc_1(WIDTH/2-1 downto 0), c_out => c_out_loc_1(0) ); csa_second_half_1 : csa generic map ( WIDTH => WIDTH / 2 ) port map ( op_1 => op_1(WIDTH-1 downto WIDTH/2), op_2 => op_2(WIDTH-1 downto WIDTH/2), c_in => c_out_loc_1(0), sum => sum_loc_1(WIDTH-1 downto WIDTH/2), c_out => c_out_loc_1(1) ); end generate; sum <= sum_loc_1 when (c_in = '1') else sum_loc_0; c_out <= c_out_loc_1(1) when (c_in = '1') else c_out_loc_0(1); end csa_arch; -- (c) Christopher Dennl