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
00037 #ifndef SIM_PIPELINE_SCHEDULER_SCHEDULER_H
00038 #define SIM_PIPELINE_SCHEDULER_SCHEDULER_H
00039
00040 #include "Env/Param/ParamExchange.h"
00041
00042 #include "Sim/Pipeline/PipelineNodeBase.h"
00043 #include "Sim/Pipeline/Pipeline.h"
00044 #include "Sim/Foundation/Hook/HookUtil.h"
00045
00046 #include "Sim/Op/OpArray/OpArray.h"
00047 #include "Sim/Op/OpContainer/OpExtraStateTable.h"
00048 #include "Sim/Op/OpContainer/OpBuffer.h"
00049 #include "Sim/Core/DataPredTypes.h"
00050 #include "Sim/Dependency/Dependency.h"
00051
00052 namespace Onikiri
00053 {
00054
00055 struct IssueState;
00056 class Thread;
00057 class LatPred;
00058 class ExecUnitIF;
00059 class IssueSelectorIF;
00060
00061 class Scheduler :
00062 public PipelineNodeBase
00063 {
00064 public:
00065
00066 static const int MAX_SCHEDULING_OPS = 4096;
00067 typedef fixed_sized_buffer< OpIterator, MAX_SCHEDULING_OPS, Scheduler > SchedulingOps;
00068
00069
00070
00071
00072 BEGIN_PARAM_MAP( GetParamPath() )
00073 PARAM_ENTRY("@Index", m_index);
00074 PARAM_ENTRY("@IssueWidth", m_issueWidth);
00075 PARAM_ENTRY("@IssueLatency" , m_issueLatency);
00076 PARAM_ENTRY("@WritebackLatency" ,m_writeBackLatency);
00077 PARAM_ENTRY("@CommunicationLatency", m_communicationLatency);
00078 PARAM_ENTRY("@WindowCapacity", m_windowCapacity);
00079 BEGIN_PARAM_BINDING( "@RemovePolicy", m_removePolicyParam, SchedulerRemovePolicy )
00080 PARAM_BINDING_ENTRY( "Core", RP_FOLLOW_CORE )
00081 PARAM_BINDING_ENTRY( "Remove", RP_REMOVE )
00082 PARAM_BINDING_ENTRY( "Retain", RP_RETAIN )
00083 PARAM_BINDING_ENTRY( "RemoveAfterFinish", RP_REMOVE_AFTER_FINISH )
00084 END_PARAM_BINDING()
00085 END_PARAM_MAP()
00086
00087 BEGIN_RESOURCE_MAP()
00088 RESOURCE_ENTRY( Core, "core", m_core )
00089 RESOURCE_ENTRY( Thread, "thread", m_thread )
00090 RESOURCE_SETTER_ENTRY( ExecUnitIF, "execUnits", SetExecUnit )
00091 RESOURCE_ENTRY( IssueSelectorIF, "selector", m_selector )
00092 END_RESOURCE_MAP()
00093
00094 Scheduler();
00095 virtual ~Scheduler();
00096
00097 void Initialize(InitPhase phase);
00098
00099
00100 void SetExecUnit( PhysicalResourceArray<ExecUnitIF>& execUnits );
00101
00102
00103 ExecUnitIF* GetExecUnit(int code);
00104
00105
00106 virtual void Begin();
00107 virtual void Evaluate();
00108 virtual void Transition();
00109 virtual void Update();
00110
00111 virtual void Commit( OpIterator op );
00112 virtual void Cancel( OpIterator op );
00113 virtual void Flush( OpIterator op );
00114 virtual void Retire( OpIterator op );
00115 virtual void ExitUpperPipeline( OpIterator op );
00116
00117
00118
00119 void EvaluateDependency( OpIterator op );
00120
00121
00122 void RegisterWakeUpEvent( OpIterator op, int latencyFromOp );
00123
00124
00125
00126 bool CanSelect( OpIterator op );
00127
00128
00129
00130 void ReserveSelect( OpIterator op );
00131
00132
00133 void Issue( OpIterator op );
00134
00135
00136 void Finished( OpIterator op );
00137
00138
00139 void WriteBackBegin( OpIterator op );
00140 void WriteBackEnd( OpIterator op );
00141
00142
00143
00144
00145
00146 bool Reschedule( OpIterator op );
00147
00148
00149 bool CanAllocate( int ops );
00150
00151
00152 bool IsInScheduler( OpIterator op );
00153
00154
00155 int GetIndex() const { return m_index; }
00156 void SetIndex(int index) { m_index = index; }
00157 const std::vector<ExecUnitIF*>&
00158 GetExecUnitList() const { return m_execUnit; }
00159 int GetIssueLatency() const { return m_issueLatency; }
00160 int GetIssueWidth() const { return m_issueWidth; }
00161
00162 const OpList& GetReadyOps() const { return m_readyOp; }
00163 const OpList& GetNotReadyOps() const { return m_notReadyOp; }
00164 const OpBuffer& GetIssuedOps() const { return m_issuedOp; }
00165 const SchedulingOps& GetWokeUpOps() const { return m_evaluated.wokeUp; }
00166
00167
00168
00169 struct RescheduleHookParam
00170 {
00171 bool canceled;
00172 };
00173
00174 static HookPoint<Scheduler> s_dispatchedHook;
00175 static HookPoint<Scheduler> s_readySigHook;
00176 static HookPoint<Scheduler> s_wakeUpHook;
00177 static HookPoint<Scheduler> s_selectHook;
00178 static HookPoint<Scheduler> s_issueHook;
00179 static HookPoint<Scheduler, RescheduleHookParam> s_rescheduleHook;
00180
00181 private:
00182 typedef PipelineNodeBase BaseType;
00183
00184 OpList m_notReadyOp;
00185 OpList m_readyOp;
00186 OpBuffer m_issuedOp;
00187
00188 struct Evaluated
00189 {
00190 DependencySet deps;
00191
00192 SchedulingOps wokeUp;
00193 SchedulingOps selected;
00194 } m_evaluated;
00195
00196 int m_index;
00197 int m_issueWidth;
00198 int m_issueLatency;
00199 int m_writeBackLatency;
00200 std::vector<int>
00201 m_communicationLatency;
00202 int m_windowCapacity;
00203
00204
00205
00206 LoadPipelineModel m_loadPipelineModel;
00207
00208
00209 SchedulerRemovePolicy m_removePolicyParam;
00210 SchedulerRemovePolicy m_removePolicy;
00211
00212
00213 std::vector<ExecUnitIF*> m_execUnit;
00214 std::vector<ExecUnitIF*> m_execUnitCodeMap;
00215
00216
00217 IssueSelectorIF* m_selector;
00218
00219
00220 struct Cluster
00221 {
00222 Scheduler* scheduler;
00223 int issueLatency;
00224 int communicationLatency;
00225 };
00226 std::vector<Cluster> m_clusters;
00227
00228
00229 void ClearEvaluated();
00230
00231
00232 void DispatchEnd(OpIterator op);
00233
00234
00235 void EvaluateWakeUp();
00236 void UpdateWakeUp();
00237 void WakeUp(OpIterator op);
00238 void CheckOnWakeUp(OpIterator op);
00239
00240
00241 void EvaluateSelect();
00242 void UpdateSelect();
00243 void Select(OpIterator op);
00244 void SelectBody(OpIterator op);
00245
00246
00247 void IssueBody(OpIterator op);
00248
00249
00250 void Delete( OpIterator op );
00251
00252
00253 int GetOpCount();
00254
00255
00256 void RegisterExecuteEvent(OpIterator op, int latency);
00257
00258 };
00259
00260 };
00261
00262 #endif
00263