source: branches/RWT/modules/vci_mem_cache/caba/source/include/xram_transaction.h @ 477

Last change on this file since 477 was 477, checked in by lgarcia, 10 years ago

Reintroducing RWT branch merging the last modifications of the
trunk (CLACK channel)
WARNING: bugs remaining (with 1c16p and small caches (L2:16*16; L1:4*4))

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