----------------------------------------------------------------------------------
-- 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;

entity BoolUnit is
   port(
      and_ins, or_ins, inv_ins, xor_ins, skwnf_ins, skwef_ins : std_logic;
      A, B : in std_logic_vector(11 downto 0);
      BOOL_OUT : out std_logic_vector(11 downto 0);
      skw_success : out std_logic
   );
end entity;

architecture beh of BoolUnit is
   signal result : std_logic_vector(11 downto 0);
   signal one_hot_ins : std_logic_vector(5 downto 0);
   signal not_all_zero, skw_suc_ef, skw_suc_nf : std_logic;
   begin

-- Create a vector of the instructions -- exactly one '1' or NO '1's
   one_hot_ins <= and_ins & or_ins & inv_ins & xor_ins & skwnf_ins & skwef_ins;

-- Perform an xor when we want to determine if operands A and B are bitwise
-- identical (or not).

   with one_hot_ins select
      result <= A and B when "100000",
                A or B when "010000",
                not B when "001000",
                A xor B when others;

-- Reduction OR -- produces 0 if result is ALL ZEROs and 1 otherwise -- good for 
-- 'not equal' condition. 
   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);

-- Gate these with the instruction so the only time skw_success is 1 is when both
-- the instruction is being executed and the conditions are right.
   skw_suc_ef <= skwef_ins and (not not_all_zero);
   skw_suc_nf <= skwnf_ins and not_all_zero;

   skw_success <= skw_suc_ef or skw_suc_nf;

-- Finally, the tri-state

   with one_hot_ins select
      BOOL_OUT <= (others => 'Z') when "000000",
                 result when others;
end beh;
