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

RWT Commit : Cosmetic

Location:
branches/RWT/modules/vci_mem_cache/caba/source/include
Files:
4 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
  • branches/RWT/modules/vci_mem_cache/caba/source/include/update_tab.h

    r814 r823  
    1212class UpdateTabEntry {
    1313
    14   typedef uint32_t size_t;
    15   typedef sc_dt::sc_uint<40> addr_t;
    16 
    17   public:
    18 
    19   bool   valid;   // It is a valid pending transaction
    20   bool   update;  // It is an update transaction
    21   bool   brdcast; // It is a broadcast invalidate
    22   bool   rsp;     // Response to the initiator required
    23   bool   ack;     // Acknowledge to the CONFIG FSM required
    24   size_t srcid;   // The srcid of the initiator which wrote the data
    25   size_t trdid;   // The trdid of the initiator which wrote the data
    26   size_t pktid;   // The pktid of the initiator which wrote the data
    27   addr_t nline;   // The identifier of the cache line
    28   size_t count;   // The number of acknowledge responses to receive
    29 
    30   UpdateTabEntry()
    31   {
    32     valid   = false;
    33     update  = false;
    34     brdcast = false;
    35     rsp     = false;
    36     ack     = false;
    37     srcid   = 0;
    38     trdid   = 0;
    39     pktid   = 0;
    40     nline   = 0;
    41     count   = 0;
    42   }
    43 
    44   UpdateTabEntry(bool   i_valid,
    45                  bool   i_update,
    46                  bool   i_brdcast,
    47                  bool   i_rsp,
    48                  bool   i_ack,
    49                  size_t i_srcid,
    50                  size_t i_trdid,
    51                  size_t i_pktid,
    52                  addr_t i_nline,
    53                  size_t i_count)
    54   {
    55     valid   = i_valid;
    56     update  = i_update;
    57     brdcast = i_brdcast;
    58     rsp     = i_rsp;
    59     ack     = i_ack;
    60     srcid   = i_srcid;
    61     trdid   = i_trdid;
    62     pktid   = i_pktid;
    63     nline   = i_nline;
    64     count   = i_count;
    65   }
    66 
    67   UpdateTabEntry(const UpdateTabEntry &source)
    68   {
    69     valid   = source.valid;
    70     update  = source.update;
    71     brdcast = source.brdcast;
    72     rsp     = source.rsp;
    73     ack     = source.ack;
    74     srcid   = source.srcid;
    75     trdid   = source.trdid;
    76     pktid   = source.pktid;
    77     nline   = source.nline;
    78     count   = source.count;
    79   }
    80 
    81   ////////////////////////////////////////////////////
    82   // The init() function initializes the entry
    83   ///////////////////////////////////////////////////
    84   void init()
    85   {
    86     valid   = false;
    87     update  = false;
    88     brdcast = false;
    89     rsp     = false;
    90     ack     = false;
    91     srcid   = 0;
    92     trdid   = 0;
    93     pktid   = 0;
    94     nline   = 0;
    95     count   = 0;
    96   }
    97 
    98   ////////////////////////////////////////////////////////////////////
    99   // The copy() function copies an existing entry
    100   // Its arguments are :
    101   // - source : the update tab entry to copy
    102   ////////////////////////////////////////////////////////////////////
    103   void copy(const UpdateTabEntry &source)
    104   {
    105     valid  = source.valid;
    106     update = source.update;
    107     brdcast= source.brdcast;
    108     rsp    = source.rsp;
    109     ack    = source.ack  ;
    110     srcid  = source.srcid;
    111     trdid  = source.trdid;
    112     pktid  = source.pktid;
    113     nline  = source.nline;
    114     count  = source.count;
    115   }
    116 
    117   ////////////////////////////////////////////////////////////////////
    118   // The print() function prints the entry
    119   ////////////////////////////////////////////////////////////////////
    120   void print()
    121   {
    122     std::cout << " val = " << std::dec << valid
    123               << " / updt = " << update
    124               << " / bc = " << brdcast
    125               << " / rsp = " << rsp
    126               << " / ack = " << ack
    127               << " / count = " << count
    128               << " / srcid = " << std::hex << srcid
    129               << " / trdid = " << trdid
    130               << " / pktid = " << pktid
    131               << " / nline = " << nline << std::endl;
    132   }
     14    typedef uint32_t size_t;
     15    typedef sc_dt::sc_uint<40> addr_t;
     16
     17    public:
     18
     19    bool   valid;   // It is a valid pending transaction
     20    bool   update;  // It is an update transaction
     21    bool   brdcast; // It is a broadcast invalidate
     22    bool   rsp;     // Response to the initiator required
     23    bool   ack;     // Acknowledge to the CONFIG FSM required
     24    size_t srcid;   // The srcid of the initiator which wrote the data
     25    size_t trdid;   // The trdid of the initiator which wrote the data
     26    size_t pktid;   // The pktid of the initiator which wrote the data
     27    addr_t nline;   // The identifier of the cache line
     28    size_t count;   // The number of acknowledge responses to receive
     29
     30    UpdateTabEntry()
     31    {
     32        valid   = false;
     33        update  = false;
     34        brdcast = false;
     35        rsp     = false;
     36        ack     = false;
     37        srcid   = 0;
     38        trdid   = 0;
     39        pktid   = 0;
     40        nline   = 0;
     41        count   = 0;
     42    }
     43
     44    UpdateTabEntry(bool   i_valid,
     45                   bool   i_update,
     46                   bool   i_brdcast,
     47                   bool   i_rsp,
     48                   bool   i_ack,
     49                   size_t i_srcid,
     50                   size_t i_trdid,
     51                   size_t i_pktid,
     52                   addr_t i_nline,
     53                   size_t i_count)
     54    {
     55        valid   = i_valid;
     56        update  = i_update;
     57        brdcast = i_brdcast;
     58        rsp     = i_rsp;
     59        ack     = i_ack;
     60        srcid   = i_srcid;
     61        trdid   = i_trdid;
     62        pktid   = i_pktid;
     63        nline   = i_nline;
     64        count   = i_count;
     65    }
     66
     67    UpdateTabEntry(const UpdateTabEntry &source)
     68    {
     69        valid   = source.valid;
     70        update  = source.update;
     71        brdcast = source.brdcast;
     72        rsp     = source.rsp;
     73        ack     = source.ack;
     74        srcid   = source.srcid;
     75        trdid   = source.trdid;
     76        pktid   = source.pktid;
     77        nline   = source.nline;
     78        count   = source.count;
     79    }
     80
     81    ////////////////////////////////////////////////////
     82    // The init() function initializes the entry
     83    ///////////////////////////////////////////////////
     84    void init()
     85    {
     86        valid   = false;
     87        update  = false;
     88        brdcast = false;
     89        rsp     = false;
     90        ack     = false;
     91        srcid   = 0;
     92        trdid   = 0;
     93        pktid   = 0;
     94        nline   = 0;
     95        count   = 0;
     96    }
     97
     98    ////////////////////////////////////////////////////////////////////
     99    // The copy() function copies an existing entry
     100    // Its arguments are :
     101    // - source : the update tab entry to copy
     102    ////////////////////////////////////////////////////////////////////
     103    void copy(const UpdateTabEntry &source)
     104    {
     105        valid   = source.valid;
     106        update = source.update;
     107        brdcast = source.brdcast;
     108        rsp     = source.rsp;
     109        ack     = source.ack;
     110        srcid   = source.srcid;
     111        trdid   = source.trdid;
     112        pktid   = source.pktid;
     113        nline   = source.nline;
     114        count   = source.count;
     115    }
     116
     117    ////////////////////////////////////////////////////////////////////
     118    // The print() function prints the entry
     119    ////////////////////////////////////////////////////////////////////
     120    void print()
     121    {
     122        std::cout << " val = " << std::dec << valid
     123                  << " / updt = " << update
     124                  << " / bc = " << brdcast
     125                  << " / rsp = " << rsp
     126                  << " / ack = " << ack
     127                  << " / count = " << count
     128                  << " / srcid = " << std::hex << srcid
     129                  << " / trdid = " << trdid
     130                  << " / pktid = " << pktid
     131                  << " / nline = " << nline << std::endl;
     132    }
    133133};
    134134
     
    138138class UpdateTab{
    139139
    140   typedef uint64_t addr_t;
    141 
    142   private:
    143   size_t                      size_tab;
    144   std::vector<UpdateTabEntry> tab;
    145 
    146   public:
    147 
    148   UpdateTab()
    149     : tab(0)
    150   {
    151     size_tab=0;
    152   }
    153 
    154   UpdateTab(size_t size_tab_i)
    155     : tab(size_tab_i)
    156   {
    157     size_tab=size_tab_i;
    158   }
    159 
    160   ////////////////////////////////////////////////////////////////////
    161   // The size() function returns the size of the tab
    162   ////////////////////////////////////////////////////////////////////
    163   const size_t size()
    164   {
    165     return size_tab;
    166   }
    167 
    168   ////////////////////////////////////////////////////////////////////
    169   // The print() function diplays the tab content
    170   ////////////////////////////////////////////////////////////////////
    171   void print()
    172   {
    173     std::cout << "UPDATE TABLE Content" << std::endl;
    174     for(size_t i=0; i<size_tab; i++)
    175     {
    176       std::cout << "[" << std::dec << i << "] ";
    177       tab[i].print();
    178     }
    179     return;
    180   }
    181 
    182   /////////////////////////////////////////////////////////////////////
    183   // The init() function initializes the tab
    184   /////////////////////////////////////////////////////////////////////
    185   void init()
    186   {
    187     for ( size_t i=0; i<size_tab; i++) tab[i].init();
    188   }
    189 
    190   /////////////////////////////////////////////////////////////////////
    191   // The reads() function reads an entry
    192   // Arguments :
    193   // - entry : the entry to read
    194   // This function returns a copy of the entry.
    195   /////////////////////////////////////////////////////////////////////
    196   UpdateTabEntry read (size_t entry)
    197   {
    198     assert(entry<size_tab && "Bad Update Tab Entry");
    199     return UpdateTabEntry(tab[entry]);
    200   }
    201 
    202   ///////////////////////////////////////////////////////////////////////////
    203   // The set() function writes an entry in the Update Table
    204   // Arguments :
    205   // - update : transaction type (bool)
    206   // - srcid : srcid of the initiator
    207   // - trdid : trdid of the initiator
    208   // - pktid : pktid of the initiator
    209   // - count : number of expected responses
    210   // - index : (return argument) index of the selected entry
    211   // This function returns true if the write successed (an entry was empty).
    212   ///////////////////////////////////////////////////////////////////////////
    213   bool set(const bool   update,
    214            const bool   brdcast,
    215            const bool   rsp,
    216            const bool   ack,
    217            const size_t srcid,
    218            const size_t trdid,
    219            const size_t pktid,
    220            const addr_t nline,
    221            const size_t count,
    222            size_t       &index)
    223   {
    224     for ( size_t i=0 ; i<size_tab ; i++ )
    225     {
    226       if( !tab[i].valid )
    227       {
    228         tab[i].valid   = true;
    229         tab[i].update  = update;
    230         tab[i].brdcast = brdcast;
    231         tab[i].rsp     = rsp;
    232         tab[i].ack     = ack;
    233         tab[i].srcid   = (size_t) srcid;
    234         tab[i].trdid   = (size_t) trdid;
    235         tab[i].pktid   = (size_t) pktid;
    236         tab[i].nline   = (addr_t) nline;
    237         tab[i].count   = (size_t) count;
    238         index          = i;
     140    typedef uint64_t addr_t;
     141
     142    private:
     143    size_t size_tab;
     144    std::vector<UpdateTabEntry> tab;
     145
     146    public:
     147
     148    UpdateTab()
     149        : tab(0)
     150    {
     151        size_tab = 0;
     152    }
     153
     154    UpdateTab(size_t size_tab_i)
     155        : tab(size_tab_i)
     156    {
     157        size_tab = size_tab_i;
     158    }
     159
     160    ////////////////////////////////////////////////////////////////////
     161    // The size() function returns the size of the tab
     162    ////////////////////////////////////////////////////////////////////
     163    const size_t size()
     164    {
     165        return size_tab;
     166    }
     167
     168    ////////////////////////////////////////////////////////////////////
     169    // The print() function diplays the tab content
     170    ////////////////////////////////////////////////////////////////////
     171    void print()
     172    {
     173        std::cout << "UPDATE TABLE Content" << std::endl;
     174        for (size_t i = 0; i < size_tab; i++)
     175        {
     176            std::cout << "[" << std::dec << i << "] ";
     177            tab[i].print();
     178        }
     179        return;
     180    }
     181
     182    /////////////////////////////////////////////////////////////////////
     183    // The init() function initializes the tab
     184    /////////////////////////////////////////////////////////////////////
     185    void init()
     186    {
     187        for (size_t i = 0; i < size_tab; i++)
     188        {
     189            tab[i].init();
     190        }
     191    }
     192
     193    /////////////////////////////////////////////////////////////////////
     194    // The reads() function reads an entry
     195    // Arguments :
     196    // - entry : the entry to read
     197    // This function returns a copy of the entry.
     198    /////////////////////////////////////////////////////////////////////
     199    UpdateTabEntry read(size_t entry)
     200    {
     201        assert(entry < size_tab && "Bad Update Tab Entry");
     202        return UpdateTabEntry(tab[entry]);
     203    }
     204
     205    ///////////////////////////////////////////////////////////////////////////
     206    // The set() function writes an entry in the Update Table
     207    // Arguments :
     208    // - update : transaction type (bool)
     209    // - srcid : srcid of the initiator
     210    // - trdid : trdid of the initiator
     211    // - pktid : pktid of the initiator
     212    // - count : number of expected responses
     213    // - index : (return argument) index of the selected entry
     214    // This function returns true if the write successed (an entry was empty).
     215    ///////////////////////////////////////////////////////////////////////////
     216    bool set(const bool   update,
     217             const bool   brdcast,
     218             const bool   rsp,
     219             const bool   ack,
     220             const size_t srcid,
     221             const size_t trdid,
     222             const size_t pktid,
     223             const addr_t nline,
     224             const size_t count,
     225             size_t       &index)
     226    {
     227        for (size_t i = 0; i < size_tab; i++)
     228        {
     229            if (!tab[i].valid)
     230            {
     231                tab[i].valid   = true;
     232                tab[i].update  = update;
     233                tab[i].brdcast = brdcast;
     234                tab[i].rsp     = rsp;
     235                tab[i].ack     = ack;
     236                tab[i].srcid   = (size_t) srcid;
     237                tab[i].trdid   = (size_t) trdid;
     238                tab[i].pktid   = (size_t) pktid;
     239                tab[i].nline   = (addr_t) nline;
     240                tab[i].count   = (size_t) count;
     241                index          = i;
     242                return true;
     243            }
     244        }
     245        return false;
     246    } // end set()
     247
     248    /////////////////////////////////////////////////////////////////////
     249    // The decrement() function decrements the counter for a given entry.
     250    // Arguments :
     251    // - index   : the index of the entry
     252    // - counter : (return argument) value of the counter after decrement
     253    // This function returns true if the entry is valid.
     254    /////////////////////////////////////////////////////////////////////
     255    bool decrement(const size_t index,
     256                   size_t       &counter)
     257    {
     258        assert((index < size_tab) && "Bad Update Tab Entry");
     259        if (tab[index].valid)
     260        {
     261            tab[index].count--;
     262            counter = tab[index].count;
     263            return true;
     264        }
     265        else
     266        {
     267            return false;
     268        }
     269    }
     270
     271    /////////////////////////////////////////////////////////////////////
     272    // The is_full() function returns true if the table is full
     273    /////////////////////////////////////////////////////////////////////
     274    bool is_full()
     275    {
     276        for (size_t i = 0; i < size_tab; i++)
     277        {
     278            if (!tab[i].valid)
     279            {
     280                return false;
     281            }
     282        }
    239283        return true;
    240       }
    241     }
    242     return false;
    243   } // end set()
    244 
    245   /////////////////////////////////////////////////////////////////////
    246   // The decrement() function decrements the counter for a given entry.
    247   // Arguments :
    248   // - index   : the index of the entry
    249   // - counter : (return argument) value of the counter after decrement
    250   // This function returns true if the entry is valid.
    251   /////////////////////////////////////////////////////////////////////
    252   bool decrement( const size_t index,
    253                   size_t &counter )
    254   {
    255     assert((index<size_tab) && "Bad Update Tab Entry");
    256     if ( tab[index].valid )
    257     {
    258       tab[index].count--;
    259       counter = tab[index].count;
    260       return true;
    261     }
    262     else
    263     {
    264       return false;
    265     }
    266   }
    267 
    268   /////////////////////////////////////////////////////////////////////
    269   // The is_full() function returns true if the table is full
    270   /////////////////////////////////////////////////////////////////////
    271   bool is_full()
    272   {
    273     for(size_t i = 0 ; i < size_tab ; i++)
    274     {
    275       if(!tab[i].valid) return false;
    276     }
    277     return true;
    278   }
    279 
    280   /////////////////////////////////////////////////////////////////////
    281   // The is_not_empty() function returns true if the table is not empty
    282   /////////////////////////////////////////////////////////////////////
    283   bool is_not_empty()
    284   {
    285     for(size_t i = 0 ; i < size_tab ; i++)
    286     {
    287       if(tab[i].valid) return true;
    288     }
    289     return false;
    290   }
    291 
    292   /////////////////////////////////////////////////////////////////////
    293   // The need_rsp() function returns the need of a response
    294   // Arguments :
    295   // - index : the index of the entry
    296   /////////////////////////////////////////////////////////////////////
    297   bool need_rsp(const size_t index)
    298   {
    299     assert(index<size_tab && "Bad Update Tab Entry");
    300     return tab[index].rsp;
    301   }
    302 
    303   /////////////////////////////////////////////////////////////////////
    304   // The need_ack() function returns the need of an acknowledge
    305   // Arguments :
    306   // - index : the index of the entry
    307   /////////////////////////////////////////////////////////////////////
    308   bool need_ack(const size_t index)
    309   {
    310     assert(index<size_tab && "Bad Update Tab Entry");
    311     return tab[index].ack;
    312   }
    313 
    314   /////////////////////////////////////////////////////////////////////
    315   // The is_brdcast() function returns the transaction type
    316   // Arguments :
    317   // - index : the index of the entry
    318   /////////////////////////////////////////////////////////////////////
    319   bool is_brdcast(const size_t index)
    320   {
    321     assert(index<size_tab && "Bad Update Tab Entry");
    322     return tab[index].brdcast;
    323   }
    324 
    325   /////////////////////////////////////////////////////////////////////
    326   // The is_update() function returns the transaction type
    327   // Arguments :
    328   // - index : the index of the entry
    329   /////////////////////////////////////////////////////////////////////
    330   bool is_update(const size_t index)
    331   {
    332     assert(index<size_tab && "Bad Update Tab Entry");
    333     return tab[index].update;
    334   }
    335 
    336   /////////////////////////////////////////////////////////////////////
    337   // The srcid() function returns the srcid value
    338   // Arguments :
    339   // - index : the index of the entry
    340   /////////////////////////////////////////////////////////////////////
    341   size_t srcid(const size_t index)
    342   {
    343     assert(index<size_tab && "Bad Update Tab Entry");
    344     return tab[index].srcid;
    345   }
    346 
    347   /////////////////////////////////////////////////////////////////////
    348   // The trdid() function returns the trdid value
    349   // Arguments :
    350   // - index : the index of the entry
    351   /////////////////////////////////////////////////////////////////////
    352   size_t trdid(const size_t index)
    353   {
    354     assert(index<size_tab && "Bad Update Tab Entry");
    355     return tab[index].trdid;
    356   }
    357 
    358   /////////////////////////////////////////////////////////////////////
    359   // The pktid() function returns the pktid value
    360   // Arguments :
    361   // - index : the index of the entry
    362   /////////////////////////////////////////////////////////////////////
    363   size_t pktid(const size_t index)
    364   {
    365     assert(index<size_tab && "Bad Update Tab Entry");
    366     return tab[index].pktid;
    367   }
    368 
    369   /////////////////////////////////////////////////////////////////////
    370   // The nline() function returns the nline value
    371   // Arguments :
    372   // - index : the index of the entry
    373   /////////////////////////////////////////////////////////////////////
    374   addr_t nline(const size_t index)
    375   {
    376     assert(index<size_tab && "Bad Update Tab Entry");
    377     return tab[index].nline;
    378   }
    379 
    380   /////////////////////////////////////////////////////////////////////
    381   // The search_inval() function returns the index of the entry in UPT
    382   // Arguments :
    383   // - nline : the line number of the entry in the directory
    384   /////////////////////////////////////////////////////////////////////
    385   bool search_inval(const addr_t nline,size_t &index)
    386   {
    387     size_t i ;
    388 
    389     for (i = 0 ; i < size_tab ; i++)
    390     {
    391       if ( (tab[i].nline == nline) and tab[i].valid and not tab[i].update )
    392       {
    393         index = i ;
    394         return true;
    395       }
    396     }
    397     return false;
    398   }
    399 
    400   /////////////////////////////////////////////////////////////////////
    401   // The read_nline() function returns the index of the entry in UPT
    402   // Arguments :
    403   // - nline : the line number of the entry in the directory
    404   /////////////////////////////////////////////////////////////////////
    405   bool read_nline(const addr_t nline,size_t &index)
    406   {
    407     size_t i ;
    408 
    409     for (i = 0 ; i < size_tab ; i++)
    410     {
    411       if ( (tab[i].nline == nline) and tab[i].valid )
    412       {
    413         index = i ;
    414         return true;
    415       }
    416     }
    417     return false;
    418   }
    419 
    420   /////////////////////////////////////////////////////////////////////
    421   // The clear() function erases an entry of the tab
    422   // Arguments :
    423   // - index : the index of the entry
    424   /////////////////////////////////////////////////////////////////////
    425   void clear(const size_t index)
    426   {
    427     assert(index<size_tab && "Bad Update Tab Entry");
    428     tab[index].valid=false;
    429     return;
    430   }
     284    }
     285
     286    /////////////////////////////////////////////////////////////////////
     287    // The is_not_empty() function returns true if the table is not empty
     288    /////////////////////////////////////////////////////////////////////
     289    bool is_not_empty()
     290    {
     291        for (size_t i = 0; i < size_tab; i++)
     292        {
     293            if (tab[i].valid)
     294            {
     295                return true;
     296            }
     297        }
     298        return false;
     299    }
     300
     301    /////////////////////////////////////////////////////////////////////
     302    // The need_rsp() function returns the need of a response
     303    // Arguments :
     304    // - index : the index of the entry
     305    /////////////////////////////////////////////////////////////////////
     306    bool need_rsp(const size_t index)
     307    {
     308        assert(index < size_tab && "Bad Update Tab Entry");
     309        return tab[index].rsp;
     310    }
     311
     312    /////////////////////////////////////////////////////////////////////
     313    // The need_ack() function returns the need of an acknowledge
     314    // Arguments :
     315    // - index : the index of the entry
     316    /////////////////////////////////////////////////////////////////////
     317    bool need_ack(const size_t index)
     318    {
     319        assert(index < size_tab && "Bad Update Tab Entry");
     320        return tab[index].ack;
     321    }
     322
     323    /////////////////////////////////////////////////////////////////////
     324    // The is_brdcast() function returns the transaction type
     325    // Arguments :
     326    // - index : the index of the entry
     327    /////////////////////////////////////////////////////////////////////
     328    bool is_brdcast(const size_t index)
     329    {
     330        assert(index < size_tab && "Bad Update Tab Entry");
     331        return tab[index].brdcast;
     332    }
     333
     334    /////////////////////////////////////////////////////////////////////
     335    // The is_update() function returns the transaction type
     336    // Arguments :
     337    // - index : the index of the entry
     338    /////////////////////////////////////////////////////////////////////
     339    bool is_update(const size_t index)
     340    {
     341        assert(index < size_tab && "Bad Update Tab Entry");
     342        return tab[index].update;
     343    }
     344
     345    /////////////////////////////////////////////////////////////////////
     346    // The srcid() function returns the srcid value
     347    // Arguments :
     348    // - index : the index of the entry
     349    /////////////////////////////////////////////////////////////////////
     350    size_t srcid(const size_t index)
     351    {
     352        assert(index < size_tab && "Bad Update Tab Entry");
     353        return tab[index].srcid;
     354    }
     355
     356    /////////////////////////////////////////////////////////////////////
     357    // The trdid() function returns the trdid value
     358    // Arguments :
     359    // - index : the index of the entry
     360    /////////////////////////////////////////////////////////////////////
     361    size_t trdid(const size_t index)
     362    {
     363        assert(index < size_tab && "Bad Update Tab Entry");
     364        return tab[index].trdid;
     365    }
     366
     367    /////////////////////////////////////////////////////////////////////
     368    // The pktid() function returns the pktid value
     369    // Arguments :
     370    // - index : the index of the entry
     371    /////////////////////////////////////////////////////////////////////
     372    size_t pktid(const size_t index)
     373    {
     374        assert(index < size_tab && "Bad Update Tab Entry");
     375        return tab[index].pktid;
     376    }
     377
     378    /////////////////////////////////////////////////////////////////////
     379    // The nline() function returns the nline value
     380    // Arguments :
     381    // - index : the index of the entry
     382    /////////////////////////////////////////////////////////////////////
     383    addr_t nline(const size_t index)
     384    {
     385        assert(index < size_tab && "Bad Update Tab Entry");
     386        return tab[index].nline;
     387    }
     388
     389    /////////////////////////////////////////////////////////////////////
     390    // The search_inval() function returns the index of the entry in UPT
     391    // Arguments :
     392    // - nline : the line number of the entry in the directory
     393    /////////////////////////////////////////////////////////////////////
     394    bool search_inval(const addr_t nline, size_t &index)
     395    {
     396        size_t i;
     397
     398        for (i = 0; i < size_tab; i++)
     399        {
     400            if ((tab[i].nline == nline) and tab[i].valid and not tab[i].update)
     401            {
     402                index = i;
     403                return true;
     404            }
     405        }
     406        return false;
     407    }
     408
     409    /////////////////////////////////////////////////////////////////////
     410    // The read_nline() function returns the index of the entry in UPT
     411    // Arguments :
     412    // - nline : the line number of the entry in the directory
     413    /////////////////////////////////////////////////////////////////////
     414    bool read_nline(const addr_t nline, size_t &index)
     415    {
     416        size_t i;
     417
     418        for (i = 0; i < size_tab; i++)
     419        {
     420            if ((tab[i].nline == nline) and tab[i].valid)
     421            {
     422                index = i;
     423                return true;
     424            }
     425        }
     426        return false;
     427    }
     428
     429    /////////////////////////////////////////////////////////////////////
     430    // The clear() function erases an entry of the tab
     431    // Arguments :
     432    // - index : the index of the entry
     433    /////////////////////////////////////////////////////////////////////
     434    void clear(const size_t index)
     435    {
     436        assert(index < size_tab && "Bad Update Tab Entry");
     437        tab[index].valid = false;
     438        return;
     439    }
    431440
    432441};
  • branches/RWT/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h

    r814 r823  
    6969    : public soclib::caba::BaseModule
    7070    {
    71       typedef typename vci_param_int::fast_addr_t  addr_t;
    72       typedef typename sc_dt::sc_uint<64>          wide_data_t;
    73       typedef uint32_t                             data_t;
    74       typedef uint32_t                             tag_t;
    75       typedef uint32_t                             be_t;
    76       typedef uint32_t                             copy_t;
     71      typedef typename vci_param_int::fast_addr_t addr_t;
     72      typedef typename sc_dt::sc_uint<64>         wide_data_t;
     73      typedef uint32_t                            data_t;
     74      typedef uint32_t                            tag_t;
     75      typedef uint32_t                            be_t;
     76      typedef uint32_t                            copy_t;
    7777
    7878      /* States of the TGT_CMD fsm */
     
    113113        CC_RECEIVE_IDLE,
    114114        CC_RECEIVE_CLEANUP,
    115         CC_RECEIVE_CLEANUP_EOP,
    116115        CC_RECEIVE_MULTI_ACK
    117116      };
     
    232231      {
    233232        IXR_RSP_IDLE,
    234         IXR_RSP_ACK,
    235233        IXR_RSP_TRT_ERASE,
    236234        IXR_RSP_TRT_READ
     
    399397          //  b1 accÚs table llsc type SW / other
    400398          //  b2 WRITE/CAS/LL/SC
    401           TYPE_READ_DATA_UNC   = 0x0,
    402           TYPE_READ_DATA_MISS  = 0x1,
    403           TYPE_READ_INS_UNC    = 0x2,
    404           TYPE_READ_INS_MISS   = 0x3,
    405           TYPE_WRITE           = 0x4,
    406           TYPE_CAS             = 0x5,
    407           TYPE_LL              = 0x6,
    408           TYPE_SC              = 0x7
     399          TYPE_READ_DATA_UNC  = 0x0,
     400          TYPE_READ_DATA_MISS = 0x1,
     401          TYPE_READ_INS_UNC   = 0x2,
     402          TYPE_READ_INS_MISS  = 0x3,
     403          TYPE_WRITE          = 0x4,
     404          TYPE_CAS            = 0x5,
     405          TYPE_LL             = 0x6,
     406          TYPE_SC             = 0x7
    409407      };
    410408
     
    425423
    426424      // instrumentation counters
    427       uint32_t m_cpt_cycles;        // Counter of cycles
     425      uint32_t m_cpt_cycles;                  // Counter of cycles
    428426
    429427      // Counters accessible in software (not yet but eventually) and tagged
    430       uint32_t m_cpt_reset_count;    // Last cycle at which counters have been reset
    431       uint32_t m_cpt_read_local;     // Number of local READ transactions
    432       uint32_t m_cpt_read_remote;    // number of remote READ transactions
    433       uint32_t m_cpt_read_cost;      // Number of (flits * distance) for READs
    434 
    435       uint32_t m_cpt_write_local;    // Number of local WRITE transactions
    436       uint32_t m_cpt_write_remote;   // number of remote WRITE transactions
    437       uint32_t m_cpt_write_flits_local;  // number of flits for local WRITEs
    438       uint32_t m_cpt_write_flits_remote; // number of flits for remote WRITEs
    439       uint32_t m_cpt_write_cost;     // Number of (flits * distance) for WRITEs
    440       uint32_t m_cpt_write_ncc_miss;   // Number of write on ncc line
    441 
    442       uint32_t m_cpt_ll_local;       // Number of local LL transactions
    443       uint32_t m_cpt_ll_remote;      // number of remote LL transactions
    444       uint32_t m_cpt_ll_cost;        // Number of (flits * distance) for LLs
    445 
    446       uint32_t m_cpt_sc_local;       // Number of local SC transactions
    447       uint32_t m_cpt_sc_remote;      // number of remote SC transactions
    448       uint32_t m_cpt_sc_cost;        // Number of (flits * distance) for SCs
    449 
    450       uint32_t m_cpt_cas_local;      // Number of local SC transactions
    451       uint32_t m_cpt_cas_remote;     // number of remote SC transactions
    452       uint32_t m_cpt_cas_cost;       // Number of (flits * distance) for SCs
    453 
    454       uint32_t m_cpt_update;         // Number of requests causing an UPDATE
    455       uint32_t m_cpt_update_local;   // Number of local UPDATE transactions
    456       uint32_t m_cpt_update_remote;  // Number of remote UPDATE transactions
    457       uint32_t m_cpt_update_cost;    // Number of (flits * distance) for UPDT
    458 
    459       uint32_t m_cpt_minval;         // Number of requests causing M_INV
    460       uint32_t m_cpt_minval_local;   // Number of local M_INV transactions
    461       uint32_t m_cpt_minval_remote;  // Number of remote M_INV transactions
    462       uint32_t m_cpt_minval_cost;    // Number of (flits * distance) for M_INV
    463 
    464       uint32_t m_cpt_binval;         // Number of BROADCAST INVAL
    465 
    466       uint32_t m_cpt_cleanup_local;  // Number of local CLEANUP transactions (all cleanup types)
    467       uint32_t m_cpt_cleanup_remote; // Number of remote CLEANUP transactions (all cleanup types)
    468       uint32_t m_cpt_cleanup_cost;   // Number of (flits * distance) for CLEANUPs (all types)
     428      uint32_t m_cpt_reset_count;             // Last cycle at which counters have been reset
     429      uint32_t m_cpt_read_local;              // Number of local READ transactions
     430      uint32_t m_cpt_read_remote;             // number of remote READ transactions
     431      uint32_t m_cpt_read_cost;               // Number of (flits * distance) for READs
     432
     433      uint32_t m_cpt_write_local;             // Number of local WRITE transactions
     434      uint32_t m_cpt_write_remote;            // number of remote WRITE transactions
     435      uint32_t m_cpt_write_flits_local;       // number of flits for local WRITEs
     436      uint32_t m_cpt_write_flits_remote;      // number of flits for remote WRITEs
     437      uint32_t m_cpt_write_cost;              // Number of (flits * distance) for WRITEs
     438      uint32_t m_cpt_write_ncc_miss;          // Number of write on ncc line
     439
     440      uint32_t m_cpt_ll_local;                // Number of local LL transactions
     441      uint32_t m_cpt_ll_remote;               // number of remote LL transactions
     442      uint32_t m_cpt_ll_cost;                 // Number of (flits * distance) for LLs
     443
     444      uint32_t m_cpt_sc_local;                // Number of local SC transactions
     445      uint32_t m_cpt_sc_remote;               // number of remote SC transactions
     446      uint32_t m_cpt_sc_cost;                 // Number of (flits * distance) for SCs
     447
     448      uint32_t m_cpt_cas_local;               // Number of local SC transactions
     449      uint32_t m_cpt_cas_remote;              // number of remote SC transactions
     450      uint32_t m_cpt_cas_cost;                // Number of (flits * distance) for SCs
     451
     452      uint32_t m_cpt_update;                  // Number of requests causing an UPDATE
     453      uint32_t m_cpt_update_local;            // Number of local UPDATE transactions
     454      uint32_t m_cpt_update_remote;           // Number of remote UPDATE transactions
     455      uint32_t m_cpt_update_cost;             // Number of (flits * distance) for UPDT
     456
     457      uint32_t m_cpt_minval;                  // Number of requests causing M_INV
     458      uint32_t m_cpt_minval_local;            // Number of local M_INV transactions
     459      uint32_t m_cpt_minval_remote;           // Number of remote M_INV transactions
     460      uint32_t m_cpt_minval_cost;             // Number of (flits * distance) for M_INV
     461
     462      uint32_t m_cpt_binval;                  // Number of BROADCAST INVAL
     463
     464      uint32_t m_cpt_cleanup_local;           // Number of local CLEANUP transactions (all cleanup types)
     465      uint32_t m_cpt_cleanup_remote;          // Number of remote CLEANUP transactions (all cleanup types)
     466      uint32_t m_cpt_cleanup_cost;            // Number of (flits * distance) for CLEANUPs (all types)
    469467
    470468      // Counters not accessible by software, but tagged
    471       uint32_t m_cpt_read_miss;       // Number of MISS READ
    472       uint32_t m_cpt_write_miss;      // Number of MISS WRITE
    473       uint32_t m_cpt_write_dirty;     // Cumulated length for WRITE transactions
    474       uint32_t m_cpt_write_broadcast; // Number of BROADCAST INVAL because write
    475 
    476       uint32_t m_cpt_trt_rb;          // Read blocked by a hit in trt
    477       uint32_t m_cpt_trt_full;        // Transaction blocked due to a full trt
     469      uint32_t m_cpt_read_miss;               // Number of MISS READ
     470      uint32_t m_cpt_write_miss;              // Number of MISS WRITE
     471      uint32_t m_cpt_write_dirty;             // Cumulated length for WRITE transactions
     472      uint32_t m_cpt_write_broadcast;         // Number of BROADCAST INVAL because write
     473
     474      uint32_t m_cpt_trt_rb;                  // Read blocked by a hit in trt
     475      uint32_t m_cpt_trt_full;                // Transaction blocked due to a full trt
    478476
    479477      uint32_t m_cpt_heap_unused;             // NB cycles HEAP LOCK unused
     
    481479      uint32_t m_cpt_heap_min_slot_available; // NB HEAP : Min of slot available
    482480
    483       uint32_t m_cpt_ncc_to_cc_read;         // NB change from NCC to CC caused by a READ
    484       uint32_t m_cpt_ncc_to_cc_write;        // NB change from NCC to CC caused by a WRITE
    485 
    486       uint32_t m_cpt_cleanup_data_local;  // Number of local cleanups with data
    487       uint32_t m_cpt_cleanup_data_remote; // Number of remote cleanups with data
    488       uint32_t m_cpt_cleanup_data_cost;   // Cost for cleanups with data
    489 
    490       uint32_t m_cpt_update_flits;  // Number of flits for UPDATEs
    491       uint32_t m_cpt_inval_cost;    // Number of (flits * distance) for INVALs
     481      uint32_t m_cpt_ncc_to_cc_read;          // NB change from NCC to CC caused by a READ
     482      uint32_t m_cpt_ncc_to_cc_write;         // NB change from NCC to CC caused by a WRITE
     483
     484      uint32_t m_cpt_cleanup_data_local;      // Number of local cleanups with data
     485      uint32_t m_cpt_cleanup_data_remote;     // Number of remote cleanups with data
     486      uint32_t m_cpt_cleanup_data_cost;       // Cost for cleanups with data
     487
     488      uint32_t m_cpt_update_flits;            // Number of flits for UPDATEs
     489      uint32_t m_cpt_inval_cost;              // Number of (flits * distance) for INVALs
    492490
    493491      uint32_t m_cpt_get;
     
    499497      uint32_t m_cpt_upt_unused; // NB cycles UPT LOCK unused
    500498
    501       // Unused
    502       uint32_t m_cpt_read_data_unc;
    503       uint32_t m_cpt_read_data_miss_CC;
    504       uint32_t m_cpt_read_ins_unc;
    505       uint32_t m_cpt_read_ins_miss;
    506       uint32_t m_cpt_read_ll_CC;
    507       uint32_t m_cpt_read_data_miss_NCC;
    508       uint32_t m_cpt_read_ll_NCC;
    509 
    510499      size_t   m_prev_count;
    511500
     
    515504
    516505      public:
    517       sc_in<bool>                                 p_clk;
    518       sc_in<bool>                                 p_resetn;
    519       sc_out<bool>                                p_irq;
    520       soclib::caba::VciTarget<vci_param_int>      p_vci_tgt;
    521       soclib::caba::VciInitiator<vci_param_ext>   p_vci_ixr;
    522       soclib::caba::DspinInput<dspin_in_width>    p_dspin_p2m;
    523       soclib::caba::DspinOutput<dspin_out_width>  p_dspin_m2p;
    524       soclib::caba::DspinOutput<dspin_out_width>  p_dspin_clack;
     506      sc_in<bool>                                p_clk;
     507      sc_in<bool>                                p_resetn;
     508      sc_out<bool>                               p_irq;
     509      soclib::caba::VciTarget<vci_param_int>     p_vci_tgt;
     510      soclib::caba::VciInitiator<vci_param_ext>  p_vci_ixr;
     511      soclib::caba::DspinInput<dspin_in_width>   p_dspin_p2m;
     512      soclib::caba::DspinOutput<dspin_out_width> p_dspin_m2p;
     513      soclib::caba::DspinOutput<dspin_out_width> p_dspin_clack;
    525514
    526515#if MONITOR_MEMCACHE_FSM == 1
     
    557546          const size_t                       nwords,          // Number of words per line
    558547          const size_t                       max_copies,      // max number of copies
    559           const size_t                       heap_size=HEAP_ENTRIES,
    560           const size_t                       trt_lines=TRT_ENTRIES,
    561           const size_t                       upt_lines=UPT_ENTRIES,
    562           const size_t                       ivt_lines=IVT_ENTRIES,
    563           const size_t                       debug_start_cycle=0,
    564           const bool                         debug_ok=false );
     548          const size_t                       heap_size = HEAP_ENTRIES,
     549          const size_t                       trt_lines = TRT_ENTRIES,
     550          const size_t                       upt_lines = UPT_ENTRIES,
     551          const size_t                       ivt_lines = IVT_ENTRIES,
     552          const size_t                       debug_start_cycle = 0,
     553          const bool                         debug_ok = false );
    565554
    566555      ~VciMemCache();
     
    568557      void reset_counters();
    569558      void print_stats(bool activity_counters = true, bool stats = false);
    570       void print_trace( size_t detailled = 0 );
     559      void print_trace(size_t detailled = 0);
    571560      void cache_monitor(addr_t addr);
    572561      void start_monitor(addr_t addr, addr_t length);
     
    581570      uint32_t min_value(uint32_t old_value, uint32_t new_value);
    582571      bool is_local_req(uint32_t req_srcid);
    583       int  read_instrumentation(uint32_t regr, uint32_t & rdata);
     572      int read_instrumentation(uint32_t regr, uint32_t & rdata);
    584573
    585574      // Component attributes
     
    616605
    617606      // adress masks
    618       const soclib::common::AddressMaskingTable<addr_t>   m_x;
    619       const soclib::common::AddressMaskingTable<addr_t>   m_y;
    620       const soclib::common::AddressMaskingTable<addr_t>   m_z;
    621       const soclib::common::AddressMaskingTable<addr_t>   m_nline;
     607      const soclib::common::AddressMaskingTable<addr_t> m_x;
     608      const soclib::common::AddressMaskingTable<addr_t> m_y;
     609      const soclib::common::AddressMaskingTable<addr_t> m_z;
     610      const soclib::common::AddressMaskingTable<addr_t> m_nline;
    622611
    623612      // broadcast address
    624       uint32_t                           m_broadcast_boundaries;
     613      uint32_t m_broadcast_boundaries;
    625614
    626615      // configuration interface constants
     
    632621
    633622      // Fifo between TGT_CMD fsm and READ fsm
    634       GenericFifo<addr_t>    m_cmd_read_addr_fifo;
    635       GenericFifo<size_t>    m_cmd_read_length_fifo;
    636       GenericFifo<size_t>    m_cmd_read_srcid_fifo;
    637       GenericFifo<size_t>    m_cmd_read_trdid_fifo;
    638       GenericFifo<size_t>    m_cmd_read_pktid_fifo;
     623      GenericFifo<addr_t> m_cmd_read_addr_fifo;
     624      GenericFifo<size_t> m_cmd_read_length_fifo;
     625      GenericFifo<size_t> m_cmd_read_srcid_fifo;
     626      GenericFifo<size_t> m_cmd_read_trdid_fifo;
     627      GenericFifo<size_t> m_cmd_read_pktid_fifo;
    639628
    640629      // Fifo between TGT_CMD fsm and WRITE fsm
    641       GenericFifo<addr_t>    m_cmd_write_addr_fifo;
    642       GenericFifo<bool>      m_cmd_write_eop_fifo;
    643       GenericFifo<size_t>    m_cmd_write_srcid_fifo;
    644       GenericFifo<size_t>    m_cmd_write_trdid_fifo;
    645       GenericFifo<size_t>    m_cmd_write_pktid_fifo;
    646       GenericFifo<data_t>    m_cmd_write_data_fifo;
    647       GenericFifo<be_t>      m_cmd_write_be_fifo;
     630      GenericFifo<addr_t> m_cmd_write_addr_fifo;
     631      GenericFifo<bool>   m_cmd_write_eop_fifo;
     632      GenericFifo<size_t> m_cmd_write_srcid_fifo;
     633      GenericFifo<size_t> m_cmd_write_trdid_fifo;
     634      GenericFifo<size_t> m_cmd_write_pktid_fifo;
     635      GenericFifo<data_t> m_cmd_write_data_fifo;
     636      GenericFifo<be_t>   m_cmd_write_be_fifo;
    648637
    649638      // Fifo between TGT_CMD fsm and CAS fsm
    650       GenericFifo<addr_t>    m_cmd_cas_addr_fifo;
    651       GenericFifo<bool>      m_cmd_cas_eop_fifo;
    652       GenericFifo<size_t>    m_cmd_cas_srcid_fifo;
    653       GenericFifo<size_t>    m_cmd_cas_trdid_fifo;
    654       GenericFifo<size_t>    m_cmd_cas_pktid_fifo;
    655       GenericFifo<data_t>    m_cmd_cas_wdata_fifo;
     639      GenericFifo<addr_t> m_cmd_cas_addr_fifo;
     640      GenericFifo<bool>   m_cmd_cas_eop_fifo;
     641      GenericFifo<size_t> m_cmd_cas_srcid_fifo;
     642      GenericFifo<size_t> m_cmd_cas_trdid_fifo;
     643      GenericFifo<size_t> m_cmd_cas_pktid_fifo;
     644      GenericFifo<data_t> m_cmd_cas_wdata_fifo;
    656645
    657646      // Fifo between CC_RECEIVE fsm and CLEANUP fsm
    658       GenericFifo<uint64_t>  m_cc_receive_to_cleanup_fifo;
     647      GenericFifo<uint64_t> m_cc_receive_to_cleanup_fifo;
    659648
    660649      // Fifo between CC_RECEIVE fsm and MULTI_ACK fsm
    661       GenericFifo<uint64_t>  m_cc_receive_to_multi_ack_fifo;
     650      GenericFifo<uint64_t> m_cc_receive_to_multi_ack_fifo;
    662651
    663652      // Buffer between TGT_CMD fsm and TGT_RSP fsm
     
    678667      //////////////////////////////////////////////////
    679668
    680       sc_signal<int>         r_tgt_cmd_fsm;
     669      sc_signal<int> r_tgt_cmd_fsm;
    681670
    682671      ///////////////////////////////////////////////////////
     
    684673      ///////////////////////////////////////////////////////
    685674
    686       sc_signal<int>      r_config_fsm;               // FSM state
    687       sc_signal<bool>     r_config_lock;              // lock protecting exclusive access
    688       sc_signal<int>      r_config_cmd;               // config request type
    689       sc_signal<addr_t>   r_config_address;           // target buffer physical address
    690       sc_signal<size_t>   r_config_srcid;             // config request srcid
    691       sc_signal<size_t>   r_config_trdid;             // config request trdid
    692       sc_signal<size_t>   r_config_pktid;             // config request pktid
    693       sc_signal<size_t>   r_config_cmd_lines;         // number of lines to be handled
    694       sc_signal<size_t>   r_config_rsp_lines;         // number of lines not completed
    695       sc_signal<size_t>   r_config_dir_way;           // DIR: selected way
    696       sc_signal<bool>     r_config_dir_lock;          // DIR: locked entry
    697       sc_signal<size_t>   r_config_dir_count;         // DIR: number of copies
    698       sc_signal<bool>     r_config_dir_is_cnt;        // DIR: counter mode (broadcast)
    699       sc_signal<size_t>   r_config_dir_copy_srcid;    // DIR: first copy SRCID
    700       sc_signal<bool>     r_config_dir_copy_inst;     // DIR: first copy L1 type
    701       sc_signal<size_t>   r_config_dir_ptr;           // DIR: index of next copy in HEAP
    702       sc_signal<size_t>   r_config_heap_next;         // current pointer to scan HEAP
    703       sc_signal<size_t>   r_config_trt_index;         // selected entry in TRT
    704       sc_signal<size_t>   r_config_ivt_index;         // selected entry in IVT
     675      sc_signal<int>    r_config_fsm;            // FSM state
     676      sc_signal<bool>   r_config_lock;           // lock protecting exclusive access
     677      sc_signal<int>    r_config_cmd;            // config request type
     678      sc_signal<addr_t> r_config_address;        // target buffer physical address
     679      sc_signal<size_t> r_config_srcid;          // config request srcid
     680      sc_signal<size_t> r_config_trdid;          // config request trdid
     681      sc_signal<size_t> r_config_pktid;          // config request pktid
     682      sc_signal<size_t> r_config_cmd_lines;      // number of lines to be handled
     683      sc_signal<size_t> r_config_rsp_lines;      // number of lines not completed
     684      sc_signal<size_t> r_config_dir_way;        // DIR: selected way
     685      sc_signal<bool>   r_config_dir_lock;       // DIR: locked entry
     686      sc_signal<size_t> r_config_dir_count;      // DIR: number of copies
     687      sc_signal<bool>   r_config_dir_is_cnt;     // DIR: counter mode (broadcast)
     688      sc_signal<size_t> r_config_dir_copy_srcid; // DIR: first copy SRCID
     689      sc_signal<bool>   r_config_dir_copy_inst;  // DIR: first copy L1 type
     690      sc_signal<size_t> r_config_dir_ptr;        // DIR: index of next copy in HEAP
     691      sc_signal<size_t> r_config_heap_next;      // current pointer to scan HEAP
     692      sc_signal<size_t> r_config_trt_index;      // selected entry in TRT
     693      sc_signal<size_t> r_config_ivt_index;      // selected entry in IVT
    705694
    706695      // Buffer between CONFIG fsm and IXR_CMD fsm
    707       sc_signal<bool>     r_config_to_ixr_cmd_req;    // valid request
    708       sc_signal<size_t>   r_config_to_ixr_cmd_index; // TRT index
     696      sc_signal<bool>   r_config_to_ixr_cmd_req;   // valid request
     697      sc_signal<size_t> r_config_to_ixr_cmd_index; // TRT index
    709698
    710699      // Buffer between CONFIG fsm and TGT_RSP fsm (send a done response to L1 cache)
    711       sc_signal<bool>     r_config_to_tgt_rsp_req;    // valid request
    712       sc_signal<bool>     r_config_to_tgt_rsp_error; // error response
    713       sc_signal<size_t>   r_config_to_tgt_rsp_srcid; // Transaction srcid
    714       sc_signal<size_t>   r_config_to_tgt_rsp_trdid; // Transaction trdid
    715       sc_signal<size_t>   r_config_to_tgt_rsp_pktid; // Transaction pktid
     700      sc_signal<bool>   r_config_to_tgt_rsp_req;   // valid request
     701      sc_signal<bool>   r_config_to_tgt_rsp_error; // error response
     702      sc_signal<size_t> r_config_to_tgt_rsp_srcid; // Transaction srcid
     703      sc_signal<size_t> r_config_to_tgt_rsp_trdid; // Transaction trdid
     704      sc_signal<size_t> r_config_to_tgt_rsp_pktid; // Transaction pktid
    716705
    717706      // Buffer between CONFIG fsm and CC_SEND fsm (multi-inval / broadcast-inval)
    718       sc_signal<bool>     r_config_to_cc_send_multi_req;    // multi-inval request
    719       sc_signal<bool>     r_config_to_cc_send_brdcast_req;  // broadcast-inval request
    720       sc_signal<addr_t>   r_config_to_cc_send_nline;        // line index
    721       sc_signal<size_t>   r_config_to_cc_send_trdid;        // UPT index
    722       GenericFifo<bool>   m_config_to_cc_send_inst_fifo;    // fifo for the L1 type
    723       GenericFifo<size_t> m_config_to_cc_send_srcid_fifo;   // fifo for owners srcid
     707      sc_signal<bool>     r_config_to_cc_send_multi_req;   // multi-inval request
     708      sc_signal<bool>     r_config_to_cc_send_brdcast_req; // broadcast-inval request
     709      sc_signal<addr_t>   r_config_to_cc_send_nline;       // line index
     710      sc_signal<size_t>   r_config_to_cc_send_trdid;       // UPT index
     711      GenericFifo<bool>   m_config_to_cc_send_inst_fifo;   // fifo for the L1 type
     712      GenericFifo<size_t> m_config_to_cc_send_srcid_fifo;  // fifo for owners srcid
    724713
    725714      ///////////////////////////////////////////////////////
     
    727716      ///////////////////////////////////////////////////////
    728717
    729       sc_signal<int>      r_read_fsm;                 // FSM state
    730       sc_signal<size_t>   r_read_copy;                // Srcid of the first copy
    731       sc_signal<size_t>   r_read_copy_cache;          // Srcid of the first copy
    732       sc_signal<bool>     r_read_copy_inst;           // Type of the first copy
    733       sc_signal<tag_t>    r_read_tag;                 // cache line tag (in directory)
    734       sc_signal<bool>     r_read_is_cnt;              // is_cnt bit (in directory)
    735       sc_signal<bool>     r_read_lock;                // lock bit (in directory)
    736       sc_signal<bool>     r_read_dirty;               // dirty bit (in directory)
    737       sc_signal<size_t>   r_read_count;               // number of copies
    738       sc_signal<size_t>   r_read_ptr;                 // pointer to the heap
    739       sc_signal<data_t> * r_read_data;                // data (one cache line)
    740       sc_signal<size_t>   r_read_way;                 // associative way (in cache)
    741       sc_signal<size_t>   r_read_trt_index;           // Transaction Table index
    742       sc_signal<size_t>   r_read_next_ptr;            // Next entry to point to
    743       sc_signal<bool>     r_read_last_free;           // Last free entry
    744       sc_signal<addr_t>   r_read_ll_key;              // LL key from llsc_global_table
     718      sc_signal<int>      r_read_fsm;        // FSM state
     719      sc_signal<size_t>   r_read_copy;       // Srcid of the first copy
     720      sc_signal<size_t>   r_read_copy_cache; // Srcid of the first copy
     721      sc_signal<bool>     r_read_copy_inst;  // Type of the first copy
     722      sc_signal<tag_t>    r_read_tag;        // cache line tag (in directory)
     723      sc_signal<bool>     r_read_is_cnt;     // is_cnt bit (in directory)
     724      sc_signal<bool>     r_read_lock;       // lock bit (in directory)
     725      sc_signal<bool>     r_read_dirty;      // dirty bit (in directory)
     726      sc_signal<size_t>   r_read_count;      // number of copies
     727      sc_signal<size_t>   r_read_ptr;        // pointer to the heap
     728      sc_signal<data_t> * r_read_data;       // data (one cache line)
     729      sc_signal<size_t>   r_read_way;        // associative way (in cache)
     730      sc_signal<size_t>   r_read_trt_index;  // Transaction Table index
     731      sc_signal<size_t>   r_read_next_ptr;   // Next entry to point to
     732      sc_signal<bool>     r_read_last_free;  // Last free entry
     733      sc_signal<addr_t>   r_read_ll_key;     // LL key from llsc_global_table
    745734
    746735      // Buffer between READ fsm and IXR_CMD fsm
    747       sc_signal<bool>     r_read_to_ixr_cmd_req;      // valid request
    748       sc_signal<size_t>   r_read_to_ixr_cmd_index;    // TRT index
     736      sc_signal<bool>     r_read_to_ixr_cmd_req;   // valid request
     737      sc_signal<size_t>   r_read_to_ixr_cmd_index; // TRT index
    749738
    750739      // Buffer between READ fsm and TGT_RSP fsm (send a hit read response to L1 cache)
    751       sc_signal<bool>     r_read_to_tgt_rsp_req;      // valid request
    752       sc_signal<size_t>   r_read_to_tgt_rsp_srcid;    // Transaction srcid
    753       sc_signal<size_t>   r_read_to_tgt_rsp_trdid;    // Transaction trdid
    754       sc_signal<size_t>   r_read_to_tgt_rsp_pktid;    // Transaction pktid
    755       sc_signal<data_t> * r_read_to_tgt_rsp_data;     // data (one cache line)
    756       sc_signal<size_t>   r_read_to_tgt_rsp_word;     // first word of the response
    757       sc_signal<size_t>   r_read_to_tgt_rsp_length;   // length of the response
    758       sc_signal<addr_t>   r_read_to_tgt_rsp_ll_key;   // LL key from llsc_global_table
     740      sc_signal<bool>     r_read_to_tgt_rsp_req;    // valid request
     741      sc_signal<size_t>   r_read_to_tgt_rsp_srcid;  // Transaction srcid
     742      sc_signal<size_t>   r_read_to_tgt_rsp_trdid;  // Transaction trdid
     743      sc_signal<size_t>   r_read_to_tgt_rsp_pktid;  // Transaction pktid
     744      sc_signal<data_t> * r_read_to_tgt_rsp_data;   // data (one cache line)
     745      sc_signal<size_t>   r_read_to_tgt_rsp_word;   // first word of the response
     746      sc_signal<size_t>   r_read_to_tgt_rsp_length; // length of the response
     747      sc_signal<addr_t>   r_read_to_tgt_rsp_ll_key; // LL key from llsc_global_table
    759748
    760749      //RWT: Buffer between READ fsm and CC_SEND fsm (send inval)
     
    777766
    778767      //RWT:
    779       sc_signal<bool>     r_read_coherent;          // State of the cache slot after transaction
     768      sc_signal<bool>     r_read_coherent; // State of the cache slot after transaction
    780769      sc_signal<bool>     r_read_ll_done;
    781770
     
    839828
    840829      // RWT: Buffer between WRITE fsm and CLEANUP fsm (change slot state)
    841       sc_signal<bool>     r_write_to_cleanup_req;         // valid request
    842       sc_signal<addr_t>   r_write_to_cleanup_nline;       // cache line index
     830      sc_signal<bool>     r_write_to_cleanup_req;    // valid request
     831      sc_signal<addr_t>   r_write_to_cleanup_nline;  // cache line index
    843832
    844833      // RWT
    845       sc_signal<bool>     r_write_coherent;               // cache slot state after transaction
     834      sc_signal<bool>     r_write_coherent;          // cache slot state after transaction
    846835
    847836      //Buffer between WRITE fsm and CC_SEND fsm (INVAL for RWT)
     
    11141103
    11151104      sc_signal<bool>      r_cleanup_ncc;
    1116       sc_signal<bool>      r_cleanup_to_ixr_cmd_ncc_l1_dirty;
    1117       sc_signal<bool>      r_xram_rsp_to_ixr_cmd_inval_ncc_pending;
    11181105
    11191106      sc_signal<bool>      r_cleanup_to_ixr_cmd_req;
  • branches/RWT/modules/vci_mem_cache/caba/source/include/xram_transaction.h

    r814 r823  
    1515class TransactionTabEntry
    1616{
    17     typedef sc_dt::sc_uint<64>    wide_data_t;
    18     typedef sc_dt::sc_uint<40>    addr_t;
    19     typedef uint32_t              data_t;
    20     typedef uint32_t              be_t;
     17    typedef sc_dt::sc_uint<64> wide_data_t;
     18    typedef sc_dt::sc_uint<40> addr_t;
     19    typedef uint32_t           data_t;
     20    typedef uint32_t           be_t;
    2121
    2222    public:
     
    154154class TransactionTab
    155155{
    156     typedef sc_dt::sc_uint<64>    wide_data_t;
    157     typedef sc_dt::sc_uint<40>    addr_t;
    158     typedef uint32_t              data_t;
    159     typedef uint32_t              be_t;
     156    typedef sc_dt::sc_uint<64> wide_data_t;
     157    typedef sc_dt::sc_uint<40> addr_t;
     158    typedef uint32_t           data_t;
     159    typedef uint32_t           be_t;
    160160
    161161    private:
    162     const std::string tab_name;                // the name for logs
    163     size_t            size_tab;                // the size of the tab
     162    const std::string tab_name; // the name for logs
     163    size_t            size_tab; // the size of the tab
    164164
    165165    data_t be_to_mask(be_t be)
    166166    {
    167167        data_t ret = 0;
    168         if ( be&0x1 ) {
     168        if (be & 0x1) {
    169169            ret = ret | 0x000000FF;
    170170        }
    171         if ( be&0x2 ) {
     171        if (be & 0x2) {
    172172            ret = ret | 0x0000FF00;
    173173        }
    174         if ( be&0x4 ) {
     174        if (be & 0x4) {
    175175            ret = ret | 0x00FF0000;
    176176        }
    177         if ( be&0x8 ) {
     177        if (be & 0x8) {
    178178            ret = ret | 0xFF000000;
    179179        }
     
    189189    TransactionTab()
    190190    {
    191         size_tab=0;
    192         tab=NULL;
     191        size_tab = 0;
     192        tab = NULL;
    193193    }
    194194
     
    196196                   size_t            n_entries,
    197197                   size_t            n_words )
    198     : tab_name( name ),
    199       size_tab( n_entries )
     198    : tab_name(name),
     199      size_tab(n_entries)
    200200    {
    201201        tab = new TransactionTabEntry[size_tab];
    202         for ( size_t i=0; i<size_tab; i++)
     202        for (size_t i = 0; i < size_tab; i++)
    203203        {
    204204            tab[i].alloc(n_words);
     
    222222    void init()
    223223    {
    224         for ( size_t i=0; i<size_tab; i++)
     224        for (size_t i = 0; i < size_tab; i++)
    225225        {
    226226            tab[i].init();
     
    234234    void print(const size_t index)
    235235    {
    236         assert( (index < size_tab) and
     236        assert((index < size_tab) and
    237237        "MEMC ERROR: The selected entry is out of range in TRT write_data_mask()");
    238238
     
    247247    TransactionTabEntry read(const size_t index)
    248248    {
    249         assert( (index < size_tab) and
     249        assert((index < size_tab) and
    250250        "MEMC ERROR: Invalid Transaction Tab Entry");
    251251
     
    260260    bool full(size_t &index)
    261261    {
    262         for(size_t i=0; i<size_tab; i++)
    263         {
    264             if(!tab[i].valid)
     262        for (size_t i = 0; i < size_tab; i++)
     263        {
     264            if (!tab[i].valid)
    265265            {
    266                 index=i;
     266                index = i;
    267267                return false;
    268268            }
     
    278278    // The function returns true if a read request has already been sent
    279279    //////////////////////////////////////////////////////////////////////
    280     bool hit_read(const addr_t nline,size_t &index)
    281     {
    282         for(size_t i=0; i<size_tab; i++)
    283         {
    284             if((tab[i].valid && (nline==tab[i].nline)) && (tab[i].xram_read))
     280    bool hit_read(const addr_t nline, size_t &index)
     281    {
     282        for (size_t i = 0; i < size_tab; i++)
     283        {
     284            if ((tab[i].valid && (nline == tab[i].nline)) && (tab[i].xram_read))
    285285            {
    286                 index=i;
     286                index = i;
    287287                return true;
    288288            }
     
    299299    bool hit_write(const addr_t nline)
    300300    {
    301         for(size_t i=0; i<size_tab; i++)
    302         {
    303             if(tab[i].valid && (nline==tab[i].nline) && !(tab[i].xram_read))
     301        for (size_t i = 0; i < size_tab; i++)
     302        {
     303            if(tab[i].valid && (nline == tab[i].nline) && !(tab[i].xram_read))
    304304            {
    305305                return true;
     
    319319    bool hit_write(const addr_t nline, size_t* index)
    320320    {
    321         for(size_t i=0; i<size_tab; i++){
    322             if(tab[i].valid && (nline==tab[i].nline) && !(tab[i].xram_read)) {
     321        for (size_t i = 0; i < size_tab; i++){
     322            if (tab[i].valid && (nline == tab[i].nline) && !(tab[i].xram_read)) {
    323323                *index = i;
    324324                return true;
     
    337337    /////////////////////////////////////////////////////////////////////
    338338    void write_data_mask(const size_t index,
    339             const std::vector<be_t> &be,
    340             const std::vector<data_t> &data)
    341     {
    342         assert( (index < size_tab) and
     339                         const std::vector<be_t> &be,
     340                         const std::vector<data_t> &data)
     341    {
     342        assert((index < size_tab) and
    343343        "MEMC ERROR: The selected entry is out of range in TRT write_data_mask()");
    344344
    345         assert( (be.size()==tab[index].wdata_be.size()) and
     345        assert((be.size() == tab[index].wdata_be.size()) and
    346346        "MEMC ERROR: Bad be size in TRT write_data_mask()");
    347347
    348         assert( (data.size()==tab[index].wdata.size()) and
     348        assert((data.size() == tab[index].wdata.size()) and
    349349        "MEMC ERROR: Bad data size in TRT write_data_mask()");
    350350
    351         for(size_t i=0; i<tab[index].wdata_be.size() ; i++)
     351        for (size_t i = 0; i < tab[index].wdata_be.size(); i++)
    352352        {
    353353            tab[index].wdata_be[i] = tab[index].wdata_be[i] | be[i];
     
    375375    /////////////////////////////////////////////////////////////////////
    376376    void set(const size_t index,
    377             const bool xram_read,
    378             const addr_t nline,
    379             const size_t srcid,
    380             const size_t trdid,
    381             const size_t pktid,
    382             const bool proc_read,
    383             const size_t read_length,
    384             const size_t word_index,
    385             const std::vector<be_t> &data_be,
    386             const std::vector<data_t> &data,
    387             const data_t ll_key = 0,
    388             const bool config = false)
    389     {
    390         assert( (index < size_tab) and
     377             const bool xram_read,
     378             const addr_t nline,
     379             const size_t srcid,
     380             const size_t trdid,
     381             const size_t pktid,
     382             const bool proc_read,
     383             const size_t read_length,
     384             const size_t word_index,
     385             const std::vector<be_t> &data_be,
     386             const std::vector<data_t> &data,
     387             const data_t ll_key = 0,
     388             const bool config = false)
     389    {
     390        assert((index < size_tab) and
    391391        "MEMC ERROR: The selected entry is out of range in TRT set()");
    392392
    393         assert( (data_be.size()==tab[index].wdata_be.size()) and
     393        assert((data_be.size() == tab[index].wdata_be.size()) and
    394394        "MEMC ERROR: Bad data_be argument in TRT set()");
    395395
    396         assert( (data.size()==tab[index].wdata.size()) and
     396        assert((data.size() == tab[index].wdata.size()) and
    397397        "MEMC ERROR: Bad data argument in TRT set()");
    398398
     
    408408        tab[index].ll_key      = ll_key;
    409409        tab[index].config      = config;
    410         for(size_t i=0; i<tab[index].wdata.size(); i++)
    411         {
    412             tab[index].wdata_be[i]    = data_be[i];
    413             tab[index].wdata[i]       = data[i];
     410        for (size_t i = 0; i < tab[index].wdata.size(); i++)
     411        {
     412            tab[index].wdata_be[i] = data_be[i];
     413            tab[index].wdata[i]    = data[i];
    414414        }
    415415    }
     
    429429                   const bool        rerror)
    430430    {
    431         data_t  value;
    432         data_t  mask;
    433 
    434         assert( (index < size_tab) and
     431        data_t value;
     432        data_t mask;
     433
     434        assert((index < size_tab) and
    435435        "MEMC ERROR: The selected entry is out of range in TRT write_rsp()");
    436436
    437         assert( (word < tab[index].wdata_be.size()) and
     437        assert((word < tab[index].wdata_be.size()) and
    438438        "MEMC ERROR: Bad word index in TRT write_rsp()");
    439439
    440         assert( (tab[index].valid) and
     440        assert((tab[index].valid) and
    441441        "MEMC ERROR: TRT entry not valid in TRT write_rsp()");
    442442
    443         assert( (tab[index].xram_read ) and
     443        assert((tab[index].xram_read ) and
    444444        "MEMC ERROR: TRT entry is not a GET in TRT write_rsp()");
    445445
    446         if ( rerror )
     446        if (rerror)
    447447        {
    448448            tab[index].rerror = true;
     
    456456
    457457        // second 32 bits word
    458         value = (data_t)(data>>32);
    459         mask  = be_to_mask(tab[index].wdata_be[word+1]);
    460         tab[index].wdata[word+1] = (tab[index].wdata[word+1] & mask) | (value & ~mask);
     458        value = (data_t)(data >> 32);
     459        mask  = be_to_mask(tab[index].wdata_be[word + 1]);
     460        tab[index].wdata[word + 1] = (tab[index].wdata[word + 1] & mask) | (value & ~mask);
    461461    }
    462462    /////////////////////////////////////////////////////////////////////
     
    467467    void erase(const size_t index)
    468468    {
    469         assert( (index < size_tab) and
     469        assert((index < size_tab) and
    470470        "MEMC ERROR: The selected entry is out of range in TRT erase()");
    471471
     
    480480    bool is_config(const size_t index)
    481481    {
    482         assert( (index < size_tab) and
     482        assert((index < size_tab) and
    483483        "MEMC ERROR: The selected entry is out of range in TRT is_config()");
    484484
Note: See TracChangeset for help on using the changeset viewer.