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

Last change on this file since 823 was 823, checked in by devigne, 9 years ago

RWT Commit : Cosmetic

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