src/Sim/Core/Core.cpp

説明を見る。
00001 // 
00002 // Copyright (c) 2005-2008 Kenichi Watanabe.
00003 // Copyright (c) 2005-2008 Yasuhiro Watari.
00004 // Copyright (c) 2005-2008 Hironori Ichibayashi.
00005 // Copyright (c) 2008-2009 Kazuo Horio.
00006 // Copyright (c) 2009-2013 Naruki Kurata.
00007 // Copyright (c) 2005-2013 Ryota Shioya.
00008 // Copyright (c) 2005-2013 Masahiro Goshima.
00009 // 
00010 // This software is provided 'as-is', without any express or implied
00011 // warranty. In no event will the authors be held liable for any damages
00012 // arising from the use of this software.
00013 // 
00014 // Permission is granted to anyone to use this software for any purpose,
00015 // including commercial applications, and to alter it and redistribute it
00016 // freely, subject to the following restrictions:
00017 // 
00018 // 1. The origin of this software must not be misrepresented; you must not
00019 // claim that you wrote the original software. If you use this software
00020 // in a product, an acknowledgment in the product documentation would be
00021 // appreciated but is not required.
00022 // 
00023 // 2. Altered source versions must be plainly marked as such, and must not be
00024 // misrepresented as being the original software.
00025 // 
00026 // 3. This notice may not be removed or altered from any source
00027 // distribution.
00028 // 
00029 // 
00030 
00031 
00032 #include <pch.h>
00033 
00034 #include "Sim/Core/Core.h"
00035 
00036 #include "Utility/RuntimeError.h"
00037 
00038 #include "Sim/Dumper/Dumper.h"
00039 
00040 #include "Sim/Foundation/Hook/HookUtil.h"
00041 #include "Sim/Memory/MemOrderManager/MemOrderManager.h"
00042 #include "Sim/Memory/Cache/Cache.h"
00043 #include "Sim/Memory/Cache/CacheSystem.h"
00044 #include "Sim/Thread/Thread.h"
00045 #include "Sim/InorderList/InorderList.h"
00046 #include "Sim/Pipeline/Scheduler/Scheduler.h"
00047 
00048 #include "Sim/Pipeline/Dispatcher/Dispatcher.h"
00049 #include "Sim/Pipeline/Retirer/Retirer.h"
00050 #include "Sim/Op/Op.h"
00051 
00052 namespace Onikiri
00053 {
00054     HookPoint<Core, Core::CheckpointDecisionHookParam> Core::s_checkpointDecisionHook;
00055 };  // namespace Onikiri
00056 
00057 
00058 
00059 using namespace std;
00060 using namespace Onikiri;
00061 
00062 Core::Core() :
00063     m_opArrayCapacity(0),
00064     m_timeWheelSize(0),
00065     m_globalClock(0),
00066     m_opArray(0),
00067     m_registerFile(0),
00068     m_fetcher(0),
00069     m_renamer(0),
00070     m_dispatcher(0),
00071     m_scheduler(0),
00072     m_retirer(0),
00073     m_latPred(0),
00074     m_cacheSystem(0),
00075     m_emulator(0),
00076     m_bPred(0),
00077     m_execLatencyInfo(0),
00078     m_loadPipeLineModel(LPM_MULTI_ISSUE),
00079     m_schedulerRemovePolicy(RP_FOLLOW_CORE),
00080     m_checkpointingPolicy(CP_AUTO)
00081 {
00082 
00083 }
00084 
00085 Core::~Core()
00086 {
00087     if( m_opArray != 0 )          delete m_opArray;
00088     ReleaseParam();
00089 }
00090 
00091 void Core::Initialize(InitPhase phase)
00092 {
00093     if(phase == INIT_PRE_CONNECTION){
00094         LoadParam();
00095 
00096         m_opArray = new OpArray( m_opArrayCapacity );
00097 
00098         m_latencyPredRecv.Validate();
00099         m_addrMatchPredRecv.Validate();
00100         m_valuePredRecv.Validate();
00101         m_partialLoadRecovery.Validate();
00102 
00103 
00104     }
00105     else if(phase == INIT_POST_CONNECTION){
00106 
00107         CheckNodeInitialized( "registerFile", m_registerFile );
00108         CheckNodeInitialized( "fetcher", m_fetcher );
00109         CheckNodeInitialized( "renamer", m_renamer );
00110         CheckNodeInitialized( "dispatcher", m_dispatcher );
00111         CheckNodeInitialized( "retirer", m_retirer );
00112         CheckNodeInitialized( "latPred", m_latPred );
00113         CheckNodeInitialized( "execLatencyInfo", m_execLatencyInfo );
00114         CheckNodeInitialized( "thread", m_thread );
00115         CheckNodeInitialized( "cacheSystem", m_cacheSystem );
00116         CheckNodeInitialized( "emulator", m_emulator );
00117 
00118         for( int localTID = 0; localTID < GetThreadCount(); localTID++ ){
00119             m_thread[localTID]->SetLocalThreadID( localTID );
00120         }
00121 
00122         // scheduler  index d`FbN
00123         for(int i = 0; i < GetNumScheduler(); ++i) {
00124             for(int k = i + 1; k < GetNumScheduler(); ++k) {
00125                 if( GetScheduler(i)->GetIndex() == GetScheduler(k)->GetIndex() ) {
00126                     THROW_RUNTIME_ERROR("same schduler index %d(%d, %d).",
00127                         GetScheduler(k)->GetIndex(), i, k);
00128                 }
00129             }
00130         }
00131 
00132         // Check OpArray's capacity.
00133         int totalInorderListCapacity = 0;
00134         for( int i = 0; i < m_thread.GetSize(); ++i ){
00135             totalInorderListCapacity +=
00136                 m_thread[i]->GetInorderList()->GetCapacity();
00137         }
00138         if( m_opArrayCapacity < totalInorderListCapacity ){
00139             THROW_RUNTIME_ERROR( 
00140                 "The capacity(%d) of 'OpArray' is too small. Make 'Core/@OpArrayCapacity' more larger.",
00141                 m_opArrayCapacity 
00142             );
00143         }
00144     }
00145 }
00146 
00147 // --- accessors
00148 int Core::GetCID()
00149 {
00150     return GetRID();
00151 }
00152 
00153 int Core::GetTID(const int index)
00154 {
00155     return PhysicalResourceNode::GetTID( index );
00156 }
00157 
00158 void Core::AddScheduler( Scheduler* scheduler )
00159 {
00160     m_scheduler.push_back( scheduler );
00161 }
00162 
00163 Scheduler* Core::GetScheduler( int index )
00164 {
00165     ASSERT(
00166         index >= 0 && index < static_cast<int>(m_scheduler.size()),
00167         "illegal index: %d", index 
00168     );
00169     return m_scheduler[index];
00170 }
00171 
00172 int Core::GetNumScheduler() const
00173 {
00174     return static_cast<int>(m_scheduler.size());
00175 }
00176 
00177 Thread* Core::GetThread(int tid)
00178 {
00179     return m_thread[tid];     
00180 }
00181 
00182 int Core::GetThreadCount()
00183 {
00184     return m_thread.GetSize();
00185 }
00186 
00187 //
00188 // -- Jo@
00189 //
00190 // tFb`OCI[_[Xe[g`FbN|CeBOKv
00191 // ANZXI[_[oCI[VtFb`JoKv
00192 bool Core::IsRequiredCheckpointBefore( const PC& pc, const OpInfo* const info)
00193 {
00194     CheckpointDecisionHookParam param = { &pc, info, true/*before*/, false/*reqruired*/ } ;
00195 
00196     HOOK_SECTION_PARAM( s_checkpointDecisionHook, param ){
00197         if( m_checkpointingPolicy == CP_ALL ){
00198             param.requried = true;
00199         }
00200         else if ( m_checkpointingPolicy == CP_AUTO ){
00201             const OpClass& opClass = param.info->GetOpClass();
00202             param.requried = 
00203                 m_latencyPredRecv.IsRequiredBeforeCheckpoint    ( opClass ) ||
00204                 m_addrMatchPredRecv.IsRequiredBeforeCheckpoint  ( opClass ) ||
00205                 m_valuePredRecv.IsRequiredBeforeCheckpoint      ( opClass ) ||
00206                 m_partialLoadRecovery.IsRequiredBeforeCheckpoint( opClass );
00207         }
00208         else{
00209             ASSERT( "Unknown check-pointing policy." );
00210         }
00211     }
00212 
00213     return param.requried;
00214 }
00215 
00216     // tFb`CI[_[Xe[g`FbN|CeBOKv
00217 // \~XJoKv
00218 bool Core::IsRequiredCheckpointAfter( const PC& pc, const OpInfo* const info)
00219 {
00220     CheckpointDecisionHookParam param = { &pc, info, false/*before*/, false/*reqruired*/ } ;
00221     HOOK_SECTION_PARAM( s_checkpointDecisionHook, param ){
00222         if( m_checkpointingPolicy == CP_ALL ){
00223             param.requried = true;
00224         }
00225         else if ( m_checkpointingPolicy == CP_AUTO ){
00226             const OpClass& opClass = param.info->GetOpClass();
00227             param.requried = 
00228                 opClass.IsBranch() ||
00229                 m_latencyPredRecv.IsRequiredAfterCheckpoint     ( opClass ) ||
00230                 m_addrMatchPredRecv.IsRequiredAfterCheckpoint   ( opClass ) ||
00231                 m_valuePredRecv.IsRequiredAfterCheckpoint       ( opClass ) ||
00232                 m_partialLoadRecovery.IsRequiredAfterCheckpoint ( opClass );
00233         }
00234         else{
00235             ASSERT( "Unknown check-pointing policy." );
00236         }
00237     }
00238 
00239     return param.requried;
00240 }
00241 
00242 // Cycle handler
00243 void Core::Evaluate()
00244 {
00245     ClockedResourceBase::Evaluate();
00246 
00247     // Front-end stall decision
00248     Cache* lv1ICache = m_cacheSystem->GetFirstLevelInsnCache();
00249     if( lv1ICache->IsStallRequired() ){
00250         m_dispatcher->StallThisCycle();
00251     }
00252     // Back-end  stall decision
00253     Cache* lv1DCache = m_cacheSystem->GetFirstLevelDataCache();
00254     if( lv1DCache->IsStallRequired() ){
00255 
00256         m_retirer->StallThisCycle();
00257         for( size_t i = 0; i < m_scheduler.size(); i++ ){
00258             m_scheduler[i]->StallThisCycle();
00259         }
00260     }
00261 
00262 }
00263 

Onikiri2に対してTue Jun 18 14:34:22 2013に生成されました。  doxygen 1.4.7