source: trunk/modules/vci_mem_cache/caba/source/include/xram_transaction.h @ 489

Last change on this file since 489 was 489, checked in by alain, 11 years ago

Implement both the SYNC and INVAL configuration commands.
Uses the TRT to transmit the cache line to XRAM in cPUT transactions.
Improve the debug.

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