OpenCores
URL https://opencores.org/ocsvn/plasma/plasma/trunk

Subversion Repositories plasma

[/] [plasma/] [trunk/] [vhdl/] [cache.vhd] - Diff between revs 352 and 377

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 352 Rev 377
Line 7... Line 7...
-- COPYRIGHT: Software placed into the public domain by the author.
-- COPYRIGHT: Software placed into the public domain by the author.
--    Software 'as is' without warranty.  Author liable for nothing.
--    Software 'as is' without warranty.  Author liable for nothing.
-- DESCRIPTION:
-- DESCRIPTION:
--    Control 4KB unified cache that uses the upper 4KB of the 8KB
--    Control 4KB unified cache that uses the upper 4KB of the 8KB
--    internal RAM.  Only lowest 2MB of DDR is cached.
--    internal RAM.  Only lowest 2MB of DDR is cached.
 
--    Only include file for Xilinx FPGAs.
---------------------------------------------------------------------
---------------------------------------------------------------------
library ieee;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_unsigned.all;
library UNISIM;
library UNISIM;
Line 47... Line 48...
   signal cache_tag_reg    : std_logic_vector(8 downto 0);
   signal cache_tag_reg    : std_logic_vector(8 downto 0);
   signal cache_tag_out    : std_logic_vector(8 downto 0);
   signal cache_tag_out    : std_logic_vector(8 downto 0);
   signal cache_we         : std_logic;
   signal cache_we         : std_logic;
begin
begin
 
 
   cache_proc: process(clk, reset, mem_busy, cache_address, cache_we,
   cache_proc: process(clk, reset, mem_busy, cache_address,
      state_reg, state, state_next,
      state_reg, state, state_next,
      address_next, byte_we_next, cache_tag_in, --Stage1
      address_next, byte_we_next, cache_tag_in, --Stage1
      cache_tag_reg, cache_tag_out,             --Stage2
      cache_tag_reg, cache_tag_out,             --Stage2
      cpu_address) --Stage3
      cpu_address) --Stage3
   begin
   begin
 
 
      case state_reg is
      case state_reg is
      when STATE_CHECK =>
      when STATE_CHECK =>           --cache idle
         cache_checking <= '0';
         cache_checking <= '0';
         cache_miss <= '0';
         cache_miss <= '0';
         state <= STATE_CHECK;
         state <= STATE_CHECK;
      when STATE_CHECKING =>
      when STATE_CHECKING =>        --current read in cached range, check if match
         cache_checking <= '1';
         cache_checking <= '1';
         if cache_tag_out /= cache_tag_reg or cache_tag_out = ONES(8 downto 0) then
         if cache_tag_out /= cache_tag_reg or cache_tag_out = ONES(8 downto 0) then
            cache_miss <= '1';
            cache_miss <= '1';
            state <= STATE_MISSED;
            state <= STATE_MISSED;
         else
         else
            cache_miss <= '0';
            cache_miss <= '0';
            state <= STATE_CHECK;
            state <= STATE_CHECK;
         end if;
         end if;
         cache_we <= '0';
      when STATE_MISSED =>          --current read cache miss
      when STATE_MISSED =>
 
         cache_checking <= '0';
         cache_checking <= '0';
         cache_miss <= '1';
         cache_miss <= '1';
         cache_we <= '1';
 
         if mem_busy = '1' then
         if mem_busy = '1' then
            state <= STATE_MISSED;
            state <= STATE_MISSED;
         else
         else
            state <= STATE_CHECK;
            state <= STATE_CHECK;
         end if;
         end if;
      when STATE_WRITING =>
      when STATE_WRITING =>         --writing back to cache and memory
         cache_checking <= '0';
         cache_checking <= '0';
         cache_miss <= '0';
         cache_miss <= '0';
         cache_we <= '0';
 
         if mem_busy = '1' then
         if mem_busy = '1' then
            state <= STATE_WRITING;
            state <= STATE_WRITING;
         else
         else
            state <= STATE_CHECK;
            state <= STATE_CHECK;
         end if;
         end if;
      when others =>
      when others =>
         cache_checking <= '0';
         cache_checking <= '0';
         cache_miss <= '0';
         cache_miss <= '0';
         cache_we <= '0';
 
         state <= STATE_CHECK;
         state <= STATE_CHECK;
      end case; --state
      end case; --state
 
 
      if state = STATE_CHECK and state_reg /= STATE_MISSED then
      if state = STATE_CHECK then   --check if next access in cached range
         cache_address <= '0' & address_next(11 downto 2);
         cache_address <= '0' & address_next(11 downto 2);
         if address_next(30 downto 21) = "0010000000" then  --first 2MB of DDR
         if address_next(30 downto 21) = "0010000000" then  --first 2MB of DDR
            cache_check <= '1';
            cache_check <= '1';
            if byte_we_next = "0000" then
            if byte_we_next = "0000" then     --read cycle
               cache_we <= '0';
               cache_we <= '0';
               state_next <= STATE_CHECKING;
               state_next <= STATE_CHECKING;  --need to check if match
            else
            else
               cache_we <= '1';
               cache_we <= '1';               --update cache tag
               state_next <= STATE_WRITING;
               state_next <= STATE_WRITING;
            end if;
            end if;
         else
         else
            cache_check <= '0';
            cache_check <= '0';
            cache_we <= '0';
            cache_we <= '0';
            state_next <= STATE_CHECK;
            state_next <= STATE_CHECK;
         end if;
         end if;
      else
      else
         cache_address <= '0' & cpu_address(11 downto 2);
         cache_address <= '0' & cpu_address(11 downto 2);
         cache_check <= '0';
         cache_check <= '0';
 
         if state = STATE_MISSED then
 
            cache_we <= '1';                  --update cache tag
 
         else
 
            cache_we <= '0';
 
         end if;
         state_next <= state;
         state_next <= state;
      end if;
      end if;
 
 
      if byte_we_next = "0000" or byte_we_next = "1111" then
      if byte_we_next = "0000" or byte_we_next = "1111" then  --read or 32-bit write
         cache_tag_in <= address_next(20 downto 12);
         cache_tag_in <= address_next(20 downto 12);
      else
      else
         cache_tag_in <= ONES(8 downto 0);  --invalid tag
         cache_tag_in <= ONES(8 downto 0);  --invalid tag
      end if;
      end if;
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.