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;

--*****************************************************************************
--**** Prefetch Buffer
--****
--**** Deskripsi: Prefetch buffer digunakan untuk menyimpan instruksi yang
--****            diambil dari memori.Prefetch buffer diset pada nilai 4.
--*****************************************************************************
ENTITY pref IS
    PORT(writeAddress, writeData            : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
         readAddress                        : IN STD_LOGIC_VECTOR(1 DOWNTO 0); 
         we, clk                            : IN STD_LOGIC;
         instruction, lastfetched           : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
         tag                                : OUT STD_LOGIC_VECTOR(13 DOWNTO 0);
         valid                              : OUT STD_LOGIC);
END ENTITY pref;

ARCHITECTURE pref_behav OF pref IS

    TYPE regArray IS ARRAY (INTEGER RANGE 0 TO 3) OF 
                                                STD_LOGIC_VECTOR(30 DOWNTO 0);
BEGIN
    name : PROCESS(clk) IS
        VARIABLE fifo_buffer : regArray;
        VARIABLE writeValue : INTEGER RANGE 0 TO 3 := 0;
        VARIABLE readValue : INTEGER RANGE 0 TO 3 :=0;
        
        BEGIN

        --If the clock is high and we is high then write the data and tag and
        --valid bits into the prefetch buffer. else do not
            IF(clk='1') THEN
                writeValue := CONV_INTEGER(UNSIGNED(writeAddress(1 DOWNTO 0)));
                IF(we='1') THEN
                    fifo_buffer(writeValue) := writeData & 
                                               writeAddress(15 DOWNTO 2) & "1";
                    lastfetched <= writeAddress;
                END IF;
            END IF;
            
            --read out the values of instruction, tag and valid bit to goto
            --the prefetching controller.
            readValue := CONV_INTEGER(UNSIGNED(readAddress(1 DOWNTO 0)));
            instruction <= fifo_buffer(readValue)(30 DOWNTO 15);
            tag <= fifo_buffer(readValue)(14 DOWNTO 1);
            valid <= fifo_buffer(readValue)(0);
            
    END PROCESS name;
END ARCHITECTURE pref_behav;
