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

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

TSAR branches -- Adding the first version of protocol MESI in TSAR architecture:

File size: 13.7 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
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  }
133};
134
135////////////////////////////////////////////////////////////////////////
136//                        The update tab             
137////////////////////////////////////////////////////////////////////////
138class UpdateTab{
139
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;
239        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 && tab[index].valid && "Bad Update Tab Entry");
333    return tab[index].update;   
334  }
335  /////////////////////////////////////////////////////////////////////
336  // The is_update() function returns the valid bit
337  // Arguments :
338  // - index : the index of the entry
339  /////////////////////////////////////////////////////////////////////
340  bool is_valid(const size_t index)
341  {
342    assert(index<size_tab && "Bad Update Tab Entry");
343    return tab[index].valid;   
344  }
345
346  /////////////////////////////////////////////////////////////////////
347  // The srcid() function returns the srcid value
348  // Arguments :
349  // - index : the index of the entry
350  /////////////////////////////////////////////////////////////////////
351  size_t srcid(const size_t index)
352  {
353    assert(index<size_tab && "Bad Update Tab Entry");
354    return tab[index].srcid;   
355  }
356
357  /////////////////////////////////////////////////////////////////////
358  // The count() function returns the count value
359  // Arguments :
360  // - index : the index of the entry
361  /////////////////////////////////////////////////////////////////////
362  size_t count(const size_t index)
363  {
364    assert(index<size_tab && "Bad Update Tab Entry");
365    return tab[index].count;   
366  }
367
368  /////////////////////////////////////////////////////////////////////
369  // The trdid() function returns the trdid value
370  // Arguments :
371  // - index : the index of the entry
372  /////////////////////////////////////////////////////////////////////
373  size_t trdid(const size_t index)
374  {
375    assert(index<size_tab && "Bad Update Tab Entry");
376    return tab[index].trdid;   
377  }
378
379  /////////////////////////////////////////////////////////////////////
380  // The pktid() function returns the pktid value
381  // Arguments :
382  // - index : the index of the entry
383  /////////////////////////////////////////////////////////////////////
384  size_t pktid(const size_t index)
385  {
386    assert(index<size_tab && "Bad Update Tab Entry");
387    return tab[index].pktid;   
388  }
389
390  /////////////////////////////////////////////////////////////////////
391  // The nline() function returns the nline value
392  // Arguments :
393  // - index : the index of the entry
394  /////////////////////////////////////////////////////////////////////
395  addr_t nline(const size_t index)
396  {
397    assert(index<size_tab && "Bad Update Tab Entry");
398    return tab[index].nline;
399  }
400
401  /////////////////////////////////////////////////////////////////////
402  // The search_inval() function returns the index of the entry in UPT
403  // Arguments :
404  // - nline : the line number of the entry in the directory
405  /////////////////////////////////////////////////////////////////////
406  bool search_inval(const addr_t nline,size_t &index)
407  {
408    size_t i ;
409
410    for (i = 0 ; i < size_tab ; i++)
411    {
412      //if ( (tab[i].nline == nline) and tab[i].valid and not tab[i].update )
413      if ( (tab[i].nline == nline) and tab[i].valid )
414      {
415        index = i ;
416        return true;
417      }
418    }
419    return false;
420  }
421
422  /////////////////////////////////////////////////////////////////////
423  // The read_nline() function returns the index of the entry in UPT
424  // Arguments :
425  // - nline : the line number of the entry in the directory
426  /////////////////////////////////////////////////////////////////////
427  bool read_nline(const addr_t nline,size_t &index) 
428  {
429    size_t i ;
430
431    for (i = 0 ; i < size_tab ; i++)
432    {
433      if ( (tab[i].nline == nline) and tab[i].valid )
434      {
435        index = i ;
436        return true;
437      }
438    }
439    return false;
440  }
441
442  /////////////////////////////////////////////////////////////////////
443  // The clear() function erases an entry of the tab
444  // Arguments :
445  // - index : the index of the entry
446  /////////////////////////////////////////////////////////////////////       
447  void clear(const size_t index)
448  {
449    assert(index<size_tab && "Bad Update Tab Entry");
450    tab[index].valid=false;
451    return;     
452  }
453
454};
455
456#endif
457
458// Local Variables:
459// tab-width: 4
460// c-basic-offset: 4
461// c-file-offsets:((innamespace . 0)(inline-open . 0))
462// indent-tabs-mode: nil
463// End:
464
465// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
466
Note: See TracBrowser for help on using the repository browser.