--
-- patrick wagstrom
-- wagspat@charlie.cns.iit.edu
-- wagspak.vhd
-- definitions for all of my parts
--

LIBRARY ieee;
USE ieee.std_logic_1164.all;

PACKAGE wagspak IS

	-- n Bit Wide 1 bit shifter
	COMPONENT shiftn_1
		GENERIC (N: INTEGER := 16);
		PORT (active, r_l_shift: IN STD_LOGIC;
			data_in: IN STD_LOGIC_VECTOR (N-1 DOWNTO 0);
			data_out: OUT STD_LOGIC_VECTOR (N-1 DOWNTO 0));
	END COMPONENT;

	-- n Bit Wide 2 bit shifter
	COMPONENT shiftn_2
		GENERIC (N: INTEGER := 16);
		PORT (active, r_l_shift: IN STD_LOGIC;
			data_in: IN STD_LOGIC_VECTOR (N-1 DOWNTO 0);
			data_out: OUT STD_LOGIC_VECTOR (N-1 DOWNTO 0));
	END COMPONENT;

	-- n Bit Wide 4 bit shifter
	COMPONENT shiftn_4
		GENERIC (N: INTEGER := 16);
		PORT (active, r_l_shift: IN STD_LOGIC;
			data_in: IN STD_LOGIC_VECTOR (N-1 DOWNTO 0);
			data_out: OUT STD_LOGIC_VECTOR (N-1 DOWNTO 0));
	END COMPONENT;

	-- n Bit Wide 8 bit shifter
	COMPONENT shiftn_8
		GENERIC (N: INTEGER := 16);
		PORT (active, r_l_shift: IN STD_LOGIC;
			data_in: IN STD_LOGIC_VECTOR (N-1 DOWNTO 0);
			data_out: OUT STD_LOGIC_VECTOR (N-1 DOWNTO 0));
	END COMPONENT;

	-- register file, variable width data registers
	COMPONENT regfile 
	    GENERIC (regWidth : integer := 16;
    	    numRegs : integer := 8;
        	selWidth : integer := 3);
	    PORT ( rs, rt, rd, displaySelect : IN STD_LOGIC_VECTOR (2 DOWNTO 0);
    	    writeEnable: IN STD_LOGIC;
        	clock : IN STD_LOGIC;
	        rdData : IN STD_LOGIC_VECTOR (regWidth - 1 DOWNTO 0);
    	    rsData : OUT STD_LOGIC_VECTOR (regWidth - 1 DOWNTO 0);
        	rtData : OUT STD_LOGIC_VECTOR (regWidth - 1 DOWNTO 0);
        	displayData : OUT STD_LOGIC_VECTOR (regWidth - 1 DOWNTO 0));
	END COMPONENT;

	-- special divider circuit to allow you to pick the high or the low bits for the reg
	COMPONENT registerOutput 
		GENERIC (dataWidth : integer := 16);
		PORT (bitSelect : IN STD_LOGIC;
			dataIn : IN STD_LOGIC_VECTOR (dataWidth-1 DOWNTO 0);
			dataOut: OUT STD_LOGIC_VECTOR ((dataWidth/2)-1 DOWNTO 0));
	END COMPONENT;
	
	-- ram for the system
	COMPONENT ram 
		GENERIC (adrWidth : integer := 5;
			dataWidth : integer := 32);
		PORT (clock, writeEnable : IN STD_LOGIC;
			data : IN STD_LOGIC_VECTOR (dataWidth - 1 DOWNTO 0);
			address: IN STD_LOGIC_VECTOR (adrWidth - 1 DOWNTO 0);
			q : OUT STD_LOGIC_VECTOR (dataWidth - 1 DOWNTO 0));
	END COMPONENT;

	-- generic size program counter
	COMPONENT progctr 
		GENERIC (ctrWidth : integer := 5);
		PORT (clock, clockEnable, load, reset : IN STD_LOGIC;
			data : IN STD_LOGIC_VECTOR (ctrWidth - 1 DOWNTO 0);
			q : OUT STD_LOGIC_VECTOR (ctrWidth - 1 DOWNTO 0));
	END COMPONENT;

	-- one bit ALU, no overflow
	COMPONENT alu1
		PORT ( a, b: IN STD_LOGIC;
			zero_in, carry_in, less: IN STD_LOGIC;
			control: IN STD_LOGIC_VECTOR (2 DOWNTO 0);
			zero_out, result, carry_out: OUT STD_LOGIC);
	END COMPONENT;

	-- one bit ALU with overflow
	COMPONENT alu1of
		PORT ( a, b: IN STD_LOGIC;
			zero_in, carry_in, less: IN STD_LOGIC;
			control: IN STD_LOGIC_VECTOR (2 DOWNTO 0);
			set, zero_out, result, carry_out, overflow: OUT STD_LOGIC);
	END COMPONENT;

	-- n bit complete ALU
	COMPONENT alu_n
		GENERIC (n : integer := 16);
		PORT (a, b: IN STD_LOGIC_VECTOR (n-1 DOWNTO 0);
			cin : IN STD_LOGIC;
			control : IN STD_LOGIC_VECTOR (2 DOWNTO 0);
			result: OUT STD_LOGIC_VECTOR (n-1 DOWNTO 0);
			overflow, zero: OUT STD_LOGIC);
	END COMPONENT;

	-- seven segment hexadecimal decoder
	COMPONENT sevenSegment
		port ( D: in STD_LOGIC_VECTOR (3 DOWNTO 0);
			signalOut: out STD_LOGIC_VECTOR (6 DOWNTO 0));
	END COMPONENT;

	-- a not so generic, incredibly specific decoder
	COMPONENT decoder 
		PORT (instruction : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
			rs, rt, rd: OUT STD_LOGIC_VECTOR (4 DOWNTO 0);
			shamt: OUT STD_LOGIC_VECTOR (4 DOWNTO 0);
			aluOp: OUT STD_LOGIC_VECTOR (2 DOWNTO 0);
			immediate: OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
			targetAddress: OUT STD_LOGIC_VECTOR (25 DOWNTO 0);
			useImmediate: OUT STD_LOGIC;
			aluActive, shiftActive, jumpActive, shiftrl, regWrite: OUT STD_LOGIC;
			bne, beq, jal, jr, lw, sw: OUT STD_LOGIC);
	END COMPONENT;
	
	-- a 16 bit shifter
	COMPONENT shift16 
		GENERIC (N: INTEGER := 16);
		PORT (control : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
			data_in : IN STD_LOGIC_VECTOR(N-1 DOWNTO 0);
			r_l_shift : IN STD_LOGIC;
			data_out: OUT STD_LOGIC_VECTOR(N-1 DOWNTO 0));
	END COMPONENT;

	-- three phase clock generator
	COMPONENT clockgen 
		PORT( clock, reset: IN STD_LOGIC; 
			clk_a, clk_b, clk_c, clk_d: OUT STD_LOGIC); 
	END COMPONENT; 

	-- instruction register
	COMPONENT instreg
		GENERIC (instWidth : integer := 32);
		PORT ( instIn : IN STD_LOGIC_VECTOR (instWidth - 1 DOWNTO 0);
			clock: IN STD_LOGIC;
			instOut : OUT STD_LOGIC_VECTOR (instWidth - 1 DOWNTO 0));
	END COMPONENT;

	-- special componennt to select the correct address for jump and link
	COMPONENT jalAddr
		PORT (jal, lw: IN STD_LOGIC;
			pcIn : IN STD_LOGIC_VECTOR (4 DOWNTO 0);
			loadData, rdDataIn : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
			rdDataOut : OUT STD_LOGIC_VECTOR (15 DOWNTO 0));
	END COMPONENT;

END wagspak;