00001 --**************************************************************
00002 --* *
00003 --* The source code for the ATLAS BCM "AAA" FPGA is made *
00004 --* available via the GNU General Public License (GPL) *
00005 --* unless otherwise stated below. *
00006 --* *
00007 --* In case of problems/questions/bug reports etc. please *
00008 --* contact michael.niegl@cern.ch *
00009 --* *
00010 --**************************************************************
00011 --* *
00012 --* Carry Look-Ahead Full-Adder *
00013 --* *
00014 --* Author: M.Niegl (michael.niegl@cern.ch) *
00015 --* License: GPL v2 *
00016 --* *
00017 --* $Source: /local/reps/bcmfpga/bcm_aaa/bcm_aaa/eth/onescomplementadder.vhd,v $
00018 --* $Revision: 2.0.2.4 $ *
00019 --* $Name: dev $ *
00020 --* $Author: mniegl $ *
00021 --* $Date: 2008/11/03 17:57:46 $ *
00022 --* *
00023
00024
00025 --* *
00026 --**************************************************************
00027
00028
00029
00030 library ieee;
00031
00032 use ieee.std_logic_1164.all;
00033
00034 use ieee.std_logic_arith.all;
00035
00036 use ieee.std_logic_unsigned.all;
00037
00038
00039 entity onescomplementadder is
00040 port (
00041 CLK : in ;
00042 RESET : in ;
00043 EN : in ;
00044 A : in (15 downto 0);
00045 B : in (15 downto 0);
00046 C_IN : in ;
00047 C_OUT : out ;
00048 Y : out (15 downto 0)
00049 );
00050 end onescomplementadder;
00051
00052
00053 architecture onescomplementadder_arc of onescomplementadder is
00054
00055 signal propagate : (15 downto 0) := (others => '0');
00056 signal gen_carry : (15 downto 0) := (others => '0');
00057 signal result : (15 downto 0) := (others => '0');
00058 signal carry : (15 downto 0) := (others => '0');
00059 signal carry_in : := '0';
00060
00061 begin
00062
00063 C_OUT <= carry(15);
00064 Y <= result;
00065
00066 propagate <= A or B when EN = '1' else (others => '0');
00067 gen_carry(15 downto 1) <= A(15 downto 1) and B(15 downto 1) when EN = '1' else (others => '0');
00068 gen_carry(0) <= '0' when EN = '0' else
00069 A(0) and B(0) when C_IN = '0'
00070 else (A(0) and B(0)) or (A(0) and C_IN) or (B(0) and C_IN);
00071
00072
00073 process(clk)
00074 variable x : := '0';
00075 begin
00076 if clk'event and clk = '1' then
00077 if RESET = '1' then
00078 result <= (others => '0');
00079 carry <= (others => '0');
00080 else
00081 if EN = '1' then
00082 if C_IN = '1' then
00083 result(0) <= A(0) xnor B(0);
00084 carry(0) <= A (0) or B(0);
00085 else
00086 result(0) <= A(0) xor B(0);
00087 carry(0) <= A(0) and B(0);
00088 end if;
00089 for i in 15 downto 1 loop
00090 if gen_carry(i-1) = '1' then
00091 result(i) <= A(i) xnor B(i);
00092 carry(i) <= A(i) or B(i);
00093 elsif propagate(i-1) = '1' then
00094 for j in (i-1) downto 0 loop
00095 if gen_carry(j) = '1' then
00096 x := '1';
00097 exit;
00098 elsif propagate(j) = '0' then
00099 x := '0';
00100 exit;
00101 else
00102 x := '0';
00103 end if;
00104 end loop;
00105 result(i) <= (A(i) xor B(i)) xor x;
00106 carry(i) <= (A(i) and B(i)) or (A(i) and x) or (B(i) and x);
00107 else
00108 result(i) <= A(i) xor B(i);
00109 carry(i) <= A(i) and B(i);
00110 end if;
00111 end loop;
00112 end if;
00113 end if;
00114 end if;
00115 end process;
00116
00117 end onescomplementadder_arc;