source: branches/v5/modules/vci_mem_cache/caba/source/include/xram_transaction.h @ 440

Last change on this file since 440 was 440, checked in by cfuguet, 11 years ago

Merging branch/v5/vci_mem_cache with trunk modifications to
start the development of new coherence protocol modifications
in this component

File size: 16.7 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 write_data_mask() function writes a vector of data (a line).
298    // The data is written only if the corresponding bits are set
299    // in the be vector.
300    // Arguments :
301    // - index : the index of the request in the transaction tab
302    // - be   : vector of be
303    // - data : vector of data
304    /////////////////////////////////////////////////////////////////////
305    void write_data_mask(const size_t index, 
306            const std::vector<be_t> &be, 
307            const std::vector<data_t> &data) 
308    {
309        assert( (index < size_tab) 
310                && "Invalid Transaction Tab Entry");
311        assert(be.size()==tab[index].wdata_be.size() 
312                && "Bad data mask in write_data_mask in TransactionTab");
313        assert(data.size()==tab[index].wdata.size() 
314                && "Bad data in write_data_mask in TransactionTab");
315
316        for(size_t i=0; i<tab[index].wdata_be.size() ; i++) {
317            tab[index].wdata_be[i] = tab[index].wdata_be[i] | be[i];
318            data_t mask = be_to_mask(be[i]);
319            tab[index].wdata[i] = (tab[index].wdata[i] & ~mask) | (data[i] & mask);
320        }
321    }
322
323    /////////////////////////////////////////////////////////////////////
324    // The set() function registers a transaction (read or write)
325    // to the XRAM in the transaction tab.
326    // Arguments :
327    // - index : index in the transaction tab
328    // - xram_read : transaction type (read or write a cache line)
329    // - nline : the index (zy) of the cache line
330    // - srcid : srcid of the initiator that caused the transaction
331    // - trdid : trdid of the initiator that caused the transaction
332    // - pktid : pktid of the initiator that caused the transaction
333    // - proc_read : does the initiator want a copy
334    // - read_length : length of read (in case of processor read)
335    // - word_index : index in the line (in case of single word read)
336    // - data : the data to write (in case of write)
337    // - data_be : the mask of the data to write (in case of write)
338    // - ll_key  : the ll key (if any) returned by the llsc_global_table
339    /////////////////////////////////////////////////////////////////////
340    void set(const size_t index,
341            const bool xram_read,
342            const addr_t nline,
343            const size_t srcid,
344            const size_t trdid,
345            const size_t pktid,
346            const bool proc_read,
347            const size_t read_length,
348            const size_t word_index,
349            const std::vector<be_t> &data_be,
350            const std::vector<data_t> &data, 
351            const data_t ll_key = 0) 
352    {
353        assert( (index < size_tab) 
354                && "The selected entry is out of range in set() Transaction Tab");
355        assert(data_be.size()==tab[index].wdata_be.size() 
356                && "Bad data_be argument in set() TransactionTab");
357        assert(data.size()==tab[index].wdata.size() 
358                && "Bad data argument in set() TransactionTab");
359
360        tab[index].valid                = true;
361        tab[index].xram_read        = xram_read;
362        tab[index].nline                = nline;
363        tab[index].srcid                = srcid;
364        tab[index].trdid                = trdid;
365        tab[index].pktid                = pktid;
366        tab[index].proc_read        = proc_read;
367        tab[index].read_length      = read_length;
368        tab[index].word_index       = word_index;
369        tab[index].ll_key           = ll_key;
370        for(size_t i=0; i<tab[index].wdata.size(); i++) 
371        {
372            tab[index].wdata_be[i]    = data_be[i];
373            tab[index].wdata[i]       = data[i];
374        }
375    }
376
377    /////////////////////////////////////////////////////////////////////
378    // The write_rsp() function writes two 32 bits words of the response
379    // to a XRAM read transaction.
380    // The BE field in TRT is taken into account.
381    // Arguments :
382    // - index : the index of the transaction in the transaction tab
383    // - word_index : the index of the data in the line
384    // - data : a 64 bits value
385    // - error : invalid data
386    /////////////////////////////////////////////////////////////////////
387    void write_rsp(const size_t      index,
388                   const size_t      word,
389                   const wide_data_t data,
390                   const bool        rerror)
391    {
392        data_t  value;
393        data_t  mask;
394
395        if ( index >= size_tab )
396        { 
397            std::cout << "VCI_MEM_CACHE ERRROR " << tab_name
398                      <<  " TRT entry  out of range in write_rsp()" << std::endl;
399            exit(0);
400        }
401        if ( word > tab[index].wdata_be.size() ) 
402        { 
403            std::cout << "VCI_MEM_CACHE ERRROR " << tab_name
404                      <<  " Bad word_index in write_rsp() in TRT" << std::endl;
405            exit(0);
406        }
407        if ( not tab[index].valid )
408        { 
409            std::cout << "VCI_MEM_CACHE ERRROR " << tab_name
410                      <<  " TRT Entry invalid in write_rsp()" << std::endl;
411            exit(0);
412        }
413        if ( not tab[index].xram_read )
414        { 
415            std::cout << "VCI_MEM_CACHE ERRROR " << tab_name
416                      <<  " TRT entry is not an XRAM GET in write_rsp()" << std::endl;
417            exit(0);
418        }
419
420        // first 32 bits word
421        value = (data_t)data;
422        mask  = be_to_mask(tab[index].wdata_be[word]);
423        tab[index].wdata[word] = (tab[index].wdata[word] & mask) | (value & ~mask);
424
425        // second 32 bits word
426        value = (data_t)(data>>32);
427        mask  = be_to_mask(tab[index].wdata_be[word+1]);
428        tab[index].wdata[word+1] = (tab[index].wdata[word+1] & mask) | (value & ~mask);
429
430        // error update
431        tab[index].rerror |= rerror;
432    }
433
434    /////////////////////////////////////////////////////////////////////
435    // The erase() function erases an entry in the transaction tab.
436    // Arguments :
437    // - index : the index of the request in the transaction tab
438    /////////////////////////////////////////////////////////////////////
439    void erase(const size_t index)
440    {
441        assert( (index < size_tab) 
442                && "The selected entry is out of range in erase() Transaction Tab");
443        tab[index].valid        = false;
444        tab[index].rerror   = false;
445    }
446}; // end class TransactionTab
447
448#endif
449
450// Local Variables:
451// tab-width: 4
452// c-basic-offset: 4
453// c-file-offsets:((innamespace . 0)(inline-open . 0))
454// indent-tabs-mode: nil
455// End:
456
457// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
458
Note: See TracBrowser for help on using the repository browser.