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 CPU
--**
--** Deskripsi: Struktur ini emnggambarkan sebuah CPU. 
--******************************************************************************
ENTITY cpu is
    PORT(InputPort, MemoryRead              : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
         Interrupts                         : IN STD_LOGIC_VECTOR(5 DOWNTO 0);
         CLOCK, clk, Undefined              : IN STD_LOGIC;
         SYSCLOCK                           : OUT STD_LOGIC; 
         OutputPort, FETCH1, FETCH2, READ   : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
         Acknowledge                        : OUT STD_LOGIC_VECTOR(5 DOWNTO 0);
         MemStageC                          : OUT STD_LOGIC_VECTOR(1 DOWNTO 0));
END ENTITY cpu;


ARCHITECTURE structural_cpu OF cpu IS
    --Menentukan isyarat yang dibutuhkan
    
    --******** 16-bit temporary signals dibutuhkan *********
    SIGNAL temp_bupc, temp_readOne, temp_intretu: STD_LOGIC_VECTOR(15 DOWNTO 0);
    SIGNAL temp_IF_PC, temp_ID_PC,  temp_INS    : STD_LOGIC_VECTOR(15 DOWNTO 0);
    SIGNAL temp_wbValue, temp_intoBU, temp_fin1 : STD_LOGIC_VECTOR(15 DOWNTO 0);                                            
    SIGNAL temp_reg2, temp_reg3, temp_exmempc   : STD_LOGIC_VECTOR(15 DOWNTO 0);
    SIGNAL temp_INSTRUCTION, temp_simmed,temp_re: STD_LOGIC_VECTOR(15 DOWNTO 0); 
    SIGNAL temp_readTwo, temp_idexpc, temp_fin2 : STD_LOGIC_VECTOR(15 DOWNTO 0);  
    SIGNAL temp_immed16Out, temp_res            : STD_LOGIC_VECTOR(15 DOWNTO 0);
     
    --******** 2-bit temporary singals dibutuhkan **********
    SIGNAL temp_regSelect, temp_exSel           : STD_LOGIC_VECTOR(1 DOWNTO 0);
    SIGNAL temp_memSel, temp_pcSelect           : STD_LOGIC_VECTOR(1 DOWNTO 0);
    SIGNAL temp_idexmemwe, temp_memstage        : STD_LOGIC_VECTOR(1 DOWNTO 0);
    
    --******** 3-bit temporary signals dibutuhkan **********
    SIGNAL temp_regtin, temp_exmemwb            : STD_LOGIC_VECTOR(2 DOWNTO 0);
    SIGNAL temp_wbc, temp_exmemcrw              : STD_LOGIC_VECTOR(2 DOWNTO 0);
    SIGNAL temp_wbWReg, temp_wbidex, temp_regin : STD_LOGIC_VECTOR(2 DOWNTO 0);
    
    --******** 8-bit temporary signals dibutuhkan **********
    SIGNAL temp_immed8Out                       : STD_LOGIC_VECTOR(7 DOWNTO 0);
    
    --******** 6-bit temporary signals dibutuhkan **********
    SIGNAL temp_ReadRegOut                      : STD_LOGIC_VECTOR(5 DOWNTO 0);
    
    --******** 1-bit temporary signals dibutuhkan **********
    SIGNAL temp_pcenableOut, temp_flushboy, temp_reti           : STD_LOGIC;
    SIGNAL temp_ifid_enableO, temp_rfenable,temp_zero           : STD_LOGIC;
    SIGNAL temp_buSelect, temp_overflow, temp_ie                : STD_LOGIC;
    SIGNAL temp_exmem, temp_idexflusher, temp_idexflushO        : STD_LOGIC;
    SIGNAL temp_dflush, temp_mflush, temp_pbpcenable            : STD_LOGIC;
    SIGNAL temp_aluSel, temp_jalcontrol, temp_iflush            : STD_LOGIC;
    SIGNAL temp_id_flush, temp_pcenableO, temp_pcanded          : STD_LOGIC;
        
    --******** 4-bit temporary signals dibutuhkan **********    
    SIGNAL temp_OPC, temp_aluFUNC               : STD_LOGIC_VECTOR(3 DOWNTO 0);
        
    
    --**************************************************************************
    --**** Kode VHDL ini menggambarkan bagaimana 
    --**** VHDL entities dibawah bekerja secara bersama-sama untuk
    --**** 16-bit RISC processor.
    --**** ENTITIES:
    --****          Stage1, Stage2, Stage3, Stage4 and 5, Control Unit, 
    --****          Hazard detection unit, forwarding units, prefecth buffer
    --****          and interrupt and exception unit.
    --**************************************************************************
    BEGIN
    
    --**************************************************************************
    --**** Stage One (Instruction Fetch Stage)
    --**** PORT MAP ini menunjukkan konstruksi dari Stage One (IF) stage
    --**** dari pipeline. 
    --**************************************************************************
    stage1 : work.stage1
        PORT MAP(temp_bupc, temp_readOne, temp_intretu, temp_INS,   
                 temp_pcenableOut, temp_flushboy, temp_ifid_enableO, clk,           
                 temp_OPC, temp_ID_PC, temp_INSTRUCTION,temp_IF_PC);

    --**************************************************************************
    --**** Stage Two (Instruction Decode Stage)
    --**** PORT MAP ini menunjukkan konstruksi dari Stage Two (ID) stage
    --**** dari pipline.
    --**************************************************************************
    stage2 : work.stage2
        PORT MAP(temp_IF_PC, temp_INSTRUCTION, temp_wbValue, temp_intoBU, 
                 temp_regSelect, temp_wbWReg, temp_rfenable, temp_buSelect, clk, 
                 temp_bupc, temp_idexpc, temp_fin1, temp_fin2, temp_immed16Out, 
                 temp_simmed, temp_readOne, temp_readTwo, temp_immed8Out,   
                 temp_wbidex, temp_regin, temp_regtin, temp_ReadRegOut);

    --**************************************************************************
    --**** Stage Three (Execution Stage)
    --**** PORT MAP ini menunjukkan konstruksi dari Stage Three (EX)         
    --**** stage dari pipeline.
    --**************************************************************************
    stage3 : work.stage3
        PORT MAP(temp_reg2, temp_reg3, temp_immed16Out, temp_simmed,    
                 temp_idexpc, temp_immed8Out, temp_aluSel, temp_jalcontrol, clk, 
                 temp_aluFUNC, temp_exSel, temp_wbidex, temp_exmempc, temp_re, 
                 temp_res, temp_exmemwb, temp_overflow);

    --**************************************************************************
    --**** Stage Four and Five (Memory and IO and Write Back)
    --**** PORT MAP ini menunjukkan konstruksi dari Stage 4 and Stage 5
    --**** (MEM and WB) stages dari pipeline.
    --**************************************************************************
    stage45 : work.stage45
        PORT MAP(InputPort, MemoryRead, temp_res, temp_exmemwb, temp_memSel, 
                 clk, temp_exmem, OutputPort, temp_wbValue, temp_wbWReg);        

    
    --**************************************************************************
    --**** Control Unit
    --**** PORT MAP ini menunjukkan hubungan antara processor
    --**** dan control unit. Control unit ini meliputi control pipeline
    --**** registers. Karenanya PORT MAP ini mengontrol setiap stages 
    --**** dari pipeline.
    --**************************************************************************
    cpucontrol : work.cpucont
        PORT MAP(temp_INSTRUCTION(15 downto 12), temp_INSTRUCTION(2 downto 0),      
                 temp_zero, clk, temp_idexflusher, temp_pcSelect, 
                 temp_regSelect, temp_exSel, temp_idexmemwe, temp_memstage, 
                 temp_memSel, temp_buSelect, temp_ie, temp_reti, temp_id_flush, 
                 temp_aluSel, temp_jalcontrol, temp_exmem, temp_rfenable, 
                 temp_aluFUNC, temp_wbc, temp_exmemcrw); 

    --**************************************************************************
    --**** Hazard Detection Unit
    --**** PORT MAP ini menunjukkan hubungan dari Hazard Detection
    --**** Unit.
    --**************************************************************************
    hazard : work.hazard
        PORT MAP(temp_INSTRUCTION(15 downto 12), temp_INSTRUCTION(2 downto 0), 
                 temp_regin, temp_regtin, temp_wbidex, temp_idexmemwe(1), 
                 temp_wbc(0), temp_exmemwb, temp_memstage(1), temp_pcenableO,   
                 temp_ifid_enableO, temp_idexflushO);
                   
    --**************************************************************************
    --**** Branch Forwarding Unit
    --**** PORT MAP ini menunjukkan hubungan dari Branch Forwarding Unit.
    --**************************************************************************
    bforward : work.branchforw
        PORT MAP(temp_readOne, temp_readTwo, temp_res, temp_wbValue, 
                 temp_exmemcrw(0), temp_rfenable, temp_exmemwb, temp_wbWReg, 
                 temp_regin, temp_INSTRUCTION(5 downto 3), temp_zero,   
                 temp_intoBU);
                 
    --**************************************************************************
    --**** Execution Forwarding Unit
    --**** PORT MAP ini menunjukkan hubungan dari Execution Forwarding Unit.
    --**************************************************************************
    eforward : work.forwardingu
        PORT MAP(temp_fin1, temp_fin2, temp_res, temp_wbValue, temp_exmemcrw(0), 
                 temp_rfenable, temp_exmemwb, temp_wbWReg, 
                 temp_ReadRegOut(5 downto 3), temp_ReadRegOut(2 downto 0),
                 temp_reg2, temp_reg3);

    --**************************************************************************
    --**** Interrupt/Exception Unit
    --**** PORT MAP ini menunjukkan hubungan dari Interrupt annd Exception
    --**** Unit.
    --**************************************************************************
    interrupt : work.intexcu
        PORT MAP(temp_IF_PC, temp_ID_PC, temp_exmempc, 
                 temp_INSTRUCTION(8 downto 3), Interrupts, temp_pcSelect, 
                 temp_overflow, Undefined, temp_pcanded, clk, temp_reti, 
                 temp_ie, temp_iflush, temp_dflush, temp_mflush, 
                 temp_pcenableOut, temp_OPC, temp_intretu, Acknowledge);
  
    --**************************************************************************
    --**** Prefetch Buffer
    --**** PORT MAP ini menunjukkan hubungan antara processor dan 
    --**** prefetch buffer.
    --**************************************************************************
    prefetcher : work.pbuffer_16
        PORT MAP(temp_IF_PC, MemoryRead, CLOCK, temp_memstage(1), temp_INS, 
                 FETCH1, temp_pbpcenable, SYSCLOCK);

    --**************************************************************************
    --**** Simple Logic Gates
    --**** PORT MAPS ini menunjukkan hubungan antara processor 
    --**** dan beberapa gerbang logika sederhana.
    --**************************************************************************
    pcenableAND : work.andgate
        PORT MAP(temp_pcenableO, temp_pbpcenable, temp_pcanded);

    idexflushOR : work.orgate
        PORT MAP(temp_idexflushO, temp_dflush, temp_idexflusher);

    ifidflushOR: work.orgate
        PORT MAP(temp_id_flush, temp_iflush, temp_flushboy);

    --**************************************************************************
    --**** Outputs
    --**** PORT MAPS digunakan untuk mengubah isyarat ke output.
    --**************************************************************************
    select13: work.through2
        PORT MAP(temp_memstage, MemStageC);

    select15 : work.through
        PORT MAP(temp_res, FETCH2);

    select16 : work.through
        PORT MAP(temp_re, READ);
        
END ARCHITECTURE structural_cpu;
