Ignore:
Timestamp:
Sep 30, 2014, 3:32:13 PM (10 years ago)
Author:
devigne
Message:

RWT Commit : Cosmetic

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/RWT/modules/vci_mem_cache/caba/source/include/mem_cache_directory.h

    r814 r823  
    1818  class LruEntry {
    1919
    20     public:
    21 
    22       bool recent;
    23 
     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
     36      public:
     37
     38          // Fields
     39          bool   inst;  // Is the owner an ICache ?
     40          size_t srcid; // The SRCID of the owner
     41
     42          ////////////////////////
     43          // Constructors
     44          ////////////////////////
     45          Owner(bool   i_inst,
     46                size_t i_srcid)
     47          {
     48              inst  = i_inst;
     49              srcid = i_srcid;
     50          }
     51
     52          Owner(const Owner &a)
     53          {
     54              inst  = a.inst;
     55              srcid = a.srcid;
     56          }
     57
     58          Owner()
     59          {
     60              inst  = false;
     61              srcid = 0;
     62          }
     63          // end constructors
     64
     65  }; // end class Owner
     66
     67
     68  ////////////////////////////////////////////////////////////////////////
     69  //                    A directory entry
     70  ////////////////////////////////////////////////////////////////////////
     71  class DirectoryEntry {
     72
     73      typedef uint32_t tag_t;
     74
     75      public:
     76
     77      bool   valid;          // entry valid
     78      bool   cache_coherent; // WB or WT policy
     79      bool   is_cnt;         // directory entry is in counter mode
     80      bool   dirty;          // entry dirty
     81      bool   lock;           // entry locked
     82      tag_t  tag;            // tag of the entry
     83      size_t count;          // number of copies
     84      Owner  owner;          // an owner of the line
     85      size_t ptr;            // pointer to the next owner
     86
     87      DirectoryEntry()
     88      {
     89          valid          = false;
     90          cache_coherent = false;
     91          is_cnt         = false;
     92          dirty          = false;
     93          lock           = false;
     94          tag            = 0;
     95          count          = 0;
     96          owner.inst     = 0;
     97          owner.srcid    = 0;
     98          ptr            = 0;
     99      }
     100
     101      DirectoryEntry(const DirectoryEntry &source)
     102      {
     103          valid          = source.valid;
     104          cache_coherent = source.cache_coherent;
     105          is_cnt         = source.is_cnt;
     106          dirty          = source.dirty;
     107          lock           = source.lock;
     108          tag            = source.tag;
     109          count          = source.count;
     110          owner          = source.owner;
     111          ptr            = source.ptr;
     112      }
     113
     114      /////////////////////////////////////////////////////////////////////
     115      // The init() function initializes the entry
     116      /////////////////////////////////////////////////////////////////////
    24117      void init()
    25118      {
    26         recent=false;
     119          valid          = false;
     120          cache_coherent = false;
     121          is_cnt         = false;
     122          dirty          = false;
     123          lock           = false;
     124          count          = 0;
    27125      }
    28126
    29   }; // end class LruEntry
    30 
    31   ////////////////////////////////////////////////////////////////////////
    32   //                    An Owner
    33   ////////////////////////////////////////////////////////////////////////
    34   class Owner{
    35 
    36     public:
    37     // Fields
    38       bool      inst;       // Is the owner an ICache ?
    39       size_t    srcid;      // The SRCID of the owner
    40 
    41     ////////////////////////
    42     // Constructors
    43     ////////////////////////
    44       Owner(bool   i_inst,
    45             size_t i_srcid)
    46       {
    47         inst    = i_inst;
    48         srcid   = i_srcid;
     127      /////////////////////////////////////////////////////////////////////
     128      // The copy() function copies an existing source entry to a target
     129      /////////////////////////////////////////////////////////////////////
     130      void copy(const DirectoryEntry &source)
     131      {
     132          valid          = source.valid;
     133          cache_coherent = source.cache_coherent;
     134          is_cnt         = source.is_cnt;
     135          dirty          = source.dirty;
     136          lock           = source.lock;
     137          tag            = source.tag;
     138          count          = source.count;
     139          owner          = source.owner;
     140          ptr            = source.ptr;
    49141      }
    50142
    51       Owner(const Owner &a)
    52       {
    53         inst    = a.inst;
    54         srcid   = a.srcid;
     143      ////////////////////////////////////////////////////////////////////
     144      // The print() function prints the entry
     145      ////////////////////////////////////////////////////////////////////
     146      void print()
     147      {
     148          std::cout << "Valid = " << valid
     149              << " ; COHERENCE = " << cache_coherent
     150              << " ; IS COUNT = " << is_cnt
     151              << " ; Dirty = " << dirty
     152              << " ; Lock = " << lock
     153              << " ; Tag = " << std::hex << tag << std::dec
     154              << " ; Count = " << count
     155              << " ; Owner = " << owner.srcid
     156              << " " << owner.inst
     157              << " ; Pointer = " << ptr << std::endl;
    55158      }
    56159
    57       Owner()
    58       {
    59         inst    = false;
    60         srcid   = 0;
     160  }; // end class DirectoryEntry
     161
     162  ////////////////////////////////////////////////////////////////////////
     163  //                       The directory
     164  ////////////////////////////////////////////////////////////////////////
     165  class CacheDirectory {
     166
     167      typedef sc_dt::sc_uint<40> addr_t;
     168      typedef uint32_t data_t;
     169      typedef uint32_t tag_t;
     170
     171      private:
     172
     173      // Directory constants
     174      size_t   m_ways;
     175      size_t   m_sets;
     176      size_t   m_words;
     177      size_t   m_width;
     178      uint32_t lfsr;
     179
     180      // the directory & lru tables
     181      DirectoryEntry **m_dir_tab;
     182      LruEntry       **m_lru_tab;
     183
     184      public:
     185
     186      ////////////////////////
     187      // Constructor
     188      ////////////////////////
     189      CacheDirectory(size_t ways, size_t sets, size_t words, size_t address_width)
     190      {
     191          m_ways  = ways;
     192          m_sets  = sets;
     193          m_words = words;
     194          m_width = address_width;
     195          lfsr    = -1;
     196
     197          m_dir_tab = new DirectoryEntry*[sets];
     198          for (size_t i = 0; i < sets; i++) {
     199              m_dir_tab[i] = new DirectoryEntry[ways];
     200              for (size_t j = 0; j < ways; j++) {
     201                  m_dir_tab[i][j].init();
     202              }
     203          }
     204
     205          m_lru_tab = new LruEntry*[sets];
     206          for (size_t i = 0; i < sets; i++) {
     207              m_lru_tab[i] = new LruEntry[ways];
     208              for (size_t j = 0; j < ways; j++) {
     209                  m_lru_tab[i][j].init();
     210              }
     211          }
     212      } // end constructor
     213
     214      /////////////////
     215      // Destructor
     216      /////////////////
     217      ~CacheDirectory()
     218      {
     219          for (size_t i = 0; i < m_sets; i++) {
     220              delete [] m_dir_tab[i];
     221              delete [] m_lru_tab[i];
     222          }
     223          delete [] m_dir_tab;
     224          delete [] m_lru_tab;
     225      } // end destructor
     226
     227      /////////////////////////////////////////////////////////////////////
     228      // The read() function reads a directory entry. In case of hit, the
     229      // LRU is updated.
     230      // Arguments :
     231      // - address : the address of the entry
     232      // - way : (return argument) the way of the entry in case of hit
     233      // The function returns a copy of a (valid or invalid) entry
     234      /////////////////////////////////////////////////////////////////////
     235      DirectoryEntry read(const addr_t &address, size_t &way)
     236      {
     237
     238#define L2 soclib::common::uint32_log2
     239          const size_t set = (size_t) (address >> (L2(m_words) + 2)) & (m_sets - 1);
     240          const tag_t  tag = (tag_t) (address >> (L2(m_sets) + L2(m_words) + 2));
     241#undef L2
     242
     243          bool hit = false;
     244
     245          for (size_t i = 0; i < m_ways; i++) {
     246              bool equal = (m_dir_tab[set][i].tag == tag);
     247              bool valid = m_dir_tab[set][i].valid;
     248              hit = equal && valid;
     249              if (hit) {
     250                  way = i;
     251                  break;
     252              }
     253          }
     254          if (hit) {
     255              m_lru_tab[set][way].recent = true;
     256              return DirectoryEntry(m_dir_tab[set][way]);
     257          } else {
     258              return DirectoryEntry();
     259          }
     260      } // end read()
     261
     262      /////////////////////////////////////////////////////////////////////
     263      // The inval function invalidate an entry defined by the set and
     264      // way arguments.
     265      /////////////////////////////////////////////////////////////////////
     266      void inval( const size_t &way, const size_t &set )
     267      {
     268          m_dir_tab[set][way].init();
    61269      }
    62       // end constructors
    63 
    64   }; // end class Owner
    65 
    66 
    67   ////////////////////////////////////////////////////////////////////////
    68   //                    A directory entry
    69   ////////////////////////////////////////////////////////////////////////
    70   class DirectoryEntry {
    71 
    72     typedef uint32_t tag_t;
    73 
    74     public:
    75 
    76     bool    valid;                  // entry valid
    77     bool    cache_coherent;         // WB or WT policy
    78     bool    is_cnt;                 // directory entry is in counter mode
    79     bool    dirty;                  // entry dirty
    80     bool    lock;                   // entry locked
    81     tag_t   tag;                    // tag of the entry
    82     size_t  count;                  // number of copies
    83     Owner   owner;                  // an owner of the line
    84     size_t  ptr;                    // pointer to the next owner
    85 
    86     DirectoryEntry()
    87     {
    88       valid         = false;
    89       cache_coherent= false;
    90       is_cnt        = false;
    91       dirty         = false;
    92       lock          = false;
    93       tag           = 0;
    94       count         = 0;
    95       owner.inst    = 0;
    96       owner.srcid   = 0;
    97       ptr           = 0;
    98     }
    99 
    100     DirectoryEntry(const DirectoryEntry &source)
    101     {
    102       valid         = source.valid;
    103       cache_coherent= source.cache_coherent;
    104       is_cnt        = source.is_cnt;
    105       dirty         = source.dirty;
    106       lock          = source.lock;
    107       tag           = source.tag;
    108       count         = source.count;
    109       owner         = source.owner;
    110       ptr           = source.ptr;
    111     }
    112 
    113     /////////////////////////////////////////////////////////////////////
    114     // The init() function initializes the entry
    115     /////////////////////////////////////////////////////////////////////
    116     void init()
    117     {
    118       valid     = false;
    119       cache_coherent = false;
    120       is_cnt    = false;
    121       dirty     = false;
    122       lock      = false;
    123       count     = 0;
    124     }
    125 
    126     /////////////////////////////////////////////////////////////////////
    127     // The copy() function copies an existing source entry to a target
    128     /////////////////////////////////////////////////////////////////////
    129     void copy(const DirectoryEntry &source)
    130     {
    131       valid     = source.valid;
    132       cache_coherent = source.cache_coherent;
    133       is_cnt    = source.is_cnt;
    134       dirty     = source.dirty;
    135       lock      = source.lock;
    136       tag       = source.tag;
    137       count     = source.count;
    138       owner     = source.owner;
    139       ptr       = source.ptr;
    140     }
    141 
    142     ////////////////////////////////////////////////////////////////////
    143     // The print() function prints the entry
    144     ////////////////////////////////////////////////////////////////////
    145     void print()
    146     {
    147       std::cout << "Valid = " << valid
    148                 << " ; COHERENCE = " << cache_coherent
    149                 << " ; IS COUNT = " << is_cnt
    150                 << " ; Dirty = " << dirty
    151                 << " ; Lock = " << lock
    152                 << " ; Tag = " << std::hex << tag << std::dec
    153                 << " ; Count = " << count
    154                 << " ; Owner = " << owner.srcid
    155                 << " " << owner.inst
    156                 << " ; Pointer = " << ptr << std::endl;
    157     }
    158 
    159   }; // end class DirectoryEntry
    160 
    161   ////////////////////////////////////////////////////////////////////////
    162   //                       The directory
    163   ////////////////////////////////////////////////////////////////////////
    164   class CacheDirectory {
    165 
    166     typedef sc_dt::sc_uint<40> addr_t;
    167     typedef uint32_t data_t;
    168     typedef uint32_t tag_t;
    169 
    170     private:
    171 
    172     // Directory constants
    173     size_t   m_ways;
    174     size_t   m_sets;
    175     size_t   m_words;
    176     size_t   m_width;
    177     uint32_t lfsr;
    178 
    179     // the directory & lru tables
    180     DirectoryEntry **m_dir_tab;
    181     LruEntry       **m_lru_tab;
    182 
    183     public:
    184 
    185     ////////////////////////
    186     // Constructor
    187     ////////////////////////
    188     CacheDirectory( size_t ways, size_t sets, size_t words, size_t address_width)
    189     {
    190       m_ways  = ways;
    191       m_sets  = sets;
    192       m_words = words;
    193       m_width = address_width;
    194       lfsr = -1;
    195 
    196       m_dir_tab = new DirectoryEntry*[sets];
    197       for ( size_t i=0; i<sets; i++ ) {
    198         m_dir_tab[i] = new DirectoryEntry[ways];
    199         for ( size_t j=0 ; j<ways ; j++) m_dir_tab[i][j].init();
    200       }
    201       m_lru_tab = new LruEntry*[sets];
    202       for ( size_t i=0; i<sets; i++ ) {
    203         m_lru_tab[i] = new LruEntry[ways];
    204         for ( size_t j=0 ; j<ways ; j++) m_lru_tab[i][j].init();
    205       }
    206     } // end constructor
    207 
    208     /////////////////
    209     // Destructor
    210     /////////////////
    211     ~CacheDirectory()
    212     {
    213       for(size_t i=0 ; i<m_sets ; i++){
    214         delete [] m_dir_tab[i];
    215         delete [] m_lru_tab[i];
    216       }
    217       delete [] m_dir_tab;
    218       delete [] m_lru_tab;
    219     } // end destructor
    220 
    221     /////////////////////////////////////////////////////////////////////
    222     // The read() function reads a directory entry. In case of hit, the
    223     // LRU is updated.
    224     // Arguments :
    225     // - address : the address of the entry
    226     // - way : (return argument) the way of the entry in case of hit
    227     // The function returns a copy of a (valid or invalid) entry
    228     /////////////////////////////////////////////////////////////////////
    229     DirectoryEntry read(const addr_t &address, size_t &way)
    230     {
     270
     271      /////////////////////////////////////////////////////////////////////
     272      // The read_neutral() function reads a directory entry, without
     273      // changing the LRU
     274      // Arguments :
     275      // - address : the address of the entry
     276      // The function returns a copy of a (valid or invalid) entry
     277      /////////////////////////////////////////////////////////////////////
     278      DirectoryEntry read_neutral(const addr_t &address,
     279                                  size_t*      ret_way,
     280                                  size_t*      ret_set)
     281      {
    231282
    232283#define L2 soclib::common::uint32_log2
    233       const size_t set = (size_t)(address >> (L2(m_words) + 2)) & (m_sets - 1);
    234       const tag_t  tag = (tag_t)(address >> (L2(m_sets) + L2(m_words) + 2));
     284          size_t set = (size_t)(address >> (L2(m_words) + 2)) & (m_sets - 1);
     285          tag_t  tag = (tag_t)(address >> (L2(m_sets) + L2(m_words) + 2));
    235286#undef L2
    236287
    237       bool hit       = false;
    238       for ( size_t i=0 ; i<m_ways ; i++ ) {
    239         bool equal = ( m_dir_tab[set][i].tag == tag );
    240         bool valid = m_dir_tab[set][i].valid;
    241         hit = equal && valid;
    242         if ( hit ) {
    243           way = i;
    244           break;
    245         }
    246       }
    247       if ( hit ) {
    248         m_lru_tab[set][way].recent = true;
    249         return DirectoryEntry(m_dir_tab[set][way]);
    250       } else {
    251         return DirectoryEntry();
    252       }
    253     } // end read()
    254 
    255     /////////////////////////////////////////////////////////////////////
    256     // The inval function invalidate an entry defined by the set and
    257     // way arguments.
    258     /////////////////////////////////////////////////////////////////////
    259     void inval( const size_t &way, const size_t &set )
    260     {
    261         m_dir_tab[set][way].init();
    262     }
    263 
    264     /////////////////////////////////////////////////////////////////////
    265     // The read_neutral() function reads a directory entry, without
    266     // changing the LRU
    267     // Arguments :
    268     // - address : the address of the entry
    269     // The function returns a copy of a (valid or invalid) entry
    270     /////////////////////////////////////////////////////////////////////
    271     DirectoryEntry read_neutral( const addr_t &address,
    272                                  size_t*      ret_way,
    273                                  size_t*      ret_set )
    274     {
    275 
    276 #define L2 soclib::common::uint32_log2
    277         size_t set = (size_t)(address >> (L2(m_words) + 2)) & (m_sets - 1);
    278         tag_t  tag = (tag_t)(address >> (L2(m_sets) + L2(m_words) + 2));
    279 #undef L2
    280 
    281         for ( size_t way = 0 ; way < m_ways ; way++ )
    282         {
    283             bool equal = ( m_dir_tab[set][way].tag == tag );
    284             bool valid = m_dir_tab[set][way].valid;
    285             if ( equal and valid )
    286             {
    287                 *ret_set = set;
    288                 *ret_way = way;
    289                 return DirectoryEntry(m_dir_tab[set][way]);
    290             }
    291         }
    292         return DirectoryEntry();
    293     } // end read_neutral()
    294 
    295     /////////////////////////////////////////////////////////////////////
    296     // The write function writes a new entry,
    297     // and updates the LRU bits if necessary.
    298     // Arguments :
    299     // - set : the set of the entry
    300     // - way : the way of the entry
    301     // - entry : the entry value
    302     /////////////////////////////////////////////////////////////////////
    303     void write( const size_t         &set,
    304                 const size_t         &way,
    305                 const DirectoryEntry &entry)
    306     {
    307       assert( (set<m_sets)
    308           && "Cache Directory write : The set index is invalid");
    309       assert( (way<m_ways)
    310           && "Cache Directory write : The way index is invalid");
    311 
    312       // update Directory
    313       m_dir_tab[set][way].copy(entry);
    314 
    315       // update LRU bits
    316       bool all_recent = true;
    317       for ( size_t i=0 ; i<m_ways ; i++ )
    318       {
    319           if ( i != way ) all_recent = m_lru_tab[set][i].recent && all_recent;
    320       }
    321       if ( all_recent )
    322       {
    323           for( size_t i=0 ; i<m_ways ; i++ ) m_lru_tab[set][i].recent = false;
    324       }
    325       else
    326       {
    327           m_lru_tab[set][way].recent = true;
    328       }
    329     } // end write()
    330 
    331     /////////////////////////////////////////////////////////////////////
    332     // The print() function prints a selected directory entry
    333     // Arguments :
    334     // - set : the set of the entry to print
    335     // - way : the way of the entry to print
    336     /////////////////////////////////////////////////////////////////////
    337     void print(const size_t &set, const size_t &way)
    338     {
    339       std::cout << std::dec << " set : " << set << " ; way : " << way << " ; " ;
    340       m_dir_tab[set][way].print();
    341     } // end print()
    342 
    343     /////////////////////////////////////////////////////////////////////
    344     // The select() function selects a directory entry to evince.
    345     // Arguments :
    346     // - set   : (input argument) the set to modify
    347     // - way   : (return argument) the way to evince
    348     /////////////////////////////////////////////////////////////////////
    349     DirectoryEntry select(const size_t &set, size_t &way)
    350     {
    351         assert( (set < m_sets)
    352           && "Cache Directory : (select) The set index is invalid");
    353 
    354         // looking for an empty slot
    355         for(size_t i=0; i<m_ways; i++)
    356         {
    357             if( not m_dir_tab[set][i].valid )
    358             {
    359                 way=i;
    360                 return DirectoryEntry(m_dir_tab[set][way]);
    361             }
    362         }
     288          for (size_t way = 0; way < m_ways; way++)
     289          {
     290              bool equal = (m_dir_tab[set][way].tag == tag);
     291              bool valid = m_dir_tab[set][way].valid;
     292              if (equal and valid)
     293              {
     294                  *ret_set = set;
     295                  *ret_way = way;
     296                  return DirectoryEntry(m_dir_tab[set][way]);
     297              }
     298          }
     299          return DirectoryEntry();
     300      } // end read_neutral()
     301
     302      /////////////////////////////////////////////////////////////////////
     303      // The write function writes a new entry,
     304      // and updates the LRU bits if necessary.
     305      // Arguments :
     306      // - set : the set of the entry
     307      // - way : the way of the entry
     308      // - entry : the entry value
     309      /////////////////////////////////////////////////////////////////////
     310      void write(const size_t         &set,
     311                 const size_t         &way,
     312                 const DirectoryEntry &entry)
     313      {
     314          assert((set<m_sets)
     315                  && "Cache Directory write : The set index is invalid");
     316          assert((way<m_ways)
     317                  && "Cache Directory write : The way index is invalid");
     318
     319          // update Directory
     320          m_dir_tab[set][way].copy(entry);
     321
     322          // update LRU bits
     323          bool all_recent = true;
     324          for (size_t i = 0; i < m_ways; i++)
     325          {
     326              if (i != way)
     327              {
     328                  all_recent = m_lru_tab[set][i].recent && all_recent;
     329              }
     330          }
     331          if (all_recent)
     332          {
     333              for (size_t i = 0; i < m_ways; i++)
     334              {
     335                  m_lru_tab[set][i].recent = false;
     336              }
     337          }
     338          else
     339          {
     340              m_lru_tab[set][way].recent = true;
     341          }
     342      } // end write()
     343
     344      /////////////////////////////////////////////////////////////////////
     345      // The print() function prints a selected directory entry
     346      // Arguments :
     347      // - set : the set of the entry to print
     348      // - way : the way of the entry to print
     349      /////////////////////////////////////////////////////////////////////
     350      void print(const size_t &set, const size_t &way)
     351      {
     352          std::cout << std::dec << " set : " << set << " ; way : " << way << " ; ";
     353          m_dir_tab[set][way].print();
     354      } // end print()
     355
     356      /////////////////////////////////////////////////////////////////////
     357      // The select() function selects a directory entry to evince.
     358      // Arguments :
     359      // - set   : (input argument) the set to modify
     360      // - way   : (return argument) the way to evince
     361      /////////////////////////////////////////////////////////////////////
     362      DirectoryEntry select(const size_t &set, size_t &way)
     363      {
     364          assert((set < m_sets)
     365                  && "Cache Directory : (select) The set index is invalid");
     366
     367          // looking for an empty slot
     368          for (size_t i = 0; i < m_ways; i++)
     369          {
     370              if (not m_dir_tab[set][i].valid)
     371              {
     372                  way = i;
     373                  return DirectoryEntry(m_dir_tab[set][way]);
     374              }
     375          }
    363376
    364377#ifdef RANDOM_EVICTION
    365         lfsr = (lfsr >> 1) ^ ((-(lfsr & 1)) & 0xd0000001);
    366         way = lfsr % m_ways;
    367         return DirectoryEntry(m_dir_tab[set][way]);
     378          lfsr = (lfsr >> 1) ^ ((-(lfsr & 1)) & 0xd0000001);
     379          way = lfsr % m_ways;
     380          return DirectoryEntry(m_dir_tab[set][way]);
    368381#endif
    369382
    370         // looking for a not locked and not recently used entry
    371         for(size_t i=0; i<m_ways; i++)
    372         {
    373             if((not m_lru_tab[set][i].recent) && (not m_dir_tab[set][i].lock) )
    374             {
    375                 way=i;
    376                 return DirectoryEntry(m_dir_tab[set][way]);
    377             }
    378         }
    379 
    380         // looking for a locked not recently used entry
    381         for(size_t i=0; i<m_ways; i++)
    382         {
    383             if( (not m_lru_tab[set][i].recent) && (m_dir_tab[set][i].lock))
    384             {
    385                 way=i;
    386                 return DirectoryEntry(m_dir_tab[set][way]);
    387             }
    388         }
    389 
    390         // looking for a recently used entry not locked
    391         for(size_t i=0; i<m_ways; i++)
    392         {
    393             if( (m_lru_tab[set][i].recent) && (not m_dir_tab[set][i].lock))
    394             {
    395                 way=i;
    396                 return DirectoryEntry(m_dir_tab[set][way]);
    397             }
    398         }
    399 
    400         // select way 0 (even if entry is locked and recently used)
    401         way = 0;
    402         return DirectoryEntry(m_dir_tab[set][0]);
    403     } // end select()
    404 
    405     /////////////////////////////////////////////////////////////////////
    406     //               Global initialisation function
    407     /////////////////////////////////////////////////////////////////////
    408     void init()
    409     {
    410       for ( size_t set=0 ; set<m_sets ; set++ )
    411       {
    412         for ( size_t way=0 ; way<m_ways ; way++ )
    413         {
    414           m_dir_tab[set][way].init();
    415           m_lru_tab[set][way].init();
    416         }
    417       }
    418     } // end init()
     383          // looking for a not locked and not recently used entry
     384          for (size_t i = 0; i < m_ways; i++)
     385          {
     386              if ((not m_lru_tab[set][i].recent) and (not m_dir_tab[set][i].lock))
     387              {
     388                  way = i;
     389                  return DirectoryEntry(m_dir_tab[set][way]);
     390              }
     391          }
     392
     393          // looking for a locked not recently used entry
     394          for (size_t i = 0; i < m_ways; i++)
     395          {
     396              if ((not m_lru_tab[set][i].recent) and (m_dir_tab[set][i].lock))
     397              {
     398                  way = i;
     399                  return DirectoryEntry(m_dir_tab[set][way]);
     400              }
     401          }
     402
     403          // looking for a recently used entry not locked
     404          for (size_t i = 0; i < m_ways; i++)
     405          {
     406              if ((m_lru_tab[set][i].recent) and (not m_dir_tab[set][i].lock))
     407              {
     408                  way = i;
     409                  return DirectoryEntry(m_dir_tab[set][way]);
     410              }
     411          }
     412
     413          // select way 0 (even if entry is locked and recently used)
     414          way = 0;
     415          return DirectoryEntry(m_dir_tab[set][0]);
     416      } // end select()
     417
     418      /////////////////////////////////////////////////////////////////////
     419      //               Global initialisation function
     420      /////////////////////////////////////////////////////////////////////
     421      void init()
     422      {
     423          for (size_t set = 0; set < m_sets; set++)
     424          {
     425              for (size_t way = 0; way < m_ways; way++)
     426              {
     427                  m_dir_tab[set][way].init();
     428                  m_lru_tab[set][way].init();
     429              }
     430          }
     431      } // end init()
    419432
    420433  }; // end class CacheDirectory
     
    425438  class HeapEntry{
    426439
    427     public:
    428     // Fields of the entry
    429       Owner     owner;
    430       size_t    next;
    431 
    432     ////////////////////////
    433     // Constructor
    434     ////////////////////////
    435       HeapEntry()
    436       :owner(false,0)
    437       {
    438         next = 0;
    439       } // end constructor
    440 
    441     ////////////////////////
    442     // Constructor
    443     ////////////////////////
    444       HeapEntry(const HeapEntry &entry)
    445       {
    446         owner.inst  = entry.owner.inst;
    447         owner.srcid = entry.owner.srcid;
    448         next        = entry.next;
    449       } // end constructor
    450 
    451     /////////////////////////////////////////////////////////////////////
    452     // The copy() function copies an existing source entry to a target
    453     /////////////////////////////////////////////////////////////////////
    454       void copy(const HeapEntry &entry)
    455       {
    456         owner.inst  = entry.owner.inst;
    457         owner.srcid = entry.owner.srcid;
    458         next        = entry.next;
    459       } // end copy()
    460 
    461     ////////////////////////////////////////////////////////////////////
    462     // The print() function prints the entry
    463     ////////////////////////////////////////////////////////////////////
    464       void print(){
    465         std::cout
    466         << " -- owner.inst     : " << std::dec << owner.inst << std::endl
    467         << " -- owner.srcid    : " << std::dec << owner.srcid << std::endl
    468         << " -- next           : " << std::dec << next << std::endl;
    469 
    470       } // end print()
     440      public:
     441          // Fields of the entry
     442          Owner  owner;
     443          size_t next;
     444
     445          ////////////////////////
     446          // Constructor
     447          ////////////////////////
     448          HeapEntry()
     449              :owner(false, 0)
     450          {
     451              next = 0;
     452          } // end constructor
     453
     454          ////////////////////////
     455          // Constructor
     456          ////////////////////////
     457          HeapEntry(const HeapEntry &entry)
     458          {
     459              owner.inst  = entry.owner.inst;
     460              owner.srcid = entry.owner.srcid;
     461              next        = entry.next;
     462          } // end constructor
     463
     464          /////////////////////////////////////////////////////////////////////
     465          // The copy() function copies an existing source entry to a target
     466          /////////////////////////////////////////////////////////////////////
     467          void copy(const HeapEntry &entry)
     468          {
     469              owner.inst  = entry.owner.inst;
     470              owner.srcid = entry.owner.srcid;
     471              next        = entry.next;
     472          } // end copy()
     473
     474          ////////////////////////////////////////////////////////////////////
     475          // The print() function prints the entry
     476          ////////////////////////////////////////////////////////////////////
     477          void print()
     478          {
     479              std::cout
     480                  << " -- owner.inst     : " << std::dec << owner.inst << std::endl
     481                  << " -- owner.srcid    : " << std::dec << owner.srcid << std::endl
     482                  << " -- next           : " << std::dec << next << std::endl;
     483
     484          } // end print()
    471485
    472486  }; // end class HeapEntry
     
    477491  class HeapDirectory{
    478492
    479     private:
    480     // Registers and the heap
    481       size_t    ptr_free;
    482       bool      full;
    483       HeapEntry *m_heap_tab;
    484 
    485     // Constants for debugging purpose
    486       size_t    tab_size;
    487 
    488     public:
    489     ////////////////////////
    490     // Constructor
    491     ////////////////////////
    492       HeapDirectory(uint32_t size){
    493         assert(size>0 && "Memory Cache, HeapDirectory constructor : invalid size");
    494         ptr_free    = 0;
    495         full        = false;
    496         m_heap_tab  = new HeapEntry[size];
    497         tab_size    = size;
    498       } // end constructor
    499 
    500     /////////////////
    501     // Destructor
    502     /////////////////
    503       ~HeapDirectory(){
    504         delete [] m_heap_tab;
    505       } // end destructor
    506 
    507     /////////////////////////////////////////////////////////////////////
    508     //              Global initialisation function
    509     /////////////////////////////////////////////////////////////////////
    510       void init(){
    511         ptr_free=0;
    512         full=false;
    513         for(size_t i=0; i< tab_size-1;i++){
    514           m_heap_tab[i].next = i+1;
    515         }
    516         m_heap_tab[tab_size-1].next = tab_size-1;
    517         return;
    518       }
    519 
    520     /////////////////////////////////////////////////////////////////////
    521     // The print() function prints a selected directory entry
    522     // Arguments :
    523     // - ptr : the pointer to the entry to print
    524     /////////////////////////////////////////////////////////////////////
    525       void print(const size_t &ptr){
    526         std::cout << "Heap, printing the entry : " << std::dec << ptr << std::endl;
    527         m_heap_tab[ptr].print();
    528       } // end print()
    529 
    530     /////////////////////////////////////////////////////////////////////
    531     // The print_list() function prints a list from selected directory entry
    532     // Arguments :
    533     // - ptr : the pointer to the first entry to print
    534     /////////////////////////////////////////////////////////////////////
    535       void print_list(const size_t &ptr){
    536         bool end = false;
    537         size_t ptr_temp = ptr;
    538         std::cout << "Heap, printing the list from : " << std::dec << ptr << std::endl;
    539         while(!end){
    540             m_heap_tab[ptr_temp].print();
    541             if(ptr_temp == m_heap_tab[ptr_temp].next) end = true;
    542             ptr_temp = m_heap_tab[ptr_temp].next;
    543         }
    544       } // end print_list()
    545 
    546     /////////////////////////////////////////////////////////////////////
    547     // The is_full() function return true if the heap is full.
    548     /////////////////////////////////////////////////////////////////////
    549       bool is_full(){
    550         return full;
    551       } // end is_full()
    552 
    553     /////////////////////////////////////////////////////////////////////
    554     // The next_free_ptr() function returns the pointer
    555     // to the next free entry.
    556     /////////////////////////////////////////////////////////////////////
    557       size_t next_free_ptr(){
    558         return ptr_free;
    559       } // end next_free_ptr()
    560 
    561     /////////////////////////////////////////////////////////////////////
    562     // The next_free_entry() function returns
    563     // a copy of the next free entry.
    564     /////////////////////////////////////////////////////////////////////
    565       HeapEntry next_free_entry(){
    566         return HeapEntry(m_heap_tab[ptr_free]);
    567       } // end next_free_entry()
    568 
    569     /////////////////////////////////////////////////////////////////////
    570     // The write_free_entry() function modify the next free entry.
    571     // Arguments :
    572     // - entry : the entry to write
    573     /////////////////////////////////////////////////////////////////////
    574       void write_free_entry(const HeapEntry &entry){
    575         m_heap_tab[ptr_free].copy(entry);
    576       } // end write_free_entry()
    577 
    578     /////////////////////////////////////////////////////////////////////
    579     // The write_free_ptr() function writes the pointer
    580     // to the next free entry
    581     /////////////////////////////////////////////////////////////////////
    582       void write_free_ptr(const size_t &ptr){
    583         assert( (ptr<tab_size) && "HeapDirectory error : try to write a wrong free pointer");
    584         ptr_free = ptr;
    585       } // end write_free_ptr()
    586 
    587     /////////////////////////////////////////////////////////////////////
    588     // The set_full() function sets the full bit (to true).
    589     /////////////////////////////////////////////////////////////////////
    590       void set_full(){
    591         full = true;
    592       } // end set_full()
    593 
    594     /////////////////////////////////////////////////////////////////////
    595     // The unset_full() function unsets the full bit (to false).
    596     /////////////////////////////////////////////////////////////////////
    597       void unset_full(){
    598         full = false;
    599       } // end unset_full()
    600 
    601     /////////////////////////////////////////////////////////////////////
    602     // The read() function returns a copy of
    603     // the entry pointed by the argument
    604     // Arguments :
    605     //  - ptr : the pointer to the entry to read
    606     /////////////////////////////////////////////////////////////////////
    607       HeapEntry read(const size_t &ptr){
    608         assert( (ptr<tab_size) && "HeapDirectory error : try to write a wrong free pointer");
    609         return HeapEntry(m_heap_tab[ptr]);
    610       } // end read()
    611 
    612     /////////////////////////////////////////////////////////////////////
    613     // The write() function writes an entry in the heap
    614     // Arguments :
    615     //  - ptr : the pointer to the entry to replace
    616     //  - entry : the entry to write
    617     /////////////////////////////////////////////////////////////////////
    618       void write(const size_t &ptr, const HeapEntry &entry){
    619         assert( (ptr<tab_size) && "HeapDirectory error : try to write a wrong free pointer");
    620         m_heap_tab[ptr].copy(entry);
    621       } // end write()
     493      private:
     494          // Registers and the heap
     495          size_t    ptr_free;
     496          bool      full;
     497          HeapEntry *m_heap_tab;
     498
     499          // Constants for debugging purpose
     500          size_t    tab_size;
     501
     502      public:
     503          ////////////////////////
     504          // Constructor
     505          ////////////////////////
     506          HeapDirectory(uint32_t size)
     507          {
     508              assert(size > 0 && "Memory Cache, HeapDirectory constructor : invalid size");
     509              ptr_free    = 0;
     510              full        = false;
     511              m_heap_tab  = new HeapEntry[size];
     512              tab_size    = size;
     513          } // end constructor
     514
     515          /////////////////
     516          // Destructor
     517          /////////////////
     518          ~HeapDirectory()
     519          {
     520              delete [] m_heap_tab;
     521          } // end destructor
     522
     523          /////////////////////////////////////////////////////////////////////
     524          //              Global initialisation function
     525          /////////////////////////////////////////////////////////////////////
     526          void init()
     527          {
     528              ptr_free = 0;
     529              full = false;
     530              for (size_t i = 0; i < tab_size - 1; i++) {
     531                  m_heap_tab[i].next = i + 1;
     532              }
     533              m_heap_tab[tab_size - 1].next = tab_size - 1;
     534              return;
     535          }
     536
     537          /////////////////////////////////////////////////////////////////////
     538          // The print() function prints a selected directory entry
     539          // Arguments :
     540          // - ptr : the pointer to the entry to print
     541          /////////////////////////////////////////////////////////////////////
     542          void print(const size_t &ptr)
     543          {
     544              std::cout << "Heap, printing the entry : " << std::dec << ptr << std::endl;
     545              m_heap_tab[ptr].print();
     546          } // end print()
     547
     548          /////////////////////////////////////////////////////////////////////
     549          // The print_list() function prints a list from selected directory entry
     550          // Arguments :
     551          // - ptr : the pointer to the first entry to print
     552          /////////////////////////////////////////////////////////////////////
     553          void print_list(const size_t &ptr)
     554          {
     555              bool end = false;
     556              size_t ptr_temp = ptr;
     557              std::cout << "Heap, printing the list from : " << std::dec << ptr << std::endl;
     558              while (!end) {
     559                  m_heap_tab[ptr_temp].print();
     560                  if (ptr_temp == m_heap_tab[ptr_temp].next) {
     561                      end = true;
     562                  }
     563                  ptr_temp = m_heap_tab[ptr_temp].next;
     564              }
     565          } // end print_list()
     566
     567          /////////////////////////////////////////////////////////////////////
     568          // The is_full() function return true if the heap is full.
     569          /////////////////////////////////////////////////////////////////////
     570          bool is_full()
     571          {
     572              return full;
     573          } // end is_full()
     574
     575          /////////////////////////////////////////////////////////////////////
     576          // The next_free_ptr() function returns the pointer
     577          // to the next free entry.
     578          /////////////////////////////////////////////////////////////////////
     579          size_t next_free_ptr()
     580          {
     581              return ptr_free;
     582          } // end next_free_ptr()
     583
     584          /////////////////////////////////////////////////////////////////////
     585          // The next_free_entry() function returns
     586          // a copy of the next free entry.
     587          /////////////////////////////////////////////////////////////////////
     588          HeapEntry next_free_entry()
     589          {
     590              return HeapEntry(m_heap_tab[ptr_free]);
     591          } // end next_free_entry()
     592
     593          /////////////////////////////////////////////////////////////////////
     594          // The write_free_entry() function modify the next free entry.
     595          // Arguments :
     596          // - entry : the entry to write
     597          /////////////////////////////////////////////////////////////////////
     598          void write_free_entry(const HeapEntry &entry)
     599          {
     600              m_heap_tab[ptr_free].copy(entry);
     601          } // end write_free_entry()
     602
     603          /////////////////////////////////////////////////////////////////////
     604          // The write_free_ptr() function writes the pointer
     605          // to the next free entry
     606          /////////////////////////////////////////////////////////////////////
     607          void write_free_ptr(const size_t &ptr)
     608          {
     609              assert((ptr < tab_size) && "HeapDirectory error : try to write a wrong free pointer");
     610              ptr_free = ptr;
     611          } // end write_free_ptr()
     612
     613          /////////////////////////////////////////////////////////////////////
     614          // The set_full() function sets the full bit (to true).
     615          /////////////////////////////////////////////////////////////////////
     616          void set_full()
     617          {
     618              full = true;
     619          } // end set_full()
     620
     621          /////////////////////////////////////////////////////////////////////
     622          // The unset_full() function unsets the full bit (to false).
     623          /////////////////////////////////////////////////////////////////////
     624          void unset_full()
     625          {
     626              full = false;
     627          } // end unset_full()
     628
     629          /////////////////////////////////////////////////////////////////////
     630          // The read() function returns a copy of
     631          // the entry pointed by the argument
     632          // Arguments :
     633          //  - ptr : the pointer to the entry to read
     634          /////////////////////////////////////////////////////////////////////
     635          HeapEntry read(const size_t &ptr)
     636          {
     637              assert((ptr < tab_size) && "HeapDirectory error : try to write a wrong free pointer");
     638              return HeapEntry(m_heap_tab[ptr]);
     639          } // end read()
     640
     641          /////////////////////////////////////////////////////////////////////
     642          // The write() function writes an entry in the heap
     643          // Arguments :
     644          //  - ptr : the pointer to the entry to replace
     645          //  - entry : the entry to write
     646          /////////////////////////////////////////////////////////////////////
     647          void write(const size_t &ptr, const HeapEntry &entry)
     648          {
     649              assert((ptr < tab_size) && "HeapDirectory error : try to write a wrong free pointer");
     650              m_heap_tab[ptr].copy(entry);
     651          } // end write()
    622652
    623653  }; // end class HeapDirectory
     
    628658  class CacheData
    629659  {
    630     private:
    631       const uint32_t m_sets;
    632       const uint32_t m_ways;
    633       const uint32_t m_words;
    634 
    635       uint32_t *** m_cache_data;
    636 
    637     public:
    638 
    639       ///////////////////////////////////////////////////////
    640       CacheData(uint32_t ways, uint32_t sets, uint32_t words)
    641         : m_sets(sets), m_ways(ways), m_words(words)
    642       {
    643           m_cache_data = new uint32_t ** [ways];
    644           for ( size_t i=0 ; i < ways ; i++ )
    645           {
    646               m_cache_data[i] = new uint32_t * [sets];
    647           }
    648           for ( size_t i=0; i<ways; i++ )
    649           {
    650               for ( size_t j=0; j<sets; j++ )
    651               {
    652                   m_cache_data[i][j] = new uint32_t [words];
    653               }
    654           }
    655       }
    656       ////////////
    657       ~CacheData()
    658       {
    659           for(size_t i=0; i<m_ways ; i++)
    660           {
    661               for(size_t j=0; j<m_sets ; j++)
    662               {
    663                   delete [] m_cache_data[i][j];
    664               }
    665           }
    666           for(size_t i=0; i<m_ways ; i++)
    667           {
    668               delete [] m_cache_data[i];
    669           }
    670           delete [] m_cache_data;
    671       }
    672       //////////////////////////////////////////
    673       uint32_t read ( const uint32_t &way,
    674                       const uint32_t &set,
    675                       const uint32_t &word) const
    676       {
    677           assert((set  < m_sets ) && "Cache data error: Trying to read a wrong set" );
    678           assert((way  < m_ways ) && "Cache data error: Trying to read a wrong way" );
    679           assert((word < m_words) && "Cache data error: Trying to read a wrong word");
    680 
    681           return m_cache_data[way][set][word];
    682       }
    683       //////////////////////////////////////////
    684       void read_line( const uint32_t &way,
    685                       const uint32_t &set,
    686                       sc_core::sc_signal<uint32_t> * cache_line)
    687       {
    688           assert((set < m_sets ) && "Cache data error: Trying to read a wrong set" );
    689           assert((way < m_ways ) && "Cache data error: Trying to read a wrong way" );
    690 
    691           for (uint32_t word=0; word<m_words; word++)
    692               cache_line[word].write(m_cache_data[way][set][word]);
    693       }
    694       /////////////////////////////////////////
    695       void write ( const uint32_t &way,
    696                    const uint32_t &set,
    697                    const uint32_t &word,
    698                    const uint32_t &data,
    699                    const uint32_t &be = 0xF)
    700       {
    701 
    702           assert((set  < m_sets ) && "Cache data error: Trying to write a wrong set" );
    703           assert((way  < m_ways ) && "Cache data error: Trying to write a wrong way" );
    704           assert((word < m_words) && "Cache data error: Trying to write a wrong word");
    705           assert((be  <= 0xF    ) && "Cache data error: Trying to write a wrong be");
    706 
    707           if (be == 0x0) return;
    708 
    709           if (be == 0xF)
    710           {
    711               m_cache_data[way][set][word] = data;
    712               return;
    713           }
    714 
    715           uint32_t mask = 0;
    716           if (be & 0x1) mask = mask | 0x000000FF;
    717           if (be & 0x2) mask = mask | 0x0000FF00;
    718           if (be & 0x4) mask = mask | 0x00FF0000;
    719           if (be & 0x8) mask = mask | 0xFF000000;
    720 
    721           m_cache_data[way][set][word] =
    722               (data & mask) | (m_cache_data[way][set][word] & ~mask);
    723       }
     660      private:
     661          const uint32_t m_sets;
     662          const uint32_t m_ways;
     663          const uint32_t m_words;
     664
     665          uint32_t *** m_cache_data;
     666
     667      public:
     668
     669          ///////////////////////////////////////////////////////
     670          CacheData(uint32_t ways, uint32_t sets, uint32_t words)
     671              : m_sets(sets), m_ways(ways), m_words(words)
     672          {
     673              m_cache_data = new uint32_t ** [ways];
     674              for (size_t i = 0; i < ways; i++)
     675              {
     676                  m_cache_data[i] = new uint32_t * [sets];
     677              }
     678              for (size_t i = 0; i < ways; i++)
     679              {
     680                  for (size_t j = 0; j < sets; j++)
     681                  {
     682                      m_cache_data[i][j] = new uint32_t [words];
     683                  }
     684              }
     685          }
     686          ////////////
     687          ~CacheData()
     688          {
     689              for (size_t i = 0; i < m_ways; i++)
     690              {
     691                  for (size_t j = 0; j < m_sets; j++)
     692                  {
     693                      delete [] m_cache_data[i][j];
     694                  }
     695              }
     696              for (size_t i = 0; i < m_ways; i++)
     697              {
     698                  delete [] m_cache_data[i];
     699              }
     700              delete [] m_cache_data;
     701          }
     702          //////////////////////////////////////////
     703          uint32_t read(const uint32_t &way,
     704                        const uint32_t &set,
     705                        const uint32_t &word) const
     706          {
     707              assert((set  < m_sets ) && "Cache data error: Trying to read a wrong set");
     708              assert((way  < m_ways ) && "Cache data error: Trying to read a wrong way");
     709              assert((word < m_words) && "Cache data error: Trying to read a wrong word");
     710
     711              return m_cache_data[way][set][word];
     712          }
     713          //////////////////////////////////////////
     714          void read_line(const uint32_t &way,
     715                         const uint32_t &set,
     716                         sc_core::sc_signal<uint32_t> * cache_line)
     717          {
     718              assert((set < m_sets) && "Cache data error: Trying to read a wrong set");
     719              assert((way < m_ways) && "Cache data error: Trying to read a wrong way");
     720
     721              for (uint32_t word = 0; word < m_words; word++) {
     722                  cache_line[word].write(m_cache_data[way][set][word]);
     723              }
     724          }
     725          /////////////////////////////////////////
     726          void write(const uint32_t &way,
     727                     const uint32_t &set,
     728                     const uint32_t &word,
     729                     const uint32_t &data,
     730                     const uint32_t &be = 0xF)
     731          {
     732              assert((set  < m_sets ) && "Cache data error: Trying to write a wrong set");
     733              assert((way  < m_ways ) && "Cache data error: Trying to write a wrong way");
     734              assert((word < m_words) && "Cache data error: Trying to write a wrong word");
     735              assert((be  <= 0xF    ) && "Cache data error: Trying to write a wrong be");
     736
     737              if (be == 0x0) return;
     738
     739              if (be == 0xF)
     740              {
     741                  m_cache_data[way][set][word] = data;
     742                  return;
     743              }
     744
     745              uint32_t mask = 0;
     746              if (be & 0x1) mask = mask | 0x000000FF;
     747              if (be & 0x2) mask = mask | 0x0000FF00;
     748              if (be & 0x4) mask = mask | 0x00FF0000;
     749              if (be & 0x8) mask = mask | 0xFF000000;
     750
     751              m_cache_data[way][set][word] =
     752                  (data & mask) | (m_cache_data[way][set][word] & ~mask);
     753          }
    724754  }; // end class CacheData
    725755
Note: See TracChangeset for help on using the changeset viewer.