00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef SIM_MEMORY_CACHE_CACHE_H
00037 #define SIM_MEMORY_CACHE_CACHE_H
00038
00039 #include "Env/Param/ParamExchange.h"
00040
00041 #include "Sim/Foundation/Resource/ResourceNode.h"
00042 #include "Sim/Op/OpArray/OpArray.h"
00043 #include "Sim/Memory/Cache/CacheTypes.h"
00044 #include "Sim/Pipeline/PipelineNodeBase.h"
00045 #include "Sim/Foundation/Hook/HookDecl.h"
00046
00047 namespace Onikiri
00048 {
00049 class CacheMissedAccessList;
00050 class CacheAccessRequestQueue;
00051 class Core;
00052 class PrefetcherIF;
00053 template <
00054 typename ValueType,
00055 typename ContainerType
00056 > class CacheExtraStateTable;
00057
00058
00059 class Cache :
00060 public CacheAccessNotifieeIF,
00061 public PipelineNodeBase
00062 {
00063 public:
00064 typedef size_t SizeType;
00065 typedef CacheAccess Access;
00066 typedef CacheAccessResult Result;
00067 typedef CacheAccessNotificationParam NotifyParam;
00068
00069 BEGIN_PARAM_MAP("")
00070 BEGIN_PARAM_PATH( GetParamPath() )
00071 PARAM_ENTRY("@Name", m_name);
00072 PARAM_ENTRY("@Latency", m_latency);
00073 PARAM_ENTRY("@Perfect", m_perfect);
00074 PARAM_ENTRY("@IndexBitSize", m_indexBitSize);
00075 PARAM_ENTRY("@OffsetBitSize", m_offsetBitSize);
00076 PARAM_ENTRY("@NumWays", m_numWays);
00077 PARAM_ENTRY("@NumPorts", m_numPorts);
00078 PARAM_ENTRY("@RequestQueueSize", m_reqQueueSize);
00079 PARAM_ENTRY("@MissedAccessListSize", m_missedAccessListSize);
00080 PARAM_ENTRY("@ExclusiveAccessCycles", m_exclusiveAccessCycles);
00081 BEGIN_PARAM_BINDING( "@WritePolicy", m_writePolicy, WritePolicy )
00082 PARAM_BINDING_ENTRY( "WriteThrough", WP_WRITE_THROUGH )
00083 PARAM_BINDING_ENTRY( "WriteBack", WP_WRITE_BACK )
00084 END_PARAM_BINDING()
00085 END_PARAM_PATH()
00086 BEGIN_PARAM_PATH( GetResultPath() )
00087 PARAM_ENTRY("@TableName", m_name);
00088 PARAM_ENTRY("@NumReadHit", m_numReadHit);
00089 PARAM_ENTRY("@NumReadMiss", m_numReadMiss);
00090 PARAM_ENTRY("@NumReadAccess", m_numReadAccess);
00091 PARAM_ENTRY("@NumReadPendingHit", m_numReadPendingHit);
00092 PARAM_ENTRY("@NumPrefetchHit", m_numPrefetchHit);
00093 PARAM_ENTRY("@NumPrefetchMiss", m_numPrefetchMiss);
00094 PARAM_ENTRY("@NumPrefetchPendingHit", m_numPrefetchPendingHit);
00095 PARAM_ENTRY("@NumPrefetchAccess", m_numPrefetchAccess);
00096 PARAM_ENTRY("@NumWriteHit", m_numWriteHit);
00097 PARAM_ENTRY("@NumWriteMiss", m_numWriteMiss);
00098 PARAM_ENTRY("@NumWriteAccess", m_numWriteAccess);
00099 PARAM_ENTRY("@NumWritePendingHit", m_numWritePendingHit);
00100 PARAM_ENTRY("@NumInvalidatedLines", m_numInvalidated);
00101 PARAM_ENTRY("@CapacityKByte", m_capacityKB);
00102 PARAM_ENTRY("@MaxThroughputBytesPerCycle", m_maxThroughputBytesPerCycle );
00103 RESULT_RATE_ENTRY("@NumReadHitRate", m_numReadHit, m_numReadAccess )
00104 RESULT_RATE_ENTRY("@NumWriteHitRate", m_numWriteHit, m_numWriteAccess )
00105 END_PARAM_PATH()
00106 END_PARAM_MAP()
00107
00108 BEGIN_RESOURCE_MAP()
00109 RESOURCE_ENTRY( Core, "core", m_core )
00110 RESOURCE_ENTRY( Thread, "thread", m_thread )
00111 RESOURCE_OPTIONAL_ENTRY( PrefetcherIF, "prefetcher", m_prefetcher )
00112 RESOURCE_OPTIONAL_SETTER_ENTRY( Cache, "cache", SetNextCache )
00113 END_RESOURCE_MAP()
00114
00115 Cache();
00116 virtual ~Cache();
00117
00118
00119
00120
00121
00122 virtual void Initialize(InitPhase phase);
00123
00124
00125 virtual void ChangeSimulationMode( PhysicalResourceNode::SimulationMode mode );
00126
00127
00128
00129
00130
00131
00132 void AccessFinished( const Access& addr, const NotifyParam& param );
00133
00134
00135
00136
00137
00138
00139 bool IsPerfect() { return m_perfect > 0; }
00140
00141
00142 const int GetStaticLatency() const { return m_latency; }
00143
00144
00145 Result Read( const Access& access, CacheAccessNotifieeIF* notifiee );
00146
00147
00148
00149 Result Write( const Access& access, CacheAccessNotifieeIF* notifiee );
00150
00151
00152 void Invalidate( const Addr& addr );
00153
00154
00155 int GetOffsetBitSize() const;
00156
00157
00158 Cache* GetNextCache();
00159
00160
00161 void SetNextCache( PhysicalResourceArray<Cache>& next );
00162
00163
00164 void AddPreviousLevelCache( Cache* prev );
00165
00166
00167 bool IsStallRequired();
00168
00169 int GetIndexCount() { return 1 << m_indexBitSize; }
00170 int GetWayCount() { return m_numWays; }
00171
00172
00173
00174
00175
00176
00177 virtual void Update();
00178
00179
00180
00181
00182
00183
00184
00185
00186 static HookPoint<Cache, CacheHookParam> s_readHook;
00187
00188
00189 static HookPoint<Cache, CacheHookParam> s_writeHook;
00190
00191
00192 static HookPoint<Cache, CacheHookParam> s_invalidateHook;
00193
00194
00195
00196
00197 static HookPoint<Cache, CacheHookParam> s_tableUpdateHook;
00198
00199 protected:
00200
00201 typedef CacheLine Line;
00202 typedef CacheLineValue Value;
00203 typedef CacheHasher HasherType;
00204 typedef CachePair PairType;
00205 typedef CacheTable TableType;
00206
00207 typedef Result::State ResultState;
00208 typedef Access::OperationType AccessType;
00209 typedef CacheAccessNotifieeIF NotifieeIF;
00210
00211 static const AccessType AOT_READ = Access::OT_READ;
00212 static const AccessType AOT_WRITE = Access::OT_WRITE;
00213 static const AccessType AOT_WRITE_BACK = Access::OT_WRITE_BACK;
00214 static const AccessType AOT_READ_FOR_WRITE_ALLOCATE = Access::OT_READ_FOR_WRITE_ALLOCATE;
00215 static const AccessType AOT_PREFETCH = Access::OT_PREFETCH;
00216
00217 int m_latency;
00218 TableType* m_cacheTable;
00219
00220
00221 struct LineState
00222 {
00223 bool dirty;
00224 };
00225 typedef CacheExtraStateTable< LineState, std::vector<LineState> > ExtraStateTableType;
00226 ExtraStateTableType* m_lineState;
00227
00228
00229 Cache* m_nextLevelCache;
00230
00231
00232 PhysicalResourceArray<Cache> m_prevLevelCaches;
00233
00234
00235 PrefetcherIF* m_prefetcher;
00236
00237 int m_perfect;
00238
00239
00240
00241
00242 String m_maxThroughputBytesPerCycle;
00243
00244
00245 int m_exclusiveAccessCycles;
00246
00247
00248 enum WritePolicy
00249 {
00250 WP_INVALID,
00251 WP_WRITE_THROUGH,
00252 WP_WRITE_BACK
00253 };
00254 WritePolicy m_writePolicy;
00255
00256
00257 CacheMissedAccessList* m_missedAccessList;
00258
00259
00260
00261 CacheAccessRequestQueue* m_accessQueue;
00262
00263 int m_level;
00264 std::string m_name;
00265
00266
00267 int m_indexBitSize;
00268 int m_offsetBitSize;
00269 int m_lineBitSize;
00270 int m_numWays;
00271 int m_numPorts;
00272 int m_reqQueueSize;
00273 int m_missedAccessListSize;
00274
00275
00276 s64 m_numReadHit;
00277 s64 m_numReadMiss;
00278 s64 m_numReadAccess;
00279 s64 m_numReadPendingHit;
00280
00281 s64 m_numPrefetchHit;
00282 s64 m_numPrefetchMiss;
00283 s64 m_numPrefetchPendingHit;
00284 s64 m_numPrefetchAccess;
00285
00286 s64 m_numWriteHit;
00287 s64 m_numWriteMiss;
00288 s64 m_numWriteAccess;
00289 s64 m_numWritePendingHit;
00290
00291 s64 m_numInvalidated;
00292 s64 m_capacityKB;
00293
00294
00295 bool IsPrefetch( const Access& access );
00296
00297
00298 void UpdateStatistics( const Access& access, Result::State state );
00299
00300
00301 void CheckValidAddress( const Addr& access );
00302
00303
00304 void AddToMissedAccessList(
00305 const Access& access,
00306 const Result& result,
00307 CacheAccessNotifieeIF* notifee,
00308 const NotifyParam& param
00309 );
00310
00311
00312
00313
00314
00315
00316 Result OnReadHit( const Access& access);
00317
00318
00319 Result OnReadPendingHit(
00320 const Access& access,
00321 const Result& phResult,
00322 CacheAccessNotifieeIF* notifee
00323 );
00324
00325
00326 Result OnReadMiss(
00327 const Access& access,
00328 CacheAccessNotifieeIF* notifee
00329 );
00330
00331
00332
00333
00334
00335
00336 Result OnWriteHit( const Access& access);
00337
00338
00339 Result OnWritePendingHit(
00340 const Access& access,
00341 const Result& phResult,
00342 CacheAccessNotifieeIF* notifee
00343 );
00344
00345
00346 Result OnWriteMiss(
00347 const Access& access,
00348 CacheAccessNotifieeIF* notifee
00349 );
00350
00351
00352 void UpdateTable( const Access& access );
00353
00354
00355
00356
00357
00358
00359
00360 void ReadBody( CacheHookParam* param );
00361
00362
00363
00364 void WriteBody( CacheHookParam* param );
00365
00366
00367 void InvalidateBody( CacheHookParam* param );
00368
00369
00370 void UpdateTableBody( CacheHookParam* param );
00371
00372 };
00373
00374 };
00375
00376 #endif // SIM_MEMORY_CACHE_CACHE_H
00377