• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

sst/elements/genericProc/ssBackEnd/ssb_cache.h

00001 /*
00002  * cache.h - cache module interfaces
00003  *
00004  * This file is a part of the SimpleScalar tool suite written by
00005  * Todd M. Austin as a part of the Multiscalar Research Project.
00006  *  
00007  * The tool suite is currently maintained by Doug Burger and Todd M. Austin.
00008  * 
00009  * Copyright (C) 1994, 1995, 1996, 1997, 1998 by Todd M. Austin
00010  *
00011  * This source file is distributed "as is" in the hope that it will be
00012  * useful.  The tool set comes with no warranty, and no author or
00013  * distributor accepts any responsibility for the consequences of its
00014  * use. 
00015  * 
00016  * Everyone is granted permission to copy, modify and redistribute
00017  * this tool set under the following conditions:
00018  * 
00019  *    This source code is distributed for non-commercial use only. 
00020  *    Please contact the maintainer for restrictions applying to 
00021  *    commercial use.
00022  *
00023  *    Permission is granted to anyone to make or distribute copies
00024  *    of this source code, either as received or modified, in any
00025  *    medium, provided that all copyright notices, permission and
00026  *    nonwarranty notices are preserved, and that the distributor
00027  *    grants the recipient permission for further redistribution as
00028  *    permitted by this document.
00029  *
00030  *    Permission is granted to distribute this file in compiled
00031  *    or executable form under the same conditions that apply for
00032  *    source code, provided that either:
00033  *
00034  *    A. it is accompanied by the corresponding machine-readable
00035  *       source code,
00036  *    B. it is accompanied by a written offer, with no time limit,
00037  *       to give anyone a machine-readable copy of the corresponding
00038  *       source code in return for reimbursement of the cost of
00039  *       distribution.  This written offer must permit verbatim
00040  *       duplication by anyone, or
00041  *    C. it is distributed by someone who received only the
00042  *       executable form, and is accompanied by a copy of the
00043  *       written offer of source code that they received concurrently.
00044  *
00045  * In other words, you are welcome to use, share and improve this
00046  * source file.  You are forbidden to forbid anyone else to use, share
00047  * and improve what you give them.
00048  *
00049  * INTERNET: dburger@cs.wisc.edu
00050  * US Mail:  1210 W. Dayton Street, Madison, WI 53706
00051  *
00052  * $Id: ssb_cache.h,v 1.2 2006-08-24 19:05:27 afrodri Exp $
00053  *
00054  * $Log: not supported by cvs2svn $
00055  * Revision 1.1.1.1  2006/01/31 16:35:49  afrodri
00056  * first entry
00057  *
00058  * Revision 1.5  2004/11/16 04:17:46  arodrig6
00059  * added more documentation
00060  *
00061  * Revision 1.4  2004/10/27 21:03:39  arodrig6
00062  * added SMP support
00063  *
00064  * Revision 1.3  2004/08/20 01:17:50  arodrig6
00065  * began integrating SW2/DRAM with ssBack
00066  *
00067  * Revision 1.2  2004/08/10 22:55:35  arodrig6
00068  * works, except for the speculative stuff, caches, and multiple procs
00069  *
00070  * Revision 1.1  2004/08/05 23:51:44  arodrig6
00071  * grabed files from SS and broke up some of them
00072  *
00073  * Revision 1.1.1.1  2000/03/07 05:15:16  karu
00074  * this is the repository created for my own maintanence.
00075  * created when spec95 (lisp and compress worked).
00076  * compress still had the scanf("%i") problem
00077  * DIFF from the repository I am using alongwith ramdass on /projects
00078  * need to merge the two sometime :-)
00079  *
00080  * Revision 1.1.1.1  2000/02/25 21:02:49  karu
00081  * creating cvs repository for ss3-ppc
00082  *
00083  * Revision 1.5  1998/08/27 08:09:13  taustin
00084  * implemented host interface description in host.h
00085  * added target interface support
00086  *
00087  * Revision 1.4  1997/03/11  01:09:45  taustin
00088  * updated copyright
00089  * long/int tweaks made for ALPHA target support
00090  *
00091  * Revision 1.3  1997/01/06  15:57:55  taustin
00092  * comments updated
00093  * cache_reg_stats() now works with stats package
00094  * cp->writebacks stat added to cache
00095  *
00096  * Revision 1.1  1996/12/05  18:50:23  taustin
00097  * Initial revision
00098  *
00099  *
00100  */
00101 
00102 #ifndef CACHE_H
00103 #define CACHE_H
00104 
00105 #include <stdio.h>
00106 
00107 #include "ssb_host.h"
00108 #include "ssb_misc.h"
00109 #include "ssb_machine.h"
00110 #include "ssb_memory.h"
00111 #include "ssb_stats.h"
00112 
00113 
00114 /* highly associative caches are implemented using a hash table lookup to
00115    speed block access, this macro decides if a cache is "highly associative" */
00116 #define CACHE_HIGHLY_ASSOC(cp)  ((cp)->assoc > 4)
00117 
00118 //: cache replacement policy 
00119 //!SEC:ssBack
00120 enum cache_policy {
00121   LRU,          /* replace least recently used block (perfect LRU) */
00122   Random,       /* replace a random block */
00123   FIFO          /* replace the oldest block in the set */
00124 };
00125 
00126 /* block status values */
00127 #define CACHE_BLK_VALID         0x00000001      /* block in valid, in use */
00128 #define CACHE_BLK_DIRTY         0x00000002      /* dirty block */
00129 
00130 //: cache block (or line) definition
00131 //!SEC:ssBack
00132 struct cache_blk_t
00133 {
00134   struct cache_blk_t *way_next; /* next block in the ordered way chain, used
00135                                    to order blocks for replacement */
00136   struct cache_blk_t *way_prev; /* previous block in the order way chain */
00137   struct cache_blk_t *hash_next;/* next block in the hash bucket chain, only
00138                                    used in highly-associative caches */
00139   /* since hash table lists are typically small, there is no previous
00140      pointer, deletion requires a trip through the hash table bucket list */
00141   md_addr_t tag;                /* data block tag value */
00142   unsigned int status;          /* block status, see CACHE_BLK_* defs above */
00143   tick_t ready;         /* time when block will be accessible, field
00144                                    is set when a miss fetch is initiated */
00145   byte_t *user_data;            /* pointer to user defined data, e.g.,
00146                                    pre-decode data or physical page address */
00147   /* DATA should be pointer-aligned due to preceeding field */
00148   /* NOTE: this is a variable-size tail array, this must be the LAST field
00149      defined in this structure! */
00150   byte_t data[1];               /* actual data block starts here, block size
00151                                    should probably be a multiple of 8 */
00152 };
00153 
00154 //: cache set definition 
00155 // cache set definition (one or more blocks sharing the same set index) 
00156 //!SEC:ssBack
00157 struct cache_set_t
00158 {
00159   struct cache_blk_t **hash;    /* hash table: for fast access w/assoc, NULL
00160                                    for low-assoc caches */
00161   struct cache_blk_t *way_head; /* head of way list */
00162   struct cache_blk_t *way_tail; /* tail pf way list */
00163   struct cache_blk_t *blks;     /* cache blocks, allocated sequentially, so
00164                                    this pointer can also be used for random
00165                                    access to cache blocks */
00166 };
00167 
00168 class convProc;
00169 
00170 //: cache definition 
00171 //
00172 // This module contains code to implement various cache-like
00173 // structures. The user instantiates caches using cache_new(). When
00174 // instantiated, the user may specify the geometry of the cache (i.e.,
00175 // number of set, line size, associativity), and supply a block access
00176 // function. The block access function indicates the latency to access
00177 // lines when the cache misses, accounting for any component of miss
00178 // latency, e.g., bus acquire latency, bus transfer latency, memory
00179 // access latency, etc... In addition, the user may allocate the cache
00180 // with or without lines allocated in the cache. Caches without tags
00181 // are useful when implementing structures that map data other than
00182 // the address space, e.g., TLBs which map the virtual address space
00183 // to physical page address, or BTBs which map text addresses to
00184 // branch prediction state. Tags are always allocated. User data may
00185 // also be optionally attached to cache lines, this space is useful to
00186 // storing auxilliary or additional cache line information, such as
00187 // predecode data, physical page address information, etc...
00188 //
00189 // The caches implemented by this module provide efficient storage
00190 // management and fast access for all cache geometries. When sets
00191 // become highly associative, a hash table (indexed by address) is
00192 // allocated for each set in the cache.
00193 //
00194 // This module also tracks latency of accessing the data cache, each
00195 // cache has a hit latency defined when instantiated, miss latency is
00196 // returned by the cache's block access function, the caches may
00197 // service any number of hits under any number of misses, the calling
00198 // simulator should limit the number of outstanding misses or the
00199 // number of hits under misses as per the limitations of the
00200 // particular microarchitecture being simulated.
00201 //
00202 // Due to the organization of this cache implementation, the latency
00203 // of a request cannot be affected by a later request to this
00204 // module. As a result, reordering of requests in the memory hierarchy
00205 // is not possible.
00206 //
00207 //!SEC:ssBack
00208 struct cache_t
00209 {
00210   /* parameters */
00211   char *name;                   /* cache name */
00212   convProc *proc;
00213   int nsets;                    /* number of sets */
00214   int bsize;                    /* block size in bytes */
00215   int balloc;                   /* maintain cache contents? */
00216   int usize;                    /* user allocated data size */
00217   int assoc;                    /* cache associativity */
00218   enum cache_policy policy;     /* cache replacement policy */
00219   unsigned int hit_latency;     /* cache hit latency */
00220 
00221   /* miss/replacement handler, read/write BSIZE bytes starting at BADDR
00222      from/into cache block BLK, returns the latency of the operation
00223      if initiated at NOW, returned latencies indicate how long it takes
00224      for the cache access to continue (e.g., fill a write buffer), the
00225      miss/repl functions are required to track how this operation will
00226      effect the latency of later operations (e.g., write buffer fills),
00227      if !BALLOC, then just return the latency; BLK_ACCESS_FN is also
00228      responsible for generating any user data and incorporating the latency
00229      of that operation */
00230   unsigned int                                  /* latency of block access */
00231   (convProc::*blk_access_fn)(enum mem_cmd cmd,  /* block access command */
00232                              md_addr_t baddr,   /* program address to access */
00233                              int bsize,         /* size of the cache block */
00234                              cache_blk_t *blk,  /* ptr to cache block struct */
00235                              tick_t now,        /* when fetch was initiated */
00236                              bool &needMM);
00237 
00238   /* derived data, for fast decoding */
00239   int hsize;                    /* cache set hash table size */
00240   md_addr_t blk_mask;
00241   int set_shift;
00242   md_addr_t set_mask;           /* use *after* shift */
00243   int tag_shift;
00244   md_addr_t tag_mask;           /* use *after* shift */
00245   md_addr_t tagset_mask;        /* used for fast hit detection */
00246 
00247   /* bus resource */
00248   tick_t bus_free;              /* time when bus to next level of cache is
00249                                    free, NOTE: the bus model assumes only a
00250                                    single, fully-pipelined port to the next
00251                                    level of memory that requires the bus only
00252                                    one cycle for cache line transfer (the
00253                                    latency of the access to the lower level
00254                                    may be more than one cycle, as specified
00255                                    by the miss handler */
00256 
00257   /* per-cache stats */
00258   counter_t hits;               /* total number of hits */
00259   counter_t misses;             /* total number of misses */
00260   counter_t replacements;       /* total number of replacements at misses */
00261   counter_t writebacks;         /* total number of writebacks at misses */
00262   counter_t invalidations;      /* total number of external invalidations */
00263   void resetStats() {
00264     hits = 0;   
00265     misses = 0;
00266     replacements = 0;   
00267     writebacks = 0;     
00268     invalidations = 0;
00269   }
00270 
00271   /* last block to hit, used to optimize cache hit processing */
00272   md_addr_t last_tagset;        /* tag of last line accessed */
00273   struct cache_blk_t *last_blk; /* cache block last accessed */
00274 
00275   /* data blocks */
00276   byte_t *data;                 /* pointer to data blocks allocation */
00277 
00278   /* NOTE: this is a variable-size tail array, this must be the LAST field
00279      defined in this structure! */
00280   struct cache_set_t sets[1];   /* each entry is a set */
00281 };
00282 
00283 //: create and initialize a general cache structure 
00284 struct cache_t *                        /* pointer to cache created */
00285 cache_create(char *name,                /* name of the cache */
00286              convProc *pr,
00287              int nsets,                 /* total number of sets in cache */
00288              int bsize,                 /* block (line) size of cache */
00289              int balloc,                /* allocate data space for blocks? */
00290              int usize,                 /* size of user data to alloc w/blks */
00291              int assoc,                 /* associativity of cache */
00292              enum cache_policy policy,  /* replacement policy w/in sets */
00293              /* block access function, see description w/in struct cache def */
00294              unsigned int (convProc::*blk_access_fn)(enum mem_cmd cmd,
00295                                            md_addr_t baddr, int bsize,
00296                                            struct cache_blk_t *blk,
00297                                                      tick_t now, bool&),
00298              unsigned int hit_latency);/* latency in cycles for a hit */
00299 
00300 //: parse policy 
00301 enum cache_policy                       /* replacement policy enum */
00302 cache_char2policy(char c);              /* replacement policy as a char */
00303 
00304 //: print cache configuration 
00305 void
00306 cache_config(struct cache_t *cp,        /* cache instance */
00307              FILE *stream);             /* output stream */
00308 
00309 //: register cache stats 
00310 void
00311 cache_reg_stats(struct cache_t *cp,     /* cache instance */
00312                 struct stat_sdb_t *sdb);/* stats database */
00313 
00314 //: print cache stats 
00315 void
00316 cache_stats(struct cache_t *cp,         /* cache instance */
00317             FILE *stream);              /* output stream */
00318 
00319 //: print cache stats 
00320 void cache_stats(struct cache_t *cp, FILE *stream);
00321 
00322 //: Access a cache
00323 //
00324 // access a cache, perform a CMD operation on cache CP at address
00325 // ADDR, places NBYTES of data at *P, returns latency of operation if
00326 // initiated at NOW, places pointer to block user data in *UDATA, *P
00327 // is untouched if cache blocks are not allocated (!CP->BALLOC), UDATA
00328 // should be NULL if no user data is attached to blocks
00329 unsigned int                            /* latency of access in cycles */
00330 cache_access(struct cache_t *cp,        /* cache to access */
00331              enum mem_cmd cmd,          /* access type, Read or Write */
00332              md_addr_t addr,            /* address of access */
00333              void *vp,                  /* ptr to buffer for input/output */
00334              int nbytes,                /* number of bytes to access */
00335              tick_t now,                /* time of access */
00336              byte_t **udata,            /* for return of user data ptr */
00337              md_addr_t *repl_addr,      /* for address of replaced block */
00338              bool &needMM,              /* does this need a main me access */
00339              md_addr_t *bumped);        /* Was an address ejected from cache */
00340 
00341 /* cache access functions, these are safe, they check alignment and
00342    permissions */
00343 /*#define cache_double(cp, cmd, addr, p, now, udata)            \
00344   cache_access(cp, cmd, addr, p, sizeof(double), now, udata)
00345 #define cache_float(cp, cmd, addr, p, now, udata)       \
00346   cache_access(cp, cmd, addr, p, sizeof(float), now, udata)
00347 #define cache_dword(cp, cmd, addr, p, now, udata)       \
00348   cache_access(cp, cmd, addr, p, sizeof(long long), now, udata)
00349 #define cache_word(cp, cmd, addr, p, now, udata)        \
00350   cache_access(cp, cmd, addr, p, sizeof(int), now, udata)
00351 #define cache_half(cp, cmd, addr, p, now, udata)        \
00352   cache_access(cp, cmd, addr, p, sizeof(short), now, udata)
00353 #define cache_byte(cp, cmd, addr, p, now, udata)        \
00354 cache_access(cp, cmd, addr, p, sizeof(char), now, udata)*/
00355 
00356 /* return non-zero if block containing address ADDR is contained in cache
00357    CP, this interface is used primarily for debugging and asserting cache
00358    invariants */
00359 int                                     /* non-zero if access would hit */
00360 cache_probe(struct cache_t *cp,         /* cache instance to probe */
00361             md_addr_t addr);            /* address of block to probe */
00362 
00363 /* flush the entire cache, returns latency of the operation */
00364 unsigned int                            /* latency of the flush operation */
00365 cache_flush(struct cache_t *cp,         /* cache instance to flush */
00366             tick_t now);                /* time of cache flush */
00367 
00368 /* flush the block containing ADDR from the cache CP, returns the latency of
00369    the block flush operation */
00370 unsigned int                            /* latency of flush operation */
00371 cache_flush_addr(struct cache_t *cp,    /* cache instance to flush */
00372                  md_addr_t addr,        /* address of block to flush */
00373                  tick_t now);           /* time of cache flush */
00374 /* invalidate the block containing ADDR from the cache CP, returns the
00375    latency of the operation. does not flush to backing store */
00376 unsigned int                            /* latency of flush operation */
00377 cache_invalidate_addr(struct cache_t *cp,       /* cache instance to flush */
00378                       md_addr_t addr,   /* address of block to flush */
00379                       tick_t now);              /* time of cache flush */
00380 
00381 md_addr_t cache_get_blkAddr(struct cache_t *cp, md_addr_t addr);
00382 #endif /* CACHE_H */

Generated on Fri Oct 22 2010 11:02:24 for SST by  doxygen 1.7.1