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

--*****************************************************************************
--**** ENTITY BSHIFTER
--****
--**** Deskripsi: Bshifter unit merespon untuk mengontrol pelaksanaan tipe pergeseran, 
--****            tergantung dari tanda dari variabel shift.
--****            Sebagai contoh jumlahnya adalah + kemudian 
--****            tipe dari pelaksanaan operasi adalah sama seperti jika jumlahnya
--****            - kemudian operasi berlawanan akan dilaksanakan pada 
--****            jumlah inverse+1. Jika jumlah untuk shift seluas
--****            -15 ke 15 kemudian data tidak akan berubah.
--*****************************************************************************
ENTITY bshifter IS
    PORT(amountToShift                  : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
          operation                     : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
          shiftLines                    : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
          shiftOp                       : OUT STD_LOGIC_VECTOR(1 DOWNTO 0));
END ENTITY bshifter;

ARCHITECTURE bshifter_behav OF bshifter IS
BEGIN
    name :PROCESS(amountToShift, operation) IS
    BEGIN
        CASE conv_integer(SIGNED(amountToShift)) IS
                
            --Jika jumlah untuk shift adalah negatif akan melaksanakan
            WHEN -15 TO -1 =>
                CASE operation IS
                    --jika operasi shift left kemudian shift right oleh 
                    --compliment dua +1 .. sama untuk semuanya.
                    WHEN "00" =>
                        shiftOp <= "01";
                        shiftLines <= SIGNED(not amountToShift) +1;
                    WHEN "01" | "10" =>
                        shiftOp <= "00";
                        shiftLines <= SIGNED(not amountToShift) +1;
                    --Ketika rotating right sederhana dirotasi oleh jumlah sign   
                    WHEN OTHERS =>
                        shiftOp <= "11";
                        shiftLines <= 
                                conv_std_logic_vector(SIGNED(amountToShift),4);
                END CASE;

            --Ketika jumlah untuk shift adalah positif, Nilainya tidak berubah.
            WHEN 0 TO 15 =>
                shiftOp <= operation;
                shiftLines <= conv_std_logic_vector(UNSIGNED(amountToShift),4);

            --Ketika jumlah batas bertambah luas kemudian tidak melakukan pergantian apa-apa
            --Kita hanya ingin melaksanakan shifts antara -16 dan 15 tidak lebih.
            WHEN OTHERS =>
                shiftOp <= operation;
                shiftLines <= "0000";
        END CASE;
    END PROCESS name;
END ARCHITECTURE bshifter_behav;
