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 #include <pch.h>
00033 #include "Sim/System/InorderSystem/InorderSystem.h"
00034 #include "Sim/Dumper/Dumper.h"
00035
00036 #include "Sim/Predictor/DepPred/RegDepPred/RegDepPredIF.h"
00037 #include "Sim/Predictor/BPred/BPred.h"
00038 #include "Sim/Predictor/LatPred/LatPredResult.h"
00039 #include "Sim/InorderList/InorderList.h"
00040 #include "Sim/Register/RegisterFile.h"
00041 #include "Sim/Memory/Cache/Cache.h"
00042 #include "Sim/Memory/Cache/CacheSystem.h"
00043 #include "Sim/Op/Op.h"
00044 #include "Sim/Op/OpInitArgs.h"
00045 #include "Sim/Pipeline/Fetcher/Fetcher.h"
00046 #include "Sim/Pipeline/Dispatcher/Steerer/OpCodeSteerer.h"
00047 #include "Sim/Pipeline/Renamer/Renamer.h"
00048 #include "Sim/Pipeline/Scheduler/Scheduler.h"
00049 #include "Sim/Predictor/HitMissPred/HitMissPredIF.h"
00050 #include "Sim/Predictor/LatPred/LatPred.h"
00051 #include "Sim/Dependency/PhyReg/PhyReg.h"
00052 #include "Sim/Memory/MemOrderManager/MemOrderManager.h"
00053
00054 using namespace std;
00055 using namespace boost;
00056 using namespace Onikiri;
00057
00058
00059
00060
00061
00062 InorderSystem::InorderSystem()
00063 {
00064 m_enableBPred = false;
00065 m_enableHMPred = false;
00066 m_enableCache = false;
00067 }
00068
00069 InorderSystem::~InorderSystem()
00070 {}
00071
00072 void InorderSystem::Run( SystemContext* context )
00073 {
00074 m_enableBPred = context->inorderParam.enableBPred;
00075 m_enableHMPred = context->inorderParam.enableHMPred;
00076 m_enableCache = context->inorderParam.enableCache;
00077
00078 const s64 numInsns = context->executionInsns;
00079 for( int i = 0; i < context->threads.GetSize(); i++ ){
00080 g_dumper.SetCurrentCycle( context->threads[i], 0 );
00081 }
00082
00083 int processCount = context->emulator->GetProcessCount();
00084
00085
00086 ArchitectureStateList& archStateList = context->architectureStateList;
00087
00088 EmulatorIF* emulator = context->emulator;
00089 s64 totalInsnCount = 0;
00090 vector<s64> insnCount;
00091 u64 opCount = 0;
00092 int curPID = 0;
00093 int terminateProcesses = 0;
00094
00095 insnCount.resize( processCount, 0 );
00096
00097 while( totalInsnCount < numInsns ){
00098
00099 PC& curThreadPC = archStateList[curPID].pc;
00100 curPID = (curPID + 1);
00101 if( curPID >= processCount ){
00102 curPID -= processCount;
00103 }
00104
00105 std::pair<OpInfo**, int> ops = emulator->GetOp(curThreadPC);
00106
00107 OpInfo** opInfoArray = ops.first;
00108 int infoCount = ops.second;
00109
00110
00111 if( opInfoArray == 0 || opInfoArray[0] == 0 ) {
00112 terminateProcesses++;
00113 if(terminateProcesses >= processCount){
00114 break;
00115 }
00116 else{
00117 continue;
00118 }
00119 }
00120
00121 totalInsnCount++;
00122 insnCount[curPID]++;
00123
00124 Thread* thread = context->threads[ curThreadPC.tid ];
00125 Core* core = thread->GetCore();
00126 InorderList* inorderList = thread->GetInorderList();
00127 BPred* bPred = core->GetFetcher()->GetBPred();
00128 RegDepPredIF* regDepPred = thread->GetRegDepPred();
00129 MemOrderManager* memOrderManager = thread->GetMemOrderManager();
00130 HitMissPredIF* hmPred = core->GetLatPred()->GetHitMissPred();
00131 CacheSystem* cacheSystem = core->GetCacheSystem();
00132 Cache* cache = cacheSystem->GetFirstLevelDataCache();
00133 MemIF* memImage = emulator->GetMemImage();
00134 Renamer* renamer = core->GetRenamer();
00135 DispatchSteererIF* steerer = renamer->GetSteerer();
00136
00137
00138 for(int infoIndex = 0; infoIndex < infoCount; ++infoIndex){
00139 OpInfo* opInfo = opInfoArray[infoIndex];
00140 OpClass opClass = opInfo->GetOpClass();
00141
00142 OpInitArgs args =
00143 {
00144
00145 &curThreadPC,
00146 opInfo,
00147 infoIndex,
00148 opCount,
00149 opCount,
00150 opCount,
00151 thread->GetCore(),
00152 thread
00153 };
00154
00155 OpIterator op = inorderList->ConstructOp( args );
00156
00157 op->SetTakenPC( Addr(curThreadPC.pid, curThreadPC.tid, curThreadPC.address+4) );
00158
00159
00160 regDepPred->Resolve(op);
00161
00162
00163 regDepPred->Allocate(op);
00164
00165
00166 if( opClass.IsLoad() ) {
00167 memOrderManager->Allocate(op);
00168 }
00169
00170
00171 if( m_enableBPred && opClass.IsBranch() ) {
00172 PC predPC = bPred->Predict(op, op->GetPC());
00173
00174
00175 predPC.pid = op->GetPC().pid;
00176 predPC.tid = op->GetPC().tid;
00177
00178 op->SetPredPC(predPC);
00179 }
00180
00181 if( !opClass.IsNop() ){
00182 Scheduler* sched = steerer->Steer( op );
00183 op->SetScheduler( sched );
00184
00185 ExecUnitIF* execUnit = op->GetExecUnit();
00186 execUnit->Begin();
00187 execUnit->Reserve( op, 0 );
00188
00189
00190 op->ExecutionBegin();
00191 op->SetStatus( OpStatus::OS_EXECUTING );
00192 op->ExecutionEnd();
00193 }
00194
00195
00196 if( opClass.IsLoad() ){
00197 CacheAccess readAccess( op->GetMemAccess(), op, CacheAccess::OT_READ );
00198 if( m_enableCache ){
00199 if( m_enableHMPred ){
00200 hmPred->Predict( op );
00201 }
00202 CacheAccessResult result = cache->Read( readAccess, NULL );
00203 op->SetCacheAccessResult( result );
00204
00205 if( m_enableHMPred ){
00206 bool hit = result.state == CacheAccessResult::ST_HIT;
00207 hmPred->Finished( op, hit );
00208 hmPred->Commit( op, hit );
00209 }
00210 }
00211
00212 if( readAccess.result != MemAccess::MAR_SUCCESS ){
00213 RUNTIME_WARNING(
00214 "An access violation occurs.\n%s\n%s",
00215 readAccess.ToString().c_str(), op->ToString().c_str()
00216 );
00217 }
00218 }
00219
00220
00221 if( opClass.IsStore() ) {
00222 CacheAccess writeAccess( op->GetMemAccess(), op, CacheAccess::OT_WRITE );
00223 memImage->Write( &writeAccess );
00224
00225 if( writeAccess.result != MemAccess::MAR_SUCCESS ){
00226 RUNTIME_WARNING(
00227 "An access violation occurs.\n%s\n%s",
00228 writeAccess.ToString().c_str(), op->ToString().c_str()
00229 );
00230 }
00231
00232 if( m_enableCache ){
00233 CacheAccessResult result = cache->Write( writeAccess, NULL );
00234 op->SetCacheAccessResult( result );
00235 }
00236 }
00237
00238
00239 if( m_enableBPred && opClass.IsBranch() ) {
00240 bPred->Finished(op);
00241 bPred->Commit(op);
00242 }
00243
00244 op->SetStatus( OpStatus::OS_WRITTEN_BACK );
00245
00246
00247 g_dumper.Dump( DS_FETCH, op );
00248 g_dumper.Dump( DS_RETIRE, op );
00249
00250
00251 if( opClass.IsLoad() ) {
00252 memOrderManager->Commit( op );
00253 memOrderManager->Retire( op );
00254 }
00255
00256 cacheSystem->Commit( op );
00257
00258
00259 emulator->Commit( &*op, opInfo );
00260
00261
00262 regDepPred->Commit(op);
00263
00264 ++opCount;
00265
00266
00267 if ( infoIndex == infoCount - 1 ) {
00268 if (op->GetTaken()) {
00269 curThreadPC = op->GetTakenPC();
00270 }else {
00271 curThreadPC.address += SimISAInfo::INSTRUCTION_WORD_BYTE_SIZE;
00272 }
00273 }
00274
00275 inorderList->Commit( op );
00276 inorderList->Retire( op );
00277 inorderList->DestroyOp( op );
00278 }
00279 }
00280
00281 context->executedInsns = insnCount;
00282 context->executedCycles = 0;
00283
00284
00285 ISAInfoIF* isaInfo = context->emulator->GetISAInfo();
00286 int logicalRegCount = isaInfo->GetRegisterCount();
00287
00288 for( int pid = 0; pid < processCount; pid++ ){
00289
00290 RegDepPredIF* regDepPred = context->threads[pid]->GetRegDepPred();
00291 RegisterFile* regFile = context->threads[pid]->GetCore()->GetRegisterFile();
00292
00293
00294 for(int i = 0; i < logicalRegCount; ++i) {
00295 int phyRegNo = regDepPred->PeekReg( i );
00296 PhyReg* reg = regFile->GetPhyReg( phyRegNo );
00297 archStateList[pid].registerValue[i] = reg->GetVal();
00298 }
00299 }
00300
00301 }