diff options
author | Nathan Binkert <nate@binkert.org> | 2011-02-16 10:57:04 -0500 |
---|---|---|
committer | Nathan Binkert <nate@binkert.org> | 2011-02-16 10:57:04 -0500 |
commit | e3d8d43b176d3a1eb69a5e5d16469d42292e514a (patch) | |
tree | edb7203cec174b20363dc8d698e860076cc1c79c /src/cpu/inorder/resource_sked.hh | |
parent | dfd4f6ad9395650f39057ceff8a6bf4d92408bfc (diff) | |
parent | 9836972a13576bcc7e9bfdf1e61b1d71ecb01cb7 (diff) | |
download | gem5-e3d8d43b176d3a1eb69a5e5d16469d42292e514a.tar.xz |
merge alpha system files into tree
Diffstat (limited to 'src/cpu/inorder/resource_sked.hh')
-rw-r--r-- | src/cpu/inorder/resource_sked.hh | 206 |
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__ |