Adding gem5 source to svn.
git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1819 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
285
simulators/gem5/src/cpu/inorder/resource_sked.hh
Normal file
285
simulators/gem5/src/cpu/inorder/resource_sked.hh
Normal file
@ -0,0 +1,285 @@
|
||||
/*
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Korey Sewell
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CPU_INORDER_RESOURCE_SKED_HH__
|
||||
#define __CPU_INORDER_RESOURCE_SKED_HH__
|
||||
|
||||
#include <cstdlib>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
/** 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,
|
||||
int _idx = 0) :
|
||||
stageNum(stage_num), resNum(res_num), cmd(_cmd),
|
||||
idx(_idx), priority(_priority)
|
||||
{ }
|
||||
|
||||
/** Stage number to perform this service. */
|
||||
int stageNum;
|
||||
|
||||
/** Resource ID to access */
|
||||
int resNum;
|
||||
|
||||
/** See specific resource for meaning */
|
||||
unsigned cmd;
|
||||
|
||||
/** See specific resource for meaning */
|
||||
unsigned idx;
|
||||
|
||||
/** 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();
|
||||
|
||||
/** Ending Entry of a specified stage */
|
||||
SkedIt end(int stage_num);
|
||||
|
||||
/** Find a schedule entry based on stage and command */
|
||||
SkedIt find(int stage_num, int cmd);
|
||||
|
||||
/** 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;
|
||||
|
||||
/** 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__
|
||||
Reference in New Issue
Block a user