---------------------------------------------------------------------------------- -- @Name Cache + Controle -- @Version 0.1 -- @Author Maximilian Passarello -- @Website atom-dragon.net ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.all; entity Cache is generic( DataWidth : integer := 32; --Die Datenbreite CacheDepth : integer := 512; --Die Anzahl der Cache einträge AdressWidth : integer := 22; --Die Allgemeine Adressbreite CacheAdressWidth : integer := 9; --Die Cache Adressbreite QueueLength : integer := 5 --Die länge des FIFOs ); port( CLK : In std_logic; CE : In std_logic; RST : In std_logic; Din : In std_logic_vector(DataWidth-1 downto 0); --Daten eingang Dout : Out std_logic_vector(DataWidth-1 downto 0); --Daten ausgang RE : In std_logic; --Read Enable WE : In std_logic; --Write Enable Adress : In std_logic_vector(AdressWidth-1 downto 0); --Adresse die gelesen oder geschrieben werden soll NewData : In std_logic; --Signals das vom RAM aus signalisiert das neue Daten anliegen Data : In std_logic_vector(DataWidth-1 downto 0); --Die Daten vom Ram CMD : Out std_logic_vector((DataWidth + AdressWidth) downto 0); --DIe Daten zum Ram in der Ordnung: Daten + Flag + Adresse FifoRE : In std_logic; --Der Read Enable vom FIFO für den Ram Bussy : Out std_logic ); end Cache; architecture Behavioral of Cache is type CacheType is array(CacheDepth-1 downto 0) of std_logic_vector((DataWidth + AdressWidth - CacheAdressWidth)-1 downto 0); signal Cache : CacheType; signal CacheRA : std_logic_vector(CacheAdressWidth-1 downto 0); signal CacheWA : std_logic_vector(CacheAdressWidth-1 downto 0); signal CacheRD : std_logic_vector((DataWidth + AdressWidth - CacheAdressWidth)-1 downto 0); signal CacheWD : std_logic_vector((DataWidth + AdressWidth - CacheAdressWidth)-1 downto 0); --signal CacheRE0 : std_logic; --signal CacheRE1 : std_logic; signal CacheWE : std_logic; type FifoType is array(QueueLength-1 downto 0) of std_logic_vector((DataWidth + AdressWidth) downto 0); signal Fifo : FifoType; signal FifoRCount : integer range 0 to QueueLength-1; signal FifoWCount : integer range 0 to QueueLength-1; signal FifoDin : std_logic_vector((DataWidth + AdressWidth) downto 0); signal FifoWE : std_logic; signal FifoFull : std_logic; signal FifoEmpty : std_logic; signal ReadState : integer range 0 to 5; signal WriteState : integer range 0 to 1; signal Aviable : std_logic; begin MainProcess: process(CLK) begin if rising_edge(CLK) then if RST = '1' then ReadState <= 0; WriteState <= 0; Aviable <= '0'; Bussy <= '0'; FifoWE <= '0'; CacheWE <= '0'; Dout <= (Others => '0'); CacheRA <= (Others => '0'); FifoDin <= (Others => '0'); CacheWA <= (Others => '0'); CacheWD <= (Others => '0'); elsif CE = '1' then if RE = '1' then if FifoFull = '1' then Bussy <= '1'; else if ReadState = 0 then CacheWE <= '0'; FifoWE <= '0'; Bussy <= '1'; CacheRA <= Adress(CacheAdressWidth-1 downto 0); ReadState <= ReadState +1; elsif ReadState = 1 then ReadState <= ReadState +1; elsif ReadState = 2 then if CacheRD((AdressWidth - CacheAdressWidth)-1 downto 0) = Adress(AdressWidth-1 downto CacheAdressWidth) then Aviable <= '1'; Bussy <= '0'; else Aviable <= '0'; end if; ReadState <= ReadState +1; elsif ReadState = 3 then if Aviable = '1' then Dout <= CacheRD((DataWidth + AdressWidth - CacheAdressWidth)-1 downto (AdressWidth - CacheAdressWidth)); ReadState <= 0; else ReadState <= ReadState +1; FifoWE <= '1'; FifoDin <= Din & '0' & Adress; end if; elsif ReadState = 4 then FifoWE <= '0'; if NewData = '1' then Dout <= Data; CacheWA <= Adress(CacheAdressWidth-1 downto 0); CacheWD <= Data & Adress(AdressWidth-1 downto CacheAdressWidth); CacheWE <= '1'; Bussy <= '0'; ReadState <= 5; end if; elsif ReadState = 5 then CacheWE <= '0'; ReadState <= 0; end if; end if; elsif WE = '1' then if FifoFull = '1' then Bussy <= '1'; else if WriteState = 0 then Bussy <= '0'; WriteState <= 1; CacheWA <= Adress(CacheAdressWidth-1 downto 0); CacheWD <= Din & Adress(AdressWidth-1 downto CacheAdressWidth); CacheWE <= '1'; FifoWE <= '1'; FifoDin <= Din & '1' & Adress; else Bussy <= '0'; CacheWE <= '0'; FifoWE <= '0'; WriteState <= 0; end if; end if; end if; end if; end if; end process; QueueProcess: process(CLK) begin if rising_edge(CLK) then if RST = '1' then FifoWCount <= 0; FifoRCount <= 0; FifoFull <= '0'; FifoEmpty <= '0'; CMD <= (Others => '0'); elsif CE = '1' then if FifoWE = '1' then if FifoFull = '0' then Fifo(FifoWCount) <= FifoDin; FifoWCount <= FifoWCount +1; FifoEmpty <= '0'; if FifoWCount +1 = FifoRCount then FifoFull <= '1'; end if; end if; end if; if FifoRE = '1' then if FifoEmpty = '0' then CMD <= Fifo(FifoRCount); FifoFull <= '0'; if FifoRCount+1 > FifoWCount then FifoEmpty <= '1'; else FifoRCount <= FifoRCount +1; end if; else CMD <= (Others => '0'); end if; end if; end if; end if; end process; CacheProcess: process(CLK) begin if rising_edge(CLK) then if RST = '1' then CacheRD <= (Others => '0'); elsif CE = '1' then if CacheWE = '1' then Cache(to_integer(unsigned(CacheWA))) <= CacheWD; end if; CacheRD <= Cache(to_integer(unsigned(CacheRA))); end if; end if; end process; end Behavioral;