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

Subversion Repositories plasma

[/] [plasma/] [trunk/] [vhdl/] [cache.vhd] - Blame information for rev 383

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

powered by: WebSVN 2.1.0

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