source: branches/ODCCP/modules/vci_mem_cache/caba/source/include/xram_transaction.h @ 460

Last change on this file since 460 was 460, checked in by devigne, 11 years ago

Introducing merged components between the last trunk TSAR version
and the ODCCP modifications

File size: 17.4 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    // - nline : the index (zy) of the requested line
301    // The function returns true if a write request has already been sent
302    ///////////////////////////////////////////////////////////////////////
303    bool hit_write(const addr_t nline, size_t *index)
304    {
305        for(size_t i=0; i<size_tab; i++){
306            if(tab[i].valid && (nline==tab[i].nline) && !(tab[i].xram_read)) {
307                *index = i;
308                return true;   
309            }
310        }
311        return false;
312    }
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.