---------------------------------------------------------------------------------- -- Company: -- Engineer: Jim Plusquellic -- -- Create Date: 16:04:58 09/23/2009 -- Design Name: -- Module Name: AddUnit -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.all; -- add_ins, sub_ins, skwlf_ins (skip is register w is less than f), and skwgf_ins are -- instructions -- only 1 or 0 of them will be '1' at any given point in time. -- A and B are the 12-bit input operands, ADD_OUT is the 12-bit result of the add or -- subtract. skw_success is set to '1' if the result of the compare instructions is -- true entity AddUnit is port( add_ins, sub_ins, skwlf_ins, skwgf_ins : std_logic; A, B : in std_logic_vector(11 downto 0); ADD_OUT : out std_logic_vector(11 downto 0); skw_success : out std_logic; carry_out : out std_logic ); end entity; architecture beh of AddUnit is -- ripple is used to connect the carry_out to the carry_in of the next higher full adder signal ripple : std_logic_vector(10 downto 0); signal B_op, result : std_logic_vector(11 downto 0); signal one_hot_ins : std_logic_vector(3 downto 0); signal do_sub : std_logic_vector(2 downto 0); signal skw_suc_lf, not_all_zero, skw_suc_gf : std_logic; signal carry_in : std_logic; begin -- set carry_in to '1' and XOR the B operand bits with 1 (invert them) if the instruction -- is one of either sub_ins, skwlf_ins or skwgf_ins do_sub <= sub_ins & skwlf_ins & skwgf_ins; with do_sub select carry_in <= '0' when "000", '1' when others; with do_sub select B_op <= B when "000", (B xor "111111111111") when others; -- instantiate 12 copies of the full_adder and wire them to implement 12 bit adder. Note -- that carry_out of the full adder of a lower order bit is used as carry_in in the full -- adder computing the sum for the higher order bit. FA0: entity work.FullAdder(beh) port map (a=>A(0), b=>B_op(0), carry_in=>carry_in, sum_out=>result(0), carry_out=>ripple(0)); FA1: entity work.FullAdder(beh) port map (a=>A(1), b=>B_op(1), carry_in=>ripple(0), sum_out=>result(1), carry_out=>ripple(1)); FA2: entity work.FullAdder(beh) port map (a=>A(2), b=>B_op(2), carry_in=>ripple(1), sum_out=>result(2), carry_out=>ripple(2)); FA3: entity work.FullAdder(beh) port map (a=>A(3), b=>B_op(3), carry_in=>ripple(2), sum_out=>result(3), carry_out=>ripple(3)); FA4: entity work.FullAdder(beh) port map (a=>A(4), b=>B_op(4), carry_in=>ripple(3), sum_out=>result(4), carry_out=>ripple(4)); FA5: entity work.FullAdder(beh) port map (a=>A(5), b=>B_op(5), carry_in=>ripple(4), sum_out=>result(5), carry_out=>ripple(5)); FA6: entity work.FullAdder(beh) port map (a=>A(6), b=>B_op(6), carry_in=>ripple(5), sum_out=>result(6), carry_out=>ripple(6)); FA7: entity work.FullAdder(beh) port map (a=>A(7), b=>B_op(7), carry_in=>ripple(6), sum_out=>result(7), carry_out=>ripple(7)); FA8: entity work.FullAdder(beh) port map (a=>A(8), b=>B_op(8), carry_in=>ripple(7), sum_out=>result(8), carry_out=>ripple(8)); FA9: entity work.FullAdder(beh) port map (a=>A(9), b=>B_op(9), carry_in=>ripple(8), sum_out=>result(9), carry_out=>ripple(9)); FA10: entity work.FullAdder(beh) port map (a=>A(10), b=>B_op(10), carry_in=>ripple(9), sum_out=>result(10), carry_out=>ripple(10)); FA11: entity work.FullAdder(beh) port map (a=>A(11), b=>B_op(11), carry_in=>ripple(10), sum_out=>result(11), carry_out=>carry_out); -- Determine the value of skw_success. If skwlf_ins is '1', then set skw_success if MSB of adder is '1'. -- (A - B) is negative, therefore A is less than B. skw_suc_lf <= skwlf_ins and result(11); -- If skwgf_ins is '1', then set skw_success if MSB of adder is '0' AND there is at least 1 '1' in -- the low order bits not_all_zero <= result(0) or result(1) or result(2) or result(3) or result(4) or result(5) or result(6) or result(7) or result(8) or result(9) or result(10); skw_suc_gf <= skwgf_ins and not result(11) and not_all_zero; -- skw_success is the or of the two conditions skw_success <= skw_suc_lf or skw_suc_gf; -- Tri-state the output. First create a vector of the four instructions (remember, they are one-hot -- or zero-hot) one_hot_ins <= add_ins & sub_ins & skwlf_ins & skwgf_ins; -- If none of the instructions are '1', then set ADD_OUT to 'Z's (un-driven), otherwise set ADD_OUT -- to the output vector of the 12-bit adder. with one_hot_ins select ADD_OUT <= (others => 'Z') when "0000", result when others; end beh;