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

Subversion Repositories mlite

[/] [mlite/] [trunk/] [vhdl/] [cache.vhd] - Blame information for rev 337

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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