source: trunk/modules/vci_mem_cache_v4/caba/source/include/xram_transaction_v4.h @ 138

Last change on this file since 138 was 138, checked in by guthmull, 13 years ago

Handle bad accesses cleanly : transmit all accesses to the xram and handle rerror in responses. The simulation is no more stopped and gdb can be used for debug.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to "Author Date Id Rev URL Revision"
  • Property svn:mime-type set to text/plain
File size: 14.1 KB
Line 
1#ifndef XRAM_TRANSACTION_V4_H_
2#define XRAM_TRANSACTION_V4_H_
3 
4#include <inttypes.h>
5#include <systemc>
6#include <cassert>
7#include "arithmetics.h"
8
9#define DEBUG_XRAM_TRANSACTION 0
10
11////////////////////////////////////////////////////////////////////////
12//                  A transaction tab entry         
13////////////////////////////////////////////////////////////////////////
14
15class TransactionTabEntry {
16  typedef uint32_t size_t;
17  typedef uint32_t data_t;
18  typedef sc_dt::sc_uint<40> addr_t;
19  typedef uint32_t be_t;
20
21 public:
22  bool                valid;                // entry valid
23  bool                xram_read;            // read request to XRAM
24  addr_t              nline;                // index (zy) of the requested line
25  size_t              srcid;                // processor requesting the transaction
26  size_t              trdid;                // processor requesting the transaction
27  size_t              pktid;                // processor requesting the transaction
28  bool                proc_read;            // read request from processor
29  size_t                  read_length;      // length of the read (for the response)
30  size_t              word_index;       // index of the first read word (for the response)
31  std::vector<data_t> wdata;        // write buffer (one cache line)
32  std::vector<be_t>   wdata_be;         // be for each data in the write buffer
33  bool            rerror;           // error returned by xram
34
35  /////////////////////////////////////////////////////////////////////
36  // The init() function initializes the entry
37  /////////////////////////////////////////////////////////////////////
38  void init()
39  {
40    valid               = false;
41  }
42
43  /////////////////////////////////////////////////////////////////////
44  // The alloc() function initializes the vectors of an entry
45  // Its arguments are :
46  // - n_words : number of words per line in the cache
47  /////////////////////////////////////////////////////////////////////
48  void alloc(size_t n_words)
49  {
50    wdata_be.reserve( (int)n_words );
51    wdata.reserve( (int)n_words );
52    for(size_t i=0; i<n_words; i++){
53      wdata_be.push_back(false);
54      wdata.push_back(0);
55    }
56  }
57
58  ////////////////////////////////////////////////////////////////////
59  // The copy() function copies an existing entry
60  // Its arguments are :
61  // - source : the transaction tab entry to copy
62  ////////////////////////////////////////////////////////////////////
63  void copy(const TransactionTabEntry &source)
64  {
65    valid           = source.valid;
66    xram_read   = source.xram_read;
67    nline           = source.nline;
68    srcid           = source.srcid;
69    trdid           = source.trdid;
70    pktid           = source.pktid;
71    proc_read   = source.proc_read;
72    read_length = source.read_length;
73    word_index  = source.word_index;
74    wdata_be.assign(source.wdata_be.begin(),source.wdata_be.end());
75    wdata.assign(source.wdata.begin(),source.wdata.end());
76    rerror      = source.rerror;
77  }
78
79  ////////////////////////////////////////////////////////////////////
80  // The print() function prints the entry
81  ////////////////////////////////////////////////////////////////////
82  void print(){
83    std::cout << "valid       = " << valid        << std::endl;
84    std::cout << "xram_read   = " << xram_read    << std::endl;
85    std::cout << "nline       = " << std::hex << nline << std::endl;
86    std::cout << "srcid       = " << srcid        << std::endl;
87    std::cout << "trdid       = " << trdid        << std::endl;
88    std::cout << "pktid       = " << pktid        << std::endl;
89    std::cout << "proc_read   = " << proc_read    << std::endl;
90    std::cout << "read_length = " << read_length  << std::endl;
91    std::cout << "word_index  = " << word_index   << std::endl;
92    for(size_t i=0; i<wdata_be.size() ; i++){
93      std::cout << "wdata_be [" << i <<"] = " << wdata_be[i] << std::endl;
94    }
95    for(size_t i=0; i<wdata.size() ; i++){
96      std::cout << "wdata [" << i <<"] = " << wdata[i] << std::endl;
97    }
98    std::cout << std::endl;
99    std::cout << "rerror      = " << rerror       << std::endl;
100  }
101
102  /////////////////////////////////////////////////////////////////////
103  //            Constructors
104  /////////////////////////////////////////////////////////////////////
105
106  TransactionTabEntry()
107    {
108      wdata_be.clear();
109      wdata.clear();
110      valid=false;
111      rerror=false;
112    }
113
114  TransactionTabEntry(const TransactionTabEntry &source){
115    valid           = source.valid;
116    xram_read   = source.xram_read;
117    nline           = source.nline;
118    srcid           = source.srcid;
119    trdid           = source.trdid;
120    pktid           = source.pktid;
121    proc_read   = source.proc_read;
122    read_length = source.read_length;
123    word_index  = source.word_index;
124    wdata_be.assign(source.wdata_be.begin(),source.wdata_be.end());
125    wdata.assign(source.wdata.begin(),source.wdata.end());     
126    rerror      = source.rerror;
127  }
128
129}; // end class TransactionTabEntry
130
131////////////////////////////////////////////////////////////////////////
132//                  The transaction tab                             
133////////////////////////////////////////////////////////////////////////
134class TransactionTab{
135  typedef uint32_t size_t;
136  typedef uint32_t data_t;
137  typedef sc_dt::sc_uint<40> addr_t;
138  typedef uint32_t be_t;
139
140 private:
141  size_t size_tab;                // The size of the tab
142
143  data_t be_to_mask(be_t be)
144  {
145    data_t ret = 0;
146    if ( be&0x1 ) {
147      ret = ret | 0x000000FF;
148    }
149    if ( be&0x2 ) {
150      ret = ret | 0x0000FF00;
151    }
152    if ( be&0x4 ) {
153      ret = ret | 0x00FF0000;
154    }
155    if ( be&0x8 ) {
156      ret = ret | 0xFF000000;
157    }
158    return ret;
159  }
160
161 public:
162  TransactionTabEntry *tab;       // The transaction tab
163
164  ////////////////////////////////////////////////////////////////////
165  //            Constructors
166  ////////////////////////////////////////////////////////////////////
167  TransactionTab()
168    {
169      size_tab=0;
170      tab=NULL;
171    }
172
173  TransactionTab(size_t n_entries, size_t n_words)
174    {
175      size_tab = n_entries;
176      tab = new TransactionTabEntry[size_tab];
177      for ( size_t i=0; i<size_tab; i++) {
178        tab[i].alloc(n_words);
179      }
180    }
181
182  ~TransactionTab()
183    {
184      delete [] tab;
185    }
186
187  /////////////////////////////////////////////////////////////////////
188  // The size() function returns the size of the tab
189  /////////////////////////////////////////////////////////////////////
190  size_t size()
191  {
192    return size_tab;
193  }
194
195  /////////////////////////////////////////////////////////////////////
196  // The init() function initializes the transaction tab entries
197  /////////////////////////////////////////////////////////////////////
198  void init()
199  {
200    for ( size_t i=0; i<size_tab; i++) {
201      tab[i].init();
202    }
203  }
204
205  /////////////////////////////////////////////////////////////////////
206  // The print() function prints a transaction tab entry
207  // Arguments :
208  // - index : the index of the entry to print
209  /////////////////////////////////////////////////////////////////////
210  void print(const size_t index)
211  {
212    assert( (index < size_tab)
213            && "Invalid Transaction Tab Entry");
214    tab[index].print();
215    return;
216  }
217
218  /////////////////////////////////////////////////////////////////////
219  // The read() function returns a transaction tab entry.
220  // Arguments :
221  // - index : the index of the entry to read
222  /////////////////////////////////////////////////////////////////////
223  TransactionTabEntry read(const size_t index)
224  {
225    assert( (index < size_tab)
226            && "Invalid Transaction Tab Entry");
227    return tab[index];
228  }
229
230  /////////////////////////////////////////////////////////////////////
231  // The full() function returns the state of the transaction tab
232  // Arguments :
233  // - index : (return argument) the index of an empty entry
234  // The function returns true if the transaction tab is full
235  /////////////////////////////////////////////////////////////////////
236  bool full(size_t &index)
237  {
238    for(size_t i=0; i<size_tab; i++){
239      if(!tab[i].valid){
240            index=i;
241            return false;       
242      }
243    }
244    return true;
245  }
246
247  /////////////////////////////////////////////////////////////////////
248  // The hit_read() function checks if an XRAM read transaction exists
249  // for a given cache line.
250  // Arguments :
251  // - index : (return argument) the index of the hit entry, if there is
252  // - nline : the index (zy) of the requested line
253  // The function returns true if a read request has already been sent
254  //////////////////////////////////////////////////////////////////////
255  bool hit_read(const addr_t nline,size_t &index)
256  {
257    for(size_t i=0; i<size_tab; i++){
258      if((tab[i].valid && (nline==tab[i].nline)) && (tab[i].xram_read)) {
259            index=i;
260            return true;       
261      }
262    }
263    return false;
264  }
265
266  ///////////////////////////////////////////////////////////////////////
267  // The hit_write() function looks if an XRAM write transaction exists
268  // for a given line.
269  // Arguments :
270  // - nline : the index (zy) of the requested line
271  // The function returns true if a write request has already been sent
272  ///////////////////////////////////////////////////////////////////////
273  bool hit_write(const addr_t nline)
274  {
275    for(size_t i=0; i<size_tab; i++){
276      if(tab[i].valid && (nline==tab[i].nline) && !(tab[i].xram_read)) {
277            return true;       
278      }
279    }
280    return false;
281  }
282
283  /////////////////////////////////////////////////////////////////////
284  // The write_data_mask() function writes a vector of data (a line).
285  // The data is written only if the corresponding bits are set
286  // in the be vector.
287  // Arguments :
288  // - index : the index of the request in the transaction tab
289  // - be   : vector of be
290  // - data : vector of data
291  /////////////////////////////////////////////////////////////////////
292  void write_data_mask(const size_t index,
293                       const std::vector<be_t> &be,
294                       const std::vector<data_t> &data)
295  {
296    assert( (index < size_tab)
297            && "Invalid Transaction Tab Entry");
298    assert(be.size()==tab[index].wdata_be.size()
299           && "Bad data mask in write_data_mask in TransactionTab");
300    assert(data.size()==tab[index].wdata.size()
301           && "Bad data in write_data_mask in TransactionTab");
302
303    for(size_t i=0; i<tab[index].wdata_be.size() ; i++) {
304      tab[index].wdata_be[i] = tab[index].wdata_be[i] | be[i];
305      data_t mask = be_to_mask(be[i]);
306      tab[index].wdata[i] = (tab[index].wdata[i] & ~mask) | (data[i] & mask);
307    }
308  }
309
310  /////////////////////////////////////////////////////////////////////
311  // The set() function registers a transaction (read or write)
312  // to the XRAM in the transaction tab.
313  // Arguments :
314  // - index : index in the transaction tab
315  // - xram_read : transaction type (read or write a cache line)
316  // - nline : the index (zy) of the cache line
317  // - srcid : srcid of the initiator that caused the transaction
318  // - trdid : trdid of the initiator that caused the transaction
319  // - pktid : pktid of the initiator that caused the transaction
320  // - proc_read : does the initiator want a copy
321  // - read_length : length of read (in case of processor read)
322  // - word_index : index in the line (in case of single word read)
323  // - data : the data to write (in case of write)
324  // - data_be : the mask of the data to write (in case of write)
325  /////////////////////////////////////////////////////////////////////
326  void set(const size_t index,
327           const bool xram_read,
328           const addr_t nline,
329           const size_t srcid,
330           const size_t trdid,
331           const size_t pktid,
332           const bool proc_read,
333           const size_t read_length,
334           const size_t word_index,
335           const std::vector<be_t> &data_be,
336           const std::vector<data_t> &data)
337  {
338    assert( (index < size_tab)
339            && "The selected entry is out of range in set() Transaction Tab");
340    assert(data_be.size()==tab[index].wdata_be.size()
341           && "Bad data_be argument in set() TransactionTab");
342    assert(data.size()==tab[index].wdata.size()
343           && "Bad data argument in set() TransactionTab");
344
345    tab[index].valid            = true;
346    tab[index].xram_read        = xram_read;
347    tab[index].nline            = nline;
348    tab[index].srcid            = srcid;
349    tab[index].trdid            = trdid;
350    tab[index].pktid            = pktid;
351    tab[index].proc_read            = proc_read;
352    tab[index].read_length          = read_length;
353    tab[index].word_index           = word_index;
354    for(size_t i=0; i<tab[index].wdata.size(); i++) {
355      tab[index].wdata_be[i]    = data_be[i];
356      tab[index].wdata[i]       = data[i];
357    }
358  }
359
360  /////////////////////////////////////////////////////////////////////
361  // The write_rsp() function writes a word of the response to an
362  // XRAM read transaction.
363  // The data is only written when the corresponding BE field is Ox0.
364  // Arguments :
365  // - index : the index of the transaction in the transaction tab
366  // - word_index : the index of the data in the line
367  // - data : the data to write
368  /////////////////////////////////////////////////////////////////////
369  void write_rsp(const size_t index,
370                 const size_t word,
371                 const data_t data,
372                 const bool   rerror)
373  {
374    assert( (index < size_tab)
375            && "Selected entry  out of range in write_rsp() Transaction Tab");
376    assert( (word <= tab[index].wdata_be.size())
377            && "Bad word_index in write_rsp() in TransactionTab");
378    assert( tab[index].valid
379            && "Transaction Tab Entry invalid in write_rsp()");
380    assert( tab[index].xram_read
381            && "Selected entry is not an XRAM read transaction in write_rsp()");
382
383    data_t mask = be_to_mask(tab[index].wdata_be[word]);
384    tab[index].wdata[word] = (tab[index].wdata[word] & mask) | (data & ~mask);
385    tab[index].rerror |= rerror;
386  }
387
388  /////////////////////////////////////////////////////////////////////
389  // The erase() function erases an entry in the transaction tab.
390  // Arguments :
391  // - index : the index of the request in the transaction tab
392  /////////////////////////////////////////////////////////////////////
393  void erase(const size_t index)
394  {
395    assert( (index < size_tab)
396            && "The selected entry is out of range in erase() Transaction Tab");
397    tab[index].valid    = false;
398  }
399}; // end class TransactionTab
400
401#endif
402
403// Local Variables:
404// tab-width: 4
405// c-basic-offset: 4
406// c-file-offsets:((innamespace . 0)(inline-open . 0))
407// indent-tabs-mode: nil
408// End:
409
410// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
411
Note: See TracBrowser for help on using the repository browser.