Line 10... |
Line 10... |
-- 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.
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use work.mlite_pack.all;
|
|
use ieee.std_logic_unsigned.all;
|
use ieee.std_logic_unsigned.all;
|
|
library UNISIM;
|
|
use UNISIM.vcomponents.all;
|
|
use work.mlite_pack.all;
|
|
|
entity cache is
|
entity cache is
|
generic(memory_type : string := "DEFAULT");
|
generic(memory_type : string := "DEFAULT");
|
port(clk : in std_logic;
|
port(clk : in std_logic;
|
reset : in std_logic;
|
reset : in std_logic;
|
Line 23... |
Line 25... |
byte_we_next : in std_logic_vector(3 downto 0);
|
byte_we_next : in std_logic_vector(3 downto 0);
|
cpu_address : in std_logic_vector(31 downto 2);
|
cpu_address : in std_logic_vector(31 downto 2);
|
mem_busy : in std_logic;
|
mem_busy : in std_logic;
|
|
|
cache_check : out std_logic; --Stage1: address_next in first 2MB DDR
|
cache_check : out std_logic; --Stage1: address_next in first 2MB DDR
|
cache_checking : out std_logic; --Stage2: comparing tags
|
cache_checking : out std_logic; --Stage2: cache checking
|
cache_miss : out std_logic); --Stage2-3: cache miss
|
cache_miss : out std_logic); --Stage2-3: cache miss
|
end; --cache
|
end; --cache
|
|
|
architecture logic of cache is
|
architecture logic of cache is
|
subtype state_type is std_logic_vector(1 downto 0);
|
subtype state_type is std_logic_vector(1 downto 0);
|
Line 45... |
Line 47... |
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, mem_busy, cache_address, cache_we,
|
cache_proc: process(clk, reset, mem_busy, cache_address, cache_we,
|
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
|
Line 61... |
Line 63... |
state <= STATE_CHECK;
|
state <= STATE_CHECK;
|
when STATE_CHECKING =>
|
when STATE_CHECKING =>
|
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';
|
cache_we <= '0';
|
|
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 =>
|
when STATE_MISSED =>
|
cache_checking <= '0';
|
cache_checking <= '0';
|
cache_miss <= '1';
|
cache_miss <= '1';
|
cache_we <= '1';
|
cache_we <= '1';
|
if mem_busy = '1' then
|
if mem_busy = '1' then
|
Line 79... |
Line 81... |
state <= STATE_CHECK;
|
state <= STATE_CHECK;
|
end if;
|
end if;
|
when STATE_WRITING =>
|
when STATE_WRITING =>
|
cache_checking <= '0';
|
cache_checking <= '0';
|
cache_miss <= '0';
|
cache_miss <= '0';
|
if mem_busy = '1' then
|
|
cache_we <= '0';
|
cache_we <= '0';
|
|
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_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 and state_reg /= STATE_MISSED then
|
cache_address <= '0' & address_next(11 downto 2);
|
cache_address <= '0' & address_next(11 downto 2);
|
Line 122... |
Line 127... |
if reset = '1' then
|
if reset = '1' then
|
state_reg <= STATE_CHECK;
|
state_reg <= STATE_CHECK;
|
cache_tag_reg <= ZERO(8 downto 0);
|
cache_tag_reg <= ZERO(8 downto 0);
|
elsif rising_edge(clk) then
|
elsif rising_edge(clk) then
|
state_reg <= state_next;
|
state_reg <= state_next;
|
if state = STATE_CHECK then
|
if state = STATE_CHECK and state_reg /= STATE_MISSED then
|
cache_tag_reg <= cache_tag_in;
|
cache_tag_reg <= cache_tag_in;
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
end process;
|
end process;
|
Line 134... |
Line 139... |
cache_xilinx: if memory_type = "XILINX_16X" generate
|
cache_xilinx: if memory_type = "XILINX_16X" generate
|
begin
|
begin
|
cache_tag: RAMB16_S9 --Xilinx specific
|
cache_tag: RAMB16_S9 --Xilinx specific
|
port map (
|
port map (
|
DO => cache_tag_out(7 downto 0),
|
DO => cache_tag_out(7 downto 0),
|
DOP => cache_tag_out(8),
|
DOP => cache_tag_out(8 downto 8),
|
ADDR => cache_address, --registered
|
ADDR => cache_address, --registered
|
CLK => clk,
|
CLK => clk,
|
DI => cache_tag_in(7 downto 0), --registered
|
DI => cache_tag_in(7 downto 0), --registered
|
DIP => cache_tag_in(8),
|
DIP => cache_tag_in(8 downto 8),
|
EN => '1',
|
EN => '1',
|
SSR => ZERO(0),
|
SSR => ZERO(0),
|
WE => cache_we);
|
WE => cache_we);
|
end generate; --cache_xilinx
|
end generate; --cache_xilinx
|
|
|