library IEEE; use IEEE.std_logic_1164.all; entity Cache is port( ------------------Every port needs commenting----------------- Clock : in std_logic; -- CLK input port Reset : in std_logic; -- Reset input port to clear the valid bits Data_In : in std_logic_vector(5 downto 0); -- Data_In input port to take the data from the ROM_16x6 Opcode : out std_logic_vector(1 downto 0); -- Opcode output port to output a 2-bit opcode to the Controller Imm_Value : out std_logic_vector(3 downto 0); -- Imm_Value output port to output a 4-bit immediate value to the ALU Hit : out std_logic; -- Hit output port to output a 1-bit signal to the controller whether the cache is hit or not Miss : out std_logic; -- Miss outpot port is the opposite of Hit output port. If it's not hit, then it's missed Addr_In : in std_logic_vector(3 downto 0); -- Addr_In input port to take a 4-bit output from the PC_Register Addr_Out : out std_logic_vector(3 downto 0) -- Addr_Out output port to output the 4-bit output from the PC_Register to the ROM_16x6 ); end Cache; architecture arch1 of Cache is --every type and signal needs commenting---- type t_data_bank is array (0 to 3) of std_logic_vector(5 downto 0); -- An array of 4 6-bit of the data field of the cache type t_tag_bank is array (0 to 3) of std_logic_vector(1 downto 0); -- An array of 4 2-bit of the tag field of the cache type t_valid_bits is array (0 to 3) of std_logic; -- An array of 4 1-bit of the valid field of the cache signal data_bank : t_data_bank; -- t_data_bank array is assigned to the data_bank signal signal tag_bank : t_tag_bank; -- t_tag_bank array is assisgned to the tag_bank signal signal valid_bits : t_valid_bits; -- t_valid_bits array is assigned to the valid_bits signal signal cache_hit : std_logic := '0'; -- Initiate the cache_hit signal to '0' signal addr_pc : std_logic_vector(3 downto 0) := "0000"; -- Initiate the addr_pc signal to "0000" signal addr_pc_tag : std_logic_vector(1 downto 0) := "00"; -- Initiate the addr_pc_tag signal to "00" signal addr_pc_line_number : std_logic_vector(1 downto 0) := "00"; -- Initiate the addr_pc_line_number signal to "00" signal selected_tag : std_logic_vector(1 downto 0) := "00"; -- Initiate the selected_tag signal to "00" signal selected_valid_bit : std_logic := '0'; -- Initiate the selected_valid_bit signal to '0' signal selected_data : std_logic_vector(5 downto 0) := "000000";-- Initiate the selected_data signal to "000000" signal selected_tag_match : std_logic := '0'; -- Initiate the selected_tag_match signal to '0' begin ------------------------------------ -- Output signals -- ------------------------------------ -- Hit: assigned from the one bit signal from cache_hit -- Miss: opposite of Hit, assgined from the opposite value of the one bit signal from cache_hit Hit <= cache_hit; Miss <= not cache_hit; Addr_Out <= addr_pc; -- Assign the 4-bit value from addr_pc to the Addr_Out port Opcode <= selected_data(5 downto 4); -- Assign the 6th and 5th bit of the selected_data to the Opcode port Imm_Value <= selected_data(3 downto 0); -- Assign from the 1st to the 4th bit of the selected_data to the Imm_Value ------------------------------------ -- Internal signals -- ------------------------------------ addr_pc <= Addr_In; -- Assign the value from the Addr_In(from the PC_Register) port to the addr_pc addr_pc_tag <= addr_pc(3 downto 2); -- Assign the value of the 4th and 3rd bit of the addr_pc to addr_pc_tag signal addr_pc_line_number <= addr_pc(1 downto 0); -- Assign the value of the 2nd and 1st bit of the addr_pc to the addr_pc_line_number signal -- Get the selected cache selected_tag <= tag_bank(to_integer(addr_pc_line_number)); -- Convert the addr_pc_line_number to integer to access that certain line number in the tag_bank array, then assign it to selected_tag signal selected_valid_bit <= valid_bits(to_integer(addr_pc_line_number)); -- Convert the addr_pc_line_number to integer to access that certain line number in the valid_bits array, then assign it to selected_valid_bit signal selected_data <= data_bank(to_integer(addr_pc_line_number)); -- Convert the addr_pc_line_number to integer to access that certain line number in the data_bank array, then assign it to selected_data signal -- Set the selected_tag_match to '1' when the selected_tag and the addr_pc_tag match. If not, set to '0' selected_tag_match <= '1' when selected_tag = addr_pc_tag else '0'; -- -- Set the cache_hit to '1' when both selected_tag_match and selected_valid_bit are true cache_hit <= selected_tag_match and selected_valid_bit; -- Update_Cache: process (Clock, Reset) variable i : integer := 0; begin if (Reset = '1') then -- If we have a reset signal, we only need to clear valid bits. for i in 0 to 3 loop valid_bits(i) <= '0'; end loop; elsif (Clock = '1' and Clock'event) then selected_valid_bit <= '1'; -- selected_valid_bit has to be '1' in order for cache_hit to be '1' selected_tag <= Data_In(5 downto 4); -- selected_tag and addr_pc_tag must be the same for cache hit to be '1' addr_pc_tag <= Data_In(5 downto 4); -- so they are assigned to by the same Data_In end if; end process Update_Cache; end arch1;