source: branches/MESI/modules/vci_mem_cache/caba/source/include/update_tab.h @ 677

Last change on this file since 677 was 677, checked in by haoliu, 10 years ago

MESI bug fixed

File size: 14.5 KB
RevLine 
[670]1#ifndef UPDATE_TAB_H_
2#define UPDATE_TAB_H_
3
4#include <inttypes.h>
5#include <systemc>
6#include <cassert>
7#include "arithmetics.h"
8
9////////////////////////////////////////////////////////////////////////
10//                  An update tab entry   
11////////////////////////////////////////////////////////////////////////
12class UpdateTabEntry {
13
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
[677]29  bool      is_change;  // multi ack miss req sends this bit to 1
[670]30
31  UpdateTabEntry()
32  {
[677]33    valid           = false;
34    update      = false;
35    brdcast     = false;
36    rsp         = false;
37    ack         = false;
38    srcid           = 0;
39    trdid           = 0;
40    pktid           = 0;
41    nline           = 0;
42    count           = 0;
43    is_change   = 0;
[670]44  }
45
46  UpdateTabEntry(bool   i_valid, 
47                 bool   i_update,
48                 bool   i_brdcast,
49                 bool   i_rsp,
50                 bool   i_ack,
51                 size_t i_srcid, 
52                 size_t i_trdid, 
53                 size_t i_pktid, 
54                 addr_t i_nline,
[677]55                 size_t i_count,
56                 size_t i_is_change) 
[670]57  {
[677]58    valid           = i_valid;
59    update          = i_update;
60    brdcast     = i_brdcast;
61    rsp         = i_rsp;
62    ack         = i_ack;
63    srcid           = i_srcid;
64    trdid           = i_trdid;
65    pktid           = i_pktid;
66    nline           = i_nline;
67    count           = i_count;
68    is_change   = i_is_change;
[670]69  }
70
71  UpdateTabEntry(const UpdateTabEntry &source)
72  {
[677]73    valid       = source.valid;
74    update      = source.update;
75    brdcast     = source.brdcast;
76    rsp         = source.rsp;
77    ack         = source.ack;
78    srcid       = source.srcid;
79    trdid       = source.trdid;
80    pktid       = source.pktid;
81    nline       = source.nline;
82    count       = source.count;
83    is_change   = source.is_change;
[670]84  }
85
86  ////////////////////////////////////////////////////
87  // The init() function initializes the entry
88  ///////////////////////////////////////////////////
89  void init()
90  {
[677]91    valid       = false;
92    update      = false;
93    brdcast     = false;
94    rsp         = false;
95    ack         = false;
96    srcid       = 0;
97    trdid       = 0;
98    pktid       = 0;
99    nline       = 0;
100    count       = 0;
101    is_change   = 0;
[670]102  }
103
104  ////////////////////////////////////////////////////////////////////
105  // The copy() function copies an existing entry
106  // Its arguments are :
107  // - source : the update tab entry to copy
108  ////////////////////////////////////////////////////////////////////
109  void copy(const UpdateTabEntry &source)
110  {
[677]111    valid       = source.valid;
112    update      = source.update;
113    brdcast     = source.brdcast;
114    rsp         = source.rsp;
115    ack         = source.ack;
116    srcid       = source.srcid;
117    trdid       = source.trdid;
118    pktid       = source.pktid;
119    nline       = source.nline;
120    count       = source.count;
121    is_change   = source.is_change;
[670]122  }
123
124  ////////////////////////////////////////////////////////////////////
125  // The print() function prints the entry 
126  ////////////////////////////////////////////////////////////////////
127  void print()
128  {
129    std::cout << " val = " << std::dec << valid
130              << " / updt = " << update
131              << " / bc = " << brdcast
132              << " / rsp = " << rsp
133              << " / ack = " << ack   
134              << " / count = " << count
135              << " / srcid = " << std::hex << srcid
136              << " / trdid = " << trdid   
137              << " / pktid = " << pktid
138              << " / nline = " << nline  << std::endl;
139  }
140};
141
142////////////////////////////////////////////////////////////////////////
143//                        The update tab             
144////////////////////////////////////////////////////////////////////////
145class UpdateTab{
146
147  typedef uint64_t addr_t;
148
149  private:
150  size_t                      size_tab;
151  std::vector<UpdateTabEntry> tab;
152
153  public:
154
155  UpdateTab()
156    : tab(0)
157  {
158    size_tab=0;
159  }
160
161  UpdateTab(size_t size_tab_i)
162    : tab(size_tab_i)
163  {
164    size_tab=size_tab_i;
165  }
166
167  ////////////////////////////////////////////////////////////////////
168  // The size() function returns the size of the tab 
169  ////////////////////////////////////////////////////////////////////
170  const size_t size()
171  {
172    return size_tab;
173  }
174
175  ////////////////////////////////////////////////////////////////////
176  // The print() function diplays the tab content
177  ////////////////////////////////////////////////////////////////////
178  void print()
179  {
180    std::cout << "UPDATE TABLE Content" << std::endl;
181    for(size_t i=0; i<size_tab; i++) 
182    {
183      std::cout << "[" << std::dec << i << "] ";
184      tab[i].print();
185    }
186    return;
187  }
188
189  /////////////////////////////////////////////////////////////////////
190  // The init() function initializes the tab
191  /////////////////////////////////////////////////////////////////////
192  void init()
193  {
194    for ( size_t i=0; i<size_tab; i++) tab[i].init();
195  }
196
197  /////////////////////////////////////////////////////////////////////
198  // The reads() function reads an entry
199  // Arguments :
200  // - entry : the entry to read
201  // This function returns a copy of the entry.
202  /////////////////////////////////////////////////////////////////////
203  UpdateTabEntry read (size_t entry)
204  {
205    assert(entry<size_tab && "Bad Update Tab Entry");
206    return UpdateTabEntry(tab[entry]);
207  }
208
209  ///////////////////////////////////////////////////////////////////////////
210  // The set() function writes an entry in the Update Table
211  // Arguments :
212  // - update : transaction type (bool)
213  // - srcid : srcid of the initiator
214  // - trdid : trdid of the initiator
215  // - pktid : pktid of the initiator
216  // - count : number of expected responses
217  // - index : (return argument) index of the selected entry
218  // This function returns true if the write successed (an entry was empty).
219  ///////////////////////////////////////////////////////////////////////////
220  bool set(const bool   update,
221           const bool   brdcast,
222           const bool   rsp,
223           const bool   ack,
224           const size_t srcid,
225           const size_t trdid,
226           const size_t pktid,
227           const addr_t nline,
228           const size_t count,
[677]229           size_t       &index,
230           const bool   is_change=false)
[670]231  {
232    for ( size_t i=0 ; i<size_tab ; i++ ) 
233    {
234      if( !tab[i].valid ) 
235      {
236        tab[i].valid            = true;
237        tab[i].update           = update;
238        tab[i].brdcast      = brdcast;
239        tab[i].rsp          = rsp;
240        tab[i].ack          = ack;
241        tab[i].srcid            = (size_t) srcid;
242        tab[i].trdid            = (size_t) trdid;
243        tab[i].pktid            = (size_t) pktid;
244        tab[i].nline            = (addr_t) nline;
245        tab[i].count            = (size_t) count;
[677]246        tab[i].is_change    = is_change;
[670]247        index                       = i;
248        return true;
249      }
250    }
251    return false;
252  } // end set()
253
254  /////////////////////////////////////////////////////////////////////
255  // The decrement() function decrements the counter for a given entry.
256  // Arguments :
257  // - index   : the index of the entry
258  // - counter : (return argument) value of the counter after decrement
259  // This function returns true if the entry is valid.
260  /////////////////////////////////////////////////////////////////////
261  bool decrement( const size_t index,
262                  size_t &counter ) 
263  {
264    assert((index<size_tab) && "Bad Update Tab Entry");
265    if ( tab[index].valid ) 
266    {
267      tab[index].count--;
268      counter = tab[index].count;
269      return true;
270    } 
271    else 
272    {
273      return false;
274    }
275  }
276
277  /////////////////////////////////////////////////////////////////////
278  // The is_full() function returns true if the table is full
279  /////////////////////////////////////////////////////////////////////
280  bool is_full()
281  {
282    for(size_t i = 0 ; i < size_tab ; i++)
283    {
284      if(!tab[i].valid) return false;
285    }
286    return true;
287  }
288
289  /////////////////////////////////////////////////////////////////////
290  // The is_not_empty() function returns true if the table is not empty
291  /////////////////////////////////////////////////////////////////////
292  bool is_not_empty()
293  {
294    for(size_t i = 0 ; i < size_tab ; i++)
295    {
296      if(tab[i].valid) return true;
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 && tab[index].valid && "Bad Update Tab Entry");
342    return tab[index].update;   
343  }
344  /////////////////////////////////////////////////////////////////////
345  // The is_update() function returns the valid bit
346  // Arguments :
347  // - index : the index of the entry
348  /////////////////////////////////////////////////////////////////////
349  bool is_valid(const size_t index)
350  {
351    assert(index<size_tab && "Bad Update Tab Entry");
352    return tab[index].valid;   
353  }
354
355  /////////////////////////////////////////////////////////////////////
356  // The srcid() function returns the srcid value
357  // Arguments :
358  // - index : the index of the entry
359  /////////////////////////////////////////////////////////////////////
360  size_t srcid(const size_t index)
361  {
362    assert(index<size_tab && "Bad Update Tab Entry");
363    return tab[index].srcid;   
364  }
365
366  /////////////////////////////////////////////////////////////////////
367  // The count() function returns the count value
368  // Arguments :
369  // - index : the index of the entry
370  /////////////////////////////////////////////////////////////////////
371  size_t count(const size_t index)
372  {
373    assert(index<size_tab && "Bad Update Tab Entry");
374    return tab[index].count;   
375  }
376
377  /////////////////////////////////////////////////////////////////////
378  // The trdid() function returns the trdid value
379  // Arguments :
380  // - index : the index of the entry
381  /////////////////////////////////////////////////////////////////////
382  size_t trdid(const size_t index)
383  {
384    assert(index<size_tab && "Bad Update Tab Entry");
385    return tab[index].trdid;   
386  }
387
388  /////////////////////////////////////////////////////////////////////
389  // The pktid() function returns the pktid value
390  // Arguments :
391  // - index : the index of the entry
392  /////////////////////////////////////////////////////////////////////
393  size_t pktid(const size_t index)
394  {
395    assert(index<size_tab && "Bad Update Tab Entry");
396    return tab[index].pktid;   
397  }
398
399  /////////////////////////////////////////////////////////////////////
400  // The nline() function returns the nline value
401  // Arguments :
402  // - index : the index of the entry
403  /////////////////////////////////////////////////////////////////////
404  addr_t nline(const size_t index)
405  {
406    assert(index<size_tab && "Bad Update Tab Entry");
407    return tab[index].nline;
408  }
409
410  /////////////////////////////////////////////////////////////////////
411  // The search_inval() function returns the index of the entry in UPT
412  // Arguments :
413  // - nline : the line number of the entry in the directory
414  /////////////////////////////////////////////////////////////////////
415  bool search_inval(const addr_t nline,size_t &index)
416  {
417    size_t i ;
418
419    for (i = 0 ; i < size_tab ; i++)
420    {
421      //if ( (tab[i].nline == nline) and tab[i].valid and not tab[i].update )
422      if ( (tab[i].nline == nline) and tab[i].valid )
423      {
424        index = i ;
425        return true;
426      }
427    }
428    return false;
429  }
430
431  /////////////////////////////////////////////////////////////////////
432  // The read_nline() function returns the index of the entry in UPT
433  // Arguments :
434  // - nline : the line number of the entry in the directory
435  /////////////////////////////////////////////////////////////////////
436  bool read_nline(const addr_t nline,size_t &index) 
437  {
438    size_t i ;
439
440    for (i = 0 ; i < size_tab ; i++)
441    {
442      if ( (tab[i].nline == nline) and tab[i].valid )
443      {
444        index = i ;
445        return true;
446      }
447    }
448    return false;
449  }
450
451  /////////////////////////////////////////////////////////////////////
452  // The clear() function erases an entry of the tab
453  // Arguments :
454  // - index : the index of the entry
455  /////////////////////////////////////////////////////////////////////       
456  void clear(const size_t index)
457  {
458    assert(index<size_tab && "Bad Update Tab Entry");
459    tab[index].valid=false;
460    return;     
461  }
462
[677]463  void change(const size_t index)
464  {
465    assert(index<size_tab && "Bad Update Tab Entry");
466    tab[index].is_change = true;
467  }
468
469  size_t is_change(const size_t index)
470  {
471    assert(index<size_tab && "Bad Update Tab Entry");
472    return tab[index].is_change;
473  }
[670]474};
475
476#endif
477
478// Local Variables:
479// tab-width: 4
480// c-basic-offset: 4
481// c-file-offsets:((innamespace . 0)(inline-open . 0))
482// indent-tabs-mode: nil
483// End:
484
485// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
486
Note: See TracBrowser for help on using the repository browser.