-
Notifications
You must be signed in to change notification settings - Fork 96
/
Copy pathsort_lru_cache.vhdl
151 lines (125 loc) · 5.01 KB
/
sort_lru_cache.vhdl
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
-- EMACS settings: -*- tab-width: 2; indent-tabs-mode: t -*-
-- vim: tabstop=2:shiftwidth=2:noexpandtab
-- kate: tab-width 2; replace-tabs off; indent-width 2;
-- =============================================================================
-- Authors: Patrick Lehmann
-- Martin Zabel
--
-- Entity: Optimized LRU list implementation for Caches.
--
-- Description:
-- -------------------------------------
-- This is an optimized implementation of ``sort_lru_list`` to be used for caches.
-- Only keys are stored within this list, and these keys are the index of the
-- cache lines. The list initially contains all indizes from 0 to ELEMENTS-1.
-- The least-recently used index ``KeyOut`` is always valid.
--
-- The first outputed least-recently used index will be ELEMENTS-1.
--
-- The inputs ``Insert``, ``Free``, ``KeyIn``, and ``Reset`` are synchronous to the
-- rising-edge of the clock ``clock``. All control signals are high-active.
--
-- Supported operations:
-- * **Insert:** Mark index ``KeyIn`` as recently used, e.g., when a cache-line
-- was accessed.
-- * **Free:** Mark index ``KeyIn`` as least-recently used. Apply this operation,
-- when a cache-line gets invalidated.
--
-- License:
-- =============================================================================
-- Copyright 2007-2016 Technische Universitaet Dresden - Germany
-- Chair of VLSI-Design, Diagnostics and Architecture
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
-- =============================================================================
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
library PoC;
use PoC.config.all;
use PoC.utils.all;
use PoC.vectors.all;
use PoC.components.all;
entity sort_lru_cache is
generic (
ELEMENTS : positive := 32
);
port (
Clock : in std_logic;
Reset : in std_logic;
Insert : in std_logic;
Free : in std_logic;
KeyIn : in std_logic_vector(log2ceilnz(ELEMENTS) - 1 downto 0);
KeyOut : out std_logic_vector(log2ceilnz(ELEMENTS) - 1 downto 0)
);
end entity;
architecture rtl of sort_lru_cache is
constant KEY_BITS : positive := log2ceilnz(ELEMENTS);
subtype T_ELEMENT is std_logic_vector(KEY_BITS - 1 downto 0);
type T_ELEMENT_VECTOR is array (natural range <>) of T_ELEMENT;
signal NewElement : T_ELEMENT;
signal ElementsUp : T_ELEMENT_VECTOR(ELEMENTS downto 0);
signal ElementsDown : T_ELEMENT_VECTOR(ELEMENTS downto 0);
signal MovesDown : std_logic_vector(ELEMENTS downto 0);
signal MovesUp : std_logic_vector(ELEMENTS downto 0);
signal UnEqual : std_logic_vector(ELEMENTS-1 downto 0);
signal MovesUpCond : std_logic_vector(ELEMENTS downto 0);
signal MovesDownCond : std_logic_vector(ELEMENTS downto 0);
signal MovesDownCondRev : std_logic_vector(ELEMENTS downto 0);
signal MovesDownRev : std_logic_vector(ELEMENTS downto 0);
begin
-- next element (top)
ElementsDown(ELEMENTS) <= NewElement;
MovesDownCond(ELEMENTS) <= Insert;
-- current element
genElements : for I in ELEMENTS - 1 downto 0 generate
constant INITIAL_ELEMENT : std_logic_vector(KEY_BITS - 1 downto 0) := std_logic_vector(to_unsigned(ELEMENTS-1 - i, KEY_BITS));
signal Element_nxt : std_logic_vector(KEY_BITS - 1 downto 0);
signal Element_d : std_logic_vector(KEY_BITS - 1 downto 0) := INITIAL_ELEMENT;
signal MoveDown : std_logic;
signal MoveUp : std_logic;
begin
-- local movements
UnEqual(i) <= to_sl(Element_d /= NewElement);
ElementsUp(I + 1) <= Element_d;
-- multiplexer
Element_nxt <= mux(MovesDown(I+1), mux(MovesUp(i), Element_d, ElementsUp(I)), ElementsDown(I + 1));
-- register
Element_d <= ffdre(q => Element_d, d => Element_nxt, rst => Reset, INIT => INITIAL_ELEMENT) when rising_edge(Clock);
ElementsDown(I) <= Element_d;
end generate;
-- MovesUp / MovesDown propagation
MovesUpCond (ELEMENTS downto 1) <= UnEqual;
MovesDownCond(ELEMENTS-1 downto 0) <= UnEqual;
MovesDownCondRev <= reverse(MovesDownCond);
MovesDown <= reverse(MovesDownRev);
MovesUpProp: entity poc.arith_prefix_and
generic map (
N => ELEMENTS+1)
port map (
-- Individual association of 'x' didn't work in QuestaSim
x => MovesUpCond,
y => MovesUp);
MovesDownProp: entity poc.arith_prefix_and
generic map (
N => ELEMENTS+1)
port map (
-- Individual association of 'x' didn't work in QuestaSim
x => MovesDownCondRev,
y => MovesDownRev);
-- previous element (bottom)
NewElement <= KeyIn;
ElementsUp(0) <= KeyIn;
MovesUpCond(0) <= Free;
KeyOut <= ElementsDown(0);
end architecture;