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 #ifndef SIM_TIME_WHEEL_CLOCKED_RESOURCE_BASE_H
00033 #define SIM_TIME_WHEEL_CLOCKED_RESOURCE_BASE_H
00034
00035 #include "Sim/Foundation/TimeWheel/ClockedResourceIF.h"
00036
00037 namespace Onikiri
00038 {
00039
00040 class ClockedResourceBase : public ClockedResourceIF
00041 {
00042 public:
00043 enum PHASE
00044 {
00045 PHASE_BEGIN,
00046 PHASE_EVALUATE,
00047 PHASE_TRANSITION,
00048 PHASE_UPDATE,
00049 PHASE_END
00050 };
00051
00052 struct ComparePriority
00053 {
00054 bool operator()( const ClockedResourceIF* lhv, const ClockedResourceIF* rhv )
00055 { return lhv->GetPriority() > rhv->GetPriority(); }
00056 };
00057
00058 ClockedResourceBase( const char* name = "" ) :
00059 m_name( name ),
00060 m_reqStallThisCycle( false ),
00061 m_stallPeriod( 0 ),
00062 m_thisCycleStalled( false ),
00063 m_lastCycleStalled( false ),
00064 m_parent( NULL ),
00065 m_cycles( 0 ),
00066 m_stalledCycles( 0 ),
00067 m_phase( PHASE_BEGIN ),
00068 m_priority( RP_DEFAULT_UPDATE )
00069 {
00070 }
00071
00072 ~ClockedResourceBase()
00073 {
00074 }
00075
00076
00077
00078
00079
00080
00081 virtual void Begin()
00082 {
00083 ASSERT( m_phase == PHASE_BEGIN );
00084
00085 m_lastCycleStalled = m_thisCycleStalled;
00086 m_thisCycleStalled = false;
00087 m_reqStallThisCycle = false;
00088
00089 if( m_stallPeriod > 0 ) {
00090 m_reqStallThisCycle = true;
00091 --m_stallPeriod;
00092 }
00093
00094 m_phase = PHASE_EVALUATE;
00095
00096 Children::iterator end = m_children.end();
00097 for( Children::iterator i = m_children.begin(); i != end; ++i ){
00098 (*i)->Begin();
00099 }
00100
00101 m_cycles++;
00102 }
00103
00104
00105 virtual void Evaluate()
00106 {
00107 ASSERT( m_phase == PHASE_EVALUATE, "Do you call Begin() of a base class?" );
00108 m_phase = PHASE_TRANSITION;
00109
00110 Children::iterator end = m_children.end();
00111 for( Children::iterator i = m_children.begin(); i != end; ++i ){
00112 (*i)->Evaluate();
00113 }
00114 }
00115
00116
00117
00118 virtual void Transition()
00119 {
00120 ASSERT( m_phase == PHASE_TRANSITION, "Do you call Evaluate() of a base class?" );
00121
00122
00123 m_thisCycleStalled = m_reqStallThisCycle;
00124 m_phase = PHASE_UPDATE;
00125
00126
00127 if( m_thisCycleStalled ){
00128
00129 m_stalledCycles++;
00130 }
00131
00132 if( !m_lastCycleStalled && m_thisCycleStalled ){
00133 BeginStall();
00134 }
00135 else if ( m_lastCycleStalled && !m_thisCycleStalled ){
00136 EndStall();
00137 }
00138
00139 Children::iterator end = m_children.end();
00140 for( Children::iterator i = m_children.begin(); i != end; ++i ){
00141 (*i)->Transition();
00142 }
00143 }
00144
00145
00146 virtual void TriggerUpdate()
00147 {
00148 ASSERT( m_phase == PHASE_UPDATE, "Do you call Event() of a base class?" );
00149
00150 if( !m_thisCycleStalled ){
00151 Update();
00152 }
00153 m_phase = PHASE_END;
00154
00155 Children::iterator end = m_children.end();
00156 for( Children::iterator i = m_children.begin(); i != end; ++i ){
00157 (*i)->TriggerUpdate();
00158 }
00159 }
00160
00161
00162 virtual void End()
00163 {
00164 ASSERT( m_phase == PHASE_END, "Do you call Process() of a base class?" );
00165 m_phase = PHASE_BEGIN;
00166
00167 Children::iterator end = m_children.end();
00168 for( Children::iterator i = m_children.begin(); i != end; ++i ){
00169 (*i)->End();
00170 }
00171
00172 if( !m_thisCycleStalled ){
00173
00174 Tick();
00175 }
00176 }
00177
00178
00179 virtual void StallThisCycle()
00180 {
00181 ASSERT(
00182 m_phase == PHASE_EVALUATE || m_phase == PHASE_TRANSITION,
00183 "IsStalledThisCycle() can be called only in PHASE_EVALUATE/TRANSITION."
00184 );
00185 m_reqStallThisCycle = true;
00186
00187 Children::iterator end = m_children.end();
00188 for( Children::iterator i = m_children.begin(); i != end; ++i ){
00189 (*i)->StallThisCycle();
00190 }
00191 }
00192
00193 void StallThisCycleExcludingChildren()
00194 {
00195 ASSERT(
00196 m_phase == PHASE_EVALUATE || m_phase == PHASE_TRANSITION,
00197 "IsStalledThisCycle() can be called only in PHASE_EVALUATE/TRANSITION."
00198 );
00199 m_reqStallThisCycle = true;
00200 }
00201
00202
00203 virtual void StallNextCycle( int cycles )
00204 {
00205 m_stallPeriod = std::max( cycles, m_stallPeriod );
00206
00207 Children::iterator end = m_children.end();
00208 for( Children::iterator i = m_children.begin(); i != end; ++i ){
00209 (*i)->StallNextCycle( cycles );
00210 }
00211 }
00212
00213
00214 virtual void CacnelStallPeriod()
00215 {
00216 m_stallPeriod = 0;
00217
00218 Children::iterator end = m_children.end();
00219 for( Children::iterator i = m_children.begin(); i != end; ++i ){
00220 (*i)->CacnelStallPeriod();
00221 }
00222 }
00223
00224
00225 bool IsStalledThisCycle()
00226 {
00227 ASSERT(
00228 m_phase == PHASE_UPDATE || m_phase == PHASE_END,
00229 "IsStalledThisCycle() can be called only in PHASE_PROCESS/END."
00230 );
00231 return m_thisCycleStalled;
00232 }
00233
00234
00235 bool IsStalledLastCycle()
00236 {
00237 ASSERT(
00238 m_phase != PHASE_BEGIN,
00239 "IsStalledLastCycle() cannot be called in PHASE_BEGIN."
00240 );
00241 return m_lastCycleStalled;
00242 }
00243
00244
00245 virtual void AddChild( ClockedResourceIF* child )
00246 {
00247 m_children.push_back( child );
00248 child->SetParent( this );
00249 }
00250
00251
00252 virtual void SetParent( ClockedResourceIF* parent )
00253 {
00254 m_parent = parent;
00255
00256 m_who = m_name + "(" + typeid(*this).name() + ")";
00257 if( m_parent ){
00258 m_who += String().format( " <= %s(Parent) ", m_parent->Who() );
00259 }
00260 }
00261
00262 virtual int GetPriority() const
00263 {
00264 return m_priority;
00265 }
00266
00267 virtual const char* Who() const
00268 {
00269
00270 return m_who.c_str();
00271 }
00272
00273
00274 virtual void Update(){};
00275
00276
00277
00278
00279 virtual void Tick(){};
00280
00281
00282 virtual void BeginStall(){};
00283 virtual void EndStall(){};
00284
00285
00286
00287 protected:
00288
00289
00290 typedef std::vector<ClockedResourceIF*> Children;
00291 Children m_children;
00292
00293 PHASE GetCurrentPhase() const
00294 {
00295 return m_phase;
00296 }
00297
00298 s64 GetCycles() const
00299 {
00300 return m_cycles;
00301 }
00302
00303 s64 GetStalledCycles() const
00304 {
00305 return m_stalledCycles;
00306 }
00307
00308
00309 void SetPriority( int priority )
00310 {
00311 m_priority = priority;
00312 }
00313
00314
00315 private:
00316 String m_name;
00317 String m_who;
00318
00319
00320 bool m_reqStallThisCycle;
00321
00322
00323 int m_stallPeriod;
00324
00325
00326 bool m_thisCycleStalled;
00327 bool m_lastCycleStalled;
00328
00329 ClockedResourceIF* m_parent;
00330
00331 s64 m_cycles;
00332
00333
00334 s64 m_stalledCycles;
00335
00336
00337 PHASE m_phase;
00338
00339
00340 int m_priority;
00341 };
00342
00343 };
00344
00345 #endif // SIM_TIME_WHEEL_CLOCKED_RESOURCE_BASE_H
00346