--======================================================-- -- -- -- NORTHEASTERN UNIVERSITY -- -- DEPARTMENT OF ELECTRICAL AND COMPUTER ENGINEERING -- -- RAPID PROTOTYPING LABORATORY -- -- -- -- FILE | fp_aac.vhd -- -- -------------+------------------------------------ -- -- DESCRIPTION | Parameterized accumulator -- -- -------------+------------------------------------ -- -- AUTHOR | Sherman Braganza -- -- -------------+------------------------------------ -- -- DATE | 20 Jan 2006 -- --======================================================-- --******************************************************************************-- -- -- -- Copyright (C) 2000 Sherman Braganza -- -- -- -- This program is free software; you can redistribute it and/or -- -- modify it under the terms of the GNU General Public License -- -- as published by the Free Software Foundation; either version 2 -- -- of the License, or (at your option) any later version. -- -- -- -- This program is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- -- GNU General Public License for more details. -- -- -- -- You should have received a copy of the GNU General Public License -- -- along with this program; if not, write to the Free Software -- -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -- -- -- --****************************************************************************** ---- IEEE Libraries -- library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use work.float_pkg.all; entity accumulator is generic ( exp_bits : integer := 11; man_bits : integer := 53; grd_bits : integer := 3 ); port ( --inputs IN1 : in std_logic_vector(exp_bits+man_bits downto 0); READY : in std_logic:='0'; EXCEPTION_IN : in std_logic:='0'; RESET : in std_logic; CLK : in std_logic; --outputs OUT1 : out std_logic_vector(exp_bits+man_bits downto 0); EXCEPTION_OUT : out std_logic; DONE : out std_logic ); end accumulator; ---------------------------------------------------------- -- Accumulator -- ---------------------------------------------------------- architecture accumulator_arch of accumulator is subtype word is std_logic_vector(man_bits+exp_bits+grd_bits+1 downto 0); type buff is array (2 downto 0) of word; type NEWOP_STATE is (REG_A,REG_B,RISE,FALL,INIT_NS); type INSERTION_STATE is (PAUSE,INSERT,INIT_IS); --These are IN1 and IN2 after registering signal RA : std_logic_vector(man_bits+exp_bits+grd_bits downto 0):=(others=>'0'); signal RB : std_logic_vector(man_bits+exp_bits+grd_bits downto 0):=(others=>'0'); --these are the registered results of fp_add/normalize to be inserted into the pipe signal IRA : std_logic_vector(man_bits+exp_bits+grd_bits downto 0):=(others=>'0'); signal IRB : std_logic_vector(man_bits+exp_bits+grd_bits downto 0):=(others=>'0'); --this maps to the adder inputs signal A : std_logic_vector(man_bits+exp_bits+grd_bits downto 0):=(others=>'0'); signal B : std_logic_vector(man_bits+exp_bits+grd_bits downto 0):=(others=>'0'); signal add_res : std_logic_vector(man_bits+exp_bits+grd_bits+1 downto 0):=(others=>'0'); signal norm_res : std_logic_vector(man_bits+exp_bits+grd_bits downto 0); signal ready_prev : std_logic:= '0'; signal nstate : NEWOP_STATE:=INIT_NS; signal nstate_next : NEWOP_STATE:=INIT_NS; signal istate : INSERTION_STATE:=INIT_IS; signal istate_next : INSERTION_STATE:=INIT_IS; signal dirty_bit_buf : std_logic_vector(2 downto 0) := (others => '0'); signal add_rdy : std_logic:='0'; signal exc0 : std_logic:='0'; signal exc1 : std_logic:='0'; signal exc_acc : std_logic:='0'; signal add_done : std_logic:='0'; signal norm_done : std_logic:='0'; signal moretwo : std_logic:='0'; signal zero : std_logic_vector(man_bits+exp_bits downto 0) := (others => '0'); signal zero_diff : std_logic_vector(grd_bits-1 downto 0):=(others =>'0'); signal add_ready1 : std_logic:='0'; signal add_ready2 : std_logic:='0'; signal add_ready3 : std_logic:='0'; signal add_ready4 : std_logic:='0'; signal add_ready5 : std_logic:='0'; signal add_ready6 : std_logic:='0'; signal add_ready7 : std_logic:='0'; signal odd0 : std_logic := '0'; signal odd0_2 : std_logic := '0'; signal odd1 : std_logic := '0'; signal odd : std_logic := '0'; signal sign1 : std_logic:='0'; signal fin : std_logic:='0'; signal ar_comb1 : std_logic_vector(4 downto 0) := (others =>'0'); signal ar_comb2 : std_logic_vector(4 downto 0) := (others =>'0'); --intermediate buffer signal buf : buff:=(others => (others=>'0')); begin plus:fp_add generic map ( exp_bits => exp_bits, man_bits => man_bits+grd_bits ) port map ( --inputs OP1 => A, OP2 => B, READY => add_rdy, EXCEPTION_IN => '0',--EXCEPTION_IN, CLK => CLK, --outputs RESULT => add_res, EXCEPTION_OUT => exc0, DONE => add_done ); norm: normalizer generic map ( exp_bits => exp_bits, man_bits => man_bits+grd_bits ) port map ( --inputs MAN_IN => add_res(man_bits+grd_bits downto 1), EXP_IN => add_res(man_bits+grd_bits+exp_bits downto man_bits+grd_bits+1), READY => add_done,--ed1, CLK => CLK, EXCEPTION_IN => exc0,--exc1, --outputs MAN_OUT => norm_res(man_bits+grd_bits-1 downto 0), EXP_OUT => norm_res(man_bits+grd_bits+exp_bits-1 downto man_bits+grd_bits), EXCEPTION_OUT => exc1, DONE => norm_done ); moretwo <= (buf(2)(man_bits+exp_bits+grd_bits+1) and buf(0)(man_bits+exp_bits+grd_bits+1)) or (buf(1)(man_bits+exp_bits+grd_bits+1) and buf(0)(man_bits+exp_bits+grd_bits+1)) or (buf(2)(man_bits+exp_bits+grd_bits+1) and buf(1)(man_bits+exp_bits+grd_bits+1)); dirty_bit_buf <= buf(2)(man_bits+exp_bits+grd_bits+1) & buf(1)(man_bits+exp_bits+grd_bits+1) & buf(0)(man_bits+exp_bits+grd_bits+1); ar_comb1 <= (moretwo & add_ready1 & add_ready2 & add_ready3 & add_ready4); ar_comb2 <= (add_ready5 & add_ready6 & add_ready7 & READY & add_rdy); odd0 <= '1' when (nstate=REG_A and nstate_next = FALL) else '0'; --odd <= '1' when (istate/=INSERT) and (odd0='1' or (odd0_2='1' and odd='1')) else '0'; --odd1 <= '1' when (odd0_2='1' and odd='1') else '0'; A <= RA when nstate=REG_B or odd='1' else IRA; B <= RB when nstate=REG_B or odd='1' else IRB; add_rdy <= '1' when nstate=REG_B or odd='1' or istate=INSERT else '0'; DONE <= fin; fin <= '1' when (ar_comb1 or ar_comb2) = "00000" else '0'; OUT1 <= RA(man_bits+exp_Bits+grd_bits downto grd_bits) when (nstate=RISE and nstate_next=FALL) else buf(0)(man_bits+exp_bits+grd_bits downto grd_bits) when fin='1' else zero; EXCEPTION_OUT <= exc_acc when fin='1' else '0'; --INSERTION state machine ins_SM:process(nstate,moretwo) begin if (nstate = REG_B and moretwo = '1') then istate_next <= INSERT; elsif (nstate = REG_A or moretwo = '0') then istate_next <= PAUSE; elsif (nstate = INIT_NS and moretwo ='1') then istate_next <= INSERT; else istate_next <= INIT_IS; end if; end process; --new op add state machine nop_SM:process(READY,nstate) begin if (READY /= ready_prev and READY = '1') then nstate_next <= RISE; elsif (READY /= ready_prev and READY = '0') then nstate_next <= FALL; elsif (nstate = REG_A) then nstate_next <= REG_B; elsif (nstate = REG_B) then nstate_next <= REG_A; elsif (nstate = RISE) then nstate_next <= REG_B; else nstate_next <= INIT_NS; end if; end process; --main clocked process aac_clk:process(CLK) begin if (RESET = '1') then RB <= zero & zero_diff; RA <= zero & zero_diff; IRA <= zero & zero_diff; IRB <= zero & zero_diff; buf(0) <= '0' & zero & zero_diff; buf(1) <= '0' & zero & zero_diff; buf(2) <= '0' & zero & zero_diff; odd0_2 <= '0'; ready_prev <= '0'; nstate <= nstate_next; istate <= istate_next; add_ready7 <= '0'; add_ready6 <= '0'; add_ready5 <= '0'; add_ready4 <= '0'; add_ready3 <= '0'; add_ready2 <= '0'; add_ready1 <= '0'; exc_acc <= '0'; elsif (rising_edge(CLK)) then -- Registering for new op state machine if (EXCEPTION_IN = '0') then if (nstate_next = REG_A) then RA <= IN1 & zero_diff; RB <= zero & zero_diff; elsif (nstate_next = REG_B) then RB <= IN1 & zero_diff; elsif (nstate_next = RISE) then exc_acc <= '0'; RA <= IN1 & zero_diff; elsif (nstate_next = FALL) then RB <= zero & zero_diff; end if; else if (nstate_next = REG_A) then RA <= zero & zero_diff; RB <= zero & zero_diff; elsif (nstate_next = REG_B) then RB <= zero & zero_diff; elsif (nstate_next = RISE) then exc_acc <= '0'; RA <= zero & zero_diff; elsif (nstate_next = FALL) then RB <= zero & zero_diff; end if; end if; --registering for insertion state machine if (dirty_bit_buf(2) = '1') then if (istate_next = INSERT) then if (norm_done = '1') then IRA <= buf(2)(man_bits+exp_bits+grd_bits downto 0); buf(2) <= '0' & zero & zero_diff; IRB <= buf(1)(man_bits+exp_bits+grd_bits downto 0); buf(1) <= '1' & norm_res; else IRA <= buf(2)(man_bits+exp_bits+grd_bits downto 0); buf(2) <= '0' & zero & zero_diff; IRB <= buf(1)(man_bits+exp_bits+grd_bits downto 0); buf(1) <= '0' & zero & zero_diff; end if; end if; elsif (dirty_bit_buf(1) = '1') then if (istate_next = INSERT) then if (norm_done = '1') then IRA <= buf(1)(man_bits+exp_bits+grd_bits downto 0); buf(1) <= '0' & zero & zero_diff; IRB <= buf(0)(man_bits+exp_bits+grd_bits downto 0); buf(0) <= '1' & norm_res; else IRA <= buf(1)(man_bits+exp_bits+grd_bits downto 0); buf(1) <= '0' & zero & zero_diff; IRB <= buf(0)(man_bits+exp_bits+grd_bits downto 0); buf(0) <= '0' & zero & zero_diff; end if; elsif (norm_done = '1') then buf(2) <= '1' & norm_res; end if; else if (norm_done = '1') then if (dirty_bit_buf(0) <= '0') then buf(0) <= '1' & norm_res; else buf(1) <= '1' & norm_res; end if; end if; end if; if (istate_next /= INSERT and odd0='1') then odd <='1'; elsif (istate_next /= INSERT and odd0_2='1') then odd<='1'; else odd <= '0'; end if; odd0_2 <= odd0; ready_prev <= READY; --state machine state variables nstate <= nstate_next; istate <= istate_next; --propagate add_ready - used to determined when completed add_ready7 <= add_ready6; add_ready6 <= add_ready5; add_ready5 <= add_ready4; add_ready4 <= add_ready3; add_ready3 <= add_ready2; add_ready2 <= add_ready1; add_ready1 <= add_rdy; exc_acc <= exc_acc or exc1; --normalize doesn't handle signs... temporarily store sign bits norm_res(man_bits+exp_bits+grd_bits) <= sign1; --sign2 <= sign1; sign1 <= add_res(man_bits+exp_bits+grd_bits+1); end if; end process; end accumulator_arch;