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

Subversion Repositories plasma

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

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 343 rhoads
use ieee.std_logic_unsigned.all;
16
library UNISIM;
17
use UNISIM.vcomponents.all;
18 337 rhoads
use work.mlite_pack.all;
19
 
20
entity cache is
21
   generic(memory_type : string := "DEFAULT");
22 343 rhoads
   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 337 rhoads
 
29 343 rhoads
        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
32 337 rhoads
end; --cache
33
 
34
architecture 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;
50
begin
51
 
52 343 rhoads
   cache_proc: process(clk, reset, mem_busy, cache_address, cache_we,
53 337 rhoads
      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 343 rhoads
         cache_we <= '0';
74 337 rhoads
      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 343 rhoads
         cache_we <= '0';
87 337 rhoads
         if mem_busy = '1' then
88
            state <= STATE_WRITING;
89
         else
90
            state <= STATE_CHECK;
91
         end if;
92
      when others =>
93 343 rhoads
         cache_checking <= '0';
94
         cache_miss <= '0';
95
         cache_we <= '0';
96 337 rhoads
         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 343 rhoads
         if state = STATE_CHECK and state_reg /= STATE_MISSED then
133 337 rhoads
            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 343 rhoads
         DOP  => cache_tag_out(8 downto 8),
145 337 rhoads
         ADDR => cache_address,             --registered
146
         CLK  => clk,
147
         DI   => cache_tag_in(7 downto 0),  --registered
148 343 rhoads
         DIP  => cache_tag_in(8 downto 8),
149 337 rhoads
         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
 
174
end; --logic
175
 

powered by: WebSVN 2.1.0

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