library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_unsigned.all;

--*****************************************************************************
--**** ENTITY - SHIFT_16
--****
--**** Deskripsi: Model struktur dari 16-bit shift unit. 
--****            SU ini sesuai dengan pelaksanaan logika SIGNED dan arithmetic shifts
--****            seperti sebuah signed rotate right. SU dibangun dari
--****            lima kesatuan terpisah. Entity pertama (bshifter) mengontrol
--****            tipe dari shift dan berapa banyak dari signed 16-bit input
--****            Selanjutnya 4 entity adalah entity shift 8, 4, 2 dan 
--****            1 bit berturt-turut, memberikan total shift dari -16 ke 15.
--***************************************************************************** 
ENTITY shift_16 IS
    PORT(dataIn, amountIn                  : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
         op                                : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
         dataOut                           : OUT STD_LOGIC_VECTOR(15 DOWNTO 0));
END ENTITY shift_16;

ARCHITECTURE structural_shift OF shift_16 IS
    --Declare signals needed
    SIGNAL shiftEnable                     : STD_LOGIC_VECTOR(3 DOWNTO 0);
    SIGNAL oper                            : STD_LOGIC_VECTOR(1 DOWNTO 0);
    SIGNAL tempResultA                     : STD_LOGIC_VECTOR(15 DOWNTO 0);
    SIGNAL tempResultB                     : STD_LOGIC_VECTOR(15 DOWNTO 0);
    SIGNAL tempResultC                     : STD_LOGIC_VECTOR(15 DOWNTO 0);
    
BEGIN

    --This is the Shifting control unit
    controlUnit: work.bshifter
        PORT MAP(amountIn, op, shiftEnable,oper);
    
    --This is the shifter that can shift something 8 places
    shiftEight: work.bshift8
        PORT MAP(dataIn, shiftEnable(3), oper, tempResultA);
    
    --This is the shifter that can shift something 4 places
    shiftFour: work.bshift4
        PORT MAP(tempResultA, shiftEnable(2), oper, tempResultB);
    
    --This is the shifter that can shift something 2 places
    shiftTwo: work.bshift2
        PORT MAP(tempResultB, shiftEnable(1), oper, tempResultC);
    
    --This is the shifter that can shift something 1 place
    shiftOne: work.bshift1
        PORT MAP(tempResultC, shiftEnable(0), oper, dataOut);

END ARCHITECTURE structural_shift;
