-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCC_LRU.vhd
More file actions
129 lines (124 loc) · 4.81 KB
/
CC_LRU.vhd
File metadata and controls
129 lines (124 loc) · 4.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity CC_LRU is
port (
clk : in std_logic;
rst : in std_logic;
addr : in std_logic_vector(31 downto 0);
memory_read : in std_logic;
inst_from_mem : in std_logic_vector(31 downto 0);
mem_done : in std_logic;
inst_to_cpu : out std_logic_vector(31 downto 0);
done : out std_logic);
end entity CC_LRU;
architecture arc_CC_LRU of CC_LRU is
signal hit, miss : std_logic;
signal cache_upd : std_logic;
signal read_en : std_logic;
signal data_sel : std_logic;
type mem_arr is array (0 to 256) of
std_logic_vector(51 downto 0);
signal cache_mem_0 : mem_arr; --two banks for LRU algorithm
signal cache_mem_1 : mem_arr;
signal flag : std_logic_vector(255 downto 0); --flag for last accessed bank
alias cache_addr : std_logic_vector(11 downto 0) is
addr(11 downto 0);
alias tag : std_logic_vector(19 downto 0) is addr(31 downto 12);
type fsm_st is (idle, wait_on_cache, wait_on_mem);
signal cs : fsm_st;
begin
-- cache memory and cache status flags (hit & miss)
process (clk, rst) is
begin
if (rst = '1') then
hit <= '0';
miss <= '0';
cache_mem_0 <= (others => (others => '0'));
cache_mem_1 <= (others => (others => '0'));
flag <= (others => '0');
elsif rising_edge(clk) then
hit <= '0';
miss <= '0';
if (read_en = '1') then
if (flag(conv_integer(cache_addr)) = '0') then --flag check
if (tag = cache_mem_0(conv_integer(cache_addr))(51 downto 32)) then
hit <= '1';
elsif (tag = cache_mem_1(conv_integer(cache_addr))) then
hit <= '1';
flag(conv_integer(cache_addr)) <= '1';
else
cache_upd <= '1';
miss <= '1';
flag(conv_integer(cache_addr)) <= '1';
end if;
elsif (tag = cache_mem_1(conv_integer(cache_addr))(51 downto 32)) then
hit <= '1';
elsif (tag = cache_mem_0(conv_integer(cache_addr))) then
hit <= '1';
flag(conv_integer(cache_addr)) <= '0';
else
cache_upd <= '1';
miss <= '1';
flag(conv_integer(cache_addr)) <= '0';
end if;
end if;
if (cache_upd = '1') then --updating cache memory at the last accessed bank
if (flag(conv_integer(cache_addr)) = '0') then
cache_mem_0(conv_integer(cache_addr)) <= tag & inst_from_mem;
else
cache_mem_1(conv_integer(cache_addr)) <= tag & inst_from_mem;
end if;
end if;
end if;
--transfer of the selected instruction to cpu
if (data_sel = '1') then
if (flag(conv_integer(cache_addr)) = '0') then
inst_to_cpu <= cache_mem_0(conv_integer(cache_addr))(inst_to_cpu'range) ;
elsif (flag(conv_integer(cache_addr)) = '1') then
inst_to_cpu <= cache_mem_1(conv_integer(cache_addr))(inst_to_cpu'range) ;
end if;
elsif (data_sel = '0') then
inst_to_cpu <= inst_from_mem ;
end if;
end process;
--Mealy FSM description by single process with registered outputs
process (clk, rst) is
variable ns : fsm_st;
begin
if (rst = '1') then
done <= '0';
cache_upd <= '0';
read_en <= '0';
data_sel <= '1';
cs <= idle;
elsif rising_edge(clk) then
ns := cs;
done <= '0';
cache_upd <= '0';
read_en <= '0';
data_sel <= '1';
case cs is
when idle => if (memory_read = '1') then
ns := wait_on_cache;
read_en <= '1';
end if;
when wait_on_cache => if (hit = '1') then
ns := idle;
done <= '1';
elsif (miss = '1') then
ns := wait_on_mem;
end if;
when wait_on_mem => if (mem_done = '1') then
ns := idle;
done <= '1';
cache_upd <= '1';
data_sel <= '0';
end if;
when others => null;
end case;
cs <= ns;
end if;
end process;
end architecture arc_CC_LRU;