--
-- Component : data_cache_ram
--
-- Generated by System Architect version v8.5_2.2 by w-hong on May 02, 97
--
-- sensitivity_attr :: 'transaction
-- Source views :-
-- $ECE_312_MP3/mips_types/types
--

ARCHITECTURE spec OF data_cache_ram IS

	type dataarray is array (3 downto 0) of CacheLine;
	signal DataStore : dataarray;

	type tagarray is array (3 downto 0) of Tag;
	signal TagStore : tagarray;

	signal valid_bits : std_logic_vector(3 downto 0);
	signal dirty_bits : std_logic_vector(3 downto 0);

BEGIN
  
   ------------------------------------------------------------------
   cache_read : PROCESS (CLK, Set_Index, DataStore, TagStore,
                         valid_bits, dirty_bits)
   ------------------------------------------------------------------
        variable SetSel : integer range 0 to 3;
        variable Data : CacheLine;
   BEGIN

	If (RESET_L = '1') then 
		SetSel := to_integer("0" & Set_Index, 0);
		Data := DataStore(SetSel);
		CacheTag <= TagStore(SetSel);
		CacheValid <= valid_bits(SetSel);
		CacheDirty <= dirty_bits(SetSel);
		CacheData <= Data;
		WBData <= Data;
	end if;
   END PROCESS cache_read;

   -----------------------------------------------------------------
   cache_write : PROCESS (CLK,WriteFromMem, WriteWord,RESET_L)
   -----------------------------------------------------------------
        variable SetSel : integer range 0 to 3;
        variable WordSel : integer range 0 to 3;
        variable dummy : std_logic;
   BEGIN
                
        IF (RESET_L = '0') then
                DataStore(0) <= to_stdlogicvector(0,128);
                DataStore(1) <= to_stdlogicvector(0,128);
                DataStore(2) <= to_stdlogicvector(0,128);
                DataStore(3) <= to_stdlogicvector(0,128);
                TagStore(0) <= to_stdlogicvector(0,26);
                TagStore(1) <= to_stdlogicvector(0,26);
                TagStore(2) <= to_stdlogicvector(0,26);
                TagStore(3) <= to_stdlogicvector(0,26);
                valid_bits <= to_stdlogicvector(0,4);
                dirty_bits <= to_stdlogicvector(0,4);
        else
                SetSel := to_integer("0" & Set_Index, 0);
                WordSel := to_integer("0" & Word_Index, 0);

                -- Writing one of three cases
                -- Only want to write on a clock edge

                if (clk'event and (clk = '1') and (clk'last_value = '0')) then
                         if (WriteFromMem = '1') then
                                -- Write the entire cache line in
                                -- at the desired location
                                -- Clear the dirty bit, set the valid bit
                                DataStore(SetSel) <= DataFromMem;
                                TagStore(SetSel) <= Addr_Tag ;
                                valid_bits(SetSel) <= '1' ;
                                dirty_bits(SetSel) <= '0';
                
			elsif (WriteWord = '1') then
                        -- This is writing just one word into the cache (write hit)
                                dirty_bits(SetSel) <= '1';
                                case WordSel is
                                when 0 =>
					DataStore(SetSel)(31 downto 0) <= ALURegOut;
                                when 1 =>
                                        DataStore(SetSel)(63 downto 32) <= ALURegOut ;
                                when 2 =>
                                        DataStore(SetSel)(95 downto 64) <= ALURegOut;
                                when 3 =>
                                        DataStore(SetSel)(127 downto 96) <= ALURegOut;
                                when others =>
					dummy := '1';
                                end case;
			end if;
	        end if;
	end if;

   end PROCESS cache_write;
END spec ;