summaryrefslogtreecommitdiff
path: root/src/cpu/inorder/resource_sked.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/inorder/resource_sked.hh')
-rw-r--r--src/cpu/inorder/resource_sked.hh206
1 files changed, 199 insertions, 7 deletions
diff --git a/src/cpu/inorder/resource_sked.hh b/src/cpu/inorder/resource_sked.hh
index 22e29d728..bd002e161 100644
--- a/src/cpu/inorder/resource_sked.hh
+++ b/src/cpu/inorder/resource_sked.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 The Regents of The University of Michigan
+ * Copyright (c) 2010-2011 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,19 @@
#include <vector>
#include <list>
+#include <cstdlib>
+/** ScheduleEntry class represents a single function that an instruction
+ wants to do at any pipeline stage. For example, if an instruction
+ needs to be decoded and do a branch prediction all in one stage
+ then each of those tasks would need it's own ScheduleEntry.
+
+ Each schedule entry corresponds to some resource that the instruction
+ wants to interact with.
+
+ The file pipeline_traits.cc shows how a typical instruction schedule is
+ made up of these schedule entries.
+*/
class ScheduleEntry {
public:
ScheduleEntry(int stage_num, int _priority, int res_num, int _cmd = 0,
@@ -43,45 +55,225 @@ class ScheduleEntry {
idx(_idx), priority(_priority)
{ }
- // Stage number to perform this service.
+ /** Stage number to perform this service. */
int stageNum;
- // Resource ID to access
+ /** Resource ID to access */
int resNum;
- // See specific resource for meaning
+ /** See specific resource for meaning */
unsigned cmd;
- // See specific resource for meaning
+ /** See specific resource for meaning */
unsigned idx;
- // Some Resources May Need Priority
+ /** Some Resources May Need Priority */
int priority;
};
+/** The ResourceSked maintains the complete schedule
+ for an instruction. That schedule includes what
+ resources an instruction wants to acquire at each
+ pipeline stage and is represented by a collection
+ of ScheduleEntry objects (described above) that
+ must be executed in-order.
+
+ In every pipeline stage, the InOrder model will
+ process all entries on the resource schedule for
+ that stage and then send the instruction to the next
+ stage if and only if the instruction successfully
+ completed each ScheduleEntry.
+*/
class ResourceSked {
public:
typedef std::list<ScheduleEntry*>::iterator SkedIt;
+ typedef std::vector<std::list<ScheduleEntry*> > StageList;
ResourceSked();
+ /** Initializee the current entry pointer to
+ pipeline stage 0 and the 1st schedule entry
+ */
void init();
+ /** Goes through the remaining stages on the schedule
+ and sums all the remaining entries left to be
+ processed
+ */
int size();
+
+ /** Is the schedule empty? */
bool empty();
+
+ /** Beginning Entry of this schedule */
+ SkedIt begin();
+
+ /** Ending Entry of this schedule */
+ SkedIt end();
+
+ /** What is the next task for this instruction schedule? */
ScheduleEntry* top();
+
+ /** Top() Task is completed, remove it from schedule */
void pop();
+
+ /** Add To Schedule based on stage num and priority of
+ Schedule Entry
+ */
void push(ScheduleEntry* sked_entry);
+
+ /** Add Schedule Entry to be in front of another Entry */
void pushBefore(ScheduleEntry* sked_entry, int sked_cmd, int sked_cmd_idx);
+
+ /** Print what's left on the instruction schedule */
void print();
+ StageList *getStages()
+ {
+ return &stages;
+ }
+
private:
+ /** Current Schedule Entry Pointer */
SkedIt curSkedEntry;
- std::vector<std::list<ScheduleEntry*> > sked;
+ /** The Stage-by-Stage Resource Schedule:
+ Resized to Number of Stages in the constructor
+ */
+ StageList stages;
+
+ /** Find a place to insert the instruction using the
+ schedule entries priority
+ */
SkedIt findIterByPriority(ScheduleEntry *sked_entry, int stage_num);
+
+ /** Find a place to insert the instruction using a particular command
+ to look for.
+ */
SkedIt findIterByCommand(ScheduleEntry *sked_entry, int stage_num,
int sked_cmd, int sked_cmd_idx = -1);
};
+/** Wrapper class around the SkedIt iterator in the Resource Sked so that
+ we can use ++ operator to automatically go to the next available
+ resource schedule entry but otherwise maintain same functionality
+ as a normal iterator.
+*/
+class RSkedIt
+{
+ public:
+ RSkedIt()
+ : curStage(0), numStages(0)
+ { }
+
+
+ /** init() must be called before the use of any other member
+ in the RSkedIt class.
+ */
+ void init(ResourceSked* rsked)
+ {
+ stages = rsked->getStages();
+ numStages = stages->size();
+ }
+
+ /* Update the encapsulated "myIt" iterator, but only
+ update curStage/curStage_end if the iterator is valid.
+ The iterator could be invalid in the case where
+ someone is saving the end of a list (i.e. std::list->end())
+ */
+ RSkedIt operator=(ResourceSked::SkedIt const &rhs)
+ {
+ myIt = rhs;
+ if (myIt != (*stages)[numStages-1].end()) {
+ curStage = (*myIt)->stageNum;
+ curStage_end = (*stages)[curStage].end();
+ }
+ return *this;
+ }
+
+ /** Increment to the next entry in current stage.
+ If no more entries then find the next stage that has
+ resource schedule to complete.
+ If no more stages, then return the end() iterator from
+ the last stage to indicate we are done.
+ */
+ RSkedIt &operator++(int unused)
+ {
+ if (++myIt == curStage_end) {
+ curStage++;
+ while (curStage < numStages) {
+ if ((*stages)[curStage].empty()) {
+ curStage++;
+ } else {
+ myIt = (*stages)[curStage].begin();
+ curStage_end = (*stages)[curStage].end();
+ return *this;
+ }
+ }
+
+ myIt = (*stages)[numStages - 1].end();
+ }
+
+ return *this;
+ }
+
+ /** The "pointer" operator can be used on a RSkedIt and it
+ will use the encapsulated iterator
+ */
+ ScheduleEntry* operator->()
+ {
+ return *myIt;
+ }
+
+ /** Dereferencing a RSKedIt will access the encapsulated
+ iterator
+ */
+ ScheduleEntry* operator*()
+ {
+ return *myIt;
+ }
+
+ /** Equality for RSkedIt only compares the "myIt" iterators,
+ as the other members are just ancillary
+ */
+ bool operator==(RSkedIt const &rhs)
+ {
+ return this->myIt == rhs.myIt;
+ }
+
+ /** Inequality for RSkedIt only compares the "myIt" iterators,
+ as the other members are just ancillary
+ */
+ bool operator!=(RSkedIt const &rhs)
+ {
+ return this->myIt != rhs.myIt;
+ }
+
+ /* The == and != operator overloads should be sufficient
+ here if need otherwise direct access to the schedule
+ iterator, then this can be used */
+ ResourceSked::SkedIt getIt()
+ {
+ return myIt;
+ }
+
+ private:
+ /** Schedule Iterator that this class is encapsulating */
+ ResourceSked::SkedIt myIt;
+
+ /** Ptr to resource schedule that the 'myIt' iterator
+ belongs to
+ */
+ ResourceSked::StageList *stages;
+
+ /** The last iterator in the current stage. */
+ ResourceSked::SkedIt curStage_end;
+
+ /** Current Stage that "myIt" refers to. */
+ int curStage;
+
+ /** Number of stages in the "*stages" object. */
+ int numStages;
+};
+
#endif //__CPU_INORDER_RESOURCE_SKED_HH__