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

sst/core/techModels/libsim-panalyzer/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: cache.h,v 1.2 2003/12/18 20:31:59 panalyzer Exp $
00053  *
00054  * $Log: cache.h,v $
00055  * Revision 1.2  2003/12/18 20:31:59  panalyzer
00056  * *** empty log message ***
00057  *
00058  * Revision 1.1.1.1  2003/09/18 00:57:54  panalyzer
00059  *
00060  *
00061  * Revision 1.1.1.1  2003/09/18 00:18:43  panalyzer
00062  *
00063  *
00064  * Revision 1.1.1.1  2003/09/16 18:48:14  gdm
00065  *
00066  *
00067  * Revision 1.1.1.1  2000/11/29 14:53:54  cu-cs
00068  * Grand unification of arm sources.
00069  *
00070  *
00071  * Revision 1.1.1.1  2000/05/26 15:18:57  taustin
00072  * SimpleScalar Tool Set
00073  *
00074  *
00075  * Revision 1.5  1998/08/27 08:09:13  taustin
00076  * implemented host interface description in host.h
00077  * added target interface support
00078  *
00079  * Revision 1.4  1997/03/11  01:09:45  taustin
00080  * updated copyright
00081  * long/int tweaks made for ALPHA target support
00082  *
00083  * Revision 1.3  1997/01/06  15:57:55  taustin
00084  * comments updated
00085  * cache_reg_stats() now works with stats package
00086  * cp->writebacks stat added to cache
00087  *
00088  * Revision 1.1  1996/12/05  18:50:23  taustin
00089  * Initial revision
00090  *
00091  *
00092  */
00093 
00094 #ifndef CACHE_H
00095 #define CACHE_H
00096 
00097 #include <stdio.h>
00098 
00099 #include "host.h"
00100 #include "misc.h"
00101 #include "machine.h"
00102 #include "memory.h"
00103 #include "stats.h"
00104 
00105 /*
00106  * This module contains code to implement various cache-like structures.  The
00107  * user instantiates caches using cache_new().  When instantiated, the user
00108  * may specify the geometry of the cache (i.e., number of set, line size,
00109  * associativity), and supply a block access function.  The block access
00110  * function indicates the latency to access lines when the cache misses,
00111  * accounting for any component of miss latency, e.g., bus acquire latency,
00112  * bus transfer latency, memory access latency, etc...  In addition, the user
00113  * may allocate the cache with or without lines allocated in the cache.
00114  * Caches without tags are useful when implementing structures that map data
00115  * other than the address space, e.g., TLBs which map the virtual address
00116  * space to physical page address, or BTBs which map text addresses to
00117  * branch prediction state.  Tags are always allocated.  User data may also be
00118  * optionally attached to cache lines, this space is useful to storing
00119  * auxilliary or additional cache line information, such as predecode data,
00120  * physical page address information, etc...
00121  *
00122  * The caches implemented by this module provide efficient storage management
00123  * and fast access for all cache geometries.  When sets become highly
00124  * associative, a hash table (indexed by address) is allocated for each set
00125  * in the cache.
00126  *
00127  * This module also tracks latency of accessing the data cache, each cache has
00128  * a hit latency defined when instantiated, miss latency is returned by the
00129  * cache's block access function, the caches may service any number of hits
00130  * under any number of misses, the calling simulator should limit the number
00131  * of outstanding misses or the number of hits under misses as per the
00132  * limitations of the particular microarchitecture being simulated.
00133  *
00134  * Due to the organization of this cache implementation, the latency of a
00135  * request cannot be affected by a later request to this module.  As a result,
00136  * reordering of requests in the memory hierarchy is not possible.
00137  */
00138 
00139 /* highly associative caches are implemented using a hash table lookup to
00140    speed block access, this macro decides if a cache is "highly associative" */
00141 #define CACHE_HIGHLY_ASSOC(cp)  ((cp)->assoc > 4)
00142 
00143 /* cache replacement policy */
00144 enum cache_policy {
00145   LRU,          /* replace least recently used block (perfect LRU) */
00146   Random,       /* replace a random block */
00147   FIFO          /* replace the oldest block in the set */
00148 };
00149 
00150 /* block status values */
00151 #define CACHE_BLK_VALID         0x00000001      /* block in valid, in use */
00152 #define CACHE_BLK_DIRTY         0x00000002      /* dirty block */
00153 
00154 /* cache block (or line) definition */
00155 struct cache_blk_t
00156 {
00157   struct cache_blk_t *way_next; /* next block in the ordered way chain, used
00158                                    to order blocks for replacement */
00159   struct cache_blk_t *way_prev; /* previous block in the order way chain */
00160   struct cache_blk_t *hash_next;/* next block in the hash bucket chain, only
00161                                    used in highly-associative caches */
00162   /* since hash table lists are typically small, there is no previous
00163      pointer, deletion requires a trip through the hash table bucket list */
00164   md_addr_t tag;                /* data block tag value */
00165   unsigned int status;          /* block status, see CACHE_BLK_* defs above */
00166   tick_t ready;         /* time when block will be accessible, field
00167                                    is set when a miss fetch is initiated */
00168   byte_t *user_data;            /* pointer to user defined data, e.g.,
00169                                    pre-decode data or physical page address */
00170   /* DATA should be pointer-aligned due to preceeding field */
00171   /* NOTE: this is a variable-size tail array, this must be the LAST field
00172      defined in this structure! */
00173   byte_t data[1];               /* actual data block starts here, block size
00174                                    should probably be a multiple of 8 */
00175 };
00176 
00177 /* cache set definition (one or more blocks sharing the same set index) */
00178 struct cache_set_t
00179 {
00180   struct cache_blk_t **hash;    /* hash table: for fast access w/assoc, NULL
00181                                    for low-assoc caches */
00182   struct cache_blk_t *way_head; /* head of way list */
00183   struct cache_blk_t *way_tail; /* tail pf way list */
00184   struct cache_blk_t *blks;     /* cache blocks, allocated sequentially, so
00185                                    this pointer can also be used for random
00186                                    access to cache blocks */
00187 };
00188 
00189 /* cache definition */
00190 struct cache_t
00191 {
00192   /* parameters */
00193   char *name;                   /* cache name */
00194   int nsets;                    /* number of sets */
00195   int bsize;                    /* block size in bytes */
00196   int balloc;                   /* maintain cache contents? */
00197   int usize;                    /* user allocated data size */
00198   int assoc;                    /* cache associativity */
00199   enum cache_policy policy;     /* cache replacement policy */
00200   unsigned int hit_latency;     /* cache hit latency */
00201 
00202   /* miss/replacement handler, read/write BSIZE bytes starting at BADDR
00203      from/into cache block BLK, returns the latency of the operation
00204      if initiated at NOW, returned latencies indicate how long it takes
00205      for the cache access to continue (e.g., fill a write buffer), the
00206      miss/repl functions are required to track how this operation will
00207      effect the latency of later operations (e.g., write buffer fills),
00208      if !BALLOC, then just return the latency; BLK_ACCESS_FN is also
00209      responsible for generating any user data and incorporating the latency
00210      of that operation */
00211   unsigned int                                  /* latency of block access */
00212     (*blk_access_fn)(enum mem_cmd cmd,          /* block access command */
00213                      md_addr_t baddr,           /* program address to access */
00214                      int bsize,                 /* size of the cache block */
00215                      struct cache_blk_t *blk,   /* ptr to cache block struct */
00216                      tick_t now);               /* when fetch was initiated */
00217 
00218   /* derived data, for fast decoding */
00219   int hsize;                    /* cache set hash table size */
00220   md_addr_t blk_mask;
00221   int set_shift;
00222   md_addr_t set_mask;           /* use *after* shift */
00223   int tag_shift;
00224   md_addr_t tag_mask;           /* use *after* shift */
00225   md_addr_t tagset_mask;        /* used for fast hit detection */
00226 
00227   /* bus resource */
00228   tick_t bus_free;              /* time when bus to next level of cache is
00229                                    free, NOTE: the bus model assumes only a
00230                                    single, fully-pipelined port to the next
00231                                    level of memory that requires the bus only
00232                                    one cycle for cache line transfer (the
00233                                    latency of the access to the lower level
00234                                    may be more than one cycle, as specified
00235                                    by the miss handler */
00236 
00237   /* per-cache stats */
00238   counter_t hits;               /* total number of hits */
00239   counter_t misses;             /* total number of misses */
00240   counter_t replacements;       /* total number of replacements at misses */
00241   counter_t writebacks;         /* total number of writebacks at misses */
00242   counter_t invalidations;      /* total number of external invalidations */
00243 
00244   /* last block to hit, used to optimize cache hit processing */
00245   md_addr_t last_tagset;        /* tag of last line accessed */
00246   struct cache_blk_t *last_blk; /* cache block last accessed */
00247 
00248   /* data blocks */
00249   byte_t *data;                 /* pointer to data blocks allocation */
00250 
00251   /* NOTE: this is a variable-size tail array, this must be the LAST field
00252      defined in this structure! */
00253   struct cache_set_t sets[1];   /* each entry is a set */
00254 };
00255 
00256 /* create and initialize a general cache structure */
00257 struct cache_t *                        /* pointer to cache created */
00258 cache_create(char *name,                /* name of the cache */
00259              int nsets,                 /* total number of sets in cache */
00260              int bsize,                 /* block (line) size of cache */
00261              int balloc,                /* allocate data space for blocks? */
00262              int usize,                 /* size of user data to alloc w/blks */
00263              int assoc,                 /* associativity of cache */
00264              enum cache_policy policy,  /* replacement policy w/in sets */
00265              /* block access function, see description w/in struct cache def */
00266              unsigned int (*blk_access_fn)(enum mem_cmd cmd,
00267                                            md_addr_t baddr, int bsize,
00268                                            struct cache_blk_t *blk,
00269                                            tick_t now),
00270              unsigned int hit_latency);/* latency in cycles for a hit */
00271 
00272 /* parse policy */
00273 enum cache_policy                       /* replacement policy enum */
00274 cache_char2policy(char c);              /* replacement policy as a char */
00275 
00276 /* print cache configuration */
00277 void
00278 cache_config(struct cache_t *cp,        /* cache instance */
00279              FILE *stream);             /* output stream */
00280 
00281 /* register cache stats */
00282 void
00283 cache_reg_stats(struct cache_t *cp,     /* cache instance */
00284                 struct stat_sdb_t *sdb);/* stats database */
00285 
00286 /* print cache stats */
00287 void
00288 cache_stats(struct cache_t *cp,         /* cache instance */
00289             FILE *stream);              /* output stream */
00290 
00291 /* print cache stats */
00292 void cache_stats(struct cache_t *cp, FILE *stream);
00293 
00294 /* access a cache, perform a CMD operation on cache CP at address ADDR,
00295    places NBYTES of data at *P, returns latency of operation if initiated
00296    at NOW, places pointer to block user data in *UDATA, *P is untouched if
00297    cache blocks are not allocated (!CP->BALLOC), UDATA should be NULL if no
00298    user data is attached to blocks */
00299 unsigned int                            /* latency of access in cycles */
00300 cache_access(struct cache_t *cp,        /* cache to access */
00301              enum mem_cmd cmd,          /* access type, Read or Write */
00302              md_addr_t addr,            /* address of access */
00303              void *vp,                  /* ptr to buffer for input/output */
00304              int nbytes,                /* number of bytes to access */
00305              tick_t now,                /* time of access */
00306              byte_t **udata,            /* for return of user data ptr */
00307              md_addr_t *repl_addr);     /* for address of replaced block */
00308 
00309 /* cache access functions, these are safe, they check alignment and
00310    permissions */
00311 #define cache_double(cp, cmd, addr, p, now, udata)      \
00312   cache_access(cp, cmd, addr, p, sizeof(double), now, udata)
00313 #define cache_float(cp, cmd, addr, p, now, udata)       \
00314   cache_access(cp, cmd, addr, p, sizeof(float), now, udata)
00315 #define cache_dword(cp, cmd, addr, p, now, udata)       \
00316   cache_access(cp, cmd, addr, p, sizeof(long long), now, udata)
00317 #define cache_word(cp, cmd, addr, p, now, udata)        \
00318   cache_access(cp, cmd, addr, p, sizeof(int), now, udata)
00319 #define cache_half(cp, cmd, addr, p, now, udata)        \
00320   cache_access(cp, cmd, addr, p, sizeof(short), now, udata)
00321 #define cache_byte(cp, cmd, addr, p, now, udata)        \
00322   cache_access(cp, cmd, addr, p, sizeof(char), now, udata)
00323 
00324 /* return non-zero if block containing address ADDR is contained in cache
00325    CP, this interface is used primarily for debugging and asserting cache
00326    invariants */
00327 int                                     /* non-zero if access would hit */
00328 cache_probe(struct cache_t *cp,         /* cache instance to probe */
00329             md_addr_t addr);            /* address of block to probe */
00330 
00331 /* flush the entire cache, returns latency of the operation */
00332 unsigned int                            /* latency of the flush operation */
00333 cache_flush(struct cache_t *cp,         /* cache instance to flush */
00334             tick_t now);                /* time of cache flush */
00335 
00336 /* flush the block containing ADDR from the cache CP, returns the latency of
00337    the block flush operation */
00338 unsigned int                            /* latency of flush operation */
00339 cache_flush_addr(struct cache_t *cp,    /* cache instance to flush */
00340                  md_addr_t addr,        /* address of block to flush */
00341                  tick_t now);           /* time of cache flush */
00342 /* cache access macros */
00343 #define CACHE_TAG(cp, addr)     ((addr) >> (cp)->tag_shift)
00344 #define CACHE_SET(cp, addr)     (((addr) >> (cp)->set_shift) & (cp)->set_mask)
00345 #define CACHE_BLK(cp, addr)     ((addr) & (cp)->blk_mask)
00346 #define CACHE_TAGSET(cp, addr)  ((addr) & (cp)->tagset_mask)
00347 
00348 
00349 #endif /* CACHE_H */

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