source: branches/wt_ideal/modules/vci_mem_cache/caba/source/include/xram_transaction.h

Last change on this file was 920, checked in by meunier, 10 years ago
  • Adding branch wt_ideal -- "ideal" write-through
File size: 17.1 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 "MEMC ERROR: Invalid Transaction Tab Entry");
244
245        return tab[index];
246    }
247    /////////////////////////////////////////////////////////////////////
248    // The full() function returns the state of the transaction tab
249    // Arguments :
250    // - index : (return argument) the index of an empty entry
251    // The function returns true if the transaction tab is full
252    /////////////////////////////////////////////////////////////////////
253    bool full(size_t & index)
254    {
255        for (size_t i = 0; i < size_tab; i++)
256        {
257            if (!tab[i].valid)
258            {
259                index = i;
260                return false;   
261            }
262        }
263        return true;
264    }
265    /////////////////////////////////////////////////////////////////////
266    // The hit_read() function checks if an XRAM read transaction exists
267    // for a given cache line.
268    // Arguments :
269    // - index : (return argument) the index of the hit entry, if there is
270    // - nline : the index (zy) of the requested line
271    // The function returns true if a read request has already been sent
272    //////////////////////////////////////////////////////////////////////
273    bool hit_read(const addr_t nline,size_t &index)
274    {
275        for (size_t i = 0; i < size_tab; i++)
276        {
277            if ((tab[i].valid && (nline == tab[i].nline)) && (tab[i].xram_read)) 
278            {
279                index = i;
280                return true;   
281            }
282        }
283        return false;
284    }
285    ///////////////////////////////////////////////////////////////////////
286    // The hit_write() function looks if an XRAM write transaction exists
287    // for a given line.
288    // Arguments :
289    // - nline : the index (zy) of the requested line
290    // The function returns true if a write request has already been sent
291    ///////////////////////////////////////////////////////////////////////
292    bool hit_write(const addr_t nline)
293    {
294        for (size_t i = 0; i < size_tab; i++)
295        {
296            if (tab[i].valid && (nline == tab[i].nline) && !(tab[i].xram_read)) 
297            {
298                return true;   
299            }
300        }
301        return false;
302    }
303    /////////////////////////////////////////////////////////////////////
304    // The write_data_mask() function writes a vector of data (a line).
305    // The data is written only if the corresponding bits are set
306    // in the be vector.
307    // Arguments :
308    // - index : the index of the request in the transaction tab
309    // - be   : vector of be
310    // - data : vector of data
311    /////////////////////////////////////////////////////////////////////
312    void write_data_mask(const size_t index, 
313            const std::vector<be_t> & be, 
314            const std::vector<data_t> & data) 
315    {
316        assert( (index < size_tab) and
317                "MEMC ERROR: The selected entry is out of range in TRT write_data_mask()");
318
319        assert( (be.size() == tab[index].wdata_be.size()) and
320                "MEMC ERROR: Bad be size in TRT write_data_mask()");
321
322        assert( (data.size() == tab[index].wdata.size()) and
323                "MEMC ERROR: Bad data size in TRT write_data_mask()");
324
325        for (size_t i = 0; i < tab[index].wdata_be.size(); i++) 
326        {
327            tab[index].wdata_be[i] = tab[index].wdata_be[i] | be[i];
328            data_t mask = be_to_mask(be[i]);
329            tab[index].wdata[i] = (tab[index].wdata[i] & ~mask) | (data[i] & mask);
330        }
331    }
332    /////////////////////////////////////////////////////////////////////
333    // The set() function registers a transaction (read or write)
334    // to the XRAM in the transaction tab.
335    // Arguments :
336    // - index : index in the transaction tab
337    // - xram_read : transaction type (read or write a cache line)
338    // - nline : the index (zy) of the cache line
339    // - srcid : srcid of the initiator that caused the transaction
340    // - trdid : trdid of the initiator that caused the transaction
341    // - pktid : pktid of the initiator that caused the transaction
342    // - proc_read : does the initiator want a copy
343    // - read_length : length of read (in case of processor read)
344    // - word_index : index in the line (in case of single word read)
345    // - data : the data to write (in case of write)
346    // - data_be : the mask of the data to write (in case of write)
347    // - ll_key  : the ll key (if any) returned by the llsc_global_table
348    // - config  : transaction required by config FSM
349    /////////////////////////////////////////////////////////////////////
350    void set(const size_t index,
351            const bool xram_read,
352            const addr_t nline,
353            const size_t srcid,
354            const size_t trdid,
355            const size_t pktid,
356            const bool proc_read,
357            const size_t read_length,
358            const size_t word_index,
359            const std::vector<be_t> & data_be,
360            const std::vector<data_t> & data, 
361            const data_t ll_key = 0,
362            const bool config = false) 
363    {
364        assert((index < size_tab) and
365                "MEMC ERROR: The selected entry is out of range in TRT set()");
366
367        assert((data_be.size()==tab[index].wdata_be.size()) and
368                "MEMC ERROR: Bad data_be argument in TRT set()");
369
370        assert((data.size()==tab[index].wdata.size()) and
371                "MEMC ERROR: Bad data argument in TRT set()");
372
373        tab[index].valid       = true;
374        tab[index].xram_read   = xram_read;
375        tab[index].nline       = nline;
376        tab[index].srcid       = srcid;
377        tab[index].trdid       = trdid;
378        tab[index].pktid       = pktid;
379        tab[index].proc_read   = proc_read;
380        tab[index].read_length = read_length;
381        tab[index].word_index  = word_index;
382        tab[index].ll_key      = ll_key;
383        tab[index].config      = config;
384        for (size_t i = 0; i < tab[index].wdata.size(); i++) 
385        {
386            tab[index].wdata_be[i] = data_be[i];
387            tab[index].wdata[i]    = data[i];
388        }
389    }
390
391    /////////////////////////////////////////////////////////////////////
392    // The write_rsp() function writes two 32 bits words of the response
393    // to a XRAM read transaction.
394    // The BE field in TRT is taken into account.
395    // Arguments :
396    // - index : index of the entry in TRT
397    // - word  : index of the 32 bits word in the line
398    // - data  : 64 bits value (first data right)
399    /////////////////////////////////////////////////////////////////////
400    void write_rsp(const size_t index,
401            const size_t        word,
402            const wide_data_t   data,
403            const bool          rerror)
404    {
405        data_t value;
406        data_t mask;
407
408        assert((index < size_tab) and
409                "MEMC ERROR: The selected entry is out of range in TRT write_rsp()");
410
411        assert((word < tab[index].wdata_be.size()) and
412                "MEMC ERROR: Bad word index in TRT write_rsp()");
413
414        assert((tab[index].valid) and
415                "MEMC ERROR: TRT entry not valid in TRT write_rsp()");
416
417        assert((tab[index].xram_read ) and
418                "MEMC ERROR: TRT entry is not a GET in TRT write_rsp()");
419
420        if (rerror)
421        {
422            tab[index].rerror = true;
423            return;
424        }
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.