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

Last change on this file since 601 was 601, checked in by cfuguet, 10 years ago

Modifications in vci_mem_cache:

  • The out of segment read or write does not activate any more an assert on the memory cache. Instead, the request is sent to the XRAM and the error from the XRAM will be propagated to the processor doing the access.

The propagation of the error is done in two different ways:

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