source: trunk/modules/vci_mem_cache_v2/caba/source/include/mem_cache_directory_v2.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: 9.5 KB
Line 
1#ifndef SOCLIB_CABA_MEM_CACHE_DIRECTORY_V2_H
2#define SOCLIB_CABA_MEM_CACHE_DIRECTORY_V2_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  ////////////////////////////////////////////////////////////////////////
16  class LruEntry {
17
18    public:
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  ////////////////////////////////////////////////////////////////////////
32  class DirectoryEntry {
33
34    typedef uint32_t tag_t;
35    typedef uint32_t size_t;
36    typedef uint32_t copy_t;
37
38    public:
39
40    bool    valid;                  // entry valid
41    bool    is_cnt;                 // directory entry is a counter
42    bool    dirty;                  // entry dirty
43    bool    lock;                   // entry locked
44    tag_t   tag;                    // tag of the entry
45    copy_t  d_copies;               // vector of copies for data
46    copy_t  i_copies;               // vector of copies for instructions
47    size_t  count;                  // number of copies
48
49    DirectoryEntry()
50    {
51      valid    = false;
52      is_cnt   = false;
53      dirty    = false;
54      lock     = false;
55      tag      = 0;
56      d_copies = 0;
57      i_copies = 0;
58      count    = 0;
59    }
60
61    DirectoryEntry(const DirectoryEntry &source)
62    {
63      valid    = source.valid;
64      is_cnt   = source.is_cnt;
65      dirty    = source.dirty;
66      tag      = source.tag;
67      lock     = source.lock;
68      d_copies = source.d_copies;
69      i_copies = source.i_copies;
70      count    = source.count;
71    }         
72
73    /////////////////////////////////////////////////////////////////////
74    // The init() function initializes the entry
75    /////////////////////////////////////////////////////////////////////
76    void init()
77    {
78      valid = false;
79      is_cnt= false;
80      dirty = false;
81      lock  = false;
82    }
83
84    /////////////////////////////////////////////////////////////////////
85    // The copy() function copies an existing source entry to a target
86    /////////////////////////////////////////////////////////////////////
87    void copy(const DirectoryEntry &source)
88    {
89      valid     = source.valid;
90      is_cnt    = source.is_cnt;
91      dirty     = source.dirty;
92      tag       = source.tag;
93      lock      = source.lock;
94      d_copies  = source.d_copies;
95      i_copies  = source.i_copies;
96      count     = source.count;
97    }
98
99    ////////////////////////////////////////////////////////////////////
100    // The print() function prints the entry
101    ////////////////////////////////////////////////////////////////////
102    void print()
103    {
104      std::cout << "Valid = " << valid << " ; IS COUNT = " << is_cnt << " ; Dirty = " << dirty << " ; Lock = "
105        << lock << " ; Tag = " << std::hex << tag << " ; d_copies = " << d_copies << " ; i_copies = " << i_copies << " ; count = " << count << std::endl;
106    }
107
108  }; // end class DirectoryEntry
109
110  ////////////////////////////////////////////////////////////////////////
111  //                       The directory 
112  ////////////////////////////////////////////////////////////////////////
113  class CacheDirectory {
114
115    typedef sc_dt::sc_uint<40> addr_t;
116    typedef uint32_t data_t;
117    typedef uint32_t tag_t;
118    typedef uint32_t size_t;
119
120    private:
121
122    // Directory constants
123    size_t                                      m_ways;
124    size_t                                      m_sets;
125    size_t                                      m_words;
126    size_t                                      m_width;
127
128    // the directory & lru tables
129    DirectoryEntry                              **m_dir_tab;
130    LruEntry                                    **m_lru_tab;
131
132    public:
133
134    ////////////////////////
135    // Constructor
136    ////////////////////////
137    CacheDirectory( size_t ways, size_t sets, size_t words, size_t address_width)       
138    {
139      m_ways  = ways;
140      m_sets  = sets;
141      m_words = words;
142      m_width = address_width;
143
144      m_dir_tab = new DirectoryEntry*[sets];
145      for ( size_t i=0; i<sets; i++ ) {
146        m_dir_tab[i] = new DirectoryEntry[ways];
147        for ( size_t j=0 ; j<ways ; j++) m_dir_tab[i][j].init();
148      }
149      m_lru_tab = new LruEntry*[sets];
150      for ( size_t i=0; i<sets; i++ ) {
151        m_lru_tab[i] = new LruEntry[ways];
152        for ( size_t j=0 ; j<ways ; j++) m_lru_tab[i][j].init();
153      }
154    } // end constructor
155
156    /////////////////
157    // Destructor
158    /////////////////
159    ~CacheDirectory()
160    {
161      for(size_t i=0 ; i<m_sets ; i++){
162        delete [] m_dir_tab[i];
163        delete [] m_lru_tab[i];
164      }
165      delete [] m_dir_tab;
166      delete [] m_lru_tab;
167    } // end destructor
168
169    /////////////////////////////////////////////////////////////////////
170    // The read() function reads a directory entry. In case of hit, the
171    // LRU is updated.
172    // Arguments :
173    // - address : the address of the entry
174    // - way : (return argument) the way of the entry in case of hit
175    // The function returns a copy of a (valid or invalid) entry 
176    /////////////////////////////////////////////////////////////////////
177    DirectoryEntry read(const addr_t &address,size_t &way)
178    {
179
180#define L2 soclib::common::uint32_log2
181      const size_t set = (size_t)(address >> (L2(m_words) + 2)) & (m_sets - 1);
182      const tag_t  tag = (tag_t)(address >> (L2(m_sets) + L2(m_words) + 2));
183#undef L2
184
185      bool hit       = false;
186      for ( size_t i=0 ; i<m_ways ; i++ ) {
187        bool equal = ( m_dir_tab[set][i].tag == tag );
188        bool valid = m_dir_tab[set][i].valid;
189        hit = equal && valid;
190        if ( hit ) {                   
191          way = i;
192          break;
193        }
194      }
195      if ( hit ) {
196        m_lru_tab[set][way].recent = true;
197        return DirectoryEntry(m_dir_tab[set][way]);
198      } else {
199        return DirectoryEntry();
200      }
201    } // end read()
202
203    /////////////////////////////////////////////////////////////////////
204    // The write function writes a new entry,
205    // and updates the LRU bits if necessary.
206    // Arguments :
207    // - set : the set of the entry
208    // - way : the way of the entry
209    // - entry : the entry value
210    /////////////////////////////////////////////////////////////////////
211    void write(const size_t &set, const size_t &way, const DirectoryEntry &entry)
212    {
213      assert( (set<m_sets)
214          && "Cache Directory write : The set index is invalid");
215      assert( (way<m_ways)
216          && "Cache Directory write : The way index is invalid");
217
218      // update Directory
219      m_dir_tab[set][way].copy(entry);
220
221      // update LRU bits
222      bool all_recent = true;
223      for ( size_t i=0 ; i<m_ways ; i++ ) {
224        if ( i != way ) all_recent = m_lru_tab[set][i].recent && all_recent;
225      }
226      if ( all_recent ) {
227        for( size_t i=0 ; i<m_ways ; i++ ) m_lru_tab[set][i].recent = false;
228      } else {
229        m_lru_tab[set][way].recent = true;
230      }
231    } // end write()
232
233    /////////////////////////////////////////////////////////////////////
234    // The print() function prints a selected directory entry
235    // Arguments :
236    // - set : the set of the entry to print
237    // - way : the way of the entry to print
238    /////////////////////////////////////////////////////////////////////
239    void print(const size_t &set, const size_t &way)
240    {
241      std::cout << std::dec << " set : " << set << " ; way : " << way << " ; " ;
242      m_dir_tab[set][way].print();
243    } // end print()
244
245    /////////////////////////////////////////////////////////////////////
246    // The select() function selects a directory entry to evince.
247    // Arguments :
248    // - set   : (input argument) the set to modify
249    // - way   : (return argument) the way to evince
250    /////////////////////////////////////////////////////////////////////
251    DirectoryEntry select(const size_t &set, size_t &way)
252    {
253      assert( (set < m_sets)
254          && "Cache Directory : (select) The set index is invalid");
255
256      for(size_t i=0; i<m_ways; i++){
257        if(!m_dir_tab[set][way].valid){
258          way=i;
259          return DirectoryEntry(m_dir_tab[set][way]);
260        }
261      }
262      for(size_t i=0; i<m_ways; i++){
263        if(!(m_lru_tab[set][i].recent) && !(m_dir_tab[set][i].lock)){
264          way=i;
265          return DirectoryEntry(m_dir_tab[set][way]);
266        }
267      }
268      for(size_t i=0; i<m_ways; i++){
269        if( !(m_lru_tab[set][i].recent) && (m_dir_tab[set][i].lock)){
270          way=i;
271          return DirectoryEntry(m_dir_tab[set][way]);
272        }
273      }
274      for(size_t i=0; i<m_ways; i++){
275        if( (m_lru_tab[set][i].recent) && !(m_dir_tab[set][i].lock)){
276          way=i;
277          return DirectoryEntry(m_dir_tab[set][way]);
278        }
279      }
280      way = 0;
281      return DirectoryEntry(m_dir_tab[set][0]);
282    } // end select()
283
284    /////////////////////////////////////////////////////////////////////
285    //          Global initialisation function
286    /////////////////////////////////////////////////////////////////////
287    void init()
288    {
289      for ( size_t set=0 ; set<m_sets ; set++ ) {
290        for ( size_t way=0 ; way<m_ways ; way++ ) {
291          m_dir_tab[set][way].init();
292          m_lru_tab[set][way].init();
293        }
294      }
295    } // end init()
296
297  }; // end class CacheDirectory
298
299}} // end namespaces
300
301#endif
302
303// Local Variables:
304// tab-width: 4
305// c-basic-offset: 4
306// c-file-offsets:((innamespace . 0)(inline-open . 0))
307// indent-tabs-mode: nil
308// End:
309
310// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
311
Note: See TracBrowser for help on using the repository browser.