source: trunk/modules/vci_mem_cache/caba/source/include/mem_cache_directory.h @ 2

Last change on this file since 2 was 2, checked in by nipo, 14 years ago

Import TSAR modules in TSAR's own svn

  • Property svn:eol-style set to native
  • Property svn:keywords set to "Author Date Id Rev URL Revision"
  • Property svn:mime-type set to text/plain
File size: 8.4 KB
Line 
1#ifndef SOCLIB_CABA_MEM_CACHE_DIRECTORY_H
2#define SOCLIB_CABA_MEM_CACHE_DIRECTORY_H
3
4#include <inttypes.h>
5#include <systemc>
6#include <cassert>
7#include "arithmetics.h"
8
9namespace soclib { namespace caba {
10
11  using namespace sc_core;
12
13////////////////////////////////////////////////////////////////////////
14//                    A LRU entry
15////////////////////////////////////////////////////////////////////////
16class LruEntry {
17
18public:
19
20    bool recent;           
21
22    void init()
23    {
24        recent=false;
25    }
26
27}; // end class LruEntry
28
29////////////////////////////////////////////////////////////////////////
30//                    A directory entry                               
31////////////////////////////////////////////////////////////////////////
32class DirectoryEntry {
33
34    typedef uint32_t tag_t;
35    typedef uint32_t size_t;
36    typedef uint32_t copy_t;
37
38public:
39
40    bool                valid;                  // entry valid
41    bool                dirty;                  // entry dirty
42    bool                lock;                   // entry locked
43    tag_t               tag;                    // tag of the entry
44    copy_t              copies;                 // vector of copies
45
46    DirectoryEntry()
47    {
48        valid   = false;
49        dirty   = false;
50        lock    = false;
51        tag     = 0;
52        copies  = 0;
53    }
54   
55    DirectoryEntry(const DirectoryEntry &source)
56    {
57        valid   = source.valid;
58        dirty   = source.dirty;
59        tag     = source.tag;
60        lock    = source.lock;
61        copies  = source.copies;
62    }
63   
64    /////////////////////////////////////////////////////////////////////
65    // The init() function initializes the entry
66    /////////////////////////////////////////////////////////////////////
67    void init()
68    {
69        valid = false;
70        dirty = false;
71        lock  = false;
72    }
73   
74    /////////////////////////////////////////////////////////////////////
75    // The copy() function copies an existing source entry to a target
76    /////////////////////////////////////////////////////////////////////
77    void copy(const DirectoryEntry &source)
78    {
79        valid   = source.valid;
80        dirty   = source.dirty;
81        tag     = source.tag;
82        lock    = source.lock;
83        copies  = source.copies;
84    }
85
86    ////////////////////////////////////////////////////////////////////
87    // The print() function prints the entry
88    ////////////////////////////////////////////////////////////////////
89    void print()
90    {
91        std::cout << "Valid = " << valid << " ; Dirty = " << dirty << " ; Lock = "
92           << lock << " ; Tag = " << std::hex << tag << " ; copies = " << copies << std::endl;
93    }
94
95}; // end class DirectoryEntry
96
97////////////////////////////////////////////////////////////////////////
98//                       The directory 
99////////////////////////////////////////////////////////////////////////
100class CacheDirectory {
101
102    typedef uint32_t addr_t;
103    typedef uint32_t data_t;
104    typedef uint32_t tag_t;
105    typedef uint32_t size_t;
106
107 private:
108
109// Directory constants
110    size_t                                      m_ways;
111    size_t                                      m_sets;
112    size_t                                      m_words;
113    size_t                                      m_width;
114
115// the directory & lru tables
116    DirectoryEntry                              **m_dir_tab;
117    LruEntry                                    **m_lru_tab;
118
119 public:
120
121    ////////////////////////
122    // Constructor
123    ////////////////////////
124    CacheDirectory( size_t ways, size_t sets, size_t words, size_t address_width)       
125    {
126        m_ways  = ways;
127        m_sets  = sets;
128        m_words = words;
129        m_width = address_width;
130
131        m_dir_tab = new DirectoryEntry*[sets];
132        for ( size_t i=0; i<sets; i++ ) {
133            m_dir_tab[i] = new DirectoryEntry[ways];
134            for ( size_t j=0 ; j<ways ; j++) m_dir_tab[i][j].init();
135        }
136        m_lru_tab = new LruEntry*[sets];
137        for ( size_t i=0; i<sets; i++ ) {
138            m_lru_tab[i] = new LruEntry[ways];
139            for ( size_t j=0 ; j<ways ; j++) m_lru_tab[i][j].init();
140        }
141    } // end constructor
142
143    /////////////////
144    // Destructor
145    /////////////////
146    ~CacheDirectory()
147    {
148        for(size_t i=0 ; i<m_sets ; i++){
149            delete [] m_dir_tab[i];
150            delete [] m_lru_tab[i];
151        }
152        delete [] m_dir_tab;
153        delete [] m_lru_tab;
154    } // end destructor
155
156    /////////////////////////////////////////////////////////////////////
157    // The read() function reads a directory entry. In case of hit, the
158    // LRU is updated.
159    // Arguments :
160    // - address : the address of the entry
161    // - way : (return argument) the way of the entry in case of hit
162    // The function returns a copy of a (valid or invalid) entry 
163    /////////////////////////////////////////////////////////////////////
164    DirectoryEntry read(const addr_t &address,size_t &way)
165    {
166
167      #define L2 soclib::common::uint32_log2
168      const size_t set = (size_t)(address >> (L2(m_words) + 2)) & (m_sets - 1);
169      const tag_t  tag = (tag_t)(address >> (L2(m_sets) + L2(m_words) + 2));
170      #undef L2
171
172      bool hit       = false;
173      for ( size_t i=0 ; i<m_ways ; i++ ) {
174        bool equal = ( m_dir_tab[set][i].tag == tag );
175        bool valid = m_dir_tab[set][i].valid;
176        hit = equal && valid;
177        if ( hit ) {                   
178          way = i;
179          break;
180        }
181      }
182      if ( hit ) {
183        m_lru_tab[set][way].recent = true;
184        return DirectoryEntry(m_dir_tab[set][way]);
185      } else {
186        return DirectoryEntry();
187      }
188    } // end read()
189
190    /////////////////////////////////////////////////////////////////////
191    // The write function writes a new entry,
192    // and updates the LRU bits if necessary.
193    // Arguments :
194    // - set : the set of the entry
195    // - way : the way of the entry
196    // - entry : the entry value
197    /////////////////////////////////////////////////////////////////////
198    void write(const size_t &set, const size_t &way, const DirectoryEntry &entry)
199    {
200      assert( (set<m_sets)
201                && "Cache Directory write : The set index is invalid");
202      assert( (way<m_ways)
203                && "Cache Directory write : The way index is invalid");
204
205      // update Directory
206      m_dir_tab[set][way].copy(entry);
207
208      // update LRU bits
209      bool all_recent = true;
210      for ( size_t i=0 ; i<m_ways ; i++ ) {
211        if ( i != way ) all_recent = m_lru_tab[set][i].recent && all_recent;
212      }
213      if ( all_recent ) {
214        for( size_t i=0 ; i<m_ways ; i++ ) m_lru_tab[set][i].recent = false;
215      } else {
216        m_lru_tab[set][way].recent = true;
217      }
218    } // end write()
219
220    /////////////////////////////////////////////////////////////////////
221    // The print() function prints a selected directory entry
222    // Arguments :
223    // - set : the set of the entry to print
224    // - way : the way of the entry to print
225    /////////////////////////////////////////////////////////////////////
226    void print(const size_t &set, const size_t &way)
227    {
228        std::cout << std::dec << " set : " << set << " ; way : " << way << " ; " ;
229        m_dir_tab[set][way].print();
230    } // end print()
231   
232    /////////////////////////////////////////////////////////////////////
233    // The select() function selects a directory entry to evince.
234    // Arguments :
235    // - set   : (input argument) the set to modify
236    // - way   : (return argument) the way to evince
237    /////////////////////////////////////////////////////////////////////
238    DirectoryEntry select(const size_t &set, size_t &way)
239    {
240        assert( (set < m_sets)
241                && "Cache Directory : (select) The set index is invalid");
242
243        for(size_t i=0; i<m_ways; i++){
244                if(!(m_lru_tab[set][i].recent) && !(m_dir_tab[set][i].lock)){
245                        way=i;
246                        return DirectoryEntry(m_dir_tab[set][way]);
247                }
248        }
249        for(size_t i=0; i<m_ways; i++){
250                if( !(m_lru_tab[set][i].recent) && (m_dir_tab[set][i].lock)){
251                        way=i;
252                        return DirectoryEntry(m_dir_tab[set][way]);
253                }
254        }
255        for(size_t i=0; i<m_ways; i++){
256                if( (m_lru_tab[set][i].recent) && !(m_dir_tab[set][i].lock)){
257                        way=i;
258                        return DirectoryEntry(m_dir_tab[set][way]);
259                }
260        }
261        for(size_t i=0; i<m_ways; i++){
262                if( (m_lru_tab[set][i].recent) && (m_dir_tab[set][i].lock)){
263                        way=i;
264                        return DirectoryEntry(m_dir_tab[set][way]);
265                }
266        }
267        way = 0;
268        return DirectoryEntry(m_dir_tab[set][0]);
269    } // end select()
270
271    /////////////////////////////////////////////////////////////////////
272    //          Global initialisation function
273    /////////////////////////////////////////////////////////////////////
274    void init()
275    {
276        for ( size_t set=0 ; set<m_sets ; set++ ) {
277            for ( size_t way=0 ; way<m_ways ; way++ ) {
278                m_dir_tab[set][way].init();
279                m_lru_tab[set][way].init();
280            }
281        }
282    } // end init()
283 
284}; // end class CacheDirectory
285 
286}} // end namespaces
287
288#endif
Note: See TracBrowser for help on using the repository browser.