Root/plasma/logic/cache.vhd

1---------------------------------------------------------------------
2-- TITLE: Cache Controller
3-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4-- DATE CREATED: 12/22/08
5-- FILENAME: cache.vhd
6-- PROJECT: Plasma CPU core
7-- COPYRIGHT: Software placed into the public domain by the author.
8-- Software 'as is' without warranty. Author liable for nothing.
9-- DESCRIPTION:
10-- Control 4KB unified cache that uses the upper 4KB of the 8KB
11-- internal RAM. Only lowest 2MB of DDR is cached.
12---------------------------------------------------------------------
13library ieee;
14use ieee.std_logic_1164.all;
15use ieee.std_logic_unsigned.all;
16library UNISIM;
17use UNISIM.vcomponents.all;
18use work.mlite_pack.all;
19
20entity cache is
21   generic(memory_type : string := "DEFAULT");
22   port(clk : in std_logic;
23        reset : in std_logic;
24        address_next : in std_logic_vector(31 downto 2);
25        byte_we_next : in std_logic_vector(3 downto 0);
26        cpu_address : in std_logic_vector(31 downto 2);
27        mem_busy : in std_logic;
28
29        cache_check : out std_logic; --Stage1: address_next in first 2MB DDR
30        cache_checking : out std_logic; --Stage2: cache checking
31        cache_miss : out std_logic); --Stage2-3: cache miss
32end; --cache
33
34architecture logic of cache is
35   subtype state_type is std_logic_vector(1 downto 0);
36   constant STATE_CHECK : state_type := "00";
37   constant STATE_CHECKING : state_type := "01";
38   constant STATE_MISSED : state_type := "10";
39   constant STATE_WRITING : state_type := "11";
40
41   signal state_reg : state_type;
42   signal state : state_type;
43   signal state_next : state_type;
44
45   signal cache_address : std_logic_vector(10 downto 0);
46   signal cache_tag_in : std_logic_vector(8 downto 0);
47   signal cache_tag_reg : std_logic_vector(8 downto 0);
48   signal cache_tag_out : std_logic_vector(8 downto 0);
49   signal cache_we : std_logic;
50begin
51
52   cache_proc: process(clk, reset, mem_busy, cache_address, cache_we,
53      state_reg, state, state_next,
54      address_next, byte_we_next, cache_tag_in, --Stage1
55      cache_tag_reg, cache_tag_out, --Stage2
56      cpu_address) --Stage3
57   begin
58
59      case state_reg is
60      when STATE_CHECK =>
61         cache_checking <= '0';
62         cache_miss <= '0';
63         state <= STATE_CHECK;
64      when STATE_CHECKING =>
65         cache_checking <= '1';
66         if cache_tag_out /= cache_tag_reg or cache_tag_out = ONES(8 downto 0) then
67            cache_miss <= '1';
68            state <= STATE_MISSED;
69         else
70            cache_miss <= '0';
71            state <= STATE_CHECK;
72         end if;
73         cache_we <= '0';
74      when STATE_MISSED =>
75         cache_checking <= '0';
76         cache_miss <= '1';
77         cache_we <= '1';
78         if mem_busy = '1' then
79            state <= STATE_MISSED;
80         else
81            state <= STATE_CHECK;
82         end if;
83      when STATE_WRITING =>
84         cache_checking <= '0';
85         cache_miss <= '0';
86         cache_we <= '0';
87         if mem_busy = '1' then
88            state <= STATE_WRITING;
89         else
90            state <= STATE_CHECK;
91         end if;
92      when others =>
93         cache_checking <= '0';
94         cache_miss <= '0';
95         cache_we <= '0';
96         state <= STATE_CHECK;
97      end case; --state
98
99      if state = STATE_CHECK and state_reg /= STATE_MISSED then
100         cache_address <= '0' & address_next(11 downto 2);
101         if address_next(30 downto 21) = "0010000000" then --first 2MB of DDR
102            cache_check <= '1';
103            if byte_we_next = "0000" then
104               cache_we <= '0';
105               state_next <= STATE_CHECKING;
106            else
107               cache_we <= '1';
108               state_next <= STATE_WRITING;
109            end if;
110         else
111            cache_check <= '0';
112            cache_we <= '0';
113            state_next <= STATE_CHECK;
114         end if;
115      else
116         cache_address <= '0' & cpu_address(11 downto 2);
117         cache_check <= '0';
118         state_next <= state;
119      end if;
120
121      if byte_we_next = "0000" or byte_we_next = "1111" then
122         cache_tag_in <= address_next(20 downto 12);
123      else
124         cache_tag_in <= ONES(8 downto 0); --invalid tag
125      end if;
126
127      if reset = '1' then
128         state_reg <= STATE_CHECK;
129         cache_tag_reg <= ZERO(8 downto 0);
130      elsif rising_edge(clk) then
131         state_reg <= state_next;
132         if state = STATE_CHECK and state_reg /= STATE_MISSED then
133            cache_tag_reg <= cache_tag_in;
134         end if;
135      end if;
136
137   end process;
138
139   cache_xilinx: if memory_type = "XILINX_16X" generate
140   begin
141      cache_tag: RAMB16_S9 --Xilinx specific
142      port map (
143         DO => cache_tag_out(7 downto 0),
144         DOP => cache_tag_out(8 downto 8),
145         ADDR => cache_address, --registered
146         CLK => clk,
147         DI => cache_tag_in(7 downto 0), --registered
148         DIP => cache_tag_in(8 downto 8),
149         EN => '1',
150         SSR => ZERO(0),
151         WE => cache_we);
152   end generate; --cache_xilinx
153      
154   cache_generic: if memory_type /= "XILINX_16X" generate
155   begin
156      cache_tag: process(clk, cache_address, cache_tag_in, cache_we)
157         constant ADDRESS_WIDTH : natural := 10;
158         type storage_array is
159            array(natural range 0 to 2 ** ADDRESS_WIDTH - 1) of
160            std_logic_vector(8 downto 0);
161         variable storage : storage_array;
162         variable index : natural := 0;
163      begin
164         if rising_edge(clk) then
165            index := conv_integer(cache_address(ADDRESS_WIDTH-1 downto 0));
166            if cache_we = '1' then
167               storage(index) := cache_tag_in;
168            end if;
169            cache_tag_out <= storage(index);
170         end if;
171      end process; --cache_tag
172   end generate; --cache_generic
173
174end; --logic
175
176

Archive Download this file

Branches:
master



interactive