src/Sim/Pipeline/PipelineNodeBase.h

説明を見る。
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 #ifndef SIM_PIPELINE_PIPELINE_NODE_BASE_H
00033 #define SIM_PIPELINE_PIPELINE_NODE_BASE_H
00034 
00035 #include "Utility/RuntimeError.h"
00036 
00037 #include "Sim/Foundation/Resource/ResourceNode.h"
00038 #include "Sim/Pipeline/PipelineNodeIF.h"
00039 #include "Sim/Pipeline/Pipeline.h"
00040 #include "Sim/Pipeline/PipelineLatch.h"
00041 
00042 namespace Onikiri 
00043 {
00044     class Thread;
00045     class Core;
00046 
00047     // A base class of Fetcher/Renamer/Dispatcher/Scheduler/Retirer
00048     class PipelineNodeBase :
00049         public ClockedResourceBase,
00050         public PipelineNodeIF,
00051         public PhysicalResourceNode
00052     {
00053 
00054     public:
00055         
00056         const char* Who() const 
00057         {
00058             return PhysicalResourceNode::Who(); 
00059         };
00060 
00061         PipelineNodeBase() : 
00062             m_initialized( false ),
00063             m_enableLatch( true ),
00064             m_upperPipelineNode( NULL ),
00065             m_upperPipeline( NULL ),
00066             m_lowerPipelineNode( NULL )
00067         {
00068             BaseT::AddChild( &m_latch );            // gcc needs 'BaseT::'
00069             BaseT::AddChild( &m_lowerPipeline );    
00070             m_lowerPipeline.AddUpperPipelineNode( this );
00071         }
00072 
00073         virtual ~PipelineNodeBase()
00074         {
00075             ASSERT( m_initialized, "Initialize() has not been called." );
00076         }
00077 
00078         virtual void Initialize( InitPhase phase )
00079         {
00080             if( phase == INIT_POST_CONNECTION ){
00081                 if( m_thread.GetSize() == 0 ) {
00082                     THROW_RUNTIME_ERROR("thread not set.");
00083                 }
00084                 if( m_core.GetSize() == 0 ) {
00085                     THROW_RUNTIME_ERROR("core not set.");
00086                 }
00087             }
00088 
00089             m_initialized = true;
00090         }
00091 
00092         // Stall handlers
00093         virtual void StallThisCycle()
00094         {
00095             BaseT::StallThisCycle();
00096             
00097             PipelineNodeIF* upper = GetUpperPipelineNode();
00098             if( upper ){
00099                 upper->StallThisCycle();
00100             }
00101         }
00102 
00103         virtual void StallNextCycle( int cycle )
00104         {
00105             BaseT::StallNextCycle( cycle );
00106 
00107             PipelineNodeIF* upper = GetUpperPipelineNode();
00108             if( upper ){
00109                 upper->StallNextCycle( cycle );
00110             }
00111         }
00112 
00113         // Stall only upper pipelines and the latch.
00114         // A pipeline next to this node is not stalled.
00115         virtual void StallThisNodeAndUpperThisCycle()
00116         {
00117             PipelineNodeIF* upper = GetUpperPipelineNode();
00118             if( upper ){
00119                 upper->StallThisCycle();
00120             }
00121             if( m_enableLatch ){
00122                 m_latch.StallThisCycle();
00123             }
00124             BaseT::StallThisCycleExcludingChildren();   // gcc needs 'BaseT::'
00125         }
00126 
00127         // This method is called when an op exits on upper pipeline.
00128         // A pipeline that writes a buffer like Dispatcher
00129         // overwrites this method.
00130         virtual void ExitUpperPipeline( OpIterator op )
00131         {
00132             if( m_enableLatch ){
00133                 m_latch.Receive( op );
00134             }
00135         };
00136         
00137         // This method is called when an op exits an lower pipeline.
00138         virtual void ExitLowerPipeline( OpIterator op )
00139         {
00140         };
00141 
00142         // Link pipeline nodes.
00143         virtual void SetUpperPipelineNode( PipelineNodeIF* upper )
00144         {
00145             m_upperPipelineNode = upper;
00146             m_upperPipeline     = upper->GetLowerPipeline();
00147             upper->SetLowerPipelineNode( this );
00148         }
00149 
00150         virtual void SetLowerPipelineNode( PipelineNodeIF* lower )
00151         {
00152             m_lowerPipelineNode = lower;
00153         }
00154 
00155         // Pipeline
00156         virtual Pipeline* GetLowerPipeline()
00157         {
00158             return &m_lowerPipeline;
00159         }
00160 
00161         // PipelineNode
00162         virtual PipelineNodeIF* GetLowerPipelineNode()
00163         {
00164             return m_lowerPipelineNode;
00165         }
00166 
00167         // pCvCm[h
00168         virtual PipelineNodeIF* GetUpperPipelineNode()
00169         {
00170             return m_upperPipelineNode;
00171         }
00172 
00173         // Returns whether this node can allocate entries or not.
00174         virtual bool CanAllocate( int ops )
00175         {
00176             return true;
00177         }
00178 
00179         // Add an external lower pipeline.
00180         virtual void AddLowerPipeline( Pipeline* pipe )
00181         {
00182             this->AddChild( pipe ); // gcc needs 'BaseT::'
00183             pipe->AddUpperPipelineNode( this );
00184             m_exLowerPipelines.push_back( pipe );
00185         }
00186 
00187         virtual void Commit( OpIterator op ){}
00188         virtual void Cancel( OpIterator op ){}
00189 
00190         virtual void Flush( OpIterator op )
00191         {
00192             if( m_enableLatch ){
00193                 m_latch.Delete( op );
00194             }
00195             m_lowerPipeline.Flush( op );
00196             for( size_t i = 0; i < m_exLowerPipelines.size(); i++ ){
00197                 m_exLowerPipelines[i]->Flush( op );
00198             }
00199         }
00200 
00201         virtual void Retire( OpIterator op )
00202         {
00203             if( m_enableLatch ){
00204                 m_latch.Delete( op );
00205             }
00206             m_lowerPipeline.Retire( op );
00207             for( size_t i = 0; i < m_exLowerPipelines.size(); i++ ){
00208                 m_exLowerPipelines[i]->Retire( op );
00209             }
00210         }
00211 
00212         // Disable a pipeline latch if a latch is not used for optimization.
00213         void DisableLatch()
00214         {
00215             for( Children::iterator i = m_children.begin(); i != m_children.end(); ++i ){
00216                 if( *i == (ClockedResourceIF*)&m_latch ){
00217                     m_children.erase( i );
00218                     break;
00219                 }
00220             }
00221             m_enableLatch = false;
00222         }
00223 
00224         // accessors
00225         Core* GetCore( int index = 0 ) { return m_core[index]; }
00226     protected:
00227         bool m_initialized;
00228         bool m_enableLatch;
00229         typedef ClockedResourceBase BaseT;
00230 
00231         PipelineLatch m_latch;
00232         PhysicalResourceArray<Thread> m_thread;
00233         PhysicalResourceArray<Core>   m_core;
00234 
00235         PipelineNodeIF* m_upperPipelineNode;
00236         Pipeline*       m_upperPipeline;
00237         PipelineNodeIF* m_lowerPipelineNode;
00238         Pipeline        m_lowerPipeline;
00239         std::vector<Pipeline*>  m_exLowerPipelines;
00240     };
00241 
00242 }; // namespace Onikiri
00243 
00244 #endif // SIM_PIPELINE_PIPELINE_NODE_BASE_H

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