source: trunk/modules/vci_mem_cache_v4/caba/source/include/mem_cache_directory_v4.h @ 140

Last change on this file since 140 was 140, checked in by kane, 13 years ago

yAjout du multi_cache : plusieurs processeur peuvent ce partager le même cache L1.
2 remarques, (1) deux nouveaux paramètres : nb_cpu, nb_cache. Pour avoir un cache dont le comportement est identique à la version d'avant, mettre ces paramètres à 1.
(2) le port d'interruption est maintenant un tableau dépendant du nombre de processeur.
Voir le fichier "platforms/caba-ring-ccxcachev4_memcachev4-mips32el/top.cpp" pour plus de détails.

--Cette ligne, et les suivantes ci-dessous, seront ignorées--

M platforms/tsarv4_dspin_generic_32/tsarv4_dspin_generic_32_top.cpp
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/segmentation.h
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/top.cpp
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/configuration/default.cfg
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/configuration/gen_config.sh
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/dhrystone/dhry21a.c
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/define.h
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/matrix_multiplication/matrix_multiplication.c
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/common/common.c
A platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/self_code_modifying
A platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/self_code_modifying/self_code_modifying.c
A platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/self_code_modifying/self_code_modifying.h
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/benchmark/benchmark.h
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/benchmark/benchmark_sort.c
A platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/benchmark/benchmark_self_code_modifying.c
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/benchmark/benchmark.c
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/benchmark/benchmark_matrix_multiplication.c
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/Makefile
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/Makefile
M platforms/tsarv4_vgmn_generic_32/tsarv4_vgmn_generic_32_top.cpp
M modules/vci_cc_xcache_wrapper_v4/caba/source/include/vci_cc_xcache_wrapper_v4.h
M modules/vci_cc_xcache_wrapper_v4/caba/source/src/vci_cc_xcache_wrapper_v4.cpp
M modules/vci_mem_cache_v4/caba/source/include/vci_mem_cache_v4.h
M modules/vci_mem_cache_v4/caba/source/include/mem_cache_directory_v4.h
M modules/vci_mem_cache_v4/caba/source/src/vci_mem_cache_v4.cpp

  • 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: 18.6 KB
Line 
1#ifndef SOCLIB_CABA_MEM_CACHE_DIRECTORY_V4_H
2#define SOCLIB_CABA_MEM_CACHE_DIRECTORY_V4_H
3
4#include <inttypes.h>
5#include <systemc>
6#include <cassert>
7#include "arithmetics.h"
8
9#define L1_MULTI_CACHE      1
10
11namespace soclib { namespace caba {
12
13  using namespace sc_core;
14
15  ////////////////////////////////////////////////////////////////////////
16  //                    A LRU entry
17  ////////////////////////////////////////////////////////////////////////
18  class LruEntry {
19
20    public:
21
22      bool recent;           
23
24      void init()
25      {
26        recent=false;
27      }
28
29  }; // end class LruEntry
30
31  ////////////////////////////////////////////////////////////////////////
32  //                    An Owner
33  ////////////////////////////////////////////////////////////////////////
34  class Owner{
35    typedef uint32_t size_t;
36   
37    public:
38    // Fields
39      bool      inst;       // Is the owner an ICache ?
40      size_t    srcid;      // The SRCID of the owner
41#if L1_MULTI_CACHE
42      size_t    cache_id;   // In multi_cache configuration
43#endif
44
45    ////////////////////////
46    // Constructors
47    ////////////////////////
48      Owner(bool   i_inst
49            ,size_t i_srcid
50#if L1_MULTI_CACHE
51            ,size_t i_cache_id
52#endif
53            ){
54        inst    = i_inst;
55        srcid   = i_srcid;
56#if L1_MULTI_CACHE
57        cache_id= i_cache_id;
58#endif
59      }
60
61      Owner(const Owner &a){
62        inst    = a.inst;
63        srcid   = a.srcid;
64#if L1_MULTI_CACHE
65        cache_id= a.cache_id;
66#endif
67      }
68
69      Owner(){
70        inst    = false;
71        srcid   = 0;
72#if L1_MULTI_CACHE
73        cache_id= 0;
74#endif
75      }
76      // end constructors
77
78  }; // end class Owner
79
80
81  ////////////////////////////////////////////////////////////////////////
82  //                    A directory entry                               
83  ////////////////////////////////////////////////////////////////////////
84  class DirectoryEntry {
85
86    typedef uint32_t tag_t;
87    typedef uint32_t size_t;
88
89    public:
90
91    bool    valid;                  // entry valid
92    bool    is_cnt;                 // directory entry is in counter mode
93    bool    dirty;                  // entry dirty
94    bool    lock;                   // entry locked
95    tag_t   tag;                    // tag of the entry
96    size_t  count;                  // number of copies
97    Owner   owner;                  // an owner of the line
98    size_t  ptr;                    // pointer to the next owner
99
100    DirectoryEntry()
101    {
102      valid         = false;
103      is_cnt        = false;
104      dirty         = false;
105      lock          = false;
106      tag           = 0;
107      count         = 0;
108      owner.inst    = 0;
109      owner.srcid   = 0;
110#if L1_MULTI_CACHE
111      owner.cache_id= 0;
112#endif
113      ptr           = 0;
114    }
115
116    DirectoryEntry(const DirectoryEntry &source)
117    {
118      valid         = source.valid;
119      is_cnt        = source.is_cnt;
120      dirty         = source.dirty;
121      lock          = source.lock;
122      tag           = source.tag;
123      count         = source.count;
124      owner         = source.owner;
125      ptr           = source.ptr;
126    }         
127
128    /////////////////////////////////////////////////////////////////////
129    // The init() function initializes the entry
130    /////////////////////////////////////////////////////////////////////
131    void init()
132    {
133      valid     = false;
134      is_cnt    = false;
135      dirty     = false;
136      lock      = false;
137      count     = 0;
138    }
139
140    /////////////////////////////////////////////////////////////////////
141    // The copy() function copies an existing source entry to a target
142    /////////////////////////////////////////////////////////////////////
143    void copy(const DirectoryEntry &source)
144    {
145      valid         = source.valid;
146      is_cnt    = source.is_cnt;
147      dirty         = source.dirty;
148      lock          = source.lock;
149      tag           = source.tag;
150      count     = source.count;
151      owner     = source.owner;
152      ptr       = source.ptr;
153    }
154
155    ////////////////////////////////////////////////////////////////////
156    // The print() function prints the entry
157    ////////////////////////////////////////////////////////////////////
158    void print()
159    {
160      std::cout << "Valid = " << valid << " ; IS COUNT = " << is_cnt << " ; Dirty = " << dirty << " ; Lock = "
161                << lock
162                << " ; Tag = " << std::hex << tag << std::dec
163                << " ; Count = " << count
164                << " ; Owner = " << owner.srcid
165#if L1_MULTI_CACHE
166                << "." << owner.cache_id
167#endif
168                << " " << owner.inst
169                << " ; Pointer = " << ptr << std::endl;
170    }
171
172  }; // end class DirectoryEntry
173
174  ////////////////////////////////////////////////////////////////////////
175  //                       The directory 
176  ////////////////////////////////////////////////////////////////////////
177  class CacheDirectory {
178
179    typedef sc_dt::sc_uint<40> addr_t;
180    typedef uint32_t data_t;
181    typedef uint32_t tag_t;
182    typedef uint32_t size_t;
183
184    private:
185
186    // Directory constants
187    size_t                                      m_ways;
188    size_t                                      m_sets;
189    size_t                                      m_words;
190    size_t                                      m_width;
191
192    // the directory & lru tables
193    DirectoryEntry                              **m_dir_tab;
194    LruEntry                                    **m_lru_tab;
195
196    public:
197
198    ////////////////////////
199    // Constructor
200    ////////////////////////
201    CacheDirectory( size_t ways, size_t sets, size_t words, size_t address_width)       
202    {
203      m_ways  = ways;
204      m_sets  = sets;
205      m_words = words;
206      m_width = address_width;
207
208      m_dir_tab = new DirectoryEntry*[sets];
209      for ( size_t i=0; i<sets; i++ ) {
210        m_dir_tab[i] = new DirectoryEntry[ways];
211        for ( size_t j=0 ; j<ways ; j++) m_dir_tab[i][j].init();
212      }
213      m_lru_tab = new LruEntry*[sets];
214      for ( size_t i=0; i<sets; i++ ) {
215        m_lru_tab[i] = new LruEntry[ways];
216        for ( size_t j=0 ; j<ways ; j++) m_lru_tab[i][j].init();
217      }
218    } // end constructor
219
220    /////////////////
221    // Destructor
222    /////////////////
223    ~CacheDirectory()
224    {
225      for(size_t i=0 ; i<m_sets ; i++){
226        delete [] m_dir_tab[i];
227        delete [] m_lru_tab[i];
228      }
229      delete [] m_dir_tab;
230      delete [] m_lru_tab;
231    } // end destructor
232
233    /////////////////////////////////////////////////////////////////////
234    // The read() function reads a directory entry. In case of hit, the
235    // LRU is updated.
236    // Arguments :
237    // - address : the address of the entry
238    // - way : (return argument) the way of the entry in case of hit
239    // The function returns a copy of a (valid or invalid) entry 
240    /////////////////////////////////////////////////////////////////////
241    DirectoryEntry read(const addr_t &address,size_t &way)
242    {
243
244#define L2 soclib::common::uint32_log2
245      const size_t set = (size_t)(address >> (L2(m_words) + 2)) & (m_sets - 1);
246      const tag_t  tag = (tag_t)(address >> (L2(m_sets) + L2(m_words) + 2));
247#undef L2
248
249      bool hit       = false;
250      for ( size_t i=0 ; i<m_ways ; i++ ) {
251        bool equal = ( m_dir_tab[set][i].tag == tag );
252        bool valid = m_dir_tab[set][i].valid;
253        hit = equal && valid;
254        if ( hit ) {                   
255          way = i;
256          break;
257        }
258      }
259      if ( hit ) {
260        m_lru_tab[set][way].recent = true;
261        return DirectoryEntry(m_dir_tab[set][way]);
262      } else {
263        return DirectoryEntry();
264      }
265    } // end read()
266
267    /////////////////////////////////////////////////////////////////////
268    // The write function writes a new entry,
269    // and updates the LRU bits if necessary.
270    // Arguments :
271    // - set : the set of the entry
272    // - way : the way of the entry
273    // - entry : the entry value
274    /////////////////////////////////////////////////////////////////////
275    void write(const size_t &set, const size_t &way, const DirectoryEntry &entry)
276    {
277      assert( (set<m_sets)
278          && "Cache Directory write : The set index is invalid");
279      assert( (way<m_ways)
280          && "Cache Directory write : The way index is invalid");
281
282      // update Directory
283      m_dir_tab[set][way].copy(entry);
284
285      // update LRU bits
286      bool all_recent = true;
287      for ( size_t i=0 ; i<m_ways ; i++ ) {
288        if ( i != way ) all_recent = m_lru_tab[set][i].recent && all_recent;
289      }
290      if ( all_recent ) {
291        for( size_t i=0 ; i<m_ways ; i++ ) m_lru_tab[set][i].recent = false;
292      } else {
293        m_lru_tab[set][way].recent = true;
294      }
295    } // end write()
296
297    /////////////////////////////////////////////////////////////////////
298    // The print() function prints a selected directory entry
299    // Arguments :
300    // - set : the set of the entry to print
301    // - way : the way of the entry to print
302    /////////////////////////////////////////////////////////////////////
303    void print(const size_t &set, const size_t &way)
304    {
305      std::cout << std::dec << " set : " << set << " ; way : " << way << " ; " ;
306      m_dir_tab[set][way].print();
307    } // end print()
308
309    /////////////////////////////////////////////////////////////////////
310    // The select() function selects a directory entry to evince.
311    // Arguments :
312    // - set   : (input argument) the set to modify
313    // - way   : (return argument) the way to evince
314    /////////////////////////////////////////////////////////////////////
315    DirectoryEntry select(const size_t &set, size_t &way)
316    {
317      assert( (set < m_sets)
318          && "Cache Directory : (select) The set index is invalid");
319
320      for(size_t i=0; i<m_ways; i++){
321        if(!m_dir_tab[set][i].valid){
322          way=i;
323          return DirectoryEntry(m_dir_tab[set][way]);
324        }
325      }
326      for(size_t i=0; i<m_ways; i++){
327        if(!(m_lru_tab[set][i].recent) && !(m_dir_tab[set][i].lock)){
328          way=i;
329          return DirectoryEntry(m_dir_tab[set][way]);
330        }
331      }
332      for(size_t i=0; i<m_ways; i++){
333        if( !(m_lru_tab[set][i].recent) && (m_dir_tab[set][i].lock)){
334          way=i;
335          return DirectoryEntry(m_dir_tab[set][way]);
336        }
337      }
338      for(size_t i=0; i<m_ways; i++){
339        if( (m_lru_tab[set][i].recent) && !(m_dir_tab[set][i].lock)){
340          way=i;
341          return DirectoryEntry(m_dir_tab[set][way]);
342        }
343      }
344      way = 0;
345      return DirectoryEntry(m_dir_tab[set][0]);
346    } // end select()
347
348    /////////////////////////////////////////////////////////////////////
349    //          Global initialisation function
350    /////////////////////////////////////////////////////////////////////
351    void init()
352    {
353      for ( size_t set=0 ; set<m_sets ; set++ ) {
354        for ( size_t way=0 ; way<m_ways ; way++ ) {
355          m_dir_tab[set][way].init();
356          m_lru_tab[set][way].init();
357        }
358      }
359    } // end init()
360
361  }; // end class CacheDirectory
362
363  ///////////////////////////////////////////////////////////////////////
364  //                    A Heap Entry
365  ///////////////////////////////////////////////////////////////////////
366  class HeapEntry{
367    typedef uint32_t size_t;
368
369    public:
370    // Fields of the entry
371      Owner     owner;
372      size_t    next;
373
374    ////////////////////////
375    // Constructor
376    ////////////////////////
377      HeapEntry()
378      :owner(false,0
379#if L1_MULTI_CACHE
380             ,0
381#endif
382             )
383      {
384        next = 0;
385      } // end constructor
386
387    ////////////////////////
388    // Constructor
389    ////////////////////////
390      HeapEntry(const HeapEntry &entry){
391        owner.inst  = entry.owner.inst;
392        owner.srcid = entry.owner.srcid;
393#if L1_MULTI_CACHE
394        owner.cache_id = entry.owner.cache_id;
395#endif       
396        next           = entry.next;
397      } // end constructor
398
399    /////////////////////////////////////////////////////////////////////
400    // The copy() function copies an existing source entry to a target
401    /////////////////////////////////////////////////////////////////////
402      void copy(const HeapEntry &entry){
403        owner.inst     = entry.owner.inst;
404        owner.srcid    = entry.owner.srcid;
405#if L1_MULTI_CACHE
406        owner.cache_id = entry.owner.cache_id;
407#endif
408        next           = entry.next;
409      } // end copy()
410
411    ////////////////////////////////////////////////////////////////////
412    // The print() function prints the entry
413    ////////////////////////////////////////////////////////////////////
414      void print(){
415        std::cout
416        << " -- owner.inst     : " << std::dec << owner.inst << std::endl
417        << " -- owner.srcid    : " << std::dec << owner.srcid << std::endl
418#if L1_MULTI_CACHE
419        << " -- owner.cache_id : " << std::dec << owner.cache_id << std::endl
420#endif
421        << " -- next           : " << std::dec << next << std::endl;
422
423      } // end print()
424
425  }; // end class HeapEntry
426
427  ////////////////////////////////////////////////////////////////////////
428  //                        The Heap
429  ////////////////////////////////////////////////////////////////////////
430  class HeapDirectory{
431    typedef uint32_t size_t;
432   
433    private:
434    // Registers and the heap
435      size_t    ptr_free;
436      bool      full;
437      HeapEntry *m_heap_tab;
438
439    // Constants for debugging purpose
440      size_t    tab_size;
441
442    public:
443    ////////////////////////
444    // Constructor
445    ////////////////////////
446      HeapDirectory(uint32_t size){
447        assert(size>0 && "Memory Cache, HeapDirectory constructor : invalid size");
448        ptr_free    = 0;
449        full        = false;
450        m_heap_tab  = new HeapEntry[size];
451        tab_size    = size;
452      } // end constructor
453
454    /////////////////
455    // Destructor
456    /////////////////
457      ~HeapDirectory(){
458        delete [] m_heap_tab;
459      } // end destructor
460
461    /////////////////////////////////////////////////////////////////////
462    //          Global initialisation function
463    /////////////////////////////////////////////////////////////////////
464      void init(){
465        ptr_free=0;
466        full=false;
467        for(size_t i=0; i< tab_size-1;i++){
468          m_heap_tab[i].next = i+1;
469        }
470        m_heap_tab[tab_size-1].next = tab_size-1;
471        return;
472      }
473
474    /////////////////////////////////////////////////////////////////////
475    // The print() function prints a selected directory entry
476    // Arguments :
477    // - ptr : the pointer to the entry to print
478    /////////////////////////////////////////////////////////////////////
479      void print(const size_t &ptr){
480        std::cout << "Heap, printing the entry : " << std::dec << ptr << std::endl;
481        m_heap_tab[ptr].print();
482      } // end print()
483
484    /////////////////////////////////////////////////////////////////////
485    // The print_list() function prints a list from selected directory entry
486    // Arguments :
487    // - ptr : the pointer to the first entry to print
488    /////////////////////////////////////////////////////////////////////
489      void print_list(const size_t &ptr){
490        bool end = false;
491        size_t ptr_temp = ptr;
492        std::cout << "Heap, printing the list from : " << std::dec << ptr << std::endl;
493        while(!end){
494            m_heap_tab[ptr_temp].print();
495            if(ptr_temp == m_heap_tab[ptr_temp].next) end = true;
496            ptr_temp = m_heap_tab[ptr_temp].next;
497        }
498      } // end print_list()
499
500    /////////////////////////////////////////////////////////////////////
501    // The is_full() function return true if the heap is full.
502    /////////////////////////////////////////////////////////////////////
503      bool is_full(){
504        return full;
505      } // end is_full()
506
507    /////////////////////////////////////////////////////////////////////
508    // The next_free_ptr() function returns the pointer
509    // to the next free entry.
510    /////////////////////////////////////////////////////////////////////
511      size_t next_free_ptr(){
512        return ptr_free;
513      } // end next_free_ptr()
514
515    /////////////////////////////////////////////////////////////////////
516    // The next_free_entry() function returns
517    // a copy of the next free entry.
518    /////////////////////////////////////////////////////////////////////
519      HeapEntry next_free_entry(){
520        return HeapEntry(m_heap_tab[ptr_free]);
521      } // end next_free_entry()
522   
523    /////////////////////////////////////////////////////////////////////
524    // The write_free_entry() function modify the next free entry.
525    // Arguments :
526    // - entry : the entry to write
527    /////////////////////////////////////////////////////////////////////
528      void write_free_entry(const HeapEntry &entry){
529        m_heap_tab[ptr_free].copy(entry);
530      } // end write_free_entry()
531
532    /////////////////////////////////////////////////////////////////////
533    // The write_free_ptr() function writes the pointer
534    // to the next free entry
535    /////////////////////////////////////////////////////////////////////
536      void write_free_ptr(const size_t &ptr){
537        assert( (ptr<tab_size) && "HeapDirectory error : try to write a wrong free pointer");
538        ptr_free = ptr;
539      } // end write_free_ptr()
540
541    /////////////////////////////////////////////////////////////////////
542    // The set_full() function sets the full bit (to true).
543    /////////////////////////////////////////////////////////////////////
544      void set_full(){
545        full = true;
546      } // end set_full()
547
548    /////////////////////////////////////////////////////////////////////
549    // The unset_full() function unsets the full bit (to false).
550    /////////////////////////////////////////////////////////////////////
551      void unset_full(){
552        full = false;
553      } // end unset_full()
554
555    /////////////////////////////////////////////////////////////////////
556    // The read() function returns a copy of
557    // the entry pointed by the argument
558    // Arguments :
559    //  - ptr : the pointer to the entry to read
560    /////////////////////////////////////////////////////////////////////
561      HeapEntry read(const size_t &ptr){
562        assert( (ptr<tab_size) && "HeapDirectory error : try to write a wrong free pointer");
563        return HeapEntry(m_heap_tab[ptr]);
564      } // end read()
565
566    /////////////////////////////////////////////////////////////////////
567    // The write() function writes an entry in the heap
568    // Arguments :
569    //  - ptr : the pointer to the entry to replace
570    //  - entry : the entry to write
571    /////////////////////////////////////////////////////////////////////
572      void write(const size_t &ptr, const HeapEntry &entry){
573        assert( (ptr<tab_size) && "HeapDirectory error : try to write a wrong free pointer");
574        m_heap_tab[ptr].copy(entry);
575      } // end write()
576
577  }; // end class HeapDirectory
578
579
580}} // end namespaces
581
582#endif
583
584// Local Variables:
585// tab-width: 4
586// c-basic-offset: 4
587// c-file-offsets:((innamespace . 0)(inline-open . 0))
588// indent-tabs-mode: nil
589// End:
590
591// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
592
Note: See TracBrowser for help on using the repository browser.