2009-02-11 00:49:29 +01:00
|
|
|
/*
|
2012-02-24 17:42:00 +01:00
|
|
|
* Copyright (c) 2012 ARM Limited
|
|
|
|
* All rights reserved
|
|
|
|
*
|
|
|
|
* The license below extends only to copyright in the software and shall
|
|
|
|
* not be construed as granting a license to any other intellectual
|
|
|
|
* property including but not limited to intellectual property relating
|
|
|
|
* to a hardware implementation of the functionality of the software
|
|
|
|
* licensed hereunder. You may use the software subject to the license
|
|
|
|
* terms below provided that you ensure that this notice is replicated
|
|
|
|
* unmodified and in its entirety in all distributions of the software,
|
|
|
|
* modified or unmodified, in source code or in binary form.
|
|
|
|
*
|
2009-02-11 00:49:29 +01:00
|
|
|
* Copyright (c) 2007 MIPS Technologies, Inc.
|
|
|
|
* 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
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <list>
|
2011-04-15 19:44:06 +02:00
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "cpu/inorder/resources/resource_list.hh"
|
|
|
|
#include "cpu/inorder/resource_pool.hh"
|
2011-04-15 19:44:32 +02:00
|
|
|
#include "debug/Resource.hh"
|
2009-02-11 00:49:29 +01:00
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using namespace ThePipeline;
|
|
|
|
|
|
|
|
ResourcePool::ResourcePool(InOrderCPU *_cpu, ThePipeline::Params *params)
|
2012-02-24 17:42:00 +01:00
|
|
|
: cpu(_cpu), instUnit(NULL), dataUnit(NULL)
|
2009-02-11 00:49:29 +01:00
|
|
|
{
|
2010-02-01 00:26:13 +01:00
|
|
|
//@todo: use this function to instantiate the resources in resource pool.
|
|
|
|
//This will help in the auto-generation of this pipeline model.
|
2009-02-11 00:49:29 +01:00
|
|
|
//ThePipeline::addResources(resources, memObjects);
|
|
|
|
|
2011-02-04 06:08:18 +01:00
|
|
|
int stage_width = cpu->stageWidth;
|
|
|
|
|
2009-02-11 00:49:29 +01:00
|
|
|
// Declare Resource Objects
|
|
|
|
// name - id - bandwidth - latency - CPU - Parameters
|
|
|
|
// --------------------------------------------------
|
2011-04-20 03:45:21 +02:00
|
|
|
resources.push_back(new FetchSeqUnit("fetch_seq_unit", FetchSeq,
|
2011-02-04 06:08:18 +01:00
|
|
|
stage_width * 2, 0, _cpu, params));
|
2009-02-11 00:49:29 +01:00
|
|
|
|
2012-02-24 17:42:00 +01:00
|
|
|
// Keep track of the instruction fetch unit so we can easily
|
|
|
|
// provide a pointer to it in the CPU.
|
|
|
|
instUnit = new FetchUnit("icache_port", ICache,
|
|
|
|
stage_width * 2 + MaxThreads, 0, _cpu,
|
|
|
|
params);
|
|
|
|
resources.push_back(instUnit);
|
2009-02-11 00:49:29 +01:00
|
|
|
|
2011-04-20 03:45:21 +02:00
|
|
|
resources.push_back(new DecodeUnit("decode_unit", Decode,
|
2011-02-04 06:08:18 +01:00
|
|
|
stage_width, 0, _cpu, params));
|
2009-02-11 00:49:29 +01:00
|
|
|
|
2011-04-20 03:45:21 +02:00
|
|
|
resources.push_back(new BranchPredictor("branch_predictor", BPred,
|
2011-02-04 06:08:18 +01:00
|
|
|
stage_width, 0, _cpu, params));
|
2009-02-11 00:49:29 +01:00
|
|
|
|
2011-04-20 03:45:21 +02:00
|
|
|
resources.push_back(new InstBuffer("fetch_buffer_t0", FetchBuff, 4,
|
2010-02-01 00:26:13 +01:00
|
|
|
0, _cpu, params));
|
2009-02-11 00:49:29 +01:00
|
|
|
|
2011-04-20 03:45:21 +02:00
|
|
|
resources.push_back(new UseDefUnit("regfile_manager", RegManager,
|
2011-02-18 20:29:31 +01:00
|
|
|
stage_width * 3, 0, _cpu,
|
2010-02-01 00:26:13 +01:00
|
|
|
params));
|
2009-02-11 00:49:29 +01:00
|
|
|
|
2011-04-20 03:45:21 +02:00
|
|
|
resources.push_back(new AGENUnit("agen_unit", AGEN,
|
2011-02-04 06:08:18 +01:00
|
|
|
stage_width, 0, _cpu, params));
|
2009-02-11 00:49:29 +01:00
|
|
|
|
2011-04-20 03:45:21 +02:00
|
|
|
resources.push_back(new ExecutionUnit("execution_unit", ExecUnit,
|
2011-02-04 06:08:18 +01:00
|
|
|
stage_width, 0, _cpu, params));
|
2009-02-11 00:49:29 +01:00
|
|
|
|
2011-04-20 03:45:21 +02:00
|
|
|
resources.push_back(new MultDivUnit("mult_div_unit", MDU,
|
2011-06-20 03:43:38 +02:00
|
|
|
stage_width * 2,
|
|
|
|
0,
|
|
|
|
_cpu,
|
|
|
|
params));
|
2009-02-11 00:49:29 +01:00
|
|
|
|
2012-02-24 17:42:00 +01:00
|
|
|
// Keep track of the data load/store unit so we can easily provide
|
|
|
|
// a pointer to it in the CPU.
|
|
|
|
dataUnit = new CacheUnit("dcache_port", DCache,
|
|
|
|
stage_width * 2 + MaxThreads, 0, _cpu,
|
|
|
|
params);
|
|
|
|
resources.push_back(dataUnit);
|
2009-02-11 00:49:29 +01:00
|
|
|
|
2011-06-20 03:43:38 +02:00
|
|
|
gradObjects.push_back(BPred);
|
2011-04-20 03:45:21 +02:00
|
|
|
resources.push_back(new GraduationUnit("graduation_unit", Grad,
|
2011-02-18 20:29:31 +01:00
|
|
|
stage_width, 0, _cpu,
|
2010-02-01 00:26:13 +01:00
|
|
|
params));
|
2009-02-11 00:49:29 +01:00
|
|
|
|
2011-04-20 03:45:21 +02:00
|
|
|
resources.push_back(new InstBuffer("fetch_buffer_t1", FetchBuff2, 4,
|
2010-02-01 00:26:13 +01:00
|
|
|
0, _cpu, params));
|
2011-02-12 16:14:45 +01:00
|
|
|
|
2009-02-11 00:49:29 +01:00
|
|
|
}
|
|
|
|
|
2010-02-01 00:30:08 +01:00
|
|
|
ResourcePool::~ResourcePool()
|
|
|
|
{
|
|
|
|
cout << "Deleting resources ..." << endl;
|
|
|
|
|
|
|
|
for (int i=0; i < resources.size(); i++) {
|
|
|
|
DPRINTF(Resource, "Deleting resource: %s.\n", resources[i]->name());
|
|
|
|
|
|
|
|
delete resources[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-02-11 00:49:29 +01:00
|
|
|
void
|
|
|
|
ResourcePool::init()
|
|
|
|
{
|
|
|
|
for (int i=0; i < resources.size(); i++) {
|
2010-02-01 00:26:13 +01:00
|
|
|
DPRINTF(Resource, "Initializing resource: %s.\n",
|
|
|
|
resources[i]->name());
|
2009-02-11 00:49:29 +01:00
|
|
|
|
|
|
|
resources[i]->init();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
string
|
|
|
|
ResourcePool::name()
|
|
|
|
{
|
|
|
|
return cpu->name() + ".ResourcePool";
|
|
|
|
}
|
|
|
|
|
2011-02-12 16:14:45 +01:00
|
|
|
void
|
|
|
|
ResourcePool::print()
|
|
|
|
{
|
|
|
|
for (int i=0; i < resources.size(); i++) {
|
|
|
|
DPRINTF(InOrderDynInst, "Res:%i %s\n",
|
|
|
|
i, resources[i]->name());
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2009-02-11 00:49:29 +01:00
|
|
|
|
|
|
|
void
|
|
|
|
ResourcePool::regStats()
|
|
|
|
{
|
|
|
|
DPRINTF(Resource, "Registering Stats Throughout Resource Pool.\n");
|
|
|
|
|
|
|
|
int num_resources = resources.size();
|
|
|
|
|
|
|
|
for (int idx = 0; idx < num_resources; idx++) {
|
|
|
|
resources[idx]->regStats();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-02-01 00:30:35 +01:00
|
|
|
unsigned
|
|
|
|
ResourcePool::getResIdx(const ThePipeline::ResourceId &res_id)
|
|
|
|
{
|
|
|
|
int num_resources = resources.size();
|
|
|
|
|
|
|
|
for (int idx = 0; idx < num_resources; idx++) {
|
|
|
|
if (resources[idx]->getId() == res_id)
|
|
|
|
return idx;
|
|
|
|
}
|
|
|
|
|
|
|
|
// todo: change return value to int and return a -1 here
|
|
|
|
// maybe even have enumerated type
|
|
|
|
// panic for now...
|
|
|
|
panic("Can't find resource idx for: %i\n", res_id);
|
|
|
|
|
2009-05-12 21:01:13 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-02-11 00:49:29 +01:00
|
|
|
ResReqPtr
|
|
|
|
ResourcePool::request(int res_idx, DynInstPtr inst)
|
|
|
|
{
|
|
|
|
//Make Sure This is a valid resource ID
|
|
|
|
assert(res_idx >= 0 && res_idx < resources.size());
|
|
|
|
|
|
|
|
return resources[res_idx]->request(inst);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2009-05-26 18:23:13 +02:00
|
|
|
ResourcePool::squash(DynInstPtr inst, int res_idx, InstSeqNum done_seq_num,
|
|
|
|
ThreadID tid)
|
2009-02-11 00:49:29 +01:00
|
|
|
{
|
2010-02-01 00:26:13 +01:00
|
|
|
resources[res_idx]->squash(inst, ThePipeline::NumStages-1, done_seq_num,
|
|
|
|
tid);
|
2009-02-11 00:49:29 +01:00
|
|
|
}
|
|
|
|
|
2011-06-20 03:43:36 +02:00
|
|
|
void
|
|
|
|
ResourcePool::trap(Fault fault, ThreadID tid, DynInstPtr inst)
|
|
|
|
{
|
|
|
|
DPRINTF(Resource, "[tid:%i] Broadcasting Trap to all "
|
|
|
|
"resources.\n", tid);
|
|
|
|
|
|
|
|
int num_resources = resources.size();
|
|
|
|
|
|
|
|
for (int idx = 0; idx < num_resources; idx++)
|
|
|
|
resources[idx]->trap(fault, tid, inst);
|
|
|
|
}
|
|
|
|
|
2009-02-11 00:49:29 +01:00
|
|
|
int
|
|
|
|
ResourcePool::slotsAvail(int res_idx)
|
|
|
|
{
|
|
|
|
return resources[res_idx]->slotsAvail();
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
ResourcePool::slotsInUse(int res_idx)
|
|
|
|
{
|
|
|
|
return resources[res_idx]->slotsInUse();
|
|
|
|
}
|
|
|
|
|
2010-02-01 00:27:49 +01:00
|
|
|
//@todo: split this function and call this version schedulePoolEvent
|
|
|
|
// and use this scheduleEvent for scheduling a specific event on
|
|
|
|
// a resource
|
2010-02-01 00:28:05 +01:00
|
|
|
//@todo: For arguments that arent being used in a ResPoolEvent, a dummyParam
|
|
|
|
// or some typedef can be used to signify what's important info
|
|
|
|
// to the event construction
|
2009-02-11 00:49:29 +01:00
|
|
|
void
|
|
|
|
ResourcePool::scheduleEvent(InOrderCPU::CPUEventType e_type, DynInstPtr inst,
|
2009-05-26 18:23:13 +02:00
|
|
|
int delay, int res_idx, ThreadID tid)
|
2009-02-11 00:49:29 +01:00
|
|
|
{
|
|
|
|
assert(delay >= 0);
|
|
|
|
|
2011-01-08 06:50:29 +01:00
|
|
|
Tick when = cpu->nextCycle(curTick() + cpu->ticks(delay));
|
2011-01-08 06:50:29 +01:00
|
|
|
|
2011-05-09 22:34:11 +02:00
|
|
|
switch ((int)e_type)
|
2009-02-11 00:49:29 +01:00
|
|
|
{
|
|
|
|
case ResourcePool::InstGraduated:
|
|
|
|
{
|
2010-02-01 00:26:13 +01:00
|
|
|
DPRINTF(Resource, "Scheduling Inst-Graduated Resource Pool "
|
2011-01-08 06:50:29 +01:00
|
|
|
"Event for tick %i.\n", curTick() + delay);
|
2011-06-20 03:43:37 +02:00
|
|
|
ResPoolEventPri grad_pri = ResGrad_Pri;
|
2010-02-01 00:26:13 +01:00
|
|
|
ResPoolEvent *res_pool_event =
|
2011-06-20 03:43:37 +02:00
|
|
|
new ResPoolEvent(this,
|
|
|
|
e_type,
|
2010-02-01 00:26:13 +01:00
|
|
|
inst,
|
|
|
|
inst->squashingStage,
|
|
|
|
inst->seqNum,
|
2011-06-20 03:43:37 +02:00
|
|
|
inst->readTid(),
|
|
|
|
grad_pri);
|
2011-01-08 06:50:29 +01:00
|
|
|
cpu->schedule(res_pool_event, when);
|
2009-02-11 00:49:29 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ResourcePool::SquashAll:
|
|
|
|
{
|
2010-02-01 00:26:13 +01:00
|
|
|
DPRINTF(Resource, "Scheduling Squash Resource Pool Event for "
|
2011-01-08 06:50:29 +01:00
|
|
|
"tick %i.\n", curTick() + delay);
|
2011-06-20 03:43:37 +02:00
|
|
|
ResPoolEventPri squash_pri = ResSquash_Pri;
|
2010-02-01 00:26:13 +01:00
|
|
|
ResPoolEvent *res_pool_event =
|
2011-06-20 03:43:37 +02:00
|
|
|
new ResPoolEvent(this,
|
|
|
|
e_type,
|
2010-02-01 00:26:13 +01:00
|
|
|
inst,
|
|
|
|
inst->squashingStage,
|
2011-06-20 03:43:36 +02:00
|
|
|
inst->squashSeqNum,
|
2011-06-20 03:43:37 +02:00
|
|
|
inst->readTid(),
|
|
|
|
squash_pri);
|
2011-01-08 06:50:29 +01:00
|
|
|
cpu->schedule(res_pool_event, when);
|
2010-02-01 00:26:13 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2010-02-01 00:27:49 +01:00
|
|
|
case ResourcePool::UpdateAfterContextSwitch:
|
|
|
|
{
|
2011-01-08 06:50:29 +01:00
|
|
|
DPRINTF(Resource, "Scheduling UpdatePC Resource Pool Event "
|
|
|
|
"for tick %i.\n",
|
2011-01-08 06:50:29 +01:00
|
|
|
curTick() + delay);
|
2011-06-20 03:43:37 +02:00
|
|
|
ResPoolEvent *res_pool_event = new ResPoolEvent(this,
|
|
|
|
e_type,
|
2010-02-01 00:27:49 +01:00
|
|
|
inst,
|
|
|
|
inst->squashingStage,
|
|
|
|
inst->seqNum,
|
|
|
|
inst->readTid());
|
2011-01-08 06:50:29 +01:00
|
|
|
cpu->schedule(res_pool_event, when);
|
2010-02-01 00:27:49 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2009-02-11 00:49:29 +01:00
|
|
|
default:
|
2010-02-01 00:26:13 +01:00
|
|
|
DPRINTF(Resource, "Ignoring Unrecognized CPU Event (%s).\n",
|
|
|
|
InOrderCPU::eventNames[e_type]);
|
2009-02-11 00:49:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ResourcePool::unscheduleEvent(int res_idx, DynInstPtr inst)
|
|
|
|
{
|
|
|
|
resources[res_idx]->unscheduleEvent(inst);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2009-05-26 18:23:13 +02:00
|
|
|
ResourcePool::squashAll(DynInstPtr inst, int stage_num,
|
|
|
|
InstSeqNum done_seq_num, ThreadID tid)
|
2009-02-11 00:49:29 +01:00
|
|
|
{
|
2010-02-01 00:27:02 +01:00
|
|
|
DPRINTF(Resource, "[tid:%i] Broadcasting Squash All Event "
|
|
|
|
" starting w/stage %i for all instructions above [sn:%i].\n",
|
|
|
|
tid, stage_num, done_seq_num);
|
2009-02-11 00:49:29 +01:00
|
|
|
|
|
|
|
int num_resources = resources.size();
|
|
|
|
|
|
|
|
for (int idx = 0; idx < num_resources; idx++) {
|
|
|
|
resources[idx]->squash(inst, stage_num, done_seq_num, tid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-02-01 00:26:13 +01:00
|
|
|
void
|
|
|
|
ResourcePool::squashDueToMemStall(DynInstPtr inst, int stage_num,
|
|
|
|
InstSeqNum done_seq_num, ThreadID tid)
|
|
|
|
{
|
2010-02-01 00:27:02 +01:00
|
|
|
DPRINTF(Resource, "[tid:%i] Broadcasting SquashDueToMemStall Event"
|
|
|
|
" starting w/stage %i for all instructions above [sn:%i].\n",
|
|
|
|
tid, stage_num, done_seq_num);
|
2010-02-01 00:26:13 +01:00
|
|
|
|
|
|
|
int num_resources = resources.size();
|
|
|
|
|
|
|
|
for (int idx = 0; idx < num_resources; idx++) {
|
|
|
|
resources[idx]->squashDueToMemStall(inst, stage_num, done_seq_num,
|
|
|
|
tid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-11 00:49:29 +01:00
|
|
|
void
|
2011-06-20 03:43:38 +02:00
|
|
|
ResourcePool::activateThread(ThreadID tid)
|
2009-02-11 00:49:29 +01:00
|
|
|
{
|
2010-02-01 00:26:32 +01:00
|
|
|
bool do_activate = cpu->threadModel != InOrderCPU::SwitchOnCacheMiss ||
|
|
|
|
cpu->numActiveThreads() < 1 ||
|
|
|
|
cpu->activeThreadId() == tid;
|
|
|
|
|
|
|
|
|
|
|
|
if (do_activate) {
|
|
|
|
DPRINTF(Resource, "[tid:%i] Broadcasting Thread Activation to all "
|
|
|
|
"resources.\n", tid);
|
|
|
|
|
|
|
|
int num_resources = resources.size();
|
|
|
|
|
|
|
|
for (int idx = 0; idx < num_resources; idx++) {
|
|
|
|
resources[idx]->activateThread(tid);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
DPRINTF(Resource, "[tid:%i] Ignoring Thread Activation to all "
|
|
|
|
"resources.\n", tid);
|
|
|
|
}
|
2009-02-11 00:49:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2011-06-20 03:43:38 +02:00
|
|
|
ResourcePool::deactivateThread(ThreadID tid)
|
2009-02-11 00:49:29 +01:00
|
|
|
{
|
2010-02-01 00:26:13 +01:00
|
|
|
DPRINTF(Resource, "[tid:%i] Broadcasting Thread Deactivation to all "
|
|
|
|
"resources.\n", tid);
|
2009-02-11 00:49:29 +01:00
|
|
|
|
|
|
|
int num_resources = resources.size();
|
|
|
|
|
|
|
|
for (int idx = 0; idx < num_resources; idx++) {
|
|
|
|
resources[idx]->deactivateThread(tid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-02-01 00:27:02 +01:00
|
|
|
void
|
2011-06-20 03:43:38 +02:00
|
|
|
ResourcePool::suspendThread(ThreadID tid)
|
2010-02-01 00:27:02 +01:00
|
|
|
{
|
2010-06-24 21:34:12 +02:00
|
|
|
DPRINTF(Resource, "[tid:%i] Broadcasting Thread Suspension to all "
|
|
|
|
"resources.\n", tid);
|
2010-02-01 00:27:02 +01:00
|
|
|
|
|
|
|
int num_resources = resources.size();
|
|
|
|
|
|
|
|
for (int idx = 0; idx < num_resources; idx++) {
|
|
|
|
resources[idx]->suspendThread(tid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-11 00:49:29 +01:00
|
|
|
void
|
2009-05-26 18:23:13 +02:00
|
|
|
ResourcePool::instGraduated(InstSeqNum seq_num, ThreadID tid)
|
2009-02-11 00:49:29 +01:00
|
|
|
{
|
2011-06-20 03:43:38 +02:00
|
|
|
DPRINTF(Resource, "[tid:%i] Broadcasting [sn:%i] graduation to "
|
|
|
|
"appropriate resources.\n", tid, seq_num);
|
2009-02-11 00:49:29 +01:00
|
|
|
|
2011-06-20 03:43:38 +02:00
|
|
|
int num_resources = gradObjects.size();
|
2009-02-11 00:49:29 +01:00
|
|
|
|
|
|
|
for (int idx = 0; idx < num_resources; idx++) {
|
2011-06-20 03:43:38 +02:00
|
|
|
resources[gradObjects[idx]]->instGraduated(seq_num, tid);
|
2009-02-11 00:49:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-02-01 00:27:49 +01:00
|
|
|
void
|
|
|
|
ResourcePool::updateAfterContextSwitch(DynInstPtr inst, ThreadID tid)
|
|
|
|
{
|
|
|
|
DPRINTF(Resource, "[tid:%i] Broadcasting Update PC to all resources.\n",
|
|
|
|
tid);
|
|
|
|
|
|
|
|
int num_resources = resources.size();
|
|
|
|
|
|
|
|
for (int idx = 0; idx < num_resources; idx++) {
|
|
|
|
resources[idx]->updateAfterContextSwitch(inst, tid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-12 21:01:16 +02:00
|
|
|
ResourcePool::ResPoolEvent::ResPoolEvent(ResourcePool *_resPool,
|
|
|
|
InOrderCPU::CPUEventType e_type,
|
|
|
|
DynInstPtr _inst,
|
|
|
|
int stage_num,
|
|
|
|
InstSeqNum seq_num,
|
2011-06-20 03:43:37 +02:00
|
|
|
ThreadID _tid,
|
|
|
|
ResPoolEventPri res_pri)
|
|
|
|
: Event(res_pri), resPool(_resPool),
|
2009-05-12 21:01:16 +02:00
|
|
|
eventType(e_type), inst(_inst), seqNum(seq_num),
|
|
|
|
stageNum(stage_num), tid(_tid)
|
|
|
|
{ }
|
|
|
|
|
2009-02-11 00:49:29 +01:00
|
|
|
|
|
|
|
void
|
|
|
|
ResourcePool::ResPoolEvent::process()
|
|
|
|
{
|
2011-05-09 22:34:11 +02:00
|
|
|
switch ((int)eventType)
|
2009-02-11 00:49:29 +01:00
|
|
|
{
|
2010-02-01 00:27:02 +01:00
|
|
|
|
2009-02-11 00:49:29 +01:00
|
|
|
case ResourcePool::InstGraduated:
|
|
|
|
resPool->instGraduated(seqNum, tid);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ResourcePool::SquashAll:
|
|
|
|
resPool->squashAll(inst, stageNum, seqNum, tid);
|
|
|
|
break;
|
|
|
|
|
2010-02-01 00:27:49 +01:00
|
|
|
case ResourcePool::UpdateAfterContextSwitch:
|
|
|
|
resPool->updateAfterContextSwitch(inst, tid);
|
|
|
|
break;
|
|
|
|
|
2009-02-11 00:49:29 +01:00
|
|
|
default:
|
|
|
|
fatal("Unrecognized Event Type");
|
|
|
|
}
|
|
|
|
|
|
|
|
resPool->cpu->cpuEventRemoveList.push(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const char *
|
2012-01-31 18:05:52 +01:00
|
|
|
ResourcePool::ResPoolEvent::description() const
|
2009-02-11 00:49:29 +01:00
|
|
|
{
|
|
|
|
return "Resource Pool event";
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Schedule resource event, regardless of its current state. */
|
|
|
|
void
|
|
|
|
ResourcePool::ResPoolEvent::scheduleEvent(int delay)
|
|
|
|
{
|
2011-01-08 06:50:29 +01:00
|
|
|
InOrderCPU *cpu = resPool->cpu;
|
2011-01-08 06:50:29 +01:00
|
|
|
assert(!scheduled() || squashed());
|
2011-01-08 06:50:29 +01:00
|
|
|
cpu->reschedule(this, cpu->nextCycle(curTick() + cpu->ticks(delay)), true);
|
2009-02-11 00:49:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Unschedule resource event, regardless of its current state. */
|
|
|
|
void
|
|
|
|
ResourcePool::ResPoolEvent::unscheduleEvent()
|
|
|
|
{
|
|
|
|
if (scheduled())
|
|
|
|
squash();
|
|
|
|
}
|