source: branches/wt_ideal/lib/generic_cache_tsar/include/generic_cache.h @ 920

Last change on this file since 920 was 920, checked in by meunier, 9 years ago
  • Adding branch wt_ideal -- "ideal" write-through
File size: 27.3 KB
Line 
1/* -*- c++ -*-
2 *
3 * SOCLIB_LGPL_HEADER_BEGIN
4 *
5 * This file is part of SoCLib, GNU LGPLv2.1.
6 *
7 * SoCLib is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; version 2.1 of the License.
10 *
11 * SoCLib is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with SoCLib; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 * SOCLIB_LGPL_HEADER_END
22 *
23 * Copyright (c) UPMC, Lip6
24 *         Alain Greiner <alain.greiner@lip6.fr> July 2008
25 *
26 * Maintainers: alain
27 */
28
29////////////////////////////////////////////////////////////////////////////////
30// File         : generic_cache.h
31// Date         : 07/01/2012
32// Authors      : Alain Greiner
33/////////////////////////////////////////////////////////////////////////////////
34// This object is a generic, set associative, cache.
35// Each slot can be in two states: VALID OR INVALID.
36// Hit if ((matching tag) and (state == VALID).
37// The replacement policy is pseudo-LRU. The victim selection process cannot
38// fail.
39/////////////////////////////////////////////////////////////////////////////////
40// Implementation note
41// The DATA part is implemented as an uint32_t array[nways*nsets*nwords].
42// The DIRECTORY part is implemented as an uint32_t array[nways*nsets].
43// All methods requiring a dual port RAM or cache modification using
44// an associative search have been deprecated.
45/////////////////////////////////////////////////////////////////////////////////
46// Constructor parameters are :
47// - std::string    &name
48// - size_t         nways   : number of associativity levels
49// - size_t         nsets   : number of sets
50// - size_t         nwords  : number of words in a cache line
51// The nways, nsets, nwords parameters must be power of 2
52// The nsets parameter cannot be larger than 1024
53// The nways parameter cannot be larger than 16
54// The nwords parameter cannot be larger than 64
55/////////////////////////////////////////////////////////////////////////////////
56// Template parameter is :
57// - addr_t : address format to access the cache
58/////////////////////////////////////////////////////////////////////////////////
59
60#ifndef SOCLIB_GENERIC_CACHE_H
61#define SOCLIB_GENERIC_CACHE_H
62
63#include <systemc>
64#include <cassert>
65#include "arithmetics.h"
66#include "static_assert.h"
67#include "mapping_table.h"
68#include <cstring>
69
70namespace soclib { 
71
72enum cache_slot_state_e
73{
74    CACHE_SLOT_STATE_INVALID,
75    CACHE_SLOT_STATE_VALID,
76};
77
78//////////////////////////
79template<typename addr_t>
80class GenericCache
81//////////////////////////
82{
83    typedef uint32_t data_t;
84    typedef uint32_t be_t;
85
86    data_t * r_data;
87    addr_t * r_tag;
88    int    * r_state;
89    bool   * r_lru;
90
91    size_t m_ways; 
92    size_t m_sets; 
93    size_t m_words;
94
95    const soclib::common::AddressMaskingTable<addr_t> m_x;
96    const soclib::common::AddressMaskingTable<addr_t> m_y;
97    const soclib::common::AddressMaskingTable<addr_t> m_z;
98
99    //////////////////////////////////////////////////////////////
100    inline data_t &cache_data(size_t way, size_t set, size_t word)
101    {
102        return r_data[(way * m_sets * m_words) + (set * m_words) + word];
103    }
104
105    //////////////////////////////////////////////
106    inline addr_t &cache_tag(size_t way, size_t set)
107    {
108        return r_tag[(way * m_sets) + set];
109    }
110
111    //////////////////////////////////////////////
112    inline bool &cache_lru(size_t way, size_t set)
113    {
114        return r_lru[(way * m_sets) + set];
115    }
116
117    //////////////////////////////////////////////
118    inline int &cache_state(size_t way, size_t set)
119    {
120        return r_state[(way * m_sets) + set];
121    }
122
123    /////////////////////////////////////////////////
124    inline void cache_set_lru(size_t way, size_t set)
125    {
126        size_t way2;
127
128        cache_lru(way, set) = true;
129
130        for (way2 = 0; way2 < m_ways; way2++) 
131        {
132            if (cache_lru(way2, set) == false) return;
133        }
134        // all lines are new -> they all become old
135        for (way2 = 0; way2 < m_ways; way2++) 
136        {
137            cache_lru(way2, set) = false;
138        }
139    }
140
141    ////////////////////////////////
142    inline data_t be2mask(be_t be)
143    {
144        data_t mask = 0;
145        if ((be & 0x1) == 0x1) mask = mask | 0x000000FF;
146        if ((be & 0x2) == 0x2) mask = mask | 0x0000FF00;
147        if ((be & 0x4) == 0x4) mask = mask | 0x00FF0000;
148        if ((be & 0x8) == 0x8) mask = mask | 0xFF000000;
149        return mask;
150    }
151
152    public:
153
154    //////////////////////////////////////////
155    GenericCache(const std::string &name,
156            size_t nways, 
157            size_t nsets, 
158            size_t nwords)
159        : m_ways(nways),
160        m_sets(nsets),
161        m_words(nwords),
162
163#define l2 soclib::common::uint32_log2
164
165        m_x( l2(nwords), l2(sizeof(data_t))),
166        m_y( l2(nsets), l2(nwords) + l2(sizeof(data_t))),
167        m_z( 8*sizeof(addr_t) - l2(nsets) - l2(nwords) - l2(sizeof(data_t)),
168                l2(nsets) + l2(nwords) + l2(sizeof(data_t)))
169#undef l2
170        {
171            assert(IS_POW_OF_2(nways));
172            assert(IS_POW_OF_2(nsets));
173            assert(IS_POW_OF_2(nwords));
174            assert(nwords);
175            assert(nsets);
176            assert(nways);
177            assert(nwords <= 64);
178            assert(nsets <= 1024);
179            assert(nways <= 16);
180
181#ifdef GENERIC_CACHE_DEBUG
182            std::cout << "constructing " << name << std::endl
183                << "- nways  = " << nways << std::endl
184                << "- nsets  = " << nsets << std::endl
185                << "- nwords = " << nwords << std::endl
186                << " m_x: " << m_x
187                << " m_y: " << m_y
188                << " m_z: " << m_z
189                << std::endl;
190#endif
191
192            r_data  = new data_t[nways * nsets * nwords];
193            r_tag   = new addr_t[nways * nsets];
194            r_state = new int[nways * nsets];
195            r_lru   = new bool[nways * nsets];
196        }
197
198    ////////////////
199    ~GenericCache()
200    {
201        delete [] r_data;
202        delete [] r_tag;
203        delete [] r_state;
204        delete [] r_lru;
205    }
206
207    ////////////////////
208    inline void reset( )
209    {
210        std::memset(r_data, 0, sizeof(*r_data) * m_ways * m_sets * m_words);
211        std::memset(r_tag, 0, sizeof(*r_tag) * m_ways * m_sets);
212        std::memset(r_state, CACHE_SLOT_STATE_INVALID, sizeof(*r_state) * m_ways * m_sets);
213        std::memset(r_lru, 0, sizeof(*r_lru) * m_ways * m_sets);
214    }
215
216    /////////////////////////////////////////////////////////////////////
217    // Read a single 32 bits word.
218    // returns true if (matching tag) and (state == VALID)
219    // Both data & directory are accessed.
220    /////////////////////////////////////////////////////////////////////
221    inline bool read(addr_t ad, 
222                     data_t * dt)
223    {
224        const addr_t tag  = m_z[ad];
225        const size_t set  = m_y[ad];
226        const size_t word = m_x[ad];
227
228        for (size_t way = 0; way < m_ways; way++)
229        {
230            if ((tag == cache_tag(way, set)) 
231                    && (cache_state(way, set) == CACHE_SLOT_STATE_VALID))
232            {
233                *dt = cache_data(way, set, word);
234                cache_set_lru(way, set);
235                return true;
236            }
237        }
238        return false;
239    }
240
241    ////////////////////////////////////////////////////////////////////
242    // Read a single 32 bits word.
243    // returns true if (matching tag) and (state == VALID)
244    // Both data & directory are accessed.
245    // The selected way, set and word index are returned in case of hit.
246    /////////////////////////////////////////////////////////////////////
247    inline bool read(addr_t ad, 
248            data_t * dt,
249            size_t * selway,
250            size_t * selset,
251            size_t * selword) 
252    {
253        const addr_t tag  = m_z[ad];
254        const size_t set  = m_y[ad];
255        const size_t word = m_x[ad];
256
257        for (size_t way = 0; way < m_ways; way++) 
258        {
259            if ((tag == cache_tag(way, set)) and (cache_state(way, set) == CACHE_SLOT_STATE_VALID))
260            {
261                *selway  = way;
262                *selset  = set;
263                *selword = word;
264                *dt = cache_data(way, set, word);
265                cache_set_lru(way, set);
266                return true;
267            }
268        }
269        return false;
270    }
271
272    ////////////////////////////////////////////////////////////////////
273    // Read a single 32 bits word
274    // Both data and directory are accessed.
275    // returns the access status in the state argument:
276    // - VALID : (matching tag) and (state == VALID)
277    // - MISS  : no matching tag or INVALID state
278    // If VALID, the data, the way, set and word index are
279    // returned in the other arguments.
280    ////////////////////////////////////////////////////////////////////
281    inline void read(addr_t ad,
282            data_t * dt,
283            size_t * selway,
284            size_t * selset,
285            size_t * selword,
286            int * state) 
287    {
288        const addr_t tag  = m_z[ad];
289        const size_t set  = m_y[ad];
290        const size_t word = m_x[ad];
291
292        // default return values
293        *state   = CACHE_SLOT_STATE_INVALID;
294        *selway  = 0;
295        *selset  = 0;
296        *selword = 0;
297        *dt      = 0;
298
299        for (size_t way = 0; way < m_ways; way++) 
300        {
301            if (tag == cache_tag(way, set))  // matching tag
302            {
303
304                if (cache_state(way, set) == CACHE_SLOT_STATE_VALID)
305                {
306                    *state   = CACHE_SLOT_STATE_VALID;
307                    *selway  = way;
308                    *selset  = set;
309                    *selword = word;
310                    *dt      = cache_data(way, set, word);
311                    cache_set_lru(way, set);
312                }
313            }
314        }
315    }
316
317    ////////////////////////////////////////////////////////////////////
318    // Read a single 32 bits word, without LRU update.
319    // returns true if (matching tag) and (state == VALID)
320    // Both data & directory are accessed.
321    // The selected way, set and word index are returned in case of hit.
322    /////////////////////////////////////////////////////////////////////
323    inline bool read_neutral(addr_t ad, 
324            data_t * dt,
325            size_t * selway,
326            size_t * selset,
327            size_t * selword) 
328    {
329        const addr_t tag  = m_z[ad];
330        const size_t set  = m_y[ad];
331        const size_t word = m_x[ad];
332
333        for (size_t way = 0; way < m_ways; way++) 
334        {
335            if ((tag == cache_tag(way, set)) && (cache_state(way, set) == CACHE_SLOT_STATE_VALID))
336            {
337                *selway  = way;
338                *selset  = set;
339                *selword = word;
340                *dt = cache_data(way, set, word);
341                return true;
342            }
343        }
344        return false;
345    }
346
347    /////////////////////////////////////////////////////////////////////////////
348    // Read one or two 32 bits word.
349    // Both data & directory are accessed.
350    // Hit if (matching tag) and (valid == true) and (zombi == false)
351    // If the addressed word is not the last in the cache line,
352    // two successive words are returned.
353    // The selected way, set and first word index are returned in case of hit.
354    // This function is used by the cc_vcache to get a 64 bits page table entry.
355    /////////////////////////////////////////////////////////////////////////////
356    inline bool read(addr_t ad, 
357            data_t * dt, 
358            data_t * dt_next,
359            size_t * selway,
360            size_t * selset,
361            size_t * selword)
362    {
363        const addr_t tag  = m_z[ad];
364        const size_t set  = m_y[ad];
365        const size_t word = m_x[ad];
366
367        for (size_t way = 0; way < m_ways; way++)
368        {
369            if ((tag == cache_tag(way, set))
370                    && (cache_state(way, set) == CACHE_SLOT_STATE_VALID))
371            {
372                *dt = cache_data(way, set, word);
373                if (word + 1 < m_words) 
374                {
375                    *dt_next = cache_data(way, set, word + 1);
376                }
377                *selway  = way;
378                *selset  = set;
379                *selword = word;
380                cache_set_lru(way, set);
381                return true;
382            }
383        }
384        return false;
385    }
386
387    ////////////////////////////////////////////////////////////////////
388    // Read one or two 32 bits word.
389    // Both data and directory are accessed.
390    // returns the access status in the state argument:
391    // - VALID : (matching tag) and (state == VALID)
392    // - MISS  : no matching tag or INVALID state
393    // If VALID, the data, the way, set and word index are
394    // returned in the other arguments.
395    ////////////////////////////////////////////////////////////////////
396    inline void read(addr_t ad,
397            data_t * dt,
398            data_t * dt_next,
399            size_t * selway,
400            size_t * selset,
401            size_t * selword,
402            int * state) 
403    {
404        const addr_t tag  = m_z[ad];
405        const size_t set  = m_y[ad];
406        const size_t word = m_x[ad];
407
408        // default return values
409        *state   = CACHE_SLOT_STATE_INVALID;
410        *selway  = 0;
411        *selset  = 0;
412        *selword = 0;
413        *dt      = 0;
414
415        for (size_t way = 0; way < m_ways; way++) 
416        {
417            if (tag == cache_tag(way, set))  // matching tag
418            {
419                if (cache_state(way, set) == CACHE_SLOT_STATE_VALID)
420                {
421                    *state   = CACHE_SLOT_STATE_VALID;
422                    *selway  = way;
423                    *selset  = set;
424                    *selword = word;
425                    *dt      = cache_data(way, set, word);
426                    if (word + 1 < m_words) 
427                    {
428                        *dt_next = cache_data(way, set, word + 1);
429                    }
430                    else {
431                        assert(false && "can't request 2 words at end of line");
432                    }
433                    cache_set_lru(way, set);
434                }
435            }
436        }
437    }
438
439    ///////////////////////////////////////////////////////////////////////////////
440    // Checks the cache state for a given address.
441    // Only the directory is accessed.
442    // returns true if (matching tag) and (state == VALID)
443    // The selected way, set and first word index are returned in case of hit.
444    // This function can be used when we need to access the directory
445    // while we write in the data part with a different address in the same cycle.
446    ///////////////////////////////////////////////////////////////////////////////
447    inline bool hit(addr_t ad, 
448            size_t * selway,
449            size_t * selset,
450            size_t * selword)
451    {
452        const addr_t tag  = m_z[ad];
453        const size_t set  = m_y[ad];
454        const size_t word = m_x[ad];
455
456        for (size_t way = 0; way < m_ways; way++) 
457        {
458            if ((tag == cache_tag(way, set)) 
459                    && (cache_state(way, set) == CACHE_SLOT_STATE_VALID)) 
460            {
461                *selway  = way;
462                *selset  = set;
463                *selword = word;
464                cache_set_lru(way, set);
465                return true;
466            }
467        }
468        return false;
469    }
470
471    ///////////////////////////////////////////////////////////////////////////////
472    // Checks the cache state for a given address.
473    // Only the directory is accessed.
474    // Returns the access status in the state argument:
475    // - VALID if (matching tag) and (state == VALID)
476    // - INVALID if no match or (state == INVALID)
477    // The selected way, set and first word index are returned if not empty.
478    // This function can be used when we need to access the directory
479    // while we write in the data part with a different address in the same cycle.
480    ///////////////////////////////////////////////////////////////////////////////
481    inline void read_dir(addr_t ad, 
482            int * state,
483            size_t * way,
484            size_t * set,
485            size_t * word)
486    {
487        const addr_t ad_tag  = m_z[ad];
488        const size_t ad_set  = m_y[ad];
489        const size_t ad_word = m_x[ad];
490
491        for (size_t _way = 0; _way < m_ways; _way++) 
492        {
493            if ((ad_tag == cache_tag(_way, ad_set)) and
494                    (cache_state(_way, ad_set) != CACHE_SLOT_STATE_INVALID)) 
495            {
496                *state = cache_state(_way, ad_set);
497                *way   = _way;
498                *set   = ad_set;
499                *word  = ad_word;
500                return;
501            }
502        }
503
504        // return value if not (VALID)
505        *state = CACHE_SLOT_STATE_INVALID;
506    }
507
508    ///////////////////////////////////////////////////////////////////////////////
509    // Checks the cache state for a slot (set,way)
510    // Only the directory is accessed.
511    // Returns the access status and the tag value in the state and tag argument.
512    ///////////////////////////////////////////////////////////////////////////////
513    inline void read_dir(size_t way,
514            size_t set,
515            addr_t * tag,
516            int * state)
517    {
518        *state = cache_state(way, set);
519        *tag   = cache_tag(way, set);
520    }
521
522    ////////////////////////////////////////////
523    inline addr_t get_tag(size_t way, size_t set)
524    {
525        return cache_tag(way, set);
526    }
527
528    ///////////////////////////////////////////////////////////////////
529    // This function writes a complete 32 bits word
530    // It does not use the directory and cannot miss.
531    //////////////////////////////////////////////////////////////////
532    inline void write(size_t  way, 
533            size_t set, 
534            size_t word, 
535            data_t data)
536    {
537        cache_data(way, set, word) = data;
538        cache_set_lru(way, set);
539    }
540
541    ////////////////////////////////////////////////////////////////////////////
542    // this function writes up to 4 bytes, taking into account the byte enable.
543    // It does not use the directory and cannot miss.
544    ////////////////////////////////////////////////////////////////////////////
545    inline void write(size_t way, 
546            size_t set, 
547            size_t word, 
548            data_t data, 
549            be_t   be)
550    {
551        data_t mask = be2mask(be);
552        data_t prev = cache_data(way, set, word);
553        cache_data(way, set, word) = (mask & data) | (~mask & prev);
554        cache_set_lru(way, set);
555    }
556
557    //////////////////////////////////////////////////////////////////////////
558    // This function invalidates a cache line identified by the set and way.
559    // It returns true if the line was valid, and returns the line index.
560    //////////////////////////////////////////////////////////////////////////
561    inline bool inval(size_t way, 
562            size_t set, 
563            addr_t * nline)
564    {
565        if (cache_state(way,set) == CACHE_SLOT_STATE_VALID ) 
566        {
567            cache_state(way,set) = CACHE_SLOT_STATE_INVALID;
568            *nline = (data_t)cache_tag(way,set) * m_sets + set;
569            return true;
570        }
571        return false;
572    }
573
574    //////////////////////////////////////////////////////////////////////////////////
575    // This function selects a victim slot in an associative set.
576    // It cannot fail.
577    // - we search first an INVALID slot
578    // - if no INVALID slot, we search an OLD slot, using lru
579    // It returns the line index (Z + Y fields), the selected slot way and set,
580    // and a Boolean indicating that a cleanup is requested.
581    //////////////////////////////////////////////////////////////////////////////////
582    inline bool victim_select(addr_t ad, 
583            addr_t * victim, 
584            size_t * way, 
585            size_t * set)
586    {
587        bool found   = false;
588        bool cleanup = false;
589
590        *set = m_y[ad];
591        *way = 0;
592
593        // Search first empty slot
594        for (size_t _way = 0; _way < m_ways && !found; _way++)
595        {
596            if (cache_state(_way, *set) != CACHE_SLOT_STATE_VALID)  // empty
597            {
598                found   = true;
599                cleanup = false;
600                *way    = _way;
601            }
602        }
603
604        // If no empty slot, search first  old slot (lru == false)
605        if (!found)
606        { 
607            for (size_t _way = 0; _way < m_ways && !found; _way++)
608            {
609                if (not cache_lru(_way, *set))
610                {
611                    found   = true;
612                    cleanup = true;
613                    *way    = _way;
614                }
615            }
616        }
617
618        assert(found && "all ways can't be new at the same time");
619        *victim = (addr_t) ((cache_tag(*way, *set) * m_sets) + *set);
620        return cleanup;
621    }
622
623    //////////////////////////////////////////////////////////////////////////////////
624    // This function selects a victim slot in an associative set.
625    // - we search first an INVALID slot
626    // - if not found we search a slot with the LRU bit unset
627    // It returns the line index (Z + Y fields), the selected slot way and set,
628    // and two Boolean indicating success and a required cleanup.
629    //////////////////////////////////////////////////////////////////////////////////
630    inline void read_select(addr_t ad, 
631            addr_t * victim, 
632            size_t * way, 
633            size_t * set,
634            bool * found,
635            bool * cleanup)
636    {
637        size_t _set = m_y[ad];
638
639        *found = false;
640
641        // Search first empty slot
642        for (size_t _way = 0; _way < m_ways && !(*found); _way++)
643        {
644            if (cache_state(_way, _set) == CACHE_SLOT_STATE_INVALID)
645            {
646                *found   = true;
647                *cleanup = false;
648                *way     = _way;
649                *set     = m_y[ad];
650                return;
651            }
652        }
653        // all ways are valid, searching one with the LRU bit at 0
654        for (size_t _way = 0; _way < m_ways && !(*found); _way++)
655        {
656            if (not cache_lru(_way, _set))
657            {
658                *found   = true;
659                *cleanup = true;
660                *way     = _way;
661                *set     = m_y[ad];
662                *victim  = cache_tag(*way, _set) * m_sets + _set;
663                return;
664            }
665        }
666        assert(false);
667        // We should not be able to arrive here
668        // returning way 0
669        *found   = true;
670        *cleanup = true;
671        *way     = 0;
672        *set     = m_y[ad];
673        *victim  = cache_tag(*way, _set) * m_sets + _set;
674        return;
675    }
676
677    //////////////////////////////////////////////////////////////////
678    // This function update the directory part of a slot
679    // identified by the way & set.
680    //////////////////////////////////////////////////////////////////
681    inline void victim_update_tag(addr_t ad, 
682            size_t way, 
683            size_t set)
684    {
685        addr_t tag = m_z[ad];
686
687        cache_tag(way, set) = tag;
688        cache_state(way, set) = CACHE_SLOT_STATE_VALID;
689        cache_set_lru(way, set);
690    }
691
692    //////////////////////////////////////////////////////////////////
693    // This function write the directory part of a slot
694    // identified by the way & set
695    //////////////////////////////////////////////////////////////////
696    inline void write_dir( addr_t ad, 
697            size_t way, 
698            size_t set,
699            int    state)
700    {
701        addr_t tag = m_z[ad];
702
703        assert(((state == CACHE_SLOT_STATE_VALID) or
704                (state == CACHE_SLOT_STATE_INVALID)) and
705                "illegal slot state argument in Generic Cache write_dir()");
706
707        assert((way < m_ways) and "too large way index argument in Generic Cache write_dir()");
708        assert((set < m_sets) and "too large set index argument in Generic Cache write_dir()");
709
710        cache_tag(way, set) = tag;
711        cache_state(way, set) = state;
712
713        if (state == CACHE_SLOT_STATE_VALID) cache_set_lru(way, set);
714    }
715
716    //////////////////////////////////////////////////////////////////
717    // This function change the state of a slot
718    // identified by the way & set.
719    // It does not affect the tag
720    //////////////////////////////////////////////////////////////////
721    inline void write_dir(size_t way, 
722            size_t set,
723            int    state)
724    {
725        assert(((state == CACHE_SLOT_STATE_VALID) or
726                (state == CACHE_SLOT_STATE_INVALID)) and
727                "illegal slot state argument in Generic Cache write_dir()");
728
729        assert((way < m_ways) and "too large way index argument in Generic Cache write_dir()");
730        assert((set < m_sets) and "too large set index argument in Generic Cache write_dir()");
731
732        cache_state(way, set) = state;
733
734        if (state == CACHE_SLOT_STATE_VALID) cache_set_lru(way, set);
735    }
736
737    ///////////////////////////////////////////////////////////////////
738    // This function writes a full cache line in one single cycle.
739    // The target slot is identified by the way & set arguments.
740    // Both DATA and DIRECTORY are written
741    ///////////////////////////////////////////////////////////////////
742    inline void update(addr_t ad, 
743            size_t way, 
744            size_t set, 
745            data_t * buf)
746    {
747        addr_t tag = m_z[ad];
748
749        cache_tag(way, set) = tag;
750        cache_state(way, set) = CACHE_SLOT_STATE_VALID;
751        cache_set_lru(way, set);
752        for (size_t word = 0; word < m_words; word++) 
753        {
754            cache_data(way, set, word) = buf[word] ;
755        }
756    }
757
758    ///////////////////////////
759    void fileTrace(FILE * file)
760    {
761        for (size_t nway = 0; nway < m_ways; nway++) 
762        {
763            for (size_t nset = 0; nset < m_sets; nset++) 
764            {
765                fprintf(file, "%d / ", (int) cache_state(nway, nset));
766                fprintf(file, "way %d / ", (int) nway);
767                fprintf(file, "set %d / ", (int) nset);
768                fprintf(file, "@ = %08zX / ", 
769                        ((cache_tag(nway, nset) * m_sets+nset) * m_words * 4));
770                for (size_t nword = m_words; nword > 0; nword--) 
771                {
772                    unsigned int data = cache_data(nway, nset, nword - 1);
773                    fprintf(file, "%08X ", data );
774                }
775                fprintf(file, "\n");
776            }
777        }
778    }
779
780    ////////////////////////
781    inline void printTrace()
782    {
783        for ( size_t way = 0; way < m_ways ; way++ ) 
784        {
785            for ( size_t set = 0 ; set < m_sets ; set++ )
786            {
787                addr_t addr = (((addr_t) cache_tag(way,set)) * m_words * m_sets + m_words * set) * 4;
788                std::cout << std::dec << cache_state(way, set) 
789                    << " | way " << way
790                    << " | set " << set
791                    << std::hex << " | @ " << addr;
792
793                for ( size_t word = 0 ; word < m_words ; word++ )
794                {
795                    std::cout << " | " << cache_data(way,set,word) ;
796                }
797                std::cout << std::endl ;
798            }
799        }
800    }
801
802};
803
804} // namespace soclib
805
806#endif
807
808// Local Variables:
809// tab-width: 4
810// c-basic-offset: 4
811// c-file-offsets:((innamespace . 0)(inline-open . 0))
812// indent-tabs-mode: nil
813// End:
814
815// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
816
Note: See TracBrowser for help on using the repository browser.