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 STAGE2
--**
--** Deskripsi: Struktur entity ini menguraikan Instruction Decode stage
--** dari pipeline. 
--******************************************************************************
ENTITY stage2 IS
    PORT(PC, INSTRUCTION, RF_WriteData      : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
         BU_Register                        : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
         RegSelect                          : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
         RF_WriteReg                        : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
         RF_Enable, Branch_Select, clk      : IN STD_LOGIC;
         BU_PC, IDEX_PC,RegOneOut, RegTwoOut: OUT STD_LOGIC_VECTOR(15 DOWNTO 0);        
         R_Immediate, S_Immediate, ReadOne  : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);    
         ReadTwo                            : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
         M_Immediate                        : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
         WriteBack, readRegOne, readRegTwo  : OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
         ReadRegisters                      : OUT STD_LOGIC_VECTOR(5 DOWNTO 0));
END ENTITY stage2;

ARCHITECTURE structural_stage2 OF stage2 IS
    --Menentukan isyarat yang dibutuhkan
    
    --******** 3-bit temporary signals diperlukan ********
    signal regOneIn, regTwoIn               : STD_LOGIC_VECTOR(2 DOWNTO 0);
    
    --******** 16-bit temporary signals diperlukan ********
    signal readOnea, readTwoa, RI_Immediate : STD_LOGIC_VECTOR(15 DOWNTO 0);
    signal I_Immediate, SI_Immediate        : STD_LOGIC_VECTOR(15 DOWNTO 0);

    --**************************************************************************
    --**** Ini dimana strukstur dari Stage Two dimulai. Stage
    --**** Two dibuat oleh entity dibawah ini.
    --**** ENTITIES:
    --****          signextension, multiplexors, registerfile, branch unit and
    --****          idex pipeline register.
    --**************************************************************************
    BEGIN
    
    --**************************************************************************
    --**** bus_mux_3
    --**** PORT MAP ini menggambarkan bagaimana bus_mux_3 digunakan untuk memilih
    --**** read1 register kedalam register file.
    --**************************************************************************
    mux1 : work.bus_mux_3
        PORT MAP(INSTRUCTION(8 downto 6), INSTRUCTION(11 downto 9), 
                 RegSelect(0), regOneIn);
    
    --**************************************************************************
    --**** bus_mux_3
    --**** PORT MAP ini menggambarkan bagaimana bus_mux_3 digunakan untuk memilih
    --**** read2 register kedalam register file.
    --**************************************************************************
    mux2 : work.bus_mux_3
        PORT MAP(INSTRUCTION(5 downto 3), INSTRUCTION(11 downto 9), 
                 RegSelect(1), regTwoIn);

    --**************************************************************************
    --**** Register File
    --**** PORT MAP ini menunjukkan hubungan dari register file ke the rest
    --**** of stage two.
    --**************************************************************************
    registerfile : work.regfile
        PORT MAP(regOneIn, regTwoIn, RF_WriteReg, RF_WriteData, RF_Enable, clk,
                 readOnea, readtwoa);

    --**************************************************************************
    --**** Sign Extension
    --**** PORT MAP ini menunjukkan bagaimana sign extender unit dihubungkan ke
    --**** komponen-komponen lainnya dalam Stage Two.
    --**************************************************************************
    signextender : work.signext
        PORT MAP(INSTRUCTION(5 downto 0), INSTRUCTION(8 downto 1),
                 RI_Immediate, I_Immediate, SI_Immediate);

    --**************************************************************************
    --**** Branch Unit
    --**** PORT MAP ini menunjukkan bagaimana branch unit dihubungkan ke the rest of
    --**** stage two.
    --**************************************************************************
    branchunit : work.branch
        PORT MAP(PC, I_Immediate, BU_Register, Branch_Select, BU_PC);

    --**************************************************************************
    --**** Instruction Decode / Execution Stage Pipeline
    --**** PORT MAP ini menunjukkan bagaimana IDEX pipeline register dihubungkan ke 
    --**** the rest of stage two.
    --**************************************************************************
    idexpipeline : work.idex
        PORT MAP(PC, readOnea, readTwoa, RI_Immediate, SI_Immediate,
                 INSTRUCTION(8 downto 1), clk, INSTRUCTION(11 downto 9),
                 regOneIn, regTwoIn, IDEX_PC, RegOneOut, RegTwoOut,
                 R_Immediate, S_Immediate, M_Immediate, WriteBack,  
                 ReadRegisters);
                 
    --**************************************************************************
    --**** OUPUTS
    --**** PORT MAPS dibawah ini mengubah beberapa dari temporary signals ke
    --**** actual outputs.
    --**************************************************************************
    select7: work.through
        PORT MAP(readOnea, readOne);
        
    select8: work.through
        PORT MAP(readTwoa, readTwo);

    select9: work.through3
        PORT MAP(regOneIn, readRegOne);
    
    select10: work.through3
        PORT MAP(regTwoIn, readRegTwo);

END ARCHITECTURE structural_stage2;
