summaryrefslogtreecommitdiff
path: root/src/cpu/inorder/resources
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/inorder/resources')
-rw-r--r--src/cpu/inorder/resources/agen_unit.cc107
-rw-r--r--src/cpu/inorder/resources/agen_unit.hh64
-rw-r--r--src/cpu/inorder/resources/branch_predictor.cc181
-rw-r--r--src/cpu/inorder/resources/branch_predictor.hh87
-rw-r--r--src/cpu/inorder/resources/cache_unit.cc1297
-rw-r--r--src/cpu/inorder/resources/cache_unit.hh269
-rw-r--r--src/cpu/inorder/resources/decode_unit.cc97
-rw-r--r--src/cpu/inorder/resources/decode_unit.hh66
-rw-r--r--src/cpu/inorder/resources/execution_unit.cc249
-rw-r--r--src/cpu/inorder/resources/execution_unit.hh83
-rw-r--r--src/cpu/inorder/resources/fetch_seq_unit.cc335
-rw-r--r--src/cpu/inorder/resources/fetch_seq_unit.hh105
-rw-r--r--src/cpu/inorder/resources/fetch_unit.cc591
-rw-r--r--src/cpu/inorder/resources/fetch_unit.hh139
-rw-r--r--src/cpu/inorder/resources/graduation_unit.cc135
-rw-r--r--src/cpu/inorder/resources/graduation_unit.hh67
-rw-r--r--src/cpu/inorder/resources/inst_buffer.cc241
-rw-r--r--src/cpu/inorder/resources/inst_buffer.hh93
-rw-r--r--src/cpu/inorder/resources/mem_dep_unit.hh66
-rw-r--r--src/cpu/inorder/resources/mult_div_unit.cc353
-rw-r--r--src/cpu/inorder/resources/mult_div_unit.hh139
-rw-r--r--src/cpu/inorder/resources/resource_list.hh50
-rw-r--r--src/cpu/inorder/resources/tlb_unit.cc259
-rw-r--r--src/cpu/inorder/resources/tlb_unit.hh152
-rw-r--r--src/cpu/inorder/resources/use_def.cc510
-rw-r--r--src/cpu/inorder/resources/use_def.hh135
26 files changed, 0 insertions, 5870 deletions
diff --git a/src/cpu/inorder/resources/agen_unit.cc b/src/cpu/inorder/resources/agen_unit.cc
deleted file mode 100644
index f978b2fa7..000000000
--- a/src/cpu/inorder/resources/agen_unit.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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 "cpu/inorder/resources/agen_unit.hh"
-#include "debug/InOrderAGEN.hh"
-
-AGENUnit::AGENUnit(std::string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params)
- : Resource(res_name, res_id, res_width, res_latency, _cpu)
-{ }
-
-void
-AGENUnit::regStats()
-{
- agens
- .name(name() + ".agens")
- .desc("Number of Address Generations");
-
- Resource::regStats();
-}
-
-void
-AGENUnit::execute(int slot_num)
-{
- ResourceRequest* agen_req = reqs[slot_num];
- DynInstPtr inst = reqs[slot_num]->inst;
-#if TRACING_ON
- ThreadID tid = inst->readTid();
-#endif
- InstSeqNum seq_num = inst->seqNum;
-
- if (inst->fault != NoFault) {
- DPRINTF(InOrderAGEN,
- "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to "
- "next stage.\n", tid, inst->seqNum, inst->fault->name(),
- inst->pcState());
- agen_req->done();
- return;
- }
-
- switch (agen_req->cmd)
- {
- case GenerateAddr:
- {
- // Load/Store Instruction
- if (inst->isMemRef()) {
- DPRINTF(InOrderAGEN,
- "[tid:%i] Generating Address for [sn:%i] (%s).\n",
- tid, seq_num, inst->staticInst->getName());
-
- inst->fault = inst->calcEA();
- inst->setMemAddr(inst->getEA());
-
- DPRINTF(InOrderAGEN,
- "[tid:%i] [sn:%i] Effective address calculated as: %#x\n",
- tid, seq_num, inst->getEA());
-
- if (inst->fault == NoFault) {
- agen_req->done();
- } else {
- fatal("%s encountered while calculating address [sn:%i] %s",
- inst->fault->name(), seq_num, inst->instName());
- }
-
- agens++;
- } else {
- DPRINTF(InOrderAGEN,
- "[tid:] Ignoring non-memory instruction [sn:%i]\n",
- tid, seq_num);
- agen_req->done();
- }
- }
- break;
-
- default:
- fatal("Unrecognized command to %s", resName);
- }
-}
diff --git a/src/cpu/inorder/resources/agen_unit.hh b/src/cpu/inorder/resources/agen_unit.hh
deleted file mode 100644
index 72c8a1339..000000000
--- a/src/cpu/inorder/resources/agen_unit.hh
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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
- *
- */
-
-#ifndef __CPU_INORDER_AGEN_UNIT_HH__
-#define __CPU_INORDER_AGEN_UNIT_HH__
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include "cpu/inorder/cpu.hh"
-#include "cpu/inorder/inorder_dyn_inst.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-#include "cpu/inorder/resource.hh"
-
-class AGENUnit : public Resource {
- public:
- typedef InOrderDynInst::DynInstPtr DynInstPtr;
-
- public:
- AGENUnit(std::string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params);
-
- enum Command {
- GenerateAddr
- };
-
- virtual void execute(int slot_num);
- void regStats();
-
- protected:
- Stats::Scalar agens;
-};
-
-#endif //__CPU_INORDER_DECODE_UNIT_HH__
diff --git a/src/cpu/inorder/resources/branch_predictor.cc b/src/cpu/inorder/resources/branch_predictor.cc
deleted file mode 100644
index 50d3847ba..000000000
--- a/src/cpu/inorder/resources/branch_predictor.cc
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * 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 "config/the_isa.hh"
-#include "cpu/inorder/resources/branch_predictor.hh"
-#include "debug/InOrderBPred.hh"
-#include "debug/InOrderStage.hh"
-#include "debug/Resource.hh"
-
-using namespace std;
-using namespace TheISA;
-using namespace ThePipeline;
-
-BranchPredictor::BranchPredictor(std::string res_name, int res_id,
- int res_width, Cycles res_latency,
- InOrderCPU *_cpu,
- ThePipeline::Params *params)
- : Resource(res_name, res_id, res_width, res_latency, _cpu),
- branchPred(params->branchPred)
-{
- instSize = sizeof(MachInst);
-}
-
-void
-BranchPredictor::regStats()
-{
- predictedTaken
- .name(name() + ".predictedTaken")
- .desc("Number of Branches Predicted As Taken (True).");
-
- predictedNotTaken
- .name(name() + ".predictedNotTaken")
- .desc("Number of Branches Predicted As Not Taken (False).");
-
- Resource::regStats();
-}
-
-void
-BranchPredictor::execute(int slot_num)
-{
- ResourceRequest* bpred_req = reqs[slot_num];
- DynInstPtr inst = bpred_req->inst;
- if (inst->fault != NoFault) {
- DPRINTF(InOrderBPred,
- "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to "
- "next stage.\n", inst->readTid(), inst->seqNum, inst->fault->name(),
- inst->pcState());
- bpred_req->done();
- return;
- }
-
- if (!inst->isControl()) {
- DPRINTF(Resource, "Ignoring %s, not a control inst.\n",
- inst->instName());
- bpred_req->done();
- return;
- }
-
- ThreadID tid = inst->readTid();
- InstSeqNum seq_num = inst->seqNum;
- switch (bpred_req->cmd)
- {
- case PredictBranch:
- {
- if (inst->seqNum > cpu->squashSeqNum[tid] &&
- curTick() == cpu->lastSquashCycle[tid]) {
- DPRINTF(InOrderStage, "[tid:%u]: [sn:%i]: squashed, "
- "skipping prediction \n", tid, inst->seqNum);
- } else {
- TheISA::PCState instPC = inst->pcState();
- TheISA::PCState pred_PC = inst->pcState();
- TheISA::advancePC(pred_PC, inst->staticInst);
-
- if (inst->isControl()) {
- // If not, the pred_PC be updated to pc+8
- // If predicted, the pred_PC will be updated to new target
- // value
- bool predict_taken = branchPred->predictInOrder(
- inst->staticInst, inst->seqNum,
- inst->asid, instPC, pred_PC, tid);
-
- if (predict_taken) {
- DPRINTF(InOrderBPred, "[tid:%i]: [sn:%i]: Branch "
- "predicted true.\n", tid, seq_num);
- predictedTaken++;
- } else {
- DPRINTF(InOrderBPred, "[tid:%i]: [sn:%i]: Branch "
- "predicted false.\n", tid, seq_num);
- predictedNotTaken++;
- }
-
- inst->setBranchPred(predict_taken);
- }
-
- //@todo: Check to see how hw_rei is handled here...how does
- //PC,NPC get updated to compare mispredict against???
- inst->setPredTarg(pred_PC);
- DPRINTF(InOrderBPred, "[tid:%i]: [sn:%i]: %s Predicted PC is "
- "%s.\n", tid, seq_num, inst->instName(), pred_PC);
- }
-
- bpred_req->done();
- }
- break;
-
- case UpdatePredictor:
- {
- if (inst->seqNum > cpu->squashSeqNum[tid] &&
- curTick() == cpu->lastSquashCycle[tid]) {
- DPRINTF(InOrderStage, "[tid:%u]: [sn:%i]: squashed, "
- "skipping branch predictor update \n",
- tid, inst->seqNum);
- } else {
- DPRINTF(InOrderBPred, "[tid:%i]: [sn:%i]: Updating "
- "Branch Predictor.\n",
- tid, seq_num);
-
-
- branchPred->update(seq_num, tid);
- }
-
- bpred_req->done();
- }
- break;
-
- default:
- fatal("Unrecognized command to %s", resName);
- }
-}
-
-void
-BranchPredictor::squash(DynInstPtr inst, int squash_stage,
- InstSeqNum squash_seq_num, ThreadID tid)
-{
- InstSeqNum bpred_squash_num = inst->seqNum;
- DPRINTF(InOrderBPred, "[tid:%i][sn:%i] Squashing...\n", tid,
- bpred_squash_num);
-
- // update due to branch resolution
- if (squash_stage >= ThePipeline::BackEndStartStage) {
- branchPred->squash(bpred_squash_num, inst->pcState(),
- inst->pcState().branching(), tid);
- } else {
- // update due to predicted taken branch
- branchPred->squash(bpred_squash_num, tid);
- }
-}
-
-void
-BranchPredictor::instGraduated(InstSeqNum seq_num, ThreadID tid)
-{
- branchPred->update(seq_num, tid);
-}
diff --git a/src/cpu/inorder/resources/branch_predictor.hh b/src/cpu/inorder/resources/branch_predictor.hh
deleted file mode 100644
index e2b7fba52..000000000
--- a/src/cpu/inorder/resources/branch_predictor.hh
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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
- *
- */
-
-#ifndef __CPU_INORDER_BRANCH_PREDICTOR_HH__
-#define __CPU_INORDER_BRANCH_PREDICTOR_HH__
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include "cpu/pred/bpred_unit.hh"
-#include "cpu/inorder/cpu.hh"
-#include "cpu/inorder/inorder_dyn_inst.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-#include "cpu/inorder/resource.hh"
-
-class BranchPredictor : public Resource {
- public:
- typedef ThePipeline::DynInstPtr DynInstPtr;
-
- public:
- enum Command {
- PredictBranch,
- UpdatePredictor
- };
-
- public:
- BranchPredictor(std::string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params);
-
- void regStats();
-
- void execute(int slot_num);
-
- void squash(DynInstPtr inst, int stage_num,
- InstSeqNum squash_seq_num, ThreadID tid);
-
- void instGraduated(InstSeqNum seq_num, ThreadID tid);
-
- protected:
- /** List of instructions this resource is currently
- * processing.
- */
- BPredUnit *branchPred;
-
- int instSize;
-
- /////////////////////////////////////////////////////////////////
- //
- // RESOURCE STATISTICS
- //
- /////////////////////////////////////////////////////////////////
- Stats::Scalar predictedTaken;
- Stats::Scalar predictedNotTaken;
-
-};
-
-#endif //__CPU_INORDER_INST_BUFF_UNIT_HH__
diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc
deleted file mode 100644
index 78b803501..000000000
--- a/src/cpu/inorder/resources/cache_unit.cc
+++ /dev/null
@@ -1,1297 +0,0 @@
-/*
- * Copyright (c) 2013 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.
- *
- * 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>
-#include <vector>
-
-#include "arch/isa_traits.hh"
-#include "arch/locked_mem.hh"
-#include "arch/utility.hh"
-#include "config/the_isa.hh"
-#include "cpu/inorder/resources/cache_unit.hh"
-#include "cpu/inorder/cpu.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-#include "cpu/inorder/resource_pool.hh"
-#include "debug/Activity.hh"
-#include "debug/AddrDep.hh"
-#include "debug/InOrderCachePort.hh"
-#include "debug/InOrderStall.hh"
-#include "debug/InOrderTLB.hh"
-#include "debug/LLSC.hh"
-#include "debug/RefCount.hh"
-#include "debug/ThreadModel.hh"
-#include "mem/request.hh"
-
-using namespace std;
-using namespace TheISA;
-using namespace ThePipeline;
-
-#if TRACING_ON
-static std::string
-printMemData(const uint8_t *data, unsigned size)
-{
- std::stringstream dataStr;
- for (unsigned pos = 0; pos < size; pos++) {
- ccprintf(dataStr, "%02x", data[pos]);
- }
- return dataStr.str();
-}
-#endif
-
-CacheUnit::CacheUnit(string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params)
- : Resource(res_name, res_id, res_width, res_latency, _cpu),
- cachePort(NULL), cachePortBlocked(false)
-{
- // Hard-Code Selection For Now
- if (res_id == ICache)
- _tlb = params->itb;
- else if (res_id == DCache)
- _tlb = params->dtb;
- else
- fatal("Unrecognized TLB name passed by user");
-
- // Note that the CPU port is not yet instantiated (as it is done
- // after the resource pool), we delay setting the cachePort
- // pointer until init().
-
- for (int i=0; i < MaxThreads; i++) {
- tlbBlocked[i] = false;
- tlbBlockSeqNum[i] = 0;
- }
-}
-
-TheISA::TLB*
-CacheUnit::tlb()
-{
- return _tlb;
-
-}
-
-void
-CacheUnit::init()
-{
- // Get the appropriate port from the CPU based on the resource name.
- if (id == ICache) {
- cachePort = &cpu->getInstPort();
- } else if (id == DCache) {
- cachePort = &cpu->getDataPort();
- }
- assert(cachePort != NULL);
-
- for (int i = 0; i < width; i++) {
- reqs[i] = new CacheRequest(this);
- }
-
- cacheBlkSize = cpu->cacheLineSize();
- cacheBlkMask = cacheBlkSize - 1;
-
- initSlots();
-}
-
-int
-CacheUnit::getSlot(DynInstPtr inst)
-{
- ThreadID tid = inst->readTid();
- if (tlbBlocked[tid]) {
- return -1;
- }
-
- // For a Split-Load, the instruction would have processed once already
- // causing the address to be unset.
- if (!inst->validMemAddr() && !inst->splitInst) {
- panic("[tid:%i][sn:%i] Mem. Addr. must be set before requesting "
- "cache access\n", inst->readTid(), inst->seqNum);
- }
-
- int new_slot = Resource::getSlot(inst);
- inst->memTime = curTick();
- //@note: add back in if you want speculative loads/store capability
- //setAddrDependency(inst);
- return new_slot;
-}
-
-void
-CacheUnit::setAddrDependency(DynInstPtr inst)
-{
- Addr req_addr = inst->getMemAddr();
- ThreadID tid = inst->readTid();
-
- addrList[tid].push_back(req_addr);
- addrMap[tid][req_addr] = inst->seqNum;
-
- DPRINTF(AddrDep,
- "[tid:%i]: [sn:%i]: Address %08p added to dependency list (size=%i)\n",
- inst->readTid(), inst->seqNum, req_addr, addrList[tid].size());
-
- //@NOTE: 10 is an arbitrarily "high" number, but to be exact
- // we would need to know the # of outstanding accesses
- // a priori. Information like fetch width, stage width,
- // fetch buffer, and the branch resolution stage would be
- // useful for the icache_port. For the dcache port, the #
- // of outstanding cache accesses (mshrs) would be a good
- // sanity check here.
- //assert(addrList[tid].size() < 10);
-}
-
-void
-CacheUnit::removeAddrDependency(DynInstPtr inst)
-{
- ThreadID tid = inst->readTid();
-
- Addr mem_addr = inst->getMemAddr();
-
- inst->unsetMemAddr();
-
- // Erase from Address List
- std::list<Addr>::iterator list_it = find(addrList[tid].begin(),
- addrList[tid].end(),
- mem_addr);
- assert(list_it != addrList[tid].end() || inst->splitInst);
-
- if (list_it != addrList[tid].end()) {
- DPRINTF(AddrDep,
- "[tid:%i]: [sn:%i] Address %08p removed from dependency "
- "list\n", inst->readTid(), inst->seqNum, (*list_it));
-
- addrList[tid].erase(list_it);
-
- // Erase From Address Map (Used for Debugging)
- addrMap[tid].erase(addrMap[tid].find(mem_addr));
- }
-
-
-}
-
-ResReqPtr
-CacheUnit::findRequest(DynInstPtr inst)
-{
- for (int i = 0; i < width; i++) {
- CacheRequest* cache_req =
- dynamic_cast<CacheRequest*>(reqs[i]);
- assert(cache_req);
-
- if (cache_req->valid &&
- cache_req->getInst() == inst &&
- cache_req->instIdx == inst->curSkedEntry->idx) {
- return cache_req;
- }
- }
-
- return NULL;
-}
-
-ResReqPtr
-CacheUnit::findRequest(DynInstPtr inst, int idx)
-{
- for (int i = 0; i < width; i++) {
- CacheRequest* cache_req =
- dynamic_cast<CacheRequest*>(reqs[i]);
- assert(cache_req);
-
- if (cache_req->valid &&
- cache_req->getInst() == inst &&
- cache_req->instIdx == idx) {
- return cache_req;
- }
- }
-
- return NULL;
-}
-
-
-ResReqPtr
-CacheUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx,
- int slot_num, unsigned cmd)
-{
- ScheduleEntry* sched_entry = *inst->curSkedEntry;
- CacheRequest* cache_req = dynamic_cast<CacheRequest*>(reqs[slot_num]);
-
- if (!inst->validMemAddr()) {
- panic("Mem. Addr. must be set before requesting cache access\n");
- }
-
- MemCmd::Command pkt_cmd;
-
- switch (sched_entry->cmd)
- {
- case InitSecondSplitRead:
- pkt_cmd = MemCmd::ReadReq;
-
- DPRINTF(InOrderCachePort,
- "[tid:%i]: Read request from [sn:%i] for addr %08p\n",
- inst->readTid(), inst->seqNum, inst->split2ndAddr);
- break;
-
- case InitiateReadData:
- pkt_cmd = MemCmd::ReadReq;
-
- DPRINTF(InOrderCachePort,
- "[tid:%i]: Read request from [sn:%i] for addr %08p\n",
- inst->readTid(), inst->seqNum, inst->getMemAddr());
- break;
-
- case InitSecondSplitWrite:
- pkt_cmd = MemCmd::WriteReq;
-
- DPRINTF(InOrderCachePort,
- "[tid:%i]: Write request from [sn:%i] for addr %08p\n",
- inst->readTid(), inst->seqNum, inst->split2ndAddr);
- break;
-
- case InitiateWriteData:
- pkt_cmd = MemCmd::WriteReq;
-
- DPRINTF(InOrderCachePort,
- "[tid:%i]: Write request from [sn:%i] for addr %08p\n",
- inst->readTid(), inst->seqNum, inst->getMemAddr());
- break;
-
- default:
- panic("%i: Unexpected request type (%i) to %s", curTick(),
- sched_entry->cmd, name());
- }
-
- cache_req->setRequest(inst, stage_num, id, slot_num,
- sched_entry->cmd, pkt_cmd,
- inst->curSkedEntry->idx);
- return cache_req;
-}
-
-void
-CacheUnit::requestAgain(DynInstPtr inst, bool &service_request)
-{
- CacheReqPtr cache_req = dynamic_cast<CacheReqPtr>(findRequest(inst));
- assert(cache_req);
-
- // Check to see if this instruction is requesting the same command
- // or a different one
- if (cache_req->cmd != inst->curSkedEntry->cmd &&
- cache_req->instIdx == inst->curSkedEntry->idx) {
- // If different, then update command in the request
- cache_req->cmd = inst->curSkedEntry->cmd;
- DPRINTF(InOrderCachePort,
- "[tid:%i]: [sn:%i]: Updating the command for this "
- "instruction\n", inst->readTid(), inst->seqNum);
-
- service_request = true;
- } else if (inst->curSkedEntry->idx != CacheUnit::InitSecondSplitRead &&
- inst->curSkedEntry->idx != CacheUnit::InitSecondSplitWrite) {
- // If same command, just check to see if memory access was completed
- // but dont try to re-execute
- DPRINTF(InOrderCachePort,
- "[tid:%i]: [sn:%i]: requesting this resource again\n",
- inst->readTid(), inst->seqNum);
-
- service_request = true;
- }
-}
-
-void
-CacheUnit::setupMemRequest(DynInstPtr inst, CacheReqPtr cache_req,
- int acc_size, int flags)
-{
- ThreadID tid = inst->readTid();
- Addr aligned_addr = inst->getMemAddr();
-
- if (!cache_req->is2ndSplit()) {
- if (cache_req->memReq == NULL) {
- cache_req->memReq =
- new Request(cpu->asid[tid], aligned_addr, acc_size, flags,
- cpu->dataMasterId(),
- inst->instAddr(),
- cpu->readCpuId(), //@todo: use context id
- tid);
- }
- } else {
- assert(inst->splitInst);
-
- if (inst->splitMemReq == NULL) {
- inst->splitMemReq = new Request(cpu->asid[tid],
- inst->split2ndAddr,
- acc_size,
- flags,
- cpu->dataMasterId(),
- inst->instAddr(),
- cpu->readCpuId(),
- tid);
- }
-
- cache_req->memReq = inst->splitMemReq;
- }
-}
-
-void
-CacheUnit::doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
- int flags, TheISA::TLB::Mode tlb_mode)
-{
- ThreadID tid = inst->readTid();
-
- setupMemRequest(inst, cache_req, acc_size, flags);
-
- //@todo: HACK: the DTB expects the correct PC in the ThreadContext
- // but how if the memory accesses are speculative? Shouldn't
- // we send along the requestor's PC to the translate functions?
- ThreadContext *tc = cpu->thread[tid]->getTC();
- PCState old_pc = tc->pcState();
- tc->pcState() = inst->pcState();
-
- inst->fault =
- _tlb->translateAtomic(cache_req->memReq, tc, tlb_mode);
- tc->pcState() = old_pc;
-
- if (inst->fault != NoFault) {
- DPRINTF(InOrderTLB, "[tid:%i]: %s encountered while translating "
- "addr:%08p for [sn:%i].\n", tid, inst->fault->name(),
- cache_req->memReq->getVaddr(), inst->seqNum);
-
- tlbBlocked[tid] = true;
- tlbBlockSeqNum[tid] = inst->seqNum;
-
- // Make sure nothing gets executed until after this faulting
- // instruction gets handled.
- inst->setSerializeAfter();
-
- // Mark it as complete so it can pass through next stage.
- // Fault Handling will happen at commit/graduation
- cache_req->setCompleted();
- } else {
- DPRINTF(InOrderTLB, "[tid:%i]: [sn:%i] virt. addr %08p translated "
- "to phys. addr:%08p.\n", tid, inst->seqNum,
- cache_req->memReq->getVaddr(),
- cache_req->memReq->getPaddr());
- }
-}
-
-void
-CacheUnit::trap(const Fault &fault, ThreadID tid, DynInstPtr inst)
-{
- tlbBlocked[tid] = false;
-}
-
-Fault
-CacheUnit::read(DynInstPtr inst, Addr addr,
- uint8_t *data, unsigned size, unsigned flags)
-{
- CacheReqPtr cache_req = dynamic_cast<CacheReqPtr>(findRequest(inst));
- assert(cache_req && "Can't Find Instruction for Read!");
-
- // The block size of our peer
- unsigned blockSize = cacheBlkSize;
-
- //The size of the data we're trying to read.
- int fullSize = size;
- inst->totalSize = size;
-
- if (inst->traceData) {
- inst->traceData->setMem(addr, size, flags);
- }
-
- if (inst->split2ndAccess) {
- size = inst->split2ndSize;
- cache_req->splitAccess = true;
- cache_req->split2ndAccess = true;
-
- DPRINTF(InOrderCachePort, "[sn:%i] Split Read Access (2 of 2) for "
- "(%#x, %#x).\n", inst->seqNum, inst->getMemAddr(),
- inst->split2ndAddr);
- }
-
-
- //The address of the second part of this access if it needs to be split
- //across a cache line boundary.
- Addr secondAddr = roundDown(addr + size - 1, blockSize);
-
-
- if (secondAddr > addr && !inst->split2ndAccess) {
-
- if (!inst->splitInst) {
- DPRINTF(InOrderCachePort, "%i: sn[%i] Split Read Access (1 of 2) for "
- "(%#x, %#x).\n", curTick(), inst->seqNum, addr, secondAddr);
-
- unsigned stage_num = cache_req->getStageNum();
- unsigned cmd = inst->curSkedEntry->cmd;
-
- // 1. Make A New Inst. Schedule w/Split Read/Complete Entered on
- // the schedule
- // ==============================
- // 2. Reassign curSkedPtr to current command (InitiateRead) on new
- // schedule
- // ==============================
- inst->splitInst = true;
- inst->setBackSked(cpu->createBackEndSked(inst));
- inst->curSkedEntry = inst->backSked->find(stage_num, cmd);
- } else {
- DPRINTF(InOrderCachePort, "[tid:%i] [sn:%i] Retrying Split Read "
- "Access (1 of 2) for (%#x, %#x).\n", inst->readTid(),
- inst->seqNum, addr, secondAddr);
- }
-
- // Save All "Total" Split Information
- // ==============================
- inst->splitMemData = new uint8_t[size];
-
- // Split Information for First Access
- // ==============================
- size = secondAddr - addr;
- cache_req->splitAccess = true;
-
- // Split Information for Second Access
- // ==============================
- inst->split2ndSize = addr + fullSize - secondAddr;
- inst->split2ndAddr = secondAddr;
- inst->split2ndDataPtr = inst->splitMemData + size;
- inst->split2ndFlags = flags;
- }
-
- doTLBAccess(inst, cache_req, size, flags, TheISA::TLB::Read);
-
- if (inst->fault == NoFault) {
- if (!cache_req->splitAccess) {
- cache_req->reqData = new uint8_t[size];
- doCacheAccess(inst, NULL);
- } else {
- if (!inst->split2ndAccess) {
- cache_req->reqData = inst->splitMemData;
- } else {
- cache_req->reqData = inst->split2ndDataPtr;
- }
-
- doCacheAccess(inst, NULL, cache_req);
- }
- }
-
- return inst->fault;
-}
-
-Fault
-CacheUnit::write(DynInstPtr inst, uint8_t *data, unsigned size,
- Addr addr, unsigned flags, uint64_t *write_res)
-{
- CacheReqPtr cache_req = dynamic_cast<CacheReqPtr>(findRequest(inst));
- assert(cache_req && "Can't Find Instruction for Write!");
-
- // The block size of our peer
- unsigned blockSize = cacheBlkSize;
-
- //The size of the data we're trying to write.
- int fullSize = size;
- inst->totalSize = size;
-
- if (inst->traceData)
- inst->traceData->setMem(addr, size, flags);
-
- if (inst->split2ndAccess) {
- size = inst->split2ndSize;
- cache_req->splitAccess = true;
- cache_req->split2ndAccess = true;
-
- DPRINTF(InOrderCachePort, "[sn:%i] Split Write Access (2 of 2) for "
- "(%#x, %#x).\n", inst->seqNum, inst->getMemAddr(),
- inst->split2ndAddr);
- }
-
- //The address of the second part of this access if it needs to be split
- //across a cache line boundary.
- Addr secondAddr = roundDown(addr + size - 1, blockSize);
-
- if (secondAddr > addr && !inst->split2ndAccess) {
-
- DPRINTF(InOrderCachePort, "[sn:%i] Split Write Access (1 of 2) for "
- "(%#x, %#x).\n", inst->seqNum, addr, secondAddr);
-
- // Save All "Total" Split Information
- // ==============================
- inst->splitInst = true;
-
- if (!inst->splitInstSked) {
- assert(0 && "Split Requests Not Supported for Now...");
-
- // Schedule Split Read/Complete for Instruction
- // ==============================
- int stage_num = cache_req->getStageNum();
- RSkedPtr inst_sked = (stage_num >= ThePipeline::BackEndStartStage) ?
- inst->backSked : inst->frontSked;
-
- // this is just an arbitrarily high priority to ensure that this
- // gets pushed to the back of the list
- int stage_pri = 20;
-
- int isplit_cmd = CacheUnit::InitSecondSplitWrite;
- inst_sked->push(new
- ScheduleEntry(stage_num,
- stage_pri,
- cpu->resPool->getResIdx(DCache),
- isplit_cmd,
- 1));
-
- int csplit_cmd = CacheUnit::CompleteSecondSplitWrite;
- inst_sked->push(new
- ScheduleEntry(stage_num + 1,
- 1/*stage_pri*/,
- cpu->resPool->getResIdx(DCache),
- csplit_cmd,
- 1));
- inst->splitInstSked = true;
- } else {
- DPRINTF(InOrderCachePort, "[tid:%i] sn:%i] Retrying Split Read "
- "Access (1 of 2) for (%#x, %#x).\n",
- inst->readTid(), inst->seqNum, addr, secondAddr);
- }
-
-
-
- // Split Information for First Access
- // ==============================
- size = secondAddr - addr;
- cache_req->splitAccess = true;
-
- // Split Information for Second Access
- // ==============================
- inst->split2ndSize = addr + fullSize - secondAddr;
- inst->split2ndAddr = secondAddr;
- inst->split2ndFlags = flags;
- inst->splitInstSked = true;
- }
-
- doTLBAccess(inst, cache_req, size, flags, TheISA::TLB::Write);
-
- if (inst->fault == NoFault) {
- if (!cache_req->splitAccess) {
- cache_req->reqData = new uint8_t[size];
- memcpy(cache_req->reqData, data, size);
-
- //inst->split2ndStoreDataPtr = cache_req->reqData;
- //inst->split2ndStoreDataPtr += size;
-
- doCacheAccess(inst, write_res);
- } else {
- doCacheAccess(inst, write_res, cache_req);
- }
-
- }
-
- return inst->fault;
-}
-
-
-void
-CacheUnit::execute(int slot_num)
-{
- CacheReqPtr cache_req = dynamic_cast<CacheReqPtr>(reqs[slot_num]);
- assert(cache_req);
-
- if (cachePortBlocked &&
- (cache_req->cmd == InitiateReadData ||
- cache_req->cmd == InitiateWriteData ||
- cache_req->cmd == InitSecondSplitRead ||
- cache_req->cmd == InitSecondSplitWrite)) {
- DPRINTF(InOrderCachePort, "Cache Port Blocked. Cannot Access\n");
- cache_req->done(false);
- return;
- }
-
- DynInstPtr inst = cache_req->inst;
- if (inst->fault != NoFault) {
- DPRINTF(InOrderCachePort,
- "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to "
- "next stage.\n", inst->readTid(), inst->seqNum, inst->fault->name(),
- inst->getMemAddr());
- finishCacheUnitReq(inst, cache_req);
- return;
- }
-
- if (inst->isSquashed()) {
- DPRINTF(InOrderCachePort,
- "[tid:%i]: [sn:%i]: Detected squashed instruction "
- "next stage.\n", inst->readTid(), inst->seqNum);
- finishCacheUnitReq(inst, cache_req);
- return;
- }
-
-#if TRACING_ON
- ThreadID tid = inst->readTid();
- std::string acc_type = "write";
-#endif
-
- switch (cache_req->cmd)
- {
-
- case InitiateReadData:
-#if TRACING_ON
- acc_type = "read";
-#endif
- case InitiateWriteData:
- if (cachePortBlocked) {
- DPRINTF(InOrderCachePort, "Cache Port Blocked. Cannot Access\n");
- cache_req->done(false);
- return;
- }
-
- DPRINTF(InOrderCachePort,
- "[tid:%u]: [sn:%i] Initiating data %s access to %s for "
- "addr. %08p\n", tid, inst->seqNum, acc_type, name(),
- cache_req->inst->getMemAddr());
-
- inst->setCurResSlot(slot_num);
-
- if (inst->isDataPrefetch() || inst->isInstPrefetch()) {
- inst->execute();
- } else {
- inst->initiateAcc();
- }
-
- break;
-
- case InitSecondSplitRead:
- DPRINTF(InOrderCachePort,
- "[tid:%u]: [sn:%i] Initiating split data read access to %s "
- "for addr. %08p\n", tid, inst->seqNum, name(),
- cache_req->inst->split2ndAddr);
- inst->split2ndAccess = true;
- assert(inst->split2ndAddr != 0);
- read(inst, inst->split2ndAddr, &inst->split2ndData,
- inst->totalSize, inst->split2ndFlags);
- break;
-
- case InitSecondSplitWrite:
- DPRINTF(InOrderCachePort,
- "[tid:%u]: [sn:%i] Initiating split data write access to %s "
- "for addr. %08p\n", tid, inst->seqNum, name(),
- cache_req->inst->getMemAddr());
-
- inst->split2ndAccess = true;
- assert(inst->split2ndAddr != 0);
- write(inst, &inst->split2ndData, inst->totalSize,
- inst->split2ndAddr, inst->split2ndFlags, NULL);
- break;
-
- case CompleteReadData:
- DPRINTF(InOrderCachePort,
- "[tid:%i]: [sn:%i]: Trying to Complete Data Read Access\n",
- tid, inst->seqNum);
-
-
- //@todo: timing translations need to check here...
- assert(!inst->isInstPrefetch() && "Can't Handle Inst. Prefecthes");
- if (cache_req->isMemAccComplete() || inst->isDataPrefetch()) {
- finishCacheUnitReq(inst, cache_req);
- } else {
- DPRINTF(InOrderStall, "STALL: [tid:%i]: Data miss from %08p\n",
- tid, cache_req->inst->getMemAddr());
- cache_req->setCompleted(false);
- cache_req->setMemStall(true);
- }
- break;
-
- case CompleteWriteData:
- {
- DPRINTF(InOrderCachePort,
- "[tid:%i]: [sn:%i]: Trying to Complete Data Write Access\n",
- tid, inst->seqNum);
-
-
- //@todo: check that timing translation is finished here
- RequestPtr mem_req = cache_req->memReq;
- if (mem_req->isCondSwap() || mem_req->isLLSC() || mem_req->isSwap()) {
- DPRINTF(InOrderCachePort, "Detected Conditional Store Inst.\n");
-
- if (!cache_req->isMemAccComplete()) {
- DPRINTF(InOrderStall, "STALL: [tid:%i]: Data miss from %08p\n",
- tid, cache_req->inst->getMemAddr());
- cache_req->setCompleted(false);
- cache_req->setMemStall(true);
- return;
- } else {
- DPRINTF(InOrderStall, "Mem Acc Completed\n");
- }
- }
-
- if (cache_req->isMemAccPending()) {
- DPRINTF(InOrderCachePort, "Store Instruction Pending Completion.\n");
- cache_req->dataPkt->reqData = cache_req->reqData;
- cache_req->dataPkt->memReq = cache_req->memReq;
- } else
- DPRINTF(InOrderCachePort, "Store Instruction Finished Completion.\n");
-
- //@todo: if split inst save data
- finishCacheUnitReq(inst, cache_req);
- }
- break;
-
- case CompleteSecondSplitRead:
- DPRINTF(InOrderCachePort,
- "[tid:%i]: [sn:%i]: Trying to Complete Split Data Read "
- "Access\n", tid, inst->seqNum);
-
- //@todo: check that timing translation is finished here
- assert(!inst->isInstPrefetch() && "Can't Handle Inst. Prefecthes");
- if (cache_req->isMemAccComplete() || inst->isDataPrefetch()) {
- finishCacheUnitReq(inst, cache_req);
- } else {
- DPRINTF(InOrderStall, "STALL: [tid:%i]: Data miss from %08p\n",
- tid, cache_req->inst->split2ndAddr);
- cache_req->setCompleted(false);
- cache_req->setMemStall(true);
- }
- break;
-
- case CompleteSecondSplitWrite:
- DPRINTF(InOrderCachePort,
- "[tid:%i]: [sn:%i]: Trying to Complete Split Data Write "
- "Access\n", tid, inst->seqNum);
- //@todo: illegal to have a unaligned cond.swap or llsc?
- assert(!cache_req->memReq->isSwap() && !cache_req->memReq->isCondSwap()
- && !cache_req->memReq->isLLSC());
-
- if (cache_req->isMemAccPending()) {
- cache_req->dataPkt->reqData = cache_req->reqData;
- cache_req->dataPkt->memReq = cache_req->memReq;
- }
-
- //@todo: check that timing translation is finished here
- finishCacheUnitReq(inst, cache_req);
- break;
-
- default:
- fatal("Unrecognized command to %s", resName);
- }
-}
-
-void
-CacheUnit::finishCacheUnitReq(DynInstPtr inst, CacheRequest *cache_req)
-{
- //@note: add back in for speculative load/store capability
- //removeAddrDependency(inst);
- cache_req->setMemStall(false);
- cache_req->done();
-}
-
-void
-CacheUnit::buildDataPacket(CacheRequest *cache_req)
-{
- MemCmd cmd;
-
- if (cache_req->pktCmd == MemCmd::ReadReq) {
- cmd = Packet::makeReadCmd(cache_req->memReq);
- } else {
- assert(cache_req->pktCmd == MemCmd::WriteReq);
- cmd = Packet::makeWriteCmd(cache_req->memReq);
- }
-
- cache_req->dataPkt = new CacheReqPacket(cache_req, cmd,
- cache_req->instIdx);
-
- DPRINTF(InOrderCachePort, "[slot:%i]: Slot marked for %x\n",
- cache_req->getSlot(),
- cache_req->dataPkt->getAddr());
-
- cache_req->dataPkt->hasSlot = true;
- cache_req->dataPkt->dataStatic(cache_req->reqData);
-}
-
-void
-CacheUnit::doCacheAccess(DynInstPtr inst, uint64_t *write_res,
- CacheReqPtr split_req)
-{
- Fault fault = NoFault;
-#if TRACING_ON
- ThreadID tid = inst->readTid();
-#endif
- bool do_access = true; // flag to suppress cache access
-
- // Special Handling if this is a split request
- CacheReqPtr cache_req;
- if (split_req == NULL)
- cache_req = dynamic_cast<CacheReqPtr>(reqs[inst->getCurResSlot()]);
- else {
- cache_req = split_req;
- assert(0);
- }
-
- // Make a new packet inside the CacheRequest object
- assert(cache_req);
- buildDataPacket(cache_req);
-
- // Special Handling for LL/SC or Compare/Swap
- bool is_write = cache_req->dataPkt->isWrite();
- RequestPtr mem_req = cache_req->dataPkt->req;
- if (is_write) {
- DPRINTF(InOrderCachePort,
- "[tid:%u]: [sn:%i]: Storing data: %s\n",
- tid, inst->seqNum,
- printMemData(cache_req->dataPkt->getConstPtr<uint8_t>(),
- cache_req->dataPkt->getSize()));
-
- if (mem_req->isCondSwap()) {
- assert(write_res);
- cache_req->memReq->setExtraData(*write_res);
- }
- if (mem_req->isLLSC()) {
- assert(cache_req->inst->isStoreConditional());
- DPRINTF(InOrderCachePort, "Evaluating Store Conditional access\n");
- do_access = TheISA::handleLockedWrite(inst.get(), mem_req, cacheBlkSize);
- }
- }
-
- // Finally, go ahead and make the access if we can...
- DPRINTF(InOrderCachePort,
- "[tid:%i] [sn:%i] attempting to access cache for addr %08p\n",
- tid, inst->seqNum, cache_req->dataPkt->getAddr());
-
- if (do_access) {
- if (!cachePort->sendTimingReq(cache_req->dataPkt)) {
- DPRINTF(InOrderCachePort,
- "[tid:%i] [sn:%i] cannot access cache, because port "
- "is blocked. now waiting to retry request\n", tid,
- inst->seqNum);
- delete cache_req->dataPkt;
- cache_req->dataPkt = NULL;
-
- delete cache_req->memReq;
- cache_req->memReq = NULL;
-
- cache_req->done(false);
- cachePortBlocked = true;
- } else {
- DPRINTF(InOrderCachePort,
- "[tid:%i] [sn:%i] is now waiting for cache response\n",
- tid, inst->seqNum);
- cache_req->setCompleted();
- cache_req->setMemAccPending();
- cachePortBlocked = false;
- }
- } else if (mem_req->isLLSC()){
- // Store-Conditional instructions complete even if they "failed"
- assert(cache_req->inst->isStoreConditional());
- cache_req->setCompleted(true);
-
- DPRINTF(LLSC,
- "[tid:%i]: T%i Ignoring Failed Store Conditional Access\n",
- tid, tid);
-
- processCacheCompletion(cache_req->dataPkt);
- } else {
- delete cache_req->dataPkt;
- cache_req->dataPkt = NULL;
-
- delete cache_req->memReq;
- cache_req->memReq = NULL;
-
- // Make cache request again since access due to
- // inability to access
- DPRINTF(InOrderStall, "STALL: \n");
- cache_req->done(false);
- }
-
-}
-
-bool
-CacheUnit::processSquash(CacheReqPacket *cache_pkt)
-{
- // The resource may no longer be actively servicing this
- // packet. Scenarios like a store that has been sent to the
- // memory system or access that's been squashed. If that's
- // the case, we can't access the request slot because it
- // will be either invalid or servicing another request.
- if (!cache_pkt->hasSlot) {
- DPRINTF(InOrderCachePort,
- "%x does not have a slot in unit, ignoring.\n",
- cache_pkt->getAddr());
-
- if (cache_pkt->reqData) {
- delete [] cache_pkt->reqData;
- cache_pkt->reqData = NULL;
- }
-
- if (cache_pkt->memReq) {
- delete cache_pkt->memReq;
- cache_pkt->memReq = NULL;
- }
-
- delete cache_pkt;
- cache_pkt = NULL;
- cpu->wakeCPU();
- return true;
- } else {
- DPRINTF(InOrderCachePort, "%x has slot %i\n",
- cache_pkt->getAddr(), cache_pkt->cacheReq->getSlot());
- }
-
-
- // It's possible that the request is squashed but the
- // packet is still acknowledged by the resource. Squashes
- // should happen at the end of the cycles and trigger the
- // code above, but if not, this would handle any timing
- // variations due to diff. user parameters.
- if (cache_pkt->cacheReq->isSquashed()) {
- DPRINTF(InOrderCachePort,
- "Ignoring completion of squashed access, [tid:%i] [sn:%i]\n",
- cache_pkt->cacheReq->getInst()->readTid(),
- cache_pkt->cacheReq->getInst()->seqNum);
-
- cache_pkt->cacheReq->setMemAccPending(false);
- cache_pkt->cacheReq->freeSlot();
- delete cache_pkt;
- cache_pkt = NULL;
- cpu->wakeCPU();
- return true;
- }
-
-
- return false;
-}
-
-void
-CacheUnit::processCacheCompletion(PacketPtr pkt)
-{
- //@todo: use packet sender state instead of deriving from packet class to
- // get special state
- CacheReqPacket* cache_pkt = dynamic_cast<CacheReqPacket*>(pkt);
- assert(cache_pkt);
-
- DPRINTF(InOrderCachePort, "Finished request for %x\n", pkt->getAddr());
-
- if (processSquash(cache_pkt))
- return;
-
- CacheRequest *cache_req = dynamic_cast<CacheReqPtr>(
- findRequest(cache_pkt->cacheReq->getInst(), cache_pkt->instIdx));
-
- if (!cache_req) {
- panic("[tid:%u]: [sn:%i]: Can't find slot for cache access to "
- "addr. %08p\n", cache_pkt->cacheReq->getInst()->readTid(),
- cache_pkt->cacheReq->getInst()->seqNum,
- cache_pkt->cacheReq->getInst()->getMemAddr());
- }
-
- assert(cache_req);
- assert(cache_req == cache_pkt->cacheReq);
-
- DPRINTF(InOrderCachePort,
- "[tid:%u]: [sn:%i]: [slot:%i] Waking from cache access (vaddr.%08p, paddr:%08p)\n",
- cache_pkt->cacheReq->getInst()->readTid(),
- cache_pkt->cacheReq->getInst()->seqNum,
- cache_req->getSlot(),
- cache_pkt->req->getVaddr(),
- cache_pkt->req->getPaddr());
-
- // Get resource request info
- unsigned stage_num = cache_req->getStageNum();
- DynInstPtr inst = cache_req->inst;
- ThreadID tid = cache_req->inst->readTid();
-
- assert(!cache_req->isSquashed());
- assert(inst->staticInst && inst->isMemRef());
-
-
- DPRINTF(InOrderCachePort,
- "[tid:%u]: [sn:%i]: Processing cache access\n",
- tid, inst->seqNum);
-
- PacketPtr split_pkt = NULL;
- if (inst->splitInst) {
- inst->splitFinishCnt++;
-
- if (inst->splitFinishCnt == 2) {
- cache_req->memReq->setVirt(0/*inst->tid*/,
- inst->getMemAddr(),
- inst->totalSize,
- 0,
- cpu->dataMasterId(),
- 0);
-
- split_pkt = new Packet(cache_req->memReq, cache_req->pktCmd);
- split_pkt->dataStatic(inst->splitMemData);
-
- DPRINTF(InOrderCachePort, "Completing Split Access.\n");
- inst->completeAcc(split_pkt);
- }
- } else {
- inst->completeAcc(cache_pkt);
- }
-
- inst->setExecuted();
-
- if (inst->isLoad()) {
- assert(cache_pkt->isRead());
-
- if (cache_pkt->req->isLLSC()) {
- DPRINTF(InOrderCachePort,
- "[tid:%u]: Handling Load-Linked for [sn:%u]\n",
- tid, inst->seqNum);
- TheISA::handleLockedRead(inst.get(), cache_pkt->req);
- }
-
- DPRINTF(InOrderCachePort,
- "[tid:%u]: [sn:%i]: Bytes loaded were: %s\n",
- tid, inst->seqNum,
- (split_pkt) ? printMemData(split_pkt->getConstPtr<uint8_t>(),
- split_pkt->getSize()) :
- printMemData(cache_pkt->getConstPtr<uint8_t>(),
- cache_pkt->getSize()));
- } else if(inst->isStore()) {
- assert(cache_pkt->isWrite());
-
- DPRINTF(InOrderCachePort,
- "[tid:%u]: [sn:%i]: Bytes stored were: %s\n",
- tid, inst->seqNum,
- (split_pkt) ? printMemData(split_pkt->getConstPtr<uint8_t>(),
- split_pkt->getSize()) :
- printMemData(cache_pkt->getConstPtr<uint8_t>(),
- cache_pkt->getSize()));
- }
-
-
- if (split_pkt) {
- delete split_pkt;
- split_pkt = NULL;
- }
-
- cache_req->setMemAccPending(false);
- cache_req->setMemAccCompleted();
-
- if (cache_req->isMemStall() &&
- cpu->threadModel == InOrderCPU::SwitchOnCacheMiss) {
- DPRINTF(InOrderCachePort, "[tid:%u] Waking up from Cache Miss.\n",
- tid);
-
- cpu->activateContext(tid);
-
- DPRINTF(ThreadModel, "Activating [tid:%i] after return from cache"
- "miss.\n", tid);
- }
-
- // Wake up the CPU (if it went to sleep and was waiting on this
- // completion event).
- cpu->wakeCPU();
-
- DPRINTF(Activity, "[tid:%u] Activating %s due to cache completion\n",
- tid, cpu->pipelineStage[stage_num]->name());
-
- cpu->switchToActive(stage_num);
-}
-
-void
-CacheUnit::recvRetry()
-{
- DPRINTF(InOrderCachePort, "Unblocking Cache Port. \n");
-
- assert(cachePortBlocked);
-
- // Clear the cache port for use again
- cachePortBlocked = false;
-
- cpu->wakeCPU();
-}
-
-CacheUnitEvent::CacheUnitEvent()
- : ResourceEvent()
-{ }
-
-void
-CacheUnitEvent::process()
-{
- DynInstPtr inst = resource->reqs[slotIdx]->inst;
- int stage_num = resource->reqs[slotIdx]->getStageNum();
- ThreadID tid = inst->threadNumber;
- CacheReqPtr req_ptr = dynamic_cast<CacheReqPtr>(resource->reqs[slotIdx]);
-
- DPRINTF(InOrderTLB, "Waking up from TLB Miss caused by [sn:%i].\n",
- inst->seqNum);
-
- CacheUnit* tlb_res = dynamic_cast<CacheUnit*>(resource);
- assert(tlb_res);
-
- //@todo: eventually, we should do a timing translation w/
- // hw page table walk on tlb miss
- DPRINTF(InOrderTLB, "Handling Fault %s : [sn:%i] %x\n", inst->fault->name(), inst->seqNum, inst->getMemAddr());
- inst->fault->invoke(tlb_res->cpu->tcBase(tid), inst->staticInst);
-
- tlb_res->tlbBlocked[tid] = false;
-
- tlb_res->cpu->pipelineStage[stage_num]->
- unsetResStall(tlb_res->reqs[slotIdx], tid);
-
- req_ptr->tlbStall = false;
-
- //@todo: timing translation needs to have some type of independent
- // info regarding if it's squashed or not so we can
- // free up the resource if a request gets squashed in the middle
- // of a table walk
- if (req_ptr->isSquashed()) {
- req_ptr->freeSlot();
- }
-
- tlb_res->cpu->wakeCPU();
-}
-
-void
-CacheUnit::squashDueToMemStall(DynInstPtr inst, int stage_num,
- InstSeqNum squash_seq_num, ThreadID tid)
-{
- // If squashing due to memory stall, then we do NOT want to
- // squash the instruction that caused the stall so we
- // increment the sequence number here to prevent that.
- //
- // NOTE: This is only for the SwitchOnCacheMiss Model
- // NOTE: If you have multiple outstanding misses from the same
- // thread then you need to reevaluate this code
- // NOTE: squash should originate from
- // pipeline_stage.cc:processInstSchedule
- DPRINTF(InOrderCachePort, "Squashing above [sn:%u]\n",
- squash_seq_num + 1);
-
- squash(inst, stage_num, squash_seq_num + 1, tid);
-}
-
-void
-CacheUnit::squashCacheRequest(CacheReqPtr req_ptr)
-{
- DynInstPtr inst = req_ptr->getInst();
- req_ptr->setSquashed();
- inst->setSquashed();
-
- //@note: add back in for speculative load/store capability
- /*if (inst->validMemAddr()) {
- DPRINTF(AddrDep, "Squash of [tid:%i] [sn:%i], attempting to "
- "remove addr. %08p dependencies.\n",
- inst->readTid(),
- inst->seqNum,
- inst->getMemAddr());
-
- removeAddrDependency(inst);
- }*/
-}
-
-
-void
-CacheUnit::squash(DynInstPtr inst, int stage_num,
- InstSeqNum squash_seq_num, ThreadID tid)
-{
- if (tlbBlocked[tid] &&
- tlbBlockSeqNum[tid] > squash_seq_num) {
- DPRINTF(InOrderCachePort, "Releasing TLB Block due to "
- " squash after [sn:%i].\n", squash_seq_num);
- tlbBlocked[tid] = false;
- }
-
- for (int i = 0; i < width; i++) {
- ResReqPtr req_ptr = reqs[i];
-
- if (req_ptr->valid &&
- req_ptr->getInst()->readTid() == tid &&
- req_ptr->getInst()->seqNum > squash_seq_num) {
-
- DPRINTF(InOrderCachePort,
- "[tid:%i] Squashing request from [sn:%i]\n",
- req_ptr->getInst()->readTid(), req_ptr->getInst()->seqNum);
-
- if (req_ptr->isSquashed()) {
- DPRINTF(AddrDep, "Request for [tid:%i] [sn:%i] already "
- "squashed, ignoring squash process.\n",
- req_ptr->getInst()->readTid(),
- req_ptr->getInst()->seqNum);
- continue;
- }
-
- CacheReqPtr cache_req = dynamic_cast<CacheReqPtr>(req_ptr);
- assert(cache_req);
-
- squashCacheRequest(cache_req);
-
- int req_slot_num = req_ptr->getSlot();
-
- if (cache_req->tlbStall) {
- tlbBlocked[tid] = false;
-
- int stall_stage = reqs[req_slot_num]->getStageNum();
-
- cpu->pipelineStage[stall_stage]->
- unsetResStall(reqs[req_slot_num], tid);
- }
-
- if (cache_req->isMemAccPending()) {
- cache_req->dataPkt->reqData = cache_req->reqData;
- cache_req->dataPkt->memReq = cache_req->memReq;
- }
-
- if (!cache_req->tlbStall)
- freeSlot(req_slot_num);
- }
- }
-
-}
-
-void
-CacheRequest::clearRequest()
-{
- if (!memAccPending) {
- if (reqData && !splitAccess)
- delete [] reqData;
-
- if (memReq)
- delete memReq;
-
- if (dataPkt)
- delete dataPkt;
- } else {
- if (dataPkt)
- dataPkt->hasSlot = false;
- }
-
- memReq = NULL;
- reqData = NULL;
- dataPkt = NULL;
- memAccComplete = false;
- memAccPending = false;
- tlbStall = false;
- splitAccess = false;
- splitAccessNum = -1;
- split2ndAccess = false;
- instIdx = 0;
- fetchBufferFill = false;
-
- ResourceRequest::clearRequest();
-}
diff --git a/src/cpu/inorder/resources/cache_unit.hh b/src/cpu/inorder/resources/cache_unit.hh
deleted file mode 100644
index 11eb9ddad..000000000
--- a/src/cpu/inorder/resources/cache_unit.hh
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * 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
- *
- */
-
-#ifndef __CPU_INORDER_CACHE_UNIT_HH__
-#define __CPU_INORDER_CACHE_UNIT_HH__
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include "arch/tlb.hh"
-#include "base/hashmap.hh"
-#include "config/the_isa.hh"
-#include "cpu/inorder/inorder_dyn_inst.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-#include "cpu/inorder/resource.hh"
-#include "mem/packet.hh"
-#include "mem/packet_access.hh"
-#include "mem/port.hh"
-#include "params/InOrderCPU.hh"
-#include "sim/sim_object.hh"
-
-class CacheReqPacket;
-typedef CacheReqPacket* CacheReqPktPtr;
-
-class CacheUnit : public Resource
-{
- public:
- typedef ThePipeline::DynInstPtr DynInstPtr;
-
- public:
- CacheUnit(std::string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params);
-
- enum Command {
- InitiateReadData,
- CompleteReadData,
- InitiateWriteData,
- CompleteWriteData,
- InitSecondSplitRead,
- InitSecondSplitWrite,
- CompleteSecondSplitRead,
- CompleteSecondSplitWrite
- };
-
- public:
-
- void init();
-
- ResourceRequest* getRequest(DynInstPtr _inst, int stage_num,
- int res_idx, int slot_num,
- unsigned cmd);
-
- ResReqPtr findRequest(DynInstPtr inst);
- ResReqPtr findRequest(DynInstPtr inst, int idx);
-
- void requestAgain(DynInstPtr inst, bool &try_request);
-
- virtual int getSlot(DynInstPtr inst);
-
- /** Executes one of the commands from the "Command" enum */
- virtual void execute(int slot_num);
-
- virtual void squash(DynInstPtr inst, int stage_num,
- InstSeqNum squash_seq_num, ThreadID tid);
-
- void squashDueToMemStall(DynInstPtr inst, int stage_num,
- InstSeqNum squash_seq_num, ThreadID tid);
-
- virtual void squashCacheRequest(CacheReqPtr req_ptr);
-
- /** After memory request is completedd in the cache, then do final
- processing to complete the request in the CPU.
- */
- virtual void processCacheCompletion(PacketPtr pkt);
-
- /** Create request that will interface w/TLB and Memory objects */
- virtual void setupMemRequest(DynInstPtr inst, CacheReqPtr cache_req,
- int acc_size, int flags);
-
- void finishCacheUnitReq(DynInstPtr inst, CacheRequest *cache_req);
-
- void buildDataPacket(CacheRequest *cache_req);
-
- bool processSquash(CacheReqPacket *cache_pkt);
-
- void trap(const Fault &fault, ThreadID tid, DynInstPtr inst);
-
- void recvRetry();
-
- Fault read(DynInstPtr inst, Addr addr,
- uint8_t *data, unsigned size, unsigned flags);
-
- Fault write(DynInstPtr inst, uint8_t *data, unsigned size,
- Addr addr, unsigned flags, uint64_t *res);
-
- void doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
- int flags, TheISA::TLB::Mode tlb_mode);
-
- /** Read/Write on behalf of an instruction.
- * curResSlot needs to be a valid value in instruction.
- */
- void doCacheAccess(DynInstPtr inst, uint64_t *write_result=NULL,
- CacheReqPtr split_req=NULL);
-
- uint64_t getMemData(Packet *packet);
-
- void setAddrDependency(DynInstPtr inst);
- virtual void removeAddrDependency(DynInstPtr inst);
-
- protected:
- /** Cache interface. */
- MasterPort *cachePort;
-
- bool cachePortBlocked;
-
- std::list<Addr> addrList[ThePipeline::MaxThreads];
-
- m5::hash_map<Addr, InstSeqNum> addrMap[ThePipeline::MaxThreads];
-
- public:
- int cacheBlkSize;
-
- int cacheBlkMask;
-
- /** Align a PC to the start of the Cache block. */
- Addr cacheBlockAlign(Addr addr)
- {
- return (addr & ~(cacheBlkMask));
- }
-
- bool tlbBlocked[ThePipeline::MaxThreads];
- InstSeqNum tlbBlockSeqNum[ThePipeline::MaxThreads];
-
- TheISA::TLB* tlb();
- TheISA::TLB *_tlb;
-};
-
-class CacheUnitEvent : public ResourceEvent {
- public:
- const std::string name() const
- {
- return "CacheUnitEvent";
- }
-
-
- /** Constructs a resource event. */
- CacheUnitEvent();
- virtual ~CacheUnitEvent() {}
-
- /** Processes a resource event. */
- void process();
-};
-
-//@todo: Move into CacheUnit Class for private access to "valid" field
-class CacheRequest : public ResourceRequest
-{
- public:
- CacheRequest(CacheUnit *cres)
- : ResourceRequest(cres), memReq(NULL), reqData(NULL),
- dataPkt(NULL), memAccComplete(false),
- memAccPending(false), tlbStall(false), splitAccess(false),
- splitAccessNum(-1), split2ndAccess(false),
- fetchBufferFill(false)
- { }
-
- virtual ~CacheRequest()
- {
- if (reqData && !splitAccess)
- delete [] reqData;
- }
-
- void setRequest(DynInstPtr _inst, int stage_num, int res_idx, int slot_num,
- unsigned _cmd, MemCmd::Command pkt_cmd, int idx)
- {
- pktCmd = pkt_cmd;
- instIdx = idx;
-
- ResourceRequest::setRequest(_inst, stage_num, res_idx, slot_num, _cmd);
- }
-
- void clearRequest();
-
- virtual PacketDataPtr getData()
- { return reqData; }
-
- void
- setMemAccCompleted(bool completed = true)
- {
- memAccComplete = completed;
- }
-
- bool is2ndSplit()
- {
- return split2ndAccess;
- }
-
- bool isMemAccComplete() { return memAccComplete; }
-
- void setMemAccPending(bool pending = true) { memAccPending = pending; }
- bool isMemAccPending() { return memAccPending; }
-
- //Make this data private/protected!
- MemCmd pktCmd;
- RequestPtr memReq;
- PacketDataPtr reqData;
- CacheReqPacket *dataPkt;
-
- bool memAccComplete;
- bool memAccPending;
- bool tlbStall;
-
- bool splitAccess;
- int splitAccessNum;
- bool split2ndAccess;
- int instIdx;
-
- /** Should we expect block from cache access or fetch buffer? */
- bool fetchBufferFill;
-};
-
-class CacheReqPacket : public Packet
-{
- public:
- CacheReqPacket(CacheRequest *_req,
- MemCmd _cmd, int _idx = 0)
- : Packet(&(*_req->memReq), _cmd), cacheReq(_req),
- instIdx(_idx), hasSlot(false), reqData(NULL), memReq(NULL)
- {
-
- }
-
- CacheRequest *cacheReq;
- int instIdx;
- bool hasSlot;
- PacketDataPtr reqData;
- RequestPtr memReq;
-};
-
-#endif //__CPU_CACHE_UNIT_HH__
diff --git a/src/cpu/inorder/resources/decode_unit.cc b/src/cpu/inorder/resources/decode_unit.cc
deleted file mode 100644
index 7b7eccd0a..000000000
--- a/src/cpu/inorder/resources/decode_unit.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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 "config/the_isa.hh"
-#include "cpu/inorder/resources/decode_unit.hh"
-#include "debug/InOrderDecode.hh"
-#include "debug/InOrderStall.hh"
-#include "debug/Resource.hh"
-
-using namespace TheISA;
-using namespace ThePipeline;
-using namespace std;
-
-DecodeUnit::DecodeUnit(std::string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params)
- : Resource(res_name, res_id, res_width, res_latency, _cpu)
-{
- for (ThreadID tid = 0; tid < MaxThreads; tid++) {
- regDepMap[tid] = &cpu->archRegDepMap[tid];
- }
-}
-
-void
-DecodeUnit::execute(int slot_num)
-{
- ResourceRequest* decode_req = reqs[slot_num];
- DynInstPtr inst = reqs[slot_num]->inst;
-
- switch (decode_req->cmd)
- {
- case DecodeInst:
- {
-
- if (inst->fault != NoFault) {
- inst->setBackSked(cpu->faultSked);
- DPRINTF(InOrderDecode,"[tid:%i]: Fault found for instruction [sn:%i]\n",
- inst->readTid(), inst->seqNum);
- } else {
- assert(!inst->staticInst->isMacroop());
- inst->setBackSked(cpu->createBackEndSked(inst));
- DPRINTF(InOrderDecode,"Decoded instruction [sn:%i]: %s : 0x%x\n",
- inst->seqNum, inst->instName(),
- inst->staticInst->machInst);
- }
-
- if (inst->backSked != NULL) {
- DPRINTF(InOrderDecode,
- "[tid:%i]: Back End Schedule created for %s [sn:%i].\n",
- inst->readTid(), inst->instName(), inst->seqNum);
- decode_req->done();
- } else {
- DPRINTF(Resource,
- "[tid:%i] Static Inst not available to decode.\n",
- inst->readTid());
- DPRINTF(Resource,
- "Unable to create schedule for instruction [sn:%i] \n",
- inst->seqNum);
- DPRINTF(InOrderStall, "STALL: \n");
- decode_req->done(false);
- }
- }
- break;
-
- default:
- fatal("Unrecognized command to %s", resName);
- }
-}
-
diff --git a/src/cpu/inorder/resources/decode_unit.hh b/src/cpu/inorder/resources/decode_unit.hh
deleted file mode 100644
index 65f82a94b..000000000
--- a/src/cpu/inorder/resources/decode_unit.hh
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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
- *
- */
-
-#ifndef __CPU_INORDER_DECODE_UNIT_HH__
-#define __CPU_INORDER_DECODE_UNIT_HH__
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include "cpu/inorder/cpu.hh"
-#include "cpu/inorder/inorder_dyn_inst.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-#include "cpu/inorder/reg_dep_map.hh"
-#include "cpu/inorder/resource.hh"
-
-class DecodeUnit : public Resource {
- public:
- typedef ThePipeline::DynInstPtr DynInstPtr;
-
- public:
- DecodeUnit(std::string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params);
-
- enum Command {
- DecodeInst
- };
-
- void execute(int slot_num);
-
- RegDepMap *regDepMap[ThePipeline::MaxThreads];
-
- protected:
- /** @todo: Add Resource Stats Here */
-};
-
-#endif //__CPU_INORDER_DECODE_UNIT_HH__
diff --git a/src/cpu/inorder/resources/execution_unit.cc b/src/cpu/inorder/resources/execution_unit.cc
deleted file mode 100644
index 296d5126f..000000000
--- a/src/cpu/inorder/resources/execution_unit.cc
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * 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>
-#include <vector>
-
-#include "cpu/inorder/resources/execution_unit.hh"
-#include "cpu/inorder/cpu.hh"
-#include "cpu/inorder/resource_pool.hh"
-#include "debug/Fault.hh"
-#include "debug/InOrderExecute.hh"
-#include "debug/InOrderStall.hh"
-#include "sim/full_system.hh"
-
-using namespace std;
-using namespace ThePipeline;
-
-ExecutionUnit::ExecutionUnit(string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params)
- : Resource(res_name, res_id, res_width, res_latency, _cpu),
- lastExecuteTick(0), lastControlTick(0)
-{ }
-
-void
-ExecutionUnit::regStats()
-{
- predictedTakenIncorrect
- .name(name() + ".predictedTakenIncorrect")
- .desc("Number of Branches Incorrectly Predicted As Taken.");
-
- predictedNotTakenIncorrect
- .name(name() + ".predictedNotTakenIncorrect")
- .desc("Number of Branches Incorrectly Predicted As Not Taken).");
-
- executions
- .name(name() + ".executions")
- .desc("Number of Instructions Executed.");
-
-
- predictedIncorrect
- .name(name() + ".mispredicted")
- .desc("Number of Branches Incorrectly Predicted");
-
- predictedCorrect
- .name(name() + ".predicted")
- .desc("Number of Branches Incorrectly Predicted");
-
- mispredictPct
- .name(name() + ".mispredictPct")
- .desc("Percentage of Incorrect Branches Predicts")
- .precision(6);
- mispredictPct = (predictedIncorrect /
- (predictedCorrect + predictedIncorrect)) * 100;
-
- Resource::regStats();
-}
-
-void
-ExecutionUnit::execute(int slot_num)
-{
- ResourceRequest* exec_req = reqs[slot_num];
- DynInstPtr inst = reqs[slot_num]->inst;
- if (inst->fault != NoFault) {
- DPRINTF(InOrderExecute,
- "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to "
- "next stage.\n", inst->readTid(), inst->seqNum, inst->fault->name(),
- inst->pcState());
- exec_req->done();
- return;
- }
-
- Fault fault = NoFault;
- Tick cur_tick = curTick();
- unsigned stage_num = exec_req->getStageNum();
- ThreadID tid = inst->readTid();
-#if TRACING_ON
- InstSeqNum seq_num = inst->seqNum;
-#endif
-
- switch (exec_req->cmd)
- {
- case ExecuteInst:
- {
- if (inst->isNop()) {
- DPRINTF(InOrderExecute, "[tid:%i] [sn:%i] [PC:%s] Ignoring execution"
- "of %s.\n", inst->readTid(), seq_num, inst->pcState(),
- inst->instName());
- inst->setExecuted();
- exec_req->done();
- return;
- } else {
- DPRINTF(InOrderExecute, "[tid:%i] Executing [sn:%i] [PC:%s] %s.\n",
- inst->readTid(), seq_num, inst->pcState(), inst->instName());
- }
-
- if (cur_tick != lastExecuteTick) {
- lastExecuteTick = cur_tick;
- }
-
- //@todo: handle address generation here
- assert(!inst->isMemRef());
-
- if (inst->isControl()) {
- if (lastControlTick == cur_tick) {
- DPRINTF(InOrderExecute, "Can not Execute More than One Control "
- "Inst Per Cycle. Blocking Request.\n");
- exec_req->done(false);
- return;
- }
- lastControlTick = curTick();
-
- // Evaluate Branch
- fault = inst->execute();
-
- // Should unconditional control , pc relative count as an
- // execution??? Probably not.
- executions++;
-
- if (fault == NoFault) {
- inst->setExecuted();
-
- if (inst->mispredicted()) {
- assert(inst->isControl());
-
- // Set up Squash Generated By this Misprediction
- TheISA::PCState pc = inst->pcState();
- TheISA::advancePC(pc, inst->staticInst);
- inst->setPredTarg(pc);
- inst->setSquashInfo(stage_num);
- setupSquash(inst, stage_num, tid);
-
- DPRINTF(InOrderExecute, "[tid:%i]: [sn:%i] Squashing from "
- "stage %i. Redirecting fetch to %s.\n", tid,
- inst->seqNum, stage_num, pc);
- DPRINTF(InOrderStall, "STALL: [tid:%i]: Branch"
- " misprediction at %s\n", tid, inst->pcState());
-
- if (inst->predTaken()) {
- predictedTakenIncorrect++;
- DPRINTF(InOrderExecute, "[tid:%i] [sn:%i] %s ..."
- "PC %s ... Mispredicts! "
- "(Prediction: Taken)\n",
- tid, inst->seqNum,
- inst->staticInst->disassemble(
- inst->instAddr()),
- inst->pcState());
- } else {
- predictedNotTakenIncorrect++;
- DPRINTF(InOrderExecute, "[tid:%i] [sn:%i] %s ..."
- "PC %s ... Mispredicts! "
- "(Prediction: Not Taken)\n",
- tid, inst->seqNum,
- inst->staticInst->disassemble(
- inst->instAddr()),
- inst->pcState());
- }
- predictedIncorrect++;
- } else {
- DPRINTF(InOrderExecute, "[tid:%i]: [sn:%i]: Prediction"
- "Correct.\n", inst->readTid(), seq_num);
- predictedCorrect++;
- }
-
- exec_req->done();
- } else {
- DPRINTF(Fault, "[tid:%i]:[sn:%i]: Fault %s found\n",
- inst->readTid(), inst->seqNum, fault->name());
- inst->fault = fault;
- exec_req->done();
- }
- } else {
- // Regular ALU instruction
- fault = inst->execute();
- executions++;
-
- if (fault == NoFault) {
- inst->setExecuted();
-
-#if TRACING_ON
- for (int didx = 0; didx < inst->numDestRegs(); didx++)
- if (inst->resultType(didx) == InOrderDynInst::Float ||
- inst->resultType(didx) == InOrderDynInst::FloatBits ||
- inst->resultType(didx) == InOrderDynInst::Double)
- DPRINTF(InOrderExecute, "[tid:%i]: [sn:%i]: Dest result %i "
- "of FP execution is %08f (%x).\n", inst->readTid(),
- seq_num, didx, inst->readFloatResult(didx),
- inst->readFloatBitsResult(didx));
- else
- DPRINTF(InOrderExecute, "[tid:%i]: [sn:%i]: Dest result %i "
- "of Int execution is 0x%x.\n", inst->readTid(),
- seq_num, didx, inst->readIntResult(didx));
-#endif
-
- if (!FullSystem) {
- // The Syscall might change the PC, so conservatively
- // squash everything behing it
- if (inst->isSyscall()) {
- inst->setSquashInfo(stage_num);
- setupSquash(inst, stage_num, tid);
- }
- }
- } else {
- DPRINTF(InOrderExecute, "[tid:%i]: [sn:%i]: had a %s "
- "fault.\n", inst->readTid(), seq_num, fault->name());
- DPRINTF(Fault, "[tid:%i]:[sn:%i]: Fault %s found\n",
- inst->readTid(), inst->seqNum, fault->name());
- inst->fault = fault;
- }
-
- exec_req->done();
- }
- }
- break;
-
- default:
- fatal("Unrecognized command to %s", resName);
- }
-}
-
-
diff --git a/src/cpu/inorder/resources/execution_unit.hh b/src/cpu/inorder/resources/execution_unit.hh
deleted file mode 100644
index e87a05c27..000000000
--- a/src/cpu/inorder/resources/execution_unit.hh
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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
- *
- */
-
-#ifndef __CPU_INORDER_EXECUTION_UNIT_HH__
-#define __CPU_INORDER_EXECUTION_UNIT_HH__
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include "cpu/inorder/first_stage.hh"
-#include "cpu/inorder/inorder_dyn_inst.hh"
-#include "cpu/inorder/resource.hh"
-#include "cpu/func_unit.hh"
-
-class ExecutionUnit : public Resource {
- public:
- typedef ThePipeline::DynInstPtr DynInstPtr;
-
- enum Command {
- ExecuteInst
- };
-
- public:
- ExecutionUnit(std::string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params);
-
- public:
- void regStats();
-
- /** Execute the function of this resource. The Default is action
- * is to do nothing. More specific models will derive from this
- * class and define their own execute function.
- */
- void execute(int slot_num);
-
- protected:
- /////////////////////////////////////////////////////////////////
- //
- // RESOURCE STATISTICS
- //
- /////////////////////////////////////////////////////////////////
- Stats::Scalar predictedTakenIncorrect;
- Stats::Scalar predictedNotTakenIncorrect;
- Stats::Scalar predictedIncorrect;
- Stats::Scalar predictedCorrect;
- Stats::Formula mispredictPct;
- Stats::Scalar executions;
- Tick lastExecuteTick;
- Tick lastControlTick;
-};
-
-
-#endif //__CPU_INORDER_EXCUTION_UNIT_HH__
diff --git a/src/cpu/inorder/resources/fetch_seq_unit.cc b/src/cpu/inorder/resources/fetch_seq_unit.cc
deleted file mode 100644
index ead4953fb..000000000
--- a/src/cpu/inorder/resources/fetch_seq_unit.cc
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * 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 "config/the_isa.hh"
-#include "cpu/inorder/resources/fetch_seq_unit.hh"
-#include "cpu/inorder/resource_pool.hh"
-#include "debug/InOrderFetchSeq.hh"
-#include "debug/InOrderStall.hh"
-
-using namespace std;
-using namespace TheISA;
-using namespace ThePipeline;
-
-FetchSeqUnit::FetchSeqUnit(std::string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params)
- : Resource(res_name, res_id, res_width, res_latency, _cpu),
- instSize(sizeof(MachInst))
-{
- for (ThreadID tid = 0; tid < ThePipeline::MaxThreads; tid++) {
- pcValid[tid] = false;
- pcBlockStage[tid] = 0;
-
- //@todo: Use CPU's squashSeqNum here instead of maintaining our own
- // state
- squashSeqNum[tid] = (InstSeqNum)-1;
- lastSquashCycle[tid] = 0;
- }
-}
-
-FetchSeqUnit::~FetchSeqUnit()
-{
- delete [] resourceEvent;
-}
-
-void
-FetchSeqUnit::init()
-{
- resourceEvent = new FetchSeqEvent[width];
-
- for (int i = 0; i < width; i++) {
- reqs[i] = new ResourceRequest(this);
- }
-
- initSlots();
-}
-
-void
-FetchSeqUnit::execute(int slot_num)
-{
- ResourceRequest* fs_req = reqs[slot_num];
- DynInstPtr inst = fs_req->inst;
- ThreadID tid = inst->readTid();
- int stage_num = fs_req->getStageNum();
-
- if (inst->fault != NoFault) {
- DPRINTF(InOrderFetchSeq,
- "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to "
- "next stage.\n", tid, inst->seqNum, inst->fault->name(),
- inst->pcState());
- fs_req->done();
- return;
- }
-
- switch (fs_req->cmd)
- {
- case AssignNextPC:
- {
- DPRINTF(InOrderFetchSeq, "[tid:%i]: Current PC is %s\n", tid,
- pc[tid]);
-
- if (pcValid[tid]) {
- inst->pcState(pc[tid]);
- inst->setMemAddr(pc[tid].instAddr());
-
- // Advance to next PC (typically PC + 4)
- pc[tid].advance();
-
- inst->setSeqNum(cpu->getAndIncrementInstSeq(tid));
-
- DPRINTF(InOrderFetchSeq, "[tid:%i]: Assigning [sn:%i] to "
- "PC %s\n", tid, inst->seqNum, inst->pcState());
-
- fs_req->done();
- } else {
- DPRINTF(InOrderStall, "STALL: [tid:%i]: NPC not valid\n", tid);
- fs_req->done(false);
- }
- }
- break;
-
- case UpdateTargetPC:
- {
- assert(!inst->isCondDelaySlot() &&
- "Not Handling Conditional Delay Slot");
-
- if (inst->isControl()) {
- if (inst->isReturn() && !inst->predTaken()) {
- // If it's a return, then we must wait for resolved address.
- // The Predictor will mark a return a false as "not taken"
- // if there is no RAS entry
- DPRINTF(InOrderFetchSeq, "[tid:%d]: Setting block signal "
- "for stage %i.\n",
- tid, stage_num);
- cpu->pipelineStage[stage_num]->
- toPrevStages->stageBlock[stage_num][tid] = true;
- pcValid[tid] = false;
- pcBlockStage[tid] = stage_num;
- } else if (inst->predTaken()) {
- // Taken Control
- inst->setSquashInfo(stage_num);
- setupSquash(inst, stage_num, tid);
-
- DPRINTF(InOrderFetchSeq, "[tid:%i] Setting up squash to "
- "start from stage %i, after [sn:%i].\n",
- tid, stage_num, inst->squashSeqNum);
- }
- } else {
- DPRINTF(InOrderFetchSeq, "[tid:%i]: [sn:%i]: Ignoring branch "
- "target update since then is not a control "
- "instruction.\n", tid, inst->seqNum);
- }
-
- fs_req->done();
- }
- break;
-
- default:
- fatal("Unrecognized command to %s", resName);
- }
-}
-
-void
-FetchSeqUnit::squash(DynInstPtr inst, int squash_stage,
- InstSeqNum squash_seq_num, ThreadID tid)
-{
- DPRINTF(InOrderFetchSeq, "[tid:%i]: Updating due to squash from %s (%s) "
- "stage %i.\n", tid, inst->instName(), inst->pcState(),
- squash_stage);
-
- if (lastSquashCycle[tid] == curTick() &&
- squashSeqNum[tid] <= squash_seq_num) {
- DPRINTF(InOrderFetchSeq, "[tid:%i]: Ignoring squash from stage %i, "
- "since there is an outstanding squash that is older.\n",
- tid, squash_stage);
- } else {
- squashSeqNum[tid] = squash_seq_num;
- lastSquashCycle[tid] = curTick();
-
- if (inst->staticInst) {
- if (inst->fault != NoFault) {
- // A Trap Caused This Fault and will update the pc state
- // when done trapping
- DPRINTF(InOrderFetchSeq, "[tid:%i] Blocking due to fault @ "
- "[sn:%i].%s %s \n", tid, inst->seqNum,
- inst->instName(), inst->pcState());
- pcValid[tid] = false;
- } else {
- TheISA::PCState nextPC;
- assert(inst->staticInst);
- if (inst->isControl()) {
- nextPC = inst->readPredTarg();
-
- // If we are already fetching this PC then advance to next PC
- // =======
- // This should handle ISAs w/delay slots and annulled delay
- // slots to figure out which is the next PC to fetch after
- // a mispredict
- DynInstPtr bdelay_inst = NULL;
- ListIt bdelay_it;
- if (inst->onInstList) {
- bdelay_it = inst->getInstListIt();
- bdelay_it++;
- } else {
- InstSeqNum branch_delay_num = inst->seqNum + 1;
- bdelay_it = cpu->findInst(branch_delay_num, tid);
- }
-
- if (bdelay_it != cpu->instList[tid].end()) {
- bdelay_inst = (*bdelay_it);
- }
-
- if (bdelay_inst) {
- if (bdelay_inst->pc.instAddr() == nextPC.instAddr()) {
- bdelay_inst->pc = nextPC;
- advancePC(nextPC, inst->staticInst);
- DPRINTF(InOrderFetchSeq, "Advanced PC to %s\n", nextPC);
- }
- }
- } else {
- nextPC = inst->pcState();
- advancePC(nextPC, inst->staticInst);
- }
-
-
- DPRINTF(InOrderFetchSeq, "[tid:%i]: Setting PC to %s.\n",
- tid, nextPC);
- pc[tid] = nextPC;
-
- // Unblock Any Stages Waiting for this information to be updated ...
- if (!pcValid[tid]) {
- DPRINTF(InOrderFetchSeq, "[tid:%d]: Setting unblock signal "
- "for stage %i.\n",
- tid, pcBlockStage[tid]);
-
- // Need to use "fromNextStages" instead of "toPrevStages"
- // because the timebuffer will have already have advanced
- // in the tick function and this squash function will happen after
- // the tick
- cpu->pipelineStage[pcBlockStage[tid]]->
- fromNextStages->stageUnblock[pcBlockStage[tid]][tid] = true;
- }
-
- pcValid[tid] = true;
- }
- }
- }
-
- Resource::squash(inst, squash_stage, squash_seq_num, tid);
-}
-
-FetchSeqUnit::FetchSeqEvent::FetchSeqEvent()
- : ResourceEvent()
-{ }
-
-void
-FetchSeqUnit::FetchSeqEvent::process()
-{
- FetchSeqUnit* fs_res = dynamic_cast<FetchSeqUnit*>(resource);
- assert(fs_res);
-
- for (int i = 0; i < MaxThreads; i++) {
- fs_res->pc[i] = fs_res->cpu->pcState(i);
- DPRINTF(InOrderFetchSeq, "[tid:%i]: Setting PC: %s.\n",
- fs_res->pc[i]);
-
- fs_res->pcValid[i] = true;
- }
-}
-
-
-void
-FetchSeqUnit::activateThread(ThreadID tid)
-{
- pcValid[tid] = true;
-
- pc[tid] = cpu->pcState(tid);
-
- cpu->fetchPriorityList.push_back(tid);
-
- DPRINTF(InOrderFetchSeq, "[tid:%i]: Reading PC: %s.\n",
- tid, pc[tid]);
-}
-
-void
-FetchSeqUnit::deactivateThread(ThreadID tid)
-{
- pcValid[tid] = false;
- pcBlockStage[tid] = 0;
-
- squashSeqNum[tid] = (InstSeqNum)-1;
- lastSquashCycle[tid] = 0;
-
- list<ThreadID>::iterator thread_it = find(cpu->fetchPriorityList.begin(),
- cpu->fetchPriorityList.end(),
- tid);
-
- if (thread_it != cpu->fetchPriorityList.end())
- cpu->fetchPriorityList.erase(thread_it);
-}
-
-void
-FetchSeqUnit::suspendThread(ThreadID tid)
-{
- deactivateThread(tid);
-}
-
-void
-FetchSeqUnit::trap(const Fault &fault, ThreadID tid, DynInstPtr inst)
-{
- pcValid[tid] = true;
- pc[tid] = cpu->pcState(tid);
- DPRINTF(InOrderFetchSeq, "[tid:%i]: Trap updating to PC: "
- "%s.\n", tid, pc[tid]);
-}
-
-void
-FetchSeqUnit::updateAfterContextSwitch(DynInstPtr inst, ThreadID tid)
-{
- pcValid[tid] = true;
-
- if (cpu->thread[tid]->lastGradIsBranch) {
- /** This function assumes that the instruction causing the context
- * switch was right after the branch. Thus, if it's not, then
- * we are updating incorrectly here
- */
- assert(cpu->nextInstAddr(tid) == inst->instAddr());
- pc[tid] = cpu->thread[tid]->lastBranchPC;
- } else {
- pc[tid] = inst->pcState();
- }
- assert(inst->staticInst);
- advancePC(pc[tid], inst->staticInst);
-
- DPRINTF(InOrderFetchSeq, "[tid:%i]: Updating PCs due to Context Switch."
- "Assigning PC: %s.\n", tid, pc[tid]);
-}
diff --git a/src/cpu/inorder/resources/fetch_seq_unit.hh b/src/cpu/inorder/resources/fetch_seq_unit.hh
deleted file mode 100644
index a8db85b06..000000000
--- a/src/cpu/inorder/resources/fetch_seq_unit.hh
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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
- *
- */
-
-#ifndef __CPU_INORDER_FETCH_SEQ_UNIT_HH__
-#define __CPU_INORDER_FETCH_SEQ_UNIT_HH__
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include "config/the_isa.hh"
-#include "cpu/inorder/cpu.hh"
-#include "cpu/inorder/inorder_dyn_inst.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-#include "cpu/inorder/resource.hh"
-
-class FetchSeqUnit : public Resource {
- public:
- typedef ThePipeline::DynInstPtr DynInstPtr;
- typedef std::list<DynInstPtr>::iterator ListIt;
-
- enum Command {
- AssignNextPC,
- UpdateTargetPC
- };
-
- public:
- FetchSeqUnit(std::string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params);
- ~FetchSeqUnit();
-
- void init();
- void activateThread(ThreadID tid);
- void deactivateThread(ThreadID tid);
- void suspendThread(ThreadID tid);
- void execute(int slot_num);
- void updateAfterContextSwitch(DynInstPtr inst, ThreadID tid);
-
-
- /** Update to correct PC from a squash */
- void squash(DynInstPtr inst, int squash_stage,
- InstSeqNum squash_seq_num, ThreadID tid);
-
- /** Update to correct PC from a trap */
- void trap(const Fault &fault, ThreadID tid, DynInstPtr inst);
-
- protected:
- unsigned instSize;
-
- bool pcValid[ThePipeline::MaxThreads];
- int pcBlockStage[ThePipeline::MaxThreads];
-
- TheISA::PCState pc[ThePipeline::MaxThreads];
-
- /** Squash Seq. Nums*/
- InstSeqNum squashSeqNum[ThePipeline::MaxThreads];
-
- /** Squash Seq. Nums*/
- Tick lastSquashCycle[ThePipeline::MaxThreads];
-
- /** @todo: Add Resource Stats Here */
-
- public:
- class FetchSeqEvent : public ResourceEvent {
- public:
- /** Constructs a resource event. */
- FetchSeqEvent();
- ~FetchSeqEvent() {}
-
- /** Processes a resource event. */
- void process();
- };
-
-};
-
-#endif
diff --git a/src/cpu/inorder/resources/fetch_unit.cc b/src/cpu/inorder/resources/fetch_unit.cc
deleted file mode 100644
index 13864e589..000000000
--- a/src/cpu/inorder/resources/fetch_unit.cc
+++ /dev/null
@@ -1,591 +0,0 @@
-/*
- * Copyright (c) 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
- *
- */
-
-#include <list>
-#include <vector>
-
-#include "arch/isa_traits.hh"
-#include "arch/locked_mem.hh"
-#include "arch/utility.hh"
-#include "config/the_isa.hh"
-#include "cpu/inorder/resources/cache_unit.hh"
-#include "cpu/inorder/resources/fetch_unit.hh"
-#include "cpu/inorder/cpu.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-#include "cpu/inorder/resource_pool.hh"
-#include "debug/Activity.hh"
-#include "debug/InOrderCachePort.hh"
-#include "debug/InOrderStall.hh"
-#include "debug/RefCount.hh"
-#include "debug/ThreadModel.hh"
-#include "mem/request.hh"
-
-using namespace std;
-using namespace TheISA;
-using namespace ThePipeline;
-
-FetchUnit::FetchUnit(string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params)
- : CacheUnit(res_name, res_id, res_width, res_latency, _cpu, params),
- instSize(sizeof(TheISA::MachInst)), fetchBuffSize(params->fetchBuffSize)
-{
- for (int tid = 0; tid < MaxThreads; tid++)
- decoder[tid] = new Decoder;
-}
-
-FetchUnit::~FetchUnit()
-{
- std::list<FetchBlock*>::iterator fetch_it = fetchBuffer.begin();
- std::list<FetchBlock*>::iterator end_it = fetchBuffer.end();
- while (fetch_it != end_it) {
- delete (*fetch_it)->block;
- delete *fetch_it;
- fetch_it++;
- }
- fetchBuffer.clear();
-
-
- std::list<FetchBlock*>::iterator pend_it = pendingFetch.begin();
- std::list<FetchBlock*>::iterator pend_end = pendingFetch.end();
- while (pend_it != pend_end) {
- if ((*pend_it)->block) {
- delete (*pend_it)->block;
- }
-
- delete *pend_it;
- pend_it++;
- }
- pendingFetch.clear();
-}
-
-void
-FetchUnit::createMachInst(std::list<FetchBlock*>::iterator fetch_it,
- DynInstPtr inst)
-{
- Addr block_addr = cacheBlockAlign(inst->getMemAddr());
- Addr fetch_addr = inst->getMemAddr();
- unsigned fetch_offset = (fetch_addr - block_addr) / instSize;
- ThreadID tid = inst->readTid();
- TheISA::PCState instPC = inst->pcState();
-
-
- DPRINTF(InOrderCachePort, "Creating instruction [sn:%i] w/fetch data @"
- "addr:%08p block:%08p\n", inst->seqNum, fetch_addr, block_addr);
-
- assert((*fetch_it)->valid);
-
- TheISA::MachInst *fetchInsts =
- reinterpret_cast<TheISA::MachInst *>((*fetch_it)->block);
-
- MachInst mach_inst =
- TheISA::gtoh(fetchInsts[fetch_offset]);
-
- decoder[tid]->moreBytes(instPC, inst->instAddr(), mach_inst);
- assert(decoder[tid]->instReady());
- inst->setStaticInst(decoder[tid]->decode(instPC));
- inst->pcState(instPC);
-}
-
-void
-FetchUnit::removeAddrDependency(DynInstPtr inst)
-{
- inst->unsetMemAddr();
-}
-
-ResReqPtr
-FetchUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx,
- int slot_num, unsigned cmd)
-{
- ScheduleEntry* sched_entry = *inst->curSkedEntry;
- CacheRequest* cache_req = dynamic_cast<CacheRequest*>(reqs[slot_num]);
-
- if (!inst->validMemAddr()) {
- panic("Mem. Addr. must be set before requesting cache access\n");
- }
-
- assert(sched_entry->cmd == InitiateFetch);
-
- DPRINTF(InOrderCachePort,
- "[tid:%i]: Fetch request from [sn:%i] for addr %08p\n",
- inst->readTid(), inst->seqNum, inst->getMemAddr());
-
- cache_req->setRequest(inst, stage_num, id, slot_num,
- sched_entry->cmd, MemCmd::ReadReq,
- inst->curSkedEntry->idx);
-
- return cache_req;
-}
-
-void
-FetchUnit::setupMemRequest(DynInstPtr inst, CacheReqPtr cache_req,
- int acc_size, int flags)
-{
- ThreadID tid = inst->readTid();
- Addr aligned_addr = cacheBlockAlign(inst->getMemAddr());
- if (cache_req->memReq == NULL) {
- cache_req->memReq =
- new Request(tid, aligned_addr, acc_size, flags,
- cpu->instMasterId(), inst->instAddr(), cpu->readCpuId(),
- tid);
- DPRINTF(InOrderCachePort, "[sn:%i] Created memReq @%x, ->%x\n",
- inst->seqNum, &cache_req->memReq, cache_req->memReq);
- }
-}
-
-std::list<FetchUnit::FetchBlock*>::iterator
-FetchUnit::findBlock(std::list<FetchBlock*> &fetch_blocks, int asid,
- Addr block_addr)
-{
- std::list<FetchBlock*>::iterator fetch_it = fetch_blocks.begin();
- std::list<FetchBlock*>::iterator end_it = fetch_blocks.end();
-
- while (fetch_it != end_it) {
- if ((*fetch_it)->asid == asid &&
- (*fetch_it)->addr == block_addr) {
- return fetch_it;
- }
-
- fetch_it++;
- }
-
- return fetch_it;
-}
-
-std::list<FetchUnit::FetchBlock*>::iterator
-FetchUnit::findReplacementBlock()
-{
- std::list<FetchBlock*>::iterator fetch_it = fetchBuffer.begin();
- std::list<FetchBlock*>::iterator end_it = fetchBuffer.end();
-
- while (fetch_it != end_it) {
- if ((*fetch_it)->cnt == 0) {
- return fetch_it;
- } else {
- DPRINTF(InOrderCachePort, "Block %08p has %i insts pending.\n",
- (*fetch_it)->addr, (*fetch_it)->cnt);
- }
- fetch_it++;
- }
-
- return fetch_it;
-}
-
-void
-FetchUnit::markBlockUsed(std::list<FetchBlock*>::iterator block_it)
-{
- // Move block from whatever location it is in fetch buffer
- // to the back (represents most-recently-used location)
- if (block_it != fetchBuffer.end()) {
- FetchBlock *mru_blk = *block_it;
- fetchBuffer.erase(block_it);
- fetchBuffer.push_back(mru_blk);
- }
-}
-
-int
-FetchUnit::blocksInUse()
-{
- std::list<FetchBlock*>::iterator fetch_it = fetchBuffer.begin();
- std::list<FetchBlock*>::iterator end_it = fetchBuffer.end();
-
- int cnt = 0;
- while (fetch_it != end_it) {
- if ((*fetch_it)->cnt > 0)
- cnt++;
-
- fetch_it++;
- }
-
- return cnt;
-}
-
-void
-FetchUnit::clearFetchBuffer()
-{
- std::list<FetchBlock*>::iterator fetch_it = fetchBuffer.begin();
- std::list<FetchBlock*>::iterator end_it = fetchBuffer.end();
-
- while (fetch_it != end_it) {
- if ((*fetch_it)->block) {
- delete [] (*fetch_it)->block;
- }
- delete *fetch_it;
- fetch_it++;
- }
- fetchBuffer.clear();
-}
-
-void
-FetchUnit::execute(int slot_num)
-{
- CacheReqPtr cache_req = dynamic_cast<CacheReqPtr>(reqs[slot_num]);
- assert(cache_req);
-
- if (cachePortBlocked && cache_req->cmd == InitiateFetch) {
- DPRINTF(InOrderCachePort, "Cache Port Blocked. Cannot Access\n");
- cache_req->done(false);
- return;
- }
-
- DynInstPtr inst = cache_req->inst;
- ThreadID tid = inst->readTid();
- Addr block_addr = cacheBlockAlign(inst->getMemAddr());
- int asid = cpu->asid[tid];
-
- if (inst->fault != NoFault) {
- DPRINTF(InOrderCachePort,
- "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to "
- "next stage.\n", tid, inst->seqNum, inst->fault->name(),
- cacheBlockAlign(inst->getMemAddr()));
- finishCacheUnitReq(inst, cache_req);
- return;
- }
-
- switch (cache_req->cmd)
- {
- case InitiateFetch:
- {
- // Check to see if we've already got this request buffered
- // or pending to be buffered
- bool do_fetch = true;
- int total_pending = pendingFetch.size() + blocksInUse();
-
- std::list<FetchBlock*>::iterator pending_it;
- pending_it = findBlock(pendingFetch, asid, block_addr);
- if (pending_it != pendingFetch.end()) {
- (*pending_it)->cnt++;
- do_fetch = false;
-
- DPRINTF(InOrderCachePort, "%08p is a pending fetch block "
- "(pending:%i).\n", block_addr,
- (*pending_it)->cnt);
- } else if (total_pending < fetchBuffSize) {
- std::list<FetchBlock*>::iterator buff_it;
- buff_it = findBlock(fetchBuffer, asid, block_addr);
- if (buff_it != fetchBuffer.end()) {
- (*buff_it)->cnt++;
- do_fetch = false;
-
- DPRINTF(InOrderCachePort, "%08p is in fetch buffer "
- "(pending:%i).\n", block_addr, (*buff_it)->cnt);
- }
- }
-
- if (!do_fetch) {
- DPRINTF(InOrderCachePort, "Inst. [sn:%i] marked to be filled "
- "through fetch buffer.\n", inst->seqNum);
- cache_req->fetchBufferFill = true;
- cache_req->setCompleted(true);
- return;
- }
-
- // Check to see if there is room in the fetchbuffer for this instruction.
- // If not, block this request.
- if (total_pending >= fetchBuffSize) {
- DPRINTF(InOrderCachePort, "No room available in fetch buffer.\n");
- cache_req->done(false);
- return;
- }
-
- doTLBAccess(inst, cache_req, cacheBlkSize, Request::INST_FETCH, TheISA::TLB::Execute);
-
- if (inst->fault == NoFault) {
- DPRINTF(InOrderCachePort,
- "[tid:%u]: Initiating fetch access to %s for "
- "addr:%#x (block:%#x)\n", tid, name(),
- cache_req->inst->getMemAddr(), block_addr);
-
- cache_req->reqData = new uint8_t[cacheBlkSize];
-
- inst->setCurResSlot(slot_num);
-
- doCacheAccess(inst);
-
- if (cache_req->isMemAccPending()) {
- pendingFetch.push_back(new FetchBlock(asid, block_addr));
-
- // mark replacement block
- }
- }
-
- break;
- }
-
- case CompleteFetch:
- if (inst->fault != NoFault) {
- DPRINTF(InOrderCachePort,
- "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to "
- "next stage.\n", tid, inst->seqNum, inst->fault->name(),
- inst->getMemAddr());
- finishCacheUnitReq(inst, cache_req);
- return;
- }
-
- if (cache_req->fetchBufferFill) {
- // Block request if it's depending on a previous fetch, but it hasnt made it yet
- std::list<FetchBlock*>::iterator fetch_it = findBlock(fetchBuffer, asid, block_addr);
- if (fetch_it == fetchBuffer.end()) {
- DPRINTF(InOrderCachePort, "%#x not available yet\n",
- block_addr);
- cache_req->setCompleted(false);
- return;
- }
-
- // Make New Instruction
- createMachInst(fetch_it, inst);
- if (inst->traceData) {
- inst->traceData->setStaticInst(inst->staticInst);
- inst->traceData->setPC(inst->pcState());
- }
-
- // FetchBuffer Book-Keeping
- (*fetch_it)->cnt--;
- assert((*fetch_it)->cnt >= 0);
- markBlockUsed(fetch_it);
-
- cache_req->done();
- return;
- }
-
- if (cache_req->isMemAccComplete()) {
- if (fetchBuffer.size() >= fetchBuffSize) {
- // If there is no replacement block, then we'll just have
- // to wait till that gets cleared before satisfying the fetch
- // for this instruction
- std::list<FetchBlock*>::iterator repl_it =
- findReplacementBlock();
- if (repl_it == fetchBuffer.end()) {
- DPRINTF(InOrderCachePort, "Unable to find replacement block"
- " and complete fetch.\n");
- cache_req->setCompleted(false);
- return;
- }
-
- delete [] (*repl_it)->block;
- delete *repl_it;
- fetchBuffer.erase(repl_it);
- }
-
- DPRINTF(InOrderCachePort,
- "[tid:%i]: Completing Fetch Access for [sn:%i]\n",
- tid, inst->seqNum);
-
- // Make New Instruction
- std::list<FetchBlock*>::iterator fetch_it =
- findBlock(pendingFetch, asid, block_addr);
-
- assert(fetch_it != pendingFetch.end());
- assert((*fetch_it)->valid);
-
- createMachInst(fetch_it, inst);
- if (inst->traceData) {
- inst->traceData->setStaticInst(inst->staticInst);
- inst->traceData->setPC(inst->pcState());
- }
-
-
- // Update instructions waiting on new fetch block
- FetchBlock *new_block = (*fetch_it);
- new_block->cnt--;
- assert(new_block->cnt >= 0);
-
- // Finally, update FetchBuffer w/Pending Block into the
- // MRU location
- pendingFetch.erase(fetch_it);
- fetchBuffer.push_back(new_block);
-
- DPRINTF(InOrderCachePort, "[tid:%i]: Instruction [sn:%i] is: %s\n",
- tid, inst->seqNum,
- inst->staticInst->disassemble(inst->instAddr()));
-
- inst->unsetMemAddr();
-
- cache_req->done();
- } else {
- DPRINTF(InOrderCachePort,
- "[tid:%i]: [sn:%i]: Unable to Complete Fetch Access\n",
- tid, inst->seqNum);
- DPRINTF(InOrderStall,
- "STALL: [tid:%i]: Fetch miss from %08p\n",
- tid, cache_req->inst->instAddr());
- cache_req->setCompleted(false);
- // NOTE: For SwitchOnCacheMiss ThreadModel, we *don't* switch on
- // fetch miss, but we could ...
- // cache_req->setMemStall(true);
- }
- break;
-
- default:
- fatal("Unrecognized command to %s", resName);
- }
-}
-
-void
-FetchUnit::processCacheCompletion(PacketPtr pkt)
-{
- // Cast to correct packet type
- // @todo: use pkt Sender state here to be consistent with other
- // cpu models
- CacheReqPacket* cache_pkt = dynamic_cast<CacheReqPacket*>(pkt);
- assert(cache_pkt);
-
- DPRINTF(InOrderCachePort, "Finished request for %x\n",
- cache_pkt->getAddr());
-
- if (processSquash(cache_pkt))
- return;
-
- Addr block_addr = cacheBlockAlign(cache_pkt->cacheReq->
- getInst()->getMemAddr());
-
- DPRINTF(InOrderCachePort,
- "[tid:%u]: [sn:%i]: Waking from fetch access to addr:%#x(phys:%#x), size:%i\n",
- cache_pkt->cacheReq->getInst()->readTid(),
- cache_pkt->cacheReq->getInst()->seqNum,
- block_addr, cache_pkt->getAddr(), cache_pkt->getSize());
-
- // Cast to correct request type
- CacheRequest *cache_req = dynamic_cast<CacheReqPtr>(
- findRequest(cache_pkt->cacheReq->getInst(), cache_pkt->instIdx));
-
- if (!cache_req) {
- panic("[tid:%u]: [sn:%i]: Can't find slot for fetch access to "
- "addr. %08p\n", cache_pkt->cacheReq->getInst()->readTid(),
- cache_pkt->cacheReq->getInst()->seqNum,
- block_addr);
- }
-
- // Get resource request info
- unsigned stage_num = cache_req->getStageNum();
- DynInstPtr inst = cache_req->inst;
- ThreadID tid = cache_req->inst->readTid();
- short asid = cpu->asid[tid];
-
- assert(!cache_req->isSquashed());
- assert(inst->curSkedEntry->cmd == CompleteFetch);
-
- DPRINTF(InOrderCachePort,
- "[tid:%u]: [sn:%i]: Processing fetch access for block %#x\n",
- tid, inst->seqNum, block_addr);
-
- std::list<FetchBlock*>::iterator pend_it = findBlock(pendingFetch, asid,
- block_addr);
- assert(pend_it != pendingFetch.end());
-
- // Copy Data to pendingFetch queue...
- (*pend_it)->block = new uint8_t[cacheBlkSize];
- memcpy((*pend_it)->block, cache_pkt->getConstPtr<uint8_t>(), cacheBlkSize);
- (*pend_it)->valid = true;
-
- cache_req->setMemAccPending(false);
- cache_req->setMemAccCompleted();
-
- if (cache_req->isMemStall() &&
- cpu->threadModel == InOrderCPU::SwitchOnCacheMiss) {
- DPRINTF(InOrderCachePort, "[tid:%u] Waking up from Cache Miss.\n",
- tid);
-
- cpu->activateContext(tid);
-
- DPRINTF(ThreadModel, "Activating [tid:%i] after return from cache"
- "miss.\n", tid);
- }
-
- // Wake up the CPU (if it went to sleep and was waiting on this
- // completion event).
- cpu->wakeCPU();
-
- DPRINTF(Activity, "[tid:%u] Activating %s due to cache completion\n",
- tid, cpu->pipelineStage[stage_num]->name());
-
- cpu->switchToActive(stage_num);
-}
-
-void
-FetchUnit::squashCacheRequest(CacheReqPtr req_ptr)
-{
- DynInstPtr inst = req_ptr->getInst();
- ThreadID tid = inst->readTid();
- Addr block_addr = cacheBlockAlign(inst->getMemAddr());
- int asid = cpu->asid[tid];
-
- // Check Fetch Buffer (or pending fetch) for this block and
- // update pending counts
- std::list<FetchBlock*>::iterator buff_it = findBlock(fetchBuffer,
- asid,
- block_addr);
- if (buff_it != fetchBuffer.end()) {
- (*buff_it)->cnt--;
- DPRINTF(InOrderCachePort, "[sn:%i] Removing Pending Access "
- "for Fetch Buffer block %08p (cnt=%i)\n", inst->seqNum,
- block_addr, (*buff_it)->cnt);
- assert((*buff_it)->cnt >= 0);
- } else {
- std::list<FetchBlock*>::iterator block_it = findBlock(pendingFetch,
- asid,
- block_addr);
- if (block_it != pendingFetch.end()) {
- (*block_it)->cnt--;
- DPRINTF(InOrderCachePort, "[sn:%i] Removing Pending Access "
- "for Pending Buffer Block %08p (cnt=%i)\n",
- inst->seqNum,
- block_addr, (*block_it)->cnt);
- assert((*block_it)->cnt >= 0);
- if ((*block_it)->cnt == 0) {
- if ((*block_it)->block) {
- delete [] (*block_it)->block;
- }
- delete *block_it;
- pendingFetch.erase(block_it);
- }
- }
- }
-
- CacheUnit::squashCacheRequest(req_ptr);
-}
-
-void
-FetchUnit::trap(const Fault &fault, ThreadID tid, DynInstPtr inst)
-{
- //@todo: per thread?
- decoder[tid]->reset();
-
- //@todo: squash using dummy inst seq num
- squash(NULL, NumStages - 1, 0, tid);
-
- //@todo: make sure no blocks are in use
- assert(blocksInUse() == 0);
- assert(pendingFetch.size() == 0);
-
- //@todo: clear pendingFetch and fetchBuffer
- clearFetchBuffer();
-}
diff --git a/src/cpu/inorder/resources/fetch_unit.hh b/src/cpu/inorder/resources/fetch_unit.hh
deleted file mode 100644
index d72721009..000000000
--- a/src/cpu/inorder/resources/fetch_unit.hh
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 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_FETCH_UNIT_HH__
-#define __CPU_INORDER_FETCH_UNIT_HH__
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include "arch/decoder.hh"
-#include "arch/tlb.hh"
-#include "config/the_isa.hh"
-#include "cpu/inorder/resources/cache_unit.hh"
-#include "cpu/inorder/inorder_dyn_inst.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-#include "cpu/inorder/resource.hh"
-#include "mem/packet.hh"
-#include "mem/packet_access.hh"
-#include "mem/port.hh"
-#include "params/InOrderCPU.hh"
-#include "sim/sim_object.hh"
-
-class FetchUnit : public CacheUnit
-{
- public:
- FetchUnit(std::string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params);
-
- virtual ~FetchUnit();
-
- typedef ThePipeline::DynInstPtr DynInstPtr;
- typedef TheISA::ExtMachInst ExtMachInst;
-
- struct FetchBlock {
- int asid;
- Addr addr;
- uint8_t *block;
- short cnt;
- bool valid;
-
- FetchBlock(int _asid, Addr _addr)
- : asid(_asid), addr(_addr), block(NULL), cnt(1), valid(false)
- { }
- };
-
- /** Actions that this resource can take on an instruction */
- enum Command {
- InitiateFetch,
- CompleteFetch
- };
-
-
- ResourceRequest* getRequest(DynInstPtr _inst, int stage_num,
- int res_idx, int slot_num,
- unsigned cmd);
-
- /** Executes one of the commands from the "Command" enum */
- void execute(int slot_num);
-
- void trap(const Fault &fault, ThreadID tid, DynInstPtr inst);
-
- TheISA::Decoder *decoder[ThePipeline::MaxThreads];
-
- private:
- void squashCacheRequest(CacheReqPtr req_ptr);
-
- void createMachInst(std::list<FetchBlock*>::iterator fetch_it,
- DynInstPtr inst);
-
- /** After memory request is completed, then turn the fetched data
- into an instruction.
- */
- void processCacheCompletion(PacketPtr pkt);
-
- /** Create request that will interface w/TLB and Memory objects */
- virtual void setupMemRequest(DynInstPtr inst, CacheReqPtr cache_req,
- int acc_size, int flags);
-
- /** Align a PC to the start of an I-cache block. */
- Addr cacheBlockAlignPC(Addr addr)
- {
- return (addr & ~(cacheBlkMask));
- }
-
- void removeAddrDependency(DynInstPtr inst);
-
- std::list<FetchBlock*>::iterator findReplacementBlock();
- std::list<FetchBlock*>::iterator findBlock(std::list<FetchBlock*>
- &fetch_blocks, int asid,
- Addr block_addr);
-
- void markBlockUsed(std::list<FetchBlock*>::iterator block_it);
-
- int blocksInUse();
-
- void clearFetchBuffer();
-
- int instSize;
-
- int fetchBuffSize;
-
- /** Valid Cache Blocks*/
- std::list<FetchBlock*> fetchBuffer;
-
- /** Cache lines that are pending */
- std::list<FetchBlock*> pendingFetch;
-};
-
-#endif //__CPU_FETCH_UNIT_HH__
diff --git a/src/cpu/inorder/resources/graduation_unit.cc b/src/cpu/inorder/resources/graduation_unit.cc
deleted file mode 100644
index ea63527b6..000000000
--- a/src/cpu/inorder/resources/graduation_unit.cc
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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 "cpu/inorder/resources/graduation_unit.hh"
-#include "debug/InOrderGraduation.hh"
-
-using namespace ThePipeline;
-
-GraduationUnit::GraduationUnit(std::string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params)
- : Resource(res_name, res_id, res_width, res_latency, _cpu)
-{
- for (ThreadID tid = 0; tid < ThePipeline::MaxThreads; tid++) {
- nonSpecInstActive[tid] = &cpu->nonSpecInstActive[tid];
- nonSpecSeqNum[tid] = &cpu->nonSpecSeqNum[tid];
- lastNonSpecTick[tid] = 0;
- lastFaultTick[tid] = 0;
- }
-}
-
-void
-GraduationUnit::execute(int slot_num)
-{
- ResourceRequest* grad_req = reqs[slot_num];
- DynInstPtr inst = reqs[slot_num]->inst;
- ThreadID tid = inst->readTid();
- int stage_num = inst->curSkedEntry->stageNum;
- Tick cur_tick = curTick();
-
- //@todo: not the common case, anyway we can move this
- // check to the stage and just ignore instructions
- // after?
- if (lastNonSpecTick[tid] == cur_tick) {
- DPRINTF(InOrderGraduation, "Unable to graduate [sn:%i]. "
- "Only 1 nonspec inst. per cycle can graduate.\n");
- grad_req->done(false);
- return;
- }
-
- //@todo: use trap Pending
- if (cpu->trapPending[tid]) {
- //if (lastFaultTick[tid] == cur_tick) {
- DPRINTF(InOrderGraduation, "Unable to graduate [sn:%i]. "
- "Only 1 fault can be handled per tick.\n");
- grad_req->done(false);
- return;
- }
-
-
- switch (grad_req->cmd)
- {
- case CheckFault:
- {
- // Handle Any Faults Before Graduating Instruction
- if (inst->fault != NoFault) {
- DPRINTF(InOrderGraduation, "[tid:%i]: [sn:%i]: fault %s found for %s\n",
- tid, inst->seqNum, inst->fault->name(),
- inst->instName());
- squashThenTrap(stage_num, inst);
- lastFaultTick[tid] = cur_tick;
- grad_req->done(false);
- return;
- }
-
- DPRINTF(InOrderGraduation, "[tid:%i] [sn:%i]: No fault found for %s\n",
- tid, inst->seqNum, inst->instName());
- grad_req->done();
- }
- break;
-
- case GraduateInst:
- {
- DPRINTF(InOrderGraduation,
- "[tid:%i]:[sn:%i]: Graduating instruction %s.\n",
- tid, inst->seqNum, inst->staticInst->disassemble(inst->instAddr()));
-
- // Release Non-Speculative "Block" on instructions that could not
- // execute because there was a non-speculative inst. active.
- // @TODO: Fix this functionality. Probably too conservative.
- // Maybe it should be, non-spec. insts should block other
- // non-spec insts because they can potentially be reading
- // system state that will be changed by the 1st non-spec inst.
- if (inst->isNonSpeculative()) {
- *nonSpecInstActive[tid] = false;
- DPRINTF(InOrderGraduation,
- "[tid:%i] Non-speculative inst [sn:%i] graduated\n",
- tid, inst->seqNum);
- lastNonSpecTick[tid] = cur_tick;
- }
-
- if (inst->traceData) {
- inst->traceData->setStageCycle(stage_num, cur_tick);
- }
-
- // Tell CPU that instruction is finished processing
- cpu->instDone(inst, tid);
-
- grad_req->done();
- }
- break;
-
- default:
- fatal("Unrecognized command to %s", resName);
- }
-
-}
diff --git a/src/cpu/inorder/resources/graduation_unit.hh b/src/cpu/inorder/resources/graduation_unit.hh
deleted file mode 100644
index 69d3322fe..000000000
--- a/src/cpu/inorder/resources/graduation_unit.hh
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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
- *
- */
-
-#ifndef __CPU_INORDER_GRAD_UNIT_HH__
-#define __CPU_INORDER_GRAD_UNIT_HH__
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include "cpu/inorder/cpu.hh"
-#include "cpu/inorder/inorder_dyn_inst.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-#include "cpu/inorder/resource.hh"
-
-class GraduationUnit : public Resource {
- public:
- typedef ThePipeline::DynInstPtr DynInstPtr;
-
- enum Command {
- CheckFault,
- GraduateInst
- };
-
- public:
- GraduationUnit(std::string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params);
-
- void execute(int slot_num);
-
- protected:
- Tick lastNonSpecTick[ThePipeline::MaxThreads];
- Tick lastFaultTick[ThePipeline::MaxThreads];
- bool *nonSpecInstActive[ThePipeline::MaxThreads];
- InstSeqNum *nonSpecSeqNum[ThePipeline::MaxThreads];
-};
-
-#endif //__CPU_INORDER_GRAD_UNIT_HH__
diff --git a/src/cpu/inorder/resources/inst_buffer.cc b/src/cpu/inorder/resources/inst_buffer.cc
deleted file mode 100644
index 19011059f..000000000
--- a/src/cpu/inorder/resources/inst_buffer.cc
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * 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>
-#include <vector>
-
-#include "arch/isa_traits.hh"
-#include "config/the_isa.hh"
-#include "cpu/inorder/resources/inst_buffer.hh"
-#include "cpu/inorder/cpu.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-#include "debug/InOrderInstBuffer.hh"
-#include "debug/Resource.hh"
-
-using namespace std;
-using namespace TheISA;
-using namespace ThePipeline;
-
-InstBuffer::InstBuffer(string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params)
- : Resource(res_name, res_id, res_width, res_latency, _cpu)
-{ }
-
-void
-InstBuffer::regStats()
-{
- instsBypassed
- .name(name() + ".instsBypassed")
- .desc("Number of Instructions Bypassed.")
- .prereq(instsBypassed);
-
- Resource::regStats();
-}
-
-void
-InstBuffer::execute(int slot_idx)
-{
- ResReqPtr ib_req = reqs[slot_idx];
- DynInstPtr inst = ib_req->inst;
- ThreadID tid = inst->readTid();
- int stage_num = ib_req->getStageNum();
-
- switch (ib_req->cmd)
- {
- case ScheduleOrBypass:
- {
- int next_stage = stage_num + 1;
- int bypass_stage = stage_num + 2;
- bool do_bypass = true;
-
- if (!instList.empty()) {
- DPRINTF(InOrderInstBuffer, "[sn:%i] cannot bypass stage %i "
- "because buffer isn't empty.\n",
- inst->seqNum, next_stage);
- do_bypass = false;
- } else if(cpu->pipelineStage[bypass_stage]->isBlocked(tid)) {
- DPRINTF(InOrderInstBuffer, "[sn:%i] cannot bypass stage %i "
- "because stage %i is blocking.\n",
- inst->seqNum, next_stage);
- do_bypass = false;
- } else if(cpu->pipelineStage[bypass_stage]->
- stageBufferAvail() <= 0) {
- DPRINTF(InOrderInstBuffer, "[sn:%i] cannot bypass stage %i "
- "because there is no room in stage %i incoming stage "
- "buffer.\n", inst->seqNum, next_stage);
- do_bypass = false;
- }
-
- if (!do_bypass) { // SCHEDULE USAGE OF BUFFER
- DPRINTF(InOrderInstBuffer, "Scheduling [sn:%i] for buffer "
- "insertion in stage %i\n",
- inst->seqNum, next_stage);
-
- // Add to schedule: Insert into buffer in next stage
- int stage_pri = 20;
- RSkedPtr insert_sked = (stage_num >= ThePipeline::BackEndStartStage) ?
- inst->backSked : inst->frontSked;
-
- insert_sked->push(new ScheduleEntry(next_stage,
- stage_pri,
- id,
- InstBuffer::InsertInst));
-
- // Add to schedule: Remove from buffer in next next (bypass)
- // stage
- stage_pri = 20;
- RSkedPtr bypass_sked = (stage_num >= ThePipeline::BackEndStartStage) ?
- inst->backSked : inst->frontSked;
-
- bypass_sked->push(new ScheduleEntry(bypass_stage,
- stage_pri,
- id,
- InstBuffer::RemoveInst));
- } else { // BYPASS BUFFER & NEXT STAGE
- DPRINTF(InOrderInstBuffer, "Setting [sn:%i] to bypass stage "
- "%i and enter stage %i.\n", inst->seqNum, next_stage,
- bypass_stage);
- inst->setNextStage(bypass_stage);
- instsBypassed++;
- }
-
- ib_req->done();
- }
- break;
-
- case InsertInst:
- {
- bool inserted = false;
-
- if (instList.size() < width) {
- DPRINTF(InOrderInstBuffer, "[tid:%i]: Inserting [sn:%i] into "
- "buffer.\n", tid, inst->seqNum);
- insert(inst);
- inserted = true;
- } else {
- DPRINTF(InOrderInstBuffer, "[tid:%i]: Denying [sn:%i] request "
- "because buffer is full.\n", tid, inst->seqNum);
-
-
- std::list<DynInstPtr>::iterator list_it = instList.begin();
- std::list<DynInstPtr>::iterator list_end = instList.end();
-
- while (list_it != list_end) {
- DPRINTF(Resource,"Serving [tid:%i] [sn:%i].\n",
- (*list_it)->readTid(), (*list_it)->seqNum);
- list_it++;
- }
- }
-
- ib_req->done(inserted);
- }
- break;
-
- case RemoveInst:
- {
- DPRINTF(InOrderInstBuffer, "[tid:%i]: Removing [sn:%i] from "
- "buffer.\n", tid, inst->seqNum);
- remove(inst);
- ib_req->done();
- }
- break;
-
- default:
- fatal("Unrecognized command to %s", resName);
- }
-
- DPRINTF(InOrderInstBuffer, "Buffer now contains %i insts.\n",
- instList.size());
-}
-
-void
-InstBuffer::insert(DynInstPtr inst)
-{
- instList.push_back(inst);
-}
-
-void
-InstBuffer::remove(DynInstPtr inst)
-{
- std::list<DynInstPtr>::iterator list_it = instList.begin();
- std::list<DynInstPtr>::iterator list_end = instList.end();
-
- while (list_it != list_end) {
- if((*list_it) == inst) {
- instList.erase(list_it);
- break;
- }
- list_it++;
- }
-}
-
-void
-InstBuffer::pop(ThreadID tid)
-{
- instList.pop_front();
-}
-
-ThePipeline::DynInstPtr
-InstBuffer::top(ThreadID tid)
-{
- return instList.front();
-}
-
-void
-InstBuffer::squash(DynInstPtr inst, int stage_num,
- InstSeqNum squash_seq_num, ThreadID tid)
-{
- queue<list<DynInstPtr>::iterator> remove_list;
- list<DynInstPtr>::iterator list_it = instList.begin();
- list<DynInstPtr>::iterator list_end = instList.end();
-
- // Collect All Instructions to be Removed in Remove List
- while (list_it != list_end) {
- if((*list_it)->readTid() == tid &&
- (*list_it)->seqNum > squash_seq_num) {
- (*list_it)->setSquashed();
- remove_list.push(list_it);
- }
-
- list_it++;
- }
-
- // Removed Instructions from InstList & Clear Remove List
- while (!remove_list.empty()) {
- DPRINTF(InOrderInstBuffer, "[tid:%i]: Removing squashed [sn:%i] from "
- "buffer.\n", tid, (*remove_list.front())->seqNum);
- instList.erase(remove_list.front());
- remove_list.pop();
- }
-
- Resource::squash(inst, stage_num, squash_seq_num, tid);
-}
diff --git a/src/cpu/inorder/resources/inst_buffer.hh b/src/cpu/inorder/resources/inst_buffer.hh
deleted file mode 100644
index 78ef900c6..000000000
--- a/src/cpu/inorder/resources/inst_buffer.hh
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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
- *
- */
-
-#ifndef __CPU_INORDER_INST_BUFF_UNIT_HH__
-#define __CPU_INORDER_INST_BUFF_UNIT_HH__
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include "cpu/inorder/cpu.hh"
-#include "cpu/inorder/inorder_dyn_inst.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-#include "cpu/inorder/resource.hh"
-
-class InstBuffer : public Resource {
- public:
- typedef ThePipeline::DynInstPtr DynInstPtr;
-
- public:
- enum Command {
- InsertInst,
- InsertAddr,
- RemoveInst,
- RemoveAddr,
- ScheduleOrBypass
- };
-
- public:
- InstBuffer(std::string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params);
-
- void regStats();
-
- void execute(int slot_num);
-
- void insert(DynInstPtr inst);
-
- void remove(DynInstPtr inst);
-
- void pop(ThreadID tid);
-
- DynInstPtr top(ThreadID tid);
-
- void squash(DynInstPtr inst, int stage_num,
- InstSeqNum squash_seq_num, ThreadID tid);
- protected:
- /** List of instructions this resource is currently
- * processing.
- */
- std::list<DynInstPtr> instList;
-
- public:
- /////////////////////////////////////////////////////////////////
- //
- // RESOURCE STATISTICS
- //
- /////////////////////////////////////////////////////////////////
- /** Number of Instruction Requests the Resource Processes */
- Stats::Scalar instsBypassed;
-
-};
-
-#endif //__CPU_INORDER_INST_BUFF_UNIT_HH__
diff --git a/src/cpu/inorder/resources/mem_dep_unit.hh b/src/cpu/inorder/resources/mem_dep_unit.hh
deleted file mode 100644
index 4e512de58..000000000
--- a/src/cpu/inorder/resources/mem_dep_unit.hh
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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
- *
- */
-
-#ifndef __CPU_INORDER_MEM_DEP_UNIT_HH__
-#define __CPU_INORDER_MEM_DEP_UNIT_HH__
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include "cpu/inorder/cpu.hh"
-#include "cpu/inorder/inorder_dyn_inst.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-#include "cpu/inorder/resource.hh"
-
-class MemDepUnit : public Resource {
- public:
- typedef ThePipeline::DynInstPtr DynInstPtr;
-
- public:
- MemDepUnit(std::string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu);
- virtual ~MemDepUnit() {}
-
- virtual void execute(int slot_num);
-
- protected:
- Tick lastCycleGrad;
- int numCycleGrad;
-
- bool *nonSpecInstActive[ThePipeline::MaxThreads];
-
- InstSeqNum *nonSpecSeqNum[ThePipeline::MaxThreads];
-
- /** @todo: Add Resource Stats Here */
-};
-
-#endif //__CPU_INORDER_GRAD_UNIT_HH__
diff --git a/src/cpu/inorder/resources/mult_div_unit.cc b/src/cpu/inorder/resources/mult_div_unit.cc
deleted file mode 100644
index 5a4d4bb55..000000000
--- a/src/cpu/inorder/resources/mult_div_unit.cc
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * 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>
-#include <vector>
-
-#include "cpu/inorder/resources/mult_div_unit.hh"
-#include "cpu/inorder/cpu.hh"
-#include "cpu/inorder/resource_pool.hh"
-#include "cpu/op_class.hh"
-#include "debug/InOrderMDU.hh"
-#include "debug/Resource.hh"
-
-using namespace std;
-using namespace ThePipeline;
-
-MultDivUnit::MultDivUnit(string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params)
- : Resource(res_name, res_id, res_width, res_latency, _cpu),
- multRepeatRate(params->multRepeatRate),
- multLatency(params->multLatency),
- div8RepeatRate(params->div8RepeatRate),
- div8Latency(params->div8Latency),
- div16RepeatRate(params->div16RepeatRate),
- div16Latency(params->div16Latency),
- div24RepeatRate(params->div24RepeatRate),
- div24Latency(params->div24Latency),
- div32RepeatRate(params->div32RepeatRate),
- div32Latency(params->div32Latency),
- lastMDUCycle(0), lastOpType(No_OpClass)
-{ }
-
-void
-MultDivUnit::regStats()
-{
- multiplies
- .name(name() + ".multiplies")
- .desc("Number of Multipy Operations Executed");
-
- divides
- .name(name() + ".divides")
- .desc("Number of Divide Operations Executed");
-
- Resource::regStats();
-}
-
-void
-MultDivUnit::init()
-{
- // Set Up Resource Events to Appropriate Resource BandWidth
- resourceEvent = new MDUEvent[width];
-
- for (int i = 0; i < width; i++) {
- reqs[i] = new ResourceRequest(this);
- }
-
- initSlots();
-}
-
-//@TODO: Should we push this behavior into base-class to generically
-// accomodate all multicyle resources?
-void
-MultDivUnit::requestAgain(DynInstPtr inst, bool &service_request)
-{
- ResReqPtr mult_div_req = findRequest(inst);
- assert(mult_div_req);
-
- service_request = true;
-
- // Check to see if this instruction is requesting the same command
- // or a different one
- if (mult_div_req->cmd != inst->curSkedEntry->cmd) {
- // If different, then update command in the request
- mult_div_req->cmd = inst->curSkedEntry->cmd;
- DPRINTF(InOrderMDU,
- "[tid:%i]: [sn:%i]: Updating the command for this "
- "instruction\n", inst->readTid(), inst->seqNum);
- } else {
- // If same command, just check to see if access was completed
- // but dont try to re-execute
- DPRINTF(InOrderMDU,
- "[tid:%i]: [sn:%i]: requesting this resource again\n",
- inst->readTid(), inst->seqNum);
- }
-}
-int
-MultDivUnit::getSlot(DynInstPtr inst)
-{
- // If MDU already has instruction, return current slot.
- int slot_num = findSlot(inst);
-
- // If we have this instruction's request already then return
- if (slot_num != -1 &&
- inst->curSkedEntry->cmd == reqs[slot_num]->cmd)
- return slot_num;
-
- unsigned repeat_rate = 0;
-
- /** Enforce MDU dependencies after a multiply is seen last */
- if (lastOpType == IntMultOp) {
- repeat_rate = multRepeatRate;
- }
-
- /** Enforce dependencies after a divide is seen last */
- if (lastOpType == IntDivOp) {
- switch (lastDivSize) {
- case 8:
- repeat_rate = div8RepeatRate;
- break;
-
- case 16:
- repeat_rate = div16RepeatRate;
- break;
-
- case 24:
- repeat_rate = div24RepeatRate;
- break;
-
- case 32:
- repeat_rate = div32RepeatRate;
- break;
- }
- }
-
- if (lastMDUCycle + repeat_rate > curTick()) {
- DPRINTF(InOrderMDU, "MDU not ready to process another inst. until %i, "
- "denying request.\n", lastMDUCycle + repeat_rate);
- return -1;
- } else {
- int rval = Resource::getSlot(inst);
- DPRINTF(InOrderMDU, "MDU request should pass: %i.\n",
- rval);
-
- if (rval != -1) {
- lastMDUCycle = curTick();
- lastOpType = inst->opClass();
- lastInstName = inst->staticInst->getName();
- }
-
- return rval;
- }
-}
-
-int
-MultDivUnit::getDivOpSize(DynInstPtr inst)
-{
- // Get RT Register from instruction (index #1)
- uint32_t div_op = inst->readIntSrc(1);
-
- if (div_op <= 0xFF) {
- return 8;
- } else if (div_op <= 0xFFFF) {
- return 16;
- } else if (div_op <= 0xFFFFFF) {
- return 24;
- } else {
- return 32;
- }
-}
-
-void
-MultDivUnit::execute(int slot_num)
-{
- ResourceRequest* mult_div_req = reqs[slot_num];
- DynInstPtr inst = reqs[slot_num]->inst;
- if (inst->fault != NoFault) {
- DPRINTF(InOrderMDU,
- "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to "
- "next stage.\n", inst->readTid(), inst->seqNum, inst->fault->name(),
- inst->pcState());
- mult_div_req->done();
- return;
- }
-
- DPRINTF(InOrderMDU, "Executing [sn:%i] ...\n", slot_num);
-
- switch (mult_div_req->cmd)
- {
- case StartMultDiv:
- {
- DPRINTF(InOrderMDU, "Start MDU called ...\n");
-
- OpClass op_class = inst->opClass();
- if (op_class == IntMultOp) {
- scheduleEvent(slot_num, multLatency);
- } else if (op_class == IntDivOp) {
- int op_size = getDivOpSize(inst);
-
- switch (op_size)
- {
- case 8:
- scheduleEvent(slot_num, div8Latency);
- break;
-
- case 16:
- scheduleEvent(slot_num, div16Latency);
- break;
-
- case 24:
- scheduleEvent(slot_num, div24Latency);
- break;
-
- case 32:
- scheduleEvent(slot_num, div32Latency);
- break;
- }
-
- lastDivSize = op_size;
- }
-
- // Allow to pass through to next stage while
- // event processes
- mult_div_req->setProcessing();
- mult_div_req->setCompleted();
- }
- break;
-
- case MultDiv:
- DPRINTF(InOrderMDU, "Execute MDU called ...\n");
- exeMulDiv(slot_num);
- mult_div_req->done();
- break;
-
-
- case EndMultDiv:
- //@TODO: Why not allow high-latency requests to sleep
- // within stage until event wakes up????
- // Seems wasteful to continually check to see if
- // this is done when we have a event in parallel
- // counting down the time
- {
- DPRINTF(InOrderMDU, "End MDU called ...\n");
- if (!mult_div_req->isProcessing()) {
- DPRINTF(InOrderMDU, "Mult/Div finished.\n");
- mult_div_req->done();
- } else {
- mult_div_req->setCompleted(false);
- }
-
- }
- break;
-
- default:
- fatal("Unrecognized command to %s", resName);
- }
-}
-
-void
-MultDivUnit::exeMulDiv(int slot_num)
-{
- ResourceRequest* mult_div_req = reqs[slot_num];
- DynInstPtr inst = reqs[slot_num]->inst;
-
- inst->fault = inst->execute();
-
- if (inst->opClass() == IntMultOp) {
- multiplies++;
- } else if (inst->opClass() == IntDivOp) {
- divides++;
- }
-
- if (inst->fault == NoFault) {
- inst->setExecuted();
-
- DPRINTF(InOrderMDU, "[tid:%i]: The result of execution is 0x%x.\n",
- inst->readTid(), inst->readIntResult(0));
- } else {
- DPRINTF(InOrderMDU, "[tid:%i]: [sn:%i]: had a %s "
- "fault.\n", inst->readTid(), inst->seqNum, inst->fault->name());
- }
-
- mult_div_req->setProcessing(false);
- cpu->wakeCPU();
-}
-
-void
-MultDivUnit::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
- ThreadID tid)
-{
- for (int i = 0; i < width; i++) {
- ResReqPtr req_ptr = reqs[i];
- DynInstPtr inst = req_ptr->getInst();
-
- if (req_ptr->valid &&
- inst->readTid() == tid &&
- inst->seqNum > squash_seq_num) {
-
- DPRINTF(InOrderMDU, "[tid:%i]: Squashing [sn:%i].\n",
- req_ptr->getInst()->readTid(),
- req_ptr->getInst()->seqNum);
-
- req_ptr->setSquashed();
-
- int req_slot_num = req_ptr->getSlot();
-
- if (req_ptr->isProcessing())
- DPRINTF(InOrderMDU, "[tid:%i]: Squashed [sn:%i], but "
- "waiting for MDU operation to complete.\n",
- req_ptr->getInst()->readTid(),
- req_ptr->getInst()->seqNum);
- else
- freeSlot(req_slot_num);
- }
- }
-}
-
-MDUEvent::MDUEvent()
- : ResourceEvent()
-{ }
-
-void
-MDUEvent::process()
-{
- MultDivUnit* mdu_res = reinterpret_cast<MultDivUnit*>(resource);
-
- mdu_res->exeMulDiv(slotIdx);
-
- ResourceRequest* mult_div_req = resource->reqs[slotIdx];
-
- if (mult_div_req->isSquashed())
- mdu_res->freeSlot(slotIdx);
-}
-
-
diff --git a/src/cpu/inorder/resources/mult_div_unit.hh b/src/cpu/inorder/resources/mult_div_unit.hh
deleted file mode 100644
index d855dbb9d..000000000
--- a/src/cpu/inorder/resources/mult_div_unit.hh
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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
- *
- */
-
-#ifndef __CPU_INORDER_MULT_DIV_UNIT_HH__
-#define __CPU_INORDER_MULT_DIV_UNIT_HH__
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include "cpu/inorder/first_stage.hh"
-#include "cpu/inorder/inorder_dyn_inst.hh"
-#include "cpu/inorder/resource.hh"
-#include "cpu/func_unit.hh"
-#include "cpu/op_class.hh"
-
-class MDUEvent;
-
-class MultDivUnit : public Resource {
- public:
- typedef ThePipeline::DynInstPtr DynInstPtr;
-
- enum Command {
- StartMultDiv,
- EndMultDiv,
- MultDiv
- };
-
- public:
- MultDivUnit(std::string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params);
-
- public:
- /** Override default Resource getSlot(). Will only getSlot if
- * valid mult/div sequence is being maintained
- */
- int getSlot(DynInstPtr inst);
-
- void init();
-
- /** Get Operand Size For A Division Operation */
- int getDivOpSize(DynInstPtr inst);
-
- /** Override default Resource execute */
- void execute(int slot_num);
-
- void exeMulDiv(int slot_num);
-
- /** Register extra resource stats */
- void regStats();
-
- void requestAgain(DynInstPtr inst, bool &try_request);
-
- void squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
- ThreadID tid);
-
- protected:
- /** Latency & Repeat Rate for Multiply Insts */
- unsigned multRepeatRate;
- Cycles multLatency;
-
- /** Latency & Repeat Rate for 8-bit Divide Insts */
- unsigned div8RepeatRate;
- Cycles div8Latency;
-
- /** Latency & Repeat Rate for 16-bit Divide Insts */
- unsigned div16RepeatRate;
- Cycles div16Latency;
-
- /** Latency & Repeat Rate for 24-bit Divide Insts */
- unsigned div24RepeatRate;
- Cycles div24Latency;
-
- /** Latency & Repeat Rate for 32-bit Divide Insts */
- unsigned div32RepeatRate;
- Cycles div32Latency;
-
- /** Last cycle that MDU was used */
- Tick lastMDUCycle;
-
- /** Last type of instruction MDU started processing */
- OpClass lastOpType;
-
- /** Last Division Operand of instruction MDU was processing */
- uint32_t lastDivSize;
-
- /** Last instruction name the MDU used */
- std::string lastInstName;
-
- /** Number of Multiplies */
- Stats::Scalar multiplies;
-
- /** Number of Divides */
- Stats::Scalar divides;
-
- MDUEvent *mduEvent;
-};
-
-class MDUEvent : public ResourceEvent
-{
- public:
- MDUEvent();
- ~MDUEvent() { }
-
-
- void process();
-};
-
-
-#endif //__CPU_INORDER_MULT_DIV_UNIT_HH__
diff --git a/src/cpu/inorder/resources/resource_list.hh b/src/cpu/inorder/resources/resource_list.hh
deleted file mode 100644
index a3876d80f..000000000
--- a/src/cpu/inorder/resources/resource_list.hh
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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
- *
- */
-
-#ifndef CPU_INORDER_RESOURCE_LIST_HH
-#define CPU_INORDER_RESOURCE_LIST_HH
-
-#include "cpu/inorder/resources/agen_unit.hh"
-#include "cpu/inorder/resources/branch_predictor.hh"
-#include "cpu/inorder/resources/cache_unit.hh"
-#include "cpu/inorder/resources/decode_unit.hh"
-#include "cpu/inorder/resources/execution_unit.hh"
-#include "cpu/inorder/resources/fetch_seq_unit.hh"
-#include "cpu/inorder/resources/fetch_unit.hh"
-#include "cpu/inorder/resources/graduation_unit.hh"
-#include "cpu/inorder/resources/inst_buffer.hh"
-#include "cpu/inorder/resources/mult_div_unit.hh"
-// The TLBUnit is only needed with the 9-stage pipe and is
-// triggering a gcc LTO bug
-//#include "cpu/inorder/resources/tlb_unit.hh"
-#include "cpu/inorder/resources/use_def.hh"
-
-#endif
diff --git a/src/cpu/inorder/resources/tlb_unit.cc b/src/cpu/inorder/resources/tlb_unit.cc
deleted file mode 100644
index c2619f15e..000000000
--- a/src/cpu/inorder/resources/tlb_unit.cc
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * 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>
-#include <vector>
-
-#include "arch/isa_traits.hh"
-#include "config/the_isa.hh"
-#include "cpu/inorder/resources/tlb_unit.hh"
-#include "cpu/inorder/cpu.hh"
-#include "cpu/inorder/first_stage.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-
-using namespace std;
-using namespace TheISA;
-using namespace ThePipeline;
-
-TLBUnit::TLBUnit(string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params)
-: Resource(res_name, res_id, res_width, res_latency, _cpu)
-{
- // Hard-Code Selection For Now
- if (res_name == "I-TLB")
- _tlb = params->itb;
- else if (res_name == "D-TLB")
- _tlb = params->dtb;
- else
- fatal("Unrecognized TLB name passed by user");
-
- for (int i=0; i < MaxThreads; i++) {
- tlbBlocked[i] = false;
- }
-}
-
-TheISA::TLB*
-TLBUnit::tlb()
-{
- return _tlb;
-
-}
-
-void
-TLBUnit::init()
-{
- resourceEvent = new TLBUnitEvent[width];
-
- for (int i = 0; i < width; i++) {
- reqs[i] = new TLBUnitRequest(this);
- }
-
- initSlots();
-}
-
-int
-TLBUnit::getSlot(DynInstPtr inst)
-{
- if (tlbBlocked[inst->threadNumber]) {
- return -1;
- } else {
- return Resource::getSlot(inst);
- }
-}
-
-ResourceRequest*
-TLBUnit::getRequest(DynInstPtr _inst, int stage_num,
- int res_idx, int slot_num,
- unsigned cmd)
-{
- TLBUnitRequest *tlb_req = dynamic_cast<TLBUnitRequest*>(reqs[slot_num]);
- tlb_req->setRequest(inst, stage_num, id, slot_num, cmd);
- return ud_req;
-}
-
-void
-TLBUnit::execute(int slot_idx)
-{
- // After this is working, change this to a reinterpret cast
- // for performance considerations
- TLBUnitRequest* tlb_req = dynamic_cast<TLBUnitRequest*>(reqs[slot_idx]);
- assert(tlb_req != 0x0);
-
- DynInstPtr inst = tlb_req->inst;
- ThreadID tid = inst->readTid();
- InstSeqNum seq_num = inst->seqNum;
- int stage_num = tlb_req->getStageNum();
-
- tlb_req->fault = NoFault;
-
- assert(cpu->thread[tid]->getTC() != 0x0);
- assert(cpu->pipelineStage[stage_num] != 0x0);
-
- switch (tlb_req->cmd)
- {
- case FetchLookup:
- {
- tlb_req->fault =
- _tlb->translateAtomic(tlb_req->memReq,
- cpu->thread[tid]->getTC(), TheISA::TLB::Execute);
-
- if (tlb_req->fault != NoFault) {
- DPRINTF(InOrderTLB, "[tid:%i]: %s encountered while translating "
- "addr:%08p for [sn:%i].\n", tid, tlb_req->fault->name(),
- tlb_req->memReq->getVaddr(), seq_num);
-
- DPRINTF(InOrderTLB, "slot:%i sn:%i schedule event.\n", slot_idx, seq_num);
-
- cpu->pipelineStage[stage_num]->setResStall(tlb_req, tid);
- tlbBlocked[tid] = true;
- scheduleEvent(slot_idx, 1);
-
- // @TODO: SHOULDNT BREAK EXECUTION at misspeculated PC Fault
- // Let CPU handle the fault
- cpu->trap(tlb_req->fault, tid);
- } else {
- DPRINTF(InOrderTLB, "[tid:%i]: [sn:%i] virt. addr %08p translated "
- "to phys. addr:%08p.\n", tid, seq_num,
- tlb_req->memReq->getVaddr(),
- tlb_req->memReq->getPaddr());
- tlb_req->done();
- }
- }
- break;
-
- case DataReadLookup:
- case DataWriteLookup:
- {
- DPRINTF(InOrderTLB, "[tid:%i]: [sn:%i]: Attempting to translate %08p.\n",
- tid, seq_num, tlb_req->memReq->getVaddr());
-
-
- TheISA::TLB::Mode tlb_mode = (tlb_req->cmd == DataReadLookup) ?
- TheISA::TLB::Read : TheISA::TLB::Write;
-
- tlb_req->fault =
- _tlb->translateAtomic(tlb_req->memReq,
- cpu->thread[tid]->getTC(), tlb_mode);
-
- if (tlb_req->fault != NoFault) {
- DPRINTF(InOrderTLB, "[tid:%i]: %s encountered while translating "
- "addr:%08p for [sn:%i] %s.\n", tid, tlb_req->fault->name(),
- tlb_req->memReq->getVaddr(), seq_num, inst->instName());
-
- if (inst->isDataPrefetch()) {
- DPRINTF(InOrderTLB, "Ignoring %s fault for data prefetch\n",
- tlb_req->fault->name());
-
- tlb_req->fault = NoFault;
-
- tlb_req->done();
- } else {
- cpu->pipelineStage[stage_num]->setResStall(tlb_req, tid);
- tlbBlocked[tid] = true;
- scheduleEvent(slot_idx, 1);
-
- // Let CPU handle the fault
- cpu->trap(tlb_req->fault, tid, inst);
- }
- } else {
- DPRINTF(InOrderTLB, "[tid:%i]: [sn:%i] virt. addr %08p translated "
- "to phys. addr:%08p.\n", tid, seq_num,
- tlb_req->memReq->getVaddr(),
- tlb_req->memReq->getPaddr());
- tlb_req->done();
- }
- }
- break;
-
- default:
- fatal("Unrecognized command to %s", resName);
- }
-}
-
-TLBUnitEvent::TLBUnitEvent()
- : ResourceEvent()
-{ }
-
-void
-TLBUnitEvent::process()
-{
- DynInstPtr inst = resource->reqs[slotIdx]->inst;
- int stage_num = resource->reqs[slotIdx]->getStageNum();
- ThreadID tid = inst->threadNumber;
-
- DPRINTF(InOrderTLB, "Waking up from TLB Miss caused by [sn:%i].\n",
- inst->seqNum);
-
- TLBUnit* tlb_res = dynamic_cast<TLBUnit*>(resource);
- assert(tlb_res);
-
- tlb_res->tlbBlocked[tid] = false;
-
- tlb_res->cpu->pipelineStage[stage_num]->
- unsetResStall(tlb_res->reqs[slotIdx], tid);
-}
-
-void
-TLBUnit::squash(DynInstPtr inst, int stage_num,
- InstSeqNum squash_seq_num, ThreadID tid)
-{
- for (int i = 0; i < width; i++) {
- ResReqPtr req_ptr = reqs[i];
-
- if (req_ptr->valid &&
- req_ptr->getInst()->readTid() == tid &&
- req_ptr->getInst()->seqNum > squash_seq_num) {
-
- DPRINTF(Resource, "[tid:%i]: Squashing [sn:%i].\n",
- req_ptr->getInst()->readTid(),
- req_ptr->getInst()->seqNum);
-
- req_ptr->setSquashed();
-
- int req_slot_num = req_ptr->getSlot();
-
- tlbBlocked[tid] = false;
-
- int stall_stage = reqs[req_slot_num]->getStageNum();
-
- cpu->pipelineStage[stall_stage]->
- unsetResStall(reqs[req_slot_num], tid);
-
- if (resourceEvent[req_slot_num].scheduled())
- unscheduleEvent(req_slot_num);
-
- freeSlot(req_slot_num);
- }
- }
-}
-
-
diff --git a/src/cpu/inorder/resources/tlb_unit.hh b/src/cpu/inorder/resources/tlb_unit.hh
deleted file mode 100644
index 916f67559..000000000
--- a/src/cpu/inorder/resources/tlb_unit.hh
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * 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
- *
- */
-
-#ifndef __CPU_INORDER_TLB_UNIT_HH__
-#define __CPU_INORDER_TLB_UNIT_HH__
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include "config/the_isa.hh"
-#include "cpu/inorder/resources/inst_buffer.hh"
-#include "cpu/inorder/cpu.hh"
-#include "cpu/inorder/inorder_dyn_inst.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-
-class TLBUnit : public Resource
-{
- public:
- typedef ThePipeline::DynInstPtr DynInstPtr;
-
- enum TLBCommand {
- FetchLookup,
- DataReadLookup,
- DataWriteLookup
- };
-
- public:
- TLBUnit(std::string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params);
- virtual ~TLBUnit() {}
-
- void init();
-
- int getSlot(DynInstPtr inst);
-
- virtual ResourceRequest* getRequest(DynInstPtr _inst, int stage_num,
- int res_idx, int slot_num,
- unsigned cmd);
-
- virtual void execute(int slot_num);
-
- void squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
- ThreadID tid);
-
- bool tlbBlocked[ThePipeline::MaxThreads];
-
- TheISA::TLB* tlb();
-
- protected:
- /** List of instructions this resource is currently
- * processing.
- */
- std::list<DynInstPtr> instList;
-
- TheISA::TLB *_tlb;
-};
-
-class TLBUnitEvent : public ResourceEvent {
- public:
- /** Constructs a resource event. */
- TLBUnitEvent();
- virtual ~TLBUnitEvent() {}
-
- /** Processes a resource event. */
- virtual void process();
-};
-
-class TLBUnitRequest : public ResourceRequest {
- public:
- typedef ThePipeline::DynInstPtr DynInstPtr;
-
- public:
- TLBUnitRequest(TLBUnit *res)
- : ResourceRequest(res), memReq(NULL)
- {
- }
-
- RequestPtr memReq;
-
- void setRequest(DynInstPtr inst, int stage_num, int res_idx, int slot_num,
- unsigned _cmd)
- {
- Addr aligned_addr;
- int req_size;
- unsigned flags;
-
- if (_cmd == TLBUnit::FetchLookup) {
- aligned_addr = inst->getMemAddr();
- req_size = sizeof(TheISA::MachInst);
- flags = 0;
- inst->fetchMemReq = new Request(inst->readTid(), aligned_addr,
- req_size, flags,
- res->cpu->instMasterId(),
- inst->instAddr(),
- res->cpu->readCpuId(),
- inst->readTid());
- memReq = inst->fetchMemReq;
- } else {
- aligned_addr = inst->getMemAddr();;
- req_size = 0; //inst->getMemAccSize();
- flags = 0; //inst->getMemFlags();
-
- if (req_size == 0 && (inst->isDataPrefetch() || inst->isInstPrefetch())) {
- req_size = 8;
- }
-
- inst->dataMemReq = new Request(inst->readTid(), aligned_addr,
- req_size, flags,
- res->cpu->dataMasterId(),
- inst->instAddr(),
- res->cpu->readCpuId(),
- inst->readTid());
- memReq = inst->dataMemReq;
- }
-
- ResourceRequest::setRequest(inst, stage_num, res_idx, slot_num, _cmd);
- }
-
-};
-
-
-#endif //__CPU_INORDER_TLB_UNIT_HH__
diff --git a/src/cpu/inorder/resources/use_def.cc b/src/cpu/inorder/resources/use_def.cc
deleted file mode 100644
index 5a871d0d4..000000000
--- a/src/cpu/inorder/resources/use_def.cc
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * Copyright (c) 2007 MIPS Technologies, Inc.
- * Copyright (c) 2013 Advanced Micro Devices, 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>
-#include <vector>
-
-#include "arch/isa_traits.hh"
-#include "config/the_isa.hh"
-#include "cpu/inorder/resources/use_def.hh"
-#include "cpu/inorder/cpu.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-#include "debug/InOrderStall.hh"
-#include "debug/InOrderUseDef.hh"
-
-using namespace std;
-using namespace TheISA;
-using namespace ThePipeline;
-
-UseDefUnit::UseDefUnit(string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params)
- : Resource(res_name, res_id, res_width, res_latency, _cpu)
-{
- for (ThreadID tid = 0; tid < ThePipeline::MaxThreads; tid++) {
- nonSpecInstActive[tid] = &cpu->nonSpecInstActive[tid];
- nonSpecSeqNum[tid] = &cpu->nonSpecSeqNum[tid];
- serializeOnNextInst[tid] = false;
- serializeAfterSeqNum[tid] = 0;
- regDepMap[tid] = &cpu->archRegDepMap[tid];
- }
-
-}
-
-void
-UseDefUnit::regStats()
-{
- uniqueRegsPerSwitch
- .name(name() + ".uniqueRegsPerSwitch")
- .desc("Number of Unique Registers Needed Per Context Switch")
- .prereq(uniqueRegsPerSwitch);
-
- intRegFileReads
- .name(name() + ".intRegFileReads")
- .desc("Number of Reads from Int. Register File");
-
- intRegFileWrites
- .name(name() + ".intRegFileWrites")
- .desc("Number of Writes to Int. Register File");
-
- intRegFileAccs
- .name(name() + ".intRegFileAccesses")
- .desc("Total Accesses (Read+Write) to the Int. Register File");
- intRegFileAccs = intRegFileReads + intRegFileWrites;
-
- floatRegFileReads
- .name(name() + ".floatRegFileReads")
- .desc("Number of Reads from FP Register File");
-
- floatRegFileWrites
- .name(name() + ".floatRegFileWrites")
- .desc("Number of Writes to FP Register File");
-
- floatRegFileAccs
- .name(name() + ".floatRegFileAccesses")
- .desc("Total Accesses (Read+Write) to the FP Register File");
- floatRegFileAccs = floatRegFileReads + floatRegFileWrites;
-
- //@todo: add miscreg reads/writes
- // add forwarding by type???
-
- regForwards
- .name(name() + ".regForwards")
- .desc("Number of Registers Read Through Forwarding Logic");
-
- Resource::regStats();
-}
-
-void
-UseDefUnit::init()
-{
- // Set Up Resource Events to Appropriate Resource BandWidth
- if (latency > Cycles(0)) {
- resourceEvent = new ResourceEvent[width];
- } else {
- resourceEvent = NULL;
- }
-
- for (int i = 0; i < width; i++) {
- reqs[i] = new UseDefRequest(this);
- }
-
- initSlots();
-}
-
-ResReqPtr
-UseDefUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx,
- int slot_num, unsigned cmd)
-{
- UseDefRequest *ud_req = dynamic_cast<UseDefRequest*>(reqs[slot_num]);
- ud_req->setRequest(inst, stage_num, id, slot_num, cmd,
- inst->curSkedEntry->idx);
- return ud_req;
-}
-
-
-ResReqPtr
-UseDefUnit::findRequest(DynInstPtr inst)
-{
- for (int i = 0; i < width; i++) {
- UseDefRequest* ud_req =
- dynamic_cast<UseDefRequest*>(reqs[i]);
- assert(ud_req);
-
- if (ud_req->valid &&
- ud_req->getInst() == inst &&
- ud_req->cmd == inst->curSkedEntry->cmd &&
- ud_req->useDefIdx == inst->curSkedEntry->idx) {
- return ud_req;
- }
- }
-
- return NULL;
-}
-
-void
-UseDefUnit::execute(int slot_idx)
-{
- UseDefRequest* ud_req = dynamic_cast<UseDefRequest*>(reqs[slot_idx]);
- DynInstPtr inst = ud_req->inst;
- ThreadID tid = inst->readTid();
- InstSeqNum seq_num = inst->seqNum;
- int ud_idx = ud_req->useDefIdx;
-
- if (serializeOnNextInst[tid] &&
- seq_num > serializeAfterSeqNum[tid]) {
- inst->setSerializeBefore();
- serializeOnNextInst[tid] = false;
- }
-
- if ((inst->isIprAccess() || inst->isSerializeBefore()) &&
- cpu->instList[tid].front() != inst) {
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] Serialize before instruction encountered."
- " Blocking until pipeline is clear.\n", tid, seq_num);
- ud_req->done(false);
- return;
- } else if (inst->isStoreConditional() || inst->isSerializeAfter()) {
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] Serialize after instruction encountered."
- " Blocking until pipeline is clear.\n", tid, seq_num);
- serializeOnNextInst[tid] = true;
- serializeAfterSeqNum[tid] = seq_num;
- }
-
- if (inst->fault != NoFault) {
- DPRINTF(InOrderUseDef,
- "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to "
- "next stage.\n", inst->readTid(), inst->seqNum, inst->fault->name(),
- inst->pcState());
- ud_req->done();
- return;
- }
-
- // If there is a non-speculative instruction
- // in the pipeline then stall instructions here
- // ---
- if (*nonSpecInstActive[tid] && seq_num > *nonSpecSeqNum[tid]) {
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] cannot execute because"
- "there is non-speculative instruction [sn:%i] has not "
- "graduated.\n", tid, seq_num, *nonSpecSeqNum[tid]);
- ud_req->done(false);
- return;
- } else if (inst->isNonSpeculative()) {
- *nonSpecInstActive[tid] = true;
- *nonSpecSeqNum[tid] = seq_num;
- }
-
- switch (ud_req->cmd)
- {
- case ReadSrcReg:
- {
- RegClass reg_type;
- RegIndex reg_idx = inst->_srcRegIdx[ud_idx];
- RegIndex flat_idx = cpu->flattenRegIdx(reg_idx, reg_type, tid);
- inst->flattenSrcReg(ud_idx, flat_idx);
-
- if (flat_idx == TheISA::ZeroReg && reg_type == IntRegClass) {
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Ignoring Reading of ISA-ZeroReg "
- "(Int. Reg %i).\n", tid, inst->seqNum, flat_idx);
- ud_req->done();
- return;
- } else {
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Attempting to read source "
- "register idx %i (reg #%i, flat#%i).\n",
- tid, seq_num, ud_idx, reg_idx, flat_idx);
- }
-
- if (regDepMap[tid]->canRead(reg_type, flat_idx, inst)) {
- switch (reg_type)
- {
- case IntRegClass:
- {
- uniqueIntRegMap[flat_idx] = true;
-
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Reading Int Reg %i"
- " (%i) from Register File:0x%x.\n",
- tid, seq_num,
- reg_idx, flat_idx,
- cpu->readIntReg(flat_idx,inst->readTid()));
- inst->setIntSrc(ud_idx,
- cpu->readIntReg(flat_idx,
- inst->readTid()));
- intRegFileReads++;
- }
- break;
-
- case FloatRegClass:
- {
- uniqueFloatRegMap[flat_idx] = true;
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Reading Float Reg %i"
- " (%i) from Register File:%x (%08f).\n",
- tid, seq_num,
- reg_idx - FP_Reg_Base, flat_idx,
- cpu->readFloatRegBits(flat_idx,
- inst->readTid()),
- cpu->readFloatReg(flat_idx,
- inst->readTid()));
-
- inst->setFloatSrc(ud_idx,
- cpu->readFloatReg(flat_idx,
- inst->readTid()));
- inst->setFloatRegBitsSrc(ud_idx,
- cpu->readFloatRegBits(flat_idx,
- inst->readTid()));
- floatRegFileReads++;
- }
- break;
-
- case MiscRegClass:
- {
- uniqueMiscRegMap[flat_idx] = true;
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Reading Misc Reg %i "
- " (%i) from Register File:0x%x.\n",
- tid, seq_num,
- reg_idx - Misc_Reg_Base, flat_idx,
- cpu->readMiscReg(flat_idx,
- inst->readTid()));
- inst->setIntSrc(ud_idx,
- cpu->readMiscReg(flat_idx,
- inst->readTid()));
- }
- break;
-
- default:
- panic("Invalid Register Type: %i", reg_type);
- }
-
- ud_req->done();
- } else {
- // Look for forwarding opportunities
- DynInstPtr forward_inst = regDepMap[tid]->canForward(reg_type,
- flat_idx,
- inst);
-
- if (forward_inst) {
- int dest_reg_idx =
- forward_inst->getDestIdxNum(flat_idx);
-
- switch (reg_type)
- {
- case IntRegClass:
- {
- DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest."
- " reg %i (%i), value 0x%x from "
- "[sn:%i] to [sn:%i] source #%x.\n",
- tid, reg_idx, flat_idx,
- forward_inst->readIntResult(dest_reg_idx),
- forward_inst->seqNum,
- inst->seqNum, ud_idx);
- inst->setIntSrc(ud_idx,
- forward_inst->
- readIntResult(dest_reg_idx));
- }
- break;
-
- case FloatRegClass:
- {
- DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest."
- " reg %i (%i) value 0x%x from "
- "[sn:%i] to [sn:%i] source #%i.\n",
- tid, reg_idx - FP_Reg_Base, flat_idx,
- forward_inst->readFloatResult(dest_reg_idx),
- forward_inst->seqNum, inst->seqNum, ud_idx);
- inst->setFloatSrc(ud_idx,
- forward_inst->
- readFloatResult(dest_reg_idx));
- }
- break;
-
- case MiscRegClass:
- {
- DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest."
- " reg %i (%i) value 0x%x from "
- "[sn:%i] to [sn:%i] source #%i.\n",
- tid, reg_idx - Misc_Reg_Base, flat_idx,
- forward_inst->readIntResult(dest_reg_idx),
- forward_inst->seqNum,
- inst->seqNum, ud_idx);
- inst->setIntSrc(ud_idx,
- forward_inst->
- readIntResult(dest_reg_idx));
- }
- break;
-
- default:
- panic("Invalid Register Type: %i", reg_type);
- }
-
- regForwards++;
- ud_req->done();
- } else {
- DPRINTF(InOrderUseDef, "[tid:%i]: Source register idx: %i "
- "is not ready to read.\n",
- tid, reg_idx);
- DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting to read "
- "register (idx=%i)\n",
- tid, reg_idx);
- ud_req->done(false);
- }
- }
- }
- break;
-
- case WriteDestReg:
- {
- RegClass reg_type;
- RegIndex reg_idx = inst->_destRegIdx[ud_idx];
- RegIndex flat_idx = cpu->flattenRegIdx(reg_idx, reg_type, tid);
-
- if (flat_idx == TheISA::ZeroReg && reg_type == IntRegClass) {
- DPRINTF(IntRegs, "[tid:%i]: Ignoring Writing of ISA-ZeroReg "
- "(Int. Reg %i)\n", tid, flat_idx);
- ud_req->done();
- return;
- }
-
- if (regDepMap[tid]->canWrite(reg_type, flat_idx, inst)) {
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Flattening register idx %i "
- "(%i) and Attempting to write to Register File.\n",
- tid, seq_num, reg_idx, flat_idx);
-
- switch (reg_type)
- {
- case IntRegClass:
- {
- uniqueIntRegMap[flat_idx] = true;
-
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Writing Int. Result "
- "0x%x to register idx %i (%i).\n",
- tid, seq_num, inst->readIntResult(ud_idx),
- reg_idx, flat_idx);
-
- // Remove Dependencies
- regDepMap[tid]->removeFront(reg_type, flat_idx, inst);
-
- cpu->setIntReg(flat_idx,
- inst->readIntResult(ud_idx),
- inst->readTid());
- intRegFileWrites++;
- }
- break;
-
- case FloatRegClass:
- {
- uniqueFloatRegMap[flat_idx] = true;
-
- // Remove Reg. Dependecny Block on this Register
- regDepMap[tid]->removeFront(reg_type, flat_idx, inst);
-
- if (inst->resultType(ud_idx) ==
- InOrderDynInst::FloatBits) {
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Writing FP-Bits "
- "Result %08f (bits:0x%x) to register "
- "idx %i (%i).\n",
- tid, seq_num,
- inst->readFloatResult(ud_idx),
- inst->readFloatBitsResult(ud_idx),
- reg_idx - FP_Reg_Base, flat_idx);
-
- // Check for FloatRegBits Here
- cpu->setFloatRegBits(flat_idx,
- inst->readFloatBitsResult(ud_idx),
- inst->readTid());
- } else if (inst->resultType(ud_idx) ==
- InOrderDynInst::Float) {
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Writing Float "
- "Result %08f (bits:0x%x) to register "
- "idx %i (%i).\n",
- tid, seq_num, inst->readFloatResult(ud_idx),
- inst->readIntResult(ud_idx),
- reg_idx - FP_Reg_Base, flat_idx);
-
- cpu->setFloatReg(flat_idx,
- inst->readFloatResult(ud_idx),
- inst->readTid());
- } else if (inst->resultType(ud_idx) ==
- InOrderDynInst::Double) {
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Writing Double "
- "Result %08f (bits:0x%x) to register "
- "idx %i (%i).\n",
- tid, seq_num,
- inst->readFloatResult(ud_idx),
- inst->readIntResult(ud_idx),
- reg_idx - FP_Reg_Base, flat_idx);
-
- cpu->setFloatReg(flat_idx,
- inst->readFloatResult(ud_idx),
- inst->readTid());
- } else {
- panic("Result Type Not Set For [sn:%i] %s.\n",
- inst->seqNum, inst->instName());
- }
-
- floatRegFileWrites++;
- }
- break;
-
- case MiscRegClass:
- {
- uniqueMiscRegMap[flat_idx] = true;
-
- DPRINTF(InOrderUseDef, "[tid:%i]: Writing Misc. 0x%x "
- "to register idx %i.\n",
- tid, inst->readIntResult(ud_idx), reg_idx - Misc_Reg_Base);
-
- // Remove Dependencies
- regDepMap[tid]->removeFront(reg_type, flat_idx, inst);
-
- cpu->setMiscReg(flat_idx,
- inst->readIntResult(ud_idx),
- inst->readTid());
- }
- break;
-
- default:
- panic("Invalid Register Type: %i", reg_type);
- }
-
- ud_req->done();
- } else {
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Dest. register idx: %i is "
- "not ready to write.\n",
- tid, seq_num, reg_idx);
- DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting to write "
- "register (idx=%i)\n",
- tid, reg_idx);
- ud_req->done(false);
- }
- }
- break;
-
- case MarkDestRegs:
- {
- regDepMap[tid]->insert(inst);
- ud_req->done();
- }
- break;
-
- default:
- fatal("Unrecognized command to %s", resName);
- }
-
-}
-
-void
-UseDefUnit::updateAfterContextSwitch(DynInstPtr inst, ThreadID tid)
-{
- uniqueRegsPerSwitch = uniqueIntRegMap.size() + uniqueFloatRegMap.size()
- + uniqueMiscRegMap.size();
- uniqueIntRegMap.clear();
- uniqueFloatRegMap.clear();
- uniqueMiscRegMap.clear();
-}
diff --git a/src/cpu/inorder/resources/use_def.hh b/src/cpu/inorder/resources/use_def.hh
deleted file mode 100644
index 9eb516345..000000000
--- a/src/cpu/inorder/resources/use_def.hh
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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
- *
- */
-
-#ifndef __CPU_INORDER_USE_DEF_UNIT_HH__
-#define __CPU_INORDER_USE_DEF_UNIT_HH__
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include "cpu/inorder/first_stage.hh"
-#include "cpu/inorder/inorder_dyn_inst.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-#include "cpu/inorder/reg_dep_map.hh"
-#include "cpu/inorder/resource.hh"
-#include "cpu/func_unit.hh"
-
-class UseDefUnit : public Resource {
- public:
- typedef ThePipeline::DynInstPtr DynInstPtr;
- typedef TheISA::RegIndex RegIndex;
-
- enum Command {
- ReadSrcReg,
- WriteDestReg,
- MarkDestRegs
- };
-
- public:
- UseDefUnit(std::string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params);
-
- void init();
-
- ResourceRequest* getRequest(DynInstPtr _inst, int stage_num,
- int res_idx, int slot_num,
- unsigned cmd);
-
- ResReqPtr findRequest(DynInstPtr inst);
-
- void execute(int slot_num);
-
- void updateAfterContextSwitch(DynInstPtr inst, ThreadID tid);
-
- void regStats();
-
- protected:
- RegDepMap *regDepMap[ThePipeline::MaxThreads];
-
- bool *nonSpecInstActive[ThePipeline::MaxThreads];
- InstSeqNum *nonSpecSeqNum[ThePipeline::MaxThreads];
-
- bool serializeOnNextInst[ThePipeline::MaxThreads];
- InstSeqNum serializeAfterSeqNum[ThePipeline::MaxThreads];
-
- Stats::Average uniqueRegsPerSwitch;
- std::map<RegIndex, bool> uniqueIntRegMap;
- std::map<RegIndex, bool> uniqueFloatRegMap;
- std::map<RegIndex, bool> uniqueMiscRegMap;
-
- public:
- class UseDefRequest : public ResourceRequest {
- public:
- typedef ThePipeline::DynInstPtr DynInstPtr;
-
- public:
- UseDefRequest(UseDefUnit *res)
- : ResourceRequest(res)
- { }
-
- int useDefIdx;
-
- void setRequest(DynInstPtr _inst, int stage_num, int res_idx,
- int slot_num, unsigned _cmd, int idx)
- {
- useDefIdx = idx;
-
- ResourceRequest::setRequest(_inst, stage_num, res_idx, slot_num,
- _cmd);
- }
- };
-
- protected:
- /** Int. Register File Reads */
- Stats::Scalar intRegFileReads;
-
- /** Int. Register File Writes */
- Stats::Scalar intRegFileWrites;
-
- /** Int. Register File Total Accesses (Read+Write) */
- Stats::Formula intRegFileAccs;
-
- /** Float Register File Reads */
- Stats::Scalar floatRegFileReads;
-
- /** Float Register File Writes */
- Stats::Scalar floatRegFileWrites;
-
- /** Float Register File Total Accesses (Read+Write) */
- Stats::Formula floatRegFileAccs;
-
- /** Source Register Forwarding */
- Stats::Scalar regForwards;
-};
-
-#endif //__CPU_INORDER_USE_DEF_UNIT_HH__