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 ALU
--**
--** Deskripsi: Ini adalah struktur dari ALU. 
--******************************************************************************
ENTITY ALU IS
    PORT(RegA, RegB, A_Immed, S_Immed       : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
         mvi_Immed                          : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
         alu_sel                            : IN STD_LOGIC;
         operation                          : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
         res_sel                            : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
         result                             : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
         overflow                           : OUT STD_LOGIC);
END ENTITY ALU;

ARCHITECTURE structural_ALU OF ALU IS
    --Menentukan isyarat yang dibutuhkan
    
    SIGNAL reg_or_immediate                 : STD_LOGIC_VECTOR(15 DOWNTO 0);
    SIGNAL reg_or_simmediate                : STD_LOGIC_VECTOR(15 DOWNTO 0);
    SIGNAL alu_result                       : STD_LOGIC_VECTOR(15 DOWNTO 0);
    SIGNAL su_result                        : STD_LOGIC_VECTOR(15 DOWNTO 0);
    SIGNAL mvi_result                       : STD_LOGIC_VECTOR(15 DOWNTO 0);
    SIGNAL overflow_result                  : STD_LOGIC;
BEGIN
--**************************************************************************
    --**** Selector
    --**** Selektor ini digunakan untuk memilih antara register dan
    --**** pilihan immediate.
    --**************************************************************************
    select1 : work.Selector
        PORT MAP(RegB, A_Immed, alu_sel, reg_or_immediate);
    
    --**************************************************************************
    --**** Selector
    --**** Selektor ini digunakan untuk memilih antara register dan
    --**** pilihan pergeseran langsung.
    --**************************************************************************
    select2 : work.Selector
        PORT MAP(RegB, S_Immed, alu_sel, reg_or_simmediate);

    --**************************************************************************
    --**** Hasil ALU dasar
    --**** PORT MAP ini menunjukkan bagaimana ALU dihubungkan ke rest of
    --**** advanced ALU.
    --**************************************************************************
    result1 : work.alu_16
        PORT MAP(RegA, reg_or_immediate, operation, overflow_result, 
                 alu_result);
    
    --**************************************************************************
    --**** Shift Unit RESULT
    --**** PORT MAP ini menunjukkan bagaimana unit shift dihubungkan ke rest of
    --**** the advanced ALU.
    --**************************************************************************
    result2 : work.shift_16
        PORT MAP(RegA, reg_or_simmediate, operation(1 downto 0), su_result);
    
    --**************************************************************************
    --**** Move Immediate RESULT
    --**** PORT MAP ini menunjukkan bagaimana move immediate unit dihubungkan ke 
    --**** rest of the advanced ALU.
    --**************************************************************************
    result3 : work.mvibox
        PORT MAP(RegA(7 downto 0), mvi_Immed, operation(0), mvi_result);

    --**************************************************************************
    --**** Final Result Selector
    --**** PORT MAP digunakan untuk memilih hasil terakhir dari
    --**** advanced ALU. Ini memilih move immediate, shift atau basic
    --**** alu result.
    --**************************************************************************
    Final_Results : work.alu_mux
        PORT MAP(alu_result, su_result, mvi_result, overflow_result, res_sel, 
                 result, overflow);
END ARCHITECTURE structural_alu;

