library ieee ;
library work;
use ieee.std_logic_1164.all ;
use ieee.std_logic_unsigned.all ;
use IEEE.NUMERIC_STD.all;

entity alu is
port(
		input_a, input_b: in std_logic_vector(15 downto 0);
		output: out std_logic_vector(15 downto 0);
		
		add, sub, inc, andi, ori, xori, noti, rot, sel_b: in std_logic;
		rot_value: in std_logic_vector(3 downto 0);
		
		n, z: out std_logic
	);
end entity alu;

architecture arch of alu is

	signal va: std_logic_vector(15 downto 0);

begin

	va <=	input_a + input_b when add = '1' else
	
			input_a - input_b when sub = '1' else
			
			input_a and input_b when andi = '1' else
			
			input_a or input_b when ori = '1' else
			
			input_a xor input_b when xori = '1' else
			
			not input_a when noti = '1' else
			
			input_b + 1 when inc = '1' else
			
			input_a((15 - to_integer(unsigned(rot_value))) mod 16) &
			input_a((14 - to_integer(unsigned(rot_value))) mod 16) &
			input_a((13 - to_integer(unsigned(rot_value))) mod 16) &
			input_a((12 - to_integer(unsigned(rot_value))) mod 16) &
			input_a((11 - to_integer(unsigned(rot_value))) mod 16) &
			input_a((10 - to_integer(unsigned(rot_value))) mod 16) &
			input_a((9 - to_integer(unsigned(rot_value))) mod 16) &
			input_a((8 - to_integer(unsigned(rot_value))) mod 16) &
			input_a((7 - to_integer(unsigned(rot_value))) mod 16) &
			input_a((6 - to_integer(unsigned(rot_value))) mod 16) &
			input_a((5 - to_integer(unsigned(rot_value))) mod 16) &
			input_a((4 - to_integer(unsigned(rot_value))) mod 16) &
			input_a((3 - to_integer(unsigned(rot_value))) mod 16) &
			input_a((2 - to_integer(unsigned(rot_value))) mod 16) &
			input_a((1 - to_integer(unsigned(rot_value))) mod 16) &
			input_a((0 - to_integer(unsigned(rot_value))) mod 16) when rot = '1' else
            input_b when sel_b = '1' else
			input_a;
	
	z <= '1' when va = X"0000" else '0';
	
	n <= '1' when va(15) = '1' else '0';
	
	output <= va;
	
end architecture arch;