diff options
author | Nathan Binkert <binkertn@umich.edu> | 2005-06-04 20:50:10 -0400 |
---|---|---|
committer | Nathan Binkert <binkertn@umich.edu> | 2005-06-04 20:50:10 -0400 |
commit | 13c005a8af79a8481879ce099b45a1f98faae165 (patch) | |
tree | 3125dfe10539270433981b39119dd727295c255c /cpu/o3/cpu.cc | |
parent | 5a94e6f2cc6ed8480063da68d20274ced2930925 (diff) | |
download | gem5-13c005a8af79a8481879ce099b45a1f98faae165.tar.xz |
shuffle files around for new directory structure
--HG--
rename : cpu/base_cpu.cc => cpu/base.cc
rename : cpu/base_cpu.hh => cpu/base.hh
rename : cpu/beta_cpu/2bit_local_pred.cc => cpu/o3/2bit_local_pred.cc
rename : cpu/beta_cpu/2bit_local_pred.hh => cpu/o3/2bit_local_pred.hh
rename : cpu/beta_cpu/alpha_full_cpu.cc => cpu/o3/alpha_cpu.cc
rename : cpu/beta_cpu/alpha_full_cpu.hh => cpu/o3/alpha_cpu.hh
rename : cpu/beta_cpu/alpha_full_cpu_builder.cc => cpu/o3/alpha_cpu_builder.cc
rename : cpu/beta_cpu/alpha_full_cpu_impl.hh => cpu/o3/alpha_cpu_impl.hh
rename : cpu/beta_cpu/alpha_dyn_inst.cc => cpu/o3/alpha_dyn_inst.cc
rename : cpu/beta_cpu/alpha_dyn_inst.hh => cpu/o3/alpha_dyn_inst.hh
rename : cpu/beta_cpu/alpha_dyn_inst_impl.hh => cpu/o3/alpha_dyn_inst_impl.hh
rename : cpu/beta_cpu/alpha_impl.hh => cpu/o3/alpha_impl.hh
rename : cpu/beta_cpu/alpha_params.hh => cpu/o3/alpha_params.hh
rename : cpu/beta_cpu/bpred_unit.cc => cpu/o3/bpred_unit.cc
rename : cpu/beta_cpu/bpred_unit.hh => cpu/o3/bpred_unit.hh
rename : cpu/beta_cpu/bpred_unit_impl.hh => cpu/o3/bpred_unit_impl.hh
rename : cpu/beta_cpu/btb.cc => cpu/o3/btb.cc
rename : cpu/beta_cpu/btb.hh => cpu/o3/btb.hh
rename : cpu/beta_cpu/comm.hh => cpu/o3/comm.hh
rename : cpu/beta_cpu/commit.cc => cpu/o3/commit.cc
rename : cpu/beta_cpu/commit.hh => cpu/o3/commit.hh
rename : cpu/beta_cpu/commit_impl.hh => cpu/o3/commit_impl.hh
rename : cpu/beta_cpu/full_cpu.cc => cpu/o3/cpu.cc
rename : cpu/beta_cpu/full_cpu.hh => cpu/o3/cpu.hh
rename : cpu/beta_cpu/cpu_policy.hh => cpu/o3/cpu_policy.hh
rename : cpu/beta_cpu/decode.cc => cpu/o3/decode.cc
rename : cpu/beta_cpu/decode.hh => cpu/o3/decode.hh
rename : cpu/beta_cpu/decode_impl.hh => cpu/o3/decode_impl.hh
rename : cpu/beta_cpu/fetch.cc => cpu/o3/fetch.cc
rename : cpu/beta_cpu/fetch.hh => cpu/o3/fetch.hh
rename : cpu/beta_cpu/fetch_impl.hh => cpu/o3/fetch_impl.hh
rename : cpu/beta_cpu/free_list.cc => cpu/o3/free_list.cc
rename : cpu/beta_cpu/free_list.hh => cpu/o3/free_list.hh
rename : cpu/beta_cpu/iew.cc => cpu/o3/iew.cc
rename : cpu/beta_cpu/iew.hh => cpu/o3/iew.hh
rename : cpu/beta_cpu/iew_impl.hh => cpu/o3/iew_impl.hh
rename : cpu/beta_cpu/inst_queue.cc => cpu/o3/inst_queue.cc
rename : cpu/beta_cpu/inst_queue.hh => cpu/o3/inst_queue.hh
rename : cpu/beta_cpu/inst_queue_impl.hh => cpu/o3/inst_queue_impl.hh
rename : cpu/beta_cpu/mem_dep_unit.cc => cpu/o3/mem_dep_unit.cc
rename : cpu/beta_cpu/mem_dep_unit.hh => cpu/o3/mem_dep_unit.hh
rename : cpu/beta_cpu/mem_dep_unit_impl.hh => cpu/o3/mem_dep_unit_impl.hh
rename : cpu/beta_cpu/ras.cc => cpu/o3/ras.cc
rename : cpu/beta_cpu/ras.hh => cpu/o3/ras.hh
rename : cpu/beta_cpu/regfile.hh => cpu/o3/regfile.hh
rename : cpu/beta_cpu/rename.cc => cpu/o3/rename.cc
rename : cpu/beta_cpu/rename.hh => cpu/o3/rename.hh
rename : cpu/beta_cpu/rename_impl.hh => cpu/o3/rename_impl.hh
rename : cpu/beta_cpu/rename_map.cc => cpu/o3/rename_map.cc
rename : cpu/beta_cpu/rename_map.hh => cpu/o3/rename_map.hh
rename : cpu/beta_cpu/rob.cc => cpu/o3/rob.cc
rename : cpu/beta_cpu/rob.hh => cpu/o3/rob.hh
rename : cpu/beta_cpu/rob_impl.hh => cpu/o3/rob_impl.hh
rename : cpu/beta_cpu/sat_counter.cc => cpu/o3/sat_counter.cc
rename : cpu/beta_cpu/sat_counter.hh => cpu/o3/sat_counter.hh
rename : cpu/beta_cpu/store_set.cc => cpu/o3/store_set.cc
rename : cpu/beta_cpu/store_set.hh => cpu/o3/store_set.hh
rename : cpu/beta_cpu/tournament_pred.cc => cpu/o3/tournament_pred.cc
rename : cpu/beta_cpu/tournament_pred.hh => cpu/o3/tournament_pred.hh
rename : cpu/ooo_cpu/ooo_cpu.cc => cpu/ozone/cpu.cc
rename : cpu/ooo_cpu/ooo_cpu.hh => cpu/ozone/cpu.hh
rename : cpu/ooo_cpu/ooo_impl.hh => cpu/ozone/cpu_impl.hh
rename : cpu/ooo_cpu/ea_list.cc => cpu/ozone/ea_list.cc
rename : cpu/ooo_cpu/ea_list.hh => cpu/ozone/ea_list.hh
rename : cpu/simple_cpu/simple_cpu.cc => cpu/simple/cpu.cc
rename : cpu/simple_cpu/simple_cpu.hh => cpu/simple/cpu.hh
rename : cpu/full_cpu/smt.hh => cpu/smt.hh
rename : cpu/full_cpu/op_class.hh => encumbered/cpu/full/op_class.hh
extra : convert_revision : c4a891d8d6d3e0e9e5ea56be47d851da44d8c032
Diffstat (limited to 'cpu/o3/cpu.cc')
-rw-r--r-- | cpu/o3/cpu.cc | 555 |
1 files changed, 555 insertions, 0 deletions
diff --git a/cpu/o3/cpu.cc b/cpu/o3/cpu.cc new file mode 100644 index 000000000..a91c36679 --- /dev/null +++ b/cpu/o3/cpu.cc @@ -0,0 +1,555 @@ +/* + * Copyright (c) 2004-2005 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. + */ + +#ifdef FULL_SYSTEM +#include "sim/system.hh" +#else +#include "sim/process.hh" +#endif +#include "sim/root.hh" + +#include "cpu/o3/alpha_dyn_inst.hh" +#include "cpu/o3/alpha_impl.hh" +#include "cpu/o3/cpu.hh" +#include "cpu/exec_context.hh" + +using namespace std; + +BaseFullCPU::BaseFullCPU(Params ¶ms) + : BaseCPU(¶ms), cpu_id(0) +{ +} + +template <class Impl> +FullBetaCPU<Impl>::TickEvent::TickEvent(FullBetaCPU<Impl> *c) + : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c) +{ +} + +template <class Impl> +void +FullBetaCPU<Impl>::TickEvent::process() +{ + cpu->tick(); +} + +template <class Impl> +const char * +FullBetaCPU<Impl>::TickEvent::description() +{ + return "FullBetaCPU tick event"; +} + +//Call constructor to all the pipeline stages here +template <class Impl> +FullBetaCPU<Impl>::FullBetaCPU(Params ¶ms) +#ifdef FULL_SYSTEM + : BaseFullCPU(params), +#else + : BaseFullCPU(params), +#endif // FULL_SYSTEM + tickEvent(this), + fetch(params), + decode(params), + rename(params), + iew(params), + commit(params), + + regFile(params.numPhysIntRegs, params.numPhysFloatRegs), + + freeList(Impl::ISA::NumIntRegs, params.numPhysIntRegs, + Impl::ISA::NumFloatRegs, params.numPhysFloatRegs), + + renameMap(Impl::ISA::NumIntRegs, params.numPhysIntRegs, + Impl::ISA::NumFloatRegs, params.numPhysFloatRegs, + Impl::ISA::NumMiscRegs, + Impl::ISA::ZeroReg, + Impl::ISA::ZeroReg + Impl::ISA::NumIntRegs), + + rob(params.numROBEntries, params.squashWidth), + + // What to pass to these time buffers? + // For now just have these time buffers be pretty big. + timeBuffer(5, 5), + fetchQueue(5, 5), + decodeQueue(5, 5), + renameQueue(5, 5), + iewQueue(5, 5), + + xc(NULL), + + globalSeqNum(1), + +#ifdef FULL_SYSTEM + system(params.system), + memCtrl(system->memctrl), + physmem(system->physmem), + itb(params.itb), + dtb(params.dtb), + mem(params.mem), +#else + // Hardcoded for a single thread!! + mem(params.workload[0]->getMemory()), +#endif // FULL_SYSTEM + + icacheInterface(params.icacheInterface), + dcacheInterface(params.dcacheInterface), + deferRegistration(params.defReg), + numInsts(0), + funcExeInst(0) +{ + _status = Idle; + +#ifndef FULL_SYSTEM + thread.resize(this->number_of_threads); +#endif + + for (int i = 0; i < this->number_of_threads; ++i) { +#ifdef FULL_SYSTEM + assert(i == 0); + system->execContexts[i] = + new ExecContext(this, i, system, itb, dtb, mem); + + // initialize CPU, including PC + TheISA::initCPU(&system->execContexts[i]->regs); + execContexts.push_back(system->execContexts[i]); +#else + if (i < params.workload.size()) { + DPRINTF(FullCPU, "FullCPU: Workload[%i]'s starting PC is %#x, " + "process is %#x", + i, params.workload[i]->prog_entry, thread[i]); + thread[i] = new ExecContext(this, i, params.workload[i], i); + } + assert(params.workload[i]->getMemory() != NULL); + assert(mem != NULL); + execContexts.push_back(thread[i]); +#endif // !FULL_SYSTEM + } + + // Note that this is a hack so that my code which still uses xc-> will + // still work. I should remove this eventually +#ifdef FULL_SYSTEM + xc = system->execContexts[0]; +#else + xc = thread[0]; +#endif + + // The stages also need their CPU pointer setup. However this must be + // done at the upper level CPU because they have pointers to the upper + // level CPU, and not this FullBetaCPU. + + // Give each of the stages the time buffer they will use. + fetch.setTimeBuffer(&timeBuffer); + decode.setTimeBuffer(&timeBuffer); + rename.setTimeBuffer(&timeBuffer); + iew.setTimeBuffer(&timeBuffer); + commit.setTimeBuffer(&timeBuffer); + + // Also setup each of the stages' queues. + fetch.setFetchQueue(&fetchQueue); + decode.setFetchQueue(&fetchQueue); + decode.setDecodeQueue(&decodeQueue); + rename.setDecodeQueue(&decodeQueue); + rename.setRenameQueue(&renameQueue); + iew.setRenameQueue(&renameQueue); + iew.setIEWQueue(&iewQueue); + commit.setIEWQueue(&iewQueue); + commit.setRenameQueue(&renameQueue); + + // Setup the rename map for whichever stages need it. + rename.setRenameMap(&renameMap); + iew.setRenameMap(&renameMap); + + // Setup the free list for whichever stages need it. + rename.setFreeList(&freeList); + renameMap.setFreeList(&freeList); + + // Setup the ROB for whichever stages need it. + commit.setROB(&rob); +} + +template <class Impl> +FullBetaCPU<Impl>::~FullBetaCPU() +{ +} + +template <class Impl> +void +FullBetaCPU<Impl>::fullCPURegStats() +{ + // Register any of the FullCPU's stats here. +} + +template <class Impl> +void +FullBetaCPU<Impl>::tick() +{ + DPRINTF(FullCPU, "\n\nFullCPU: Ticking main, FullBetaCPU.\n"); + + //Tick each of the stages if they're actually running. + //Will want to figure out a way to unschedule itself if they're all + //going to be idle for a long time. + fetch.tick(); + + decode.tick(); + + rename.tick(); + + iew.tick(); + + commit.tick(); + + // Now advance the time buffers, unless the stage is stalled. + timeBuffer.advance(); + + fetchQueue.advance(); + decodeQueue.advance(); + renameQueue.advance(); + iewQueue.advance(); + + if (_status == Running && !tickEvent.scheduled()) + tickEvent.schedule(curTick + 1); +} + +template <class Impl> +void +FullBetaCPU<Impl>::init() +{ + if(!deferRegistration) + { + this->registerExecContexts(); + + // Need to do a copy of the xc->regs into the CPU's regfile so + // that it can start properly. +#ifdef FULL_SYSTEM + ExecContext *src_xc = system->execContexts[0]; +#else + ExecContext *src_xc = thread[0]; +#endif + // First loop through the integer registers. + for (int i = 0; i < Impl::ISA::NumIntRegs; ++i) + { + regFile.intRegFile[i] = src_xc->regs.intRegFile[i]; + } + + // Then loop through the floating point registers. + for (int i = 0; i < Impl::ISA::NumFloatRegs; ++i) + { + regFile.floatRegFile[i].d = src_xc->regs.floatRegFile.d[i]; + regFile.floatRegFile[i].q = src_xc->regs.floatRegFile.q[i]; + } + + // Then loop through the misc registers. + regFile.miscRegs.fpcr = src_xc->regs.miscRegs.fpcr; + regFile.miscRegs.uniq = src_xc->regs.miscRegs.uniq; + regFile.miscRegs.lock_flag = src_xc->regs.miscRegs.lock_flag; + regFile.miscRegs.lock_addr = src_xc->regs.miscRegs.lock_addr; + + // Then finally set the PC and the next PC. + regFile.pc = src_xc->regs.pc; + regFile.npc = src_xc->regs.npc; + } +} + +template <class Impl> +void +FullBetaCPU<Impl>::activateContext(int thread_num, int delay) +{ + // Needs to set each stage to running as well. + + scheduleTickEvent(delay); + + _status = Running; +} + +template <class Impl> +void +FullBetaCPU<Impl>::suspendContext(int thread_num) +{ + panic("suspendContext unimplemented!"); +} + +template <class Impl> +void +FullBetaCPU<Impl>::deallocateContext(int thread_num) +{ + panic("deallocateContext unimplemented!"); +} + +template <class Impl> +void +FullBetaCPU<Impl>::haltContext(int thread_num) +{ + panic("haltContext unimplemented!"); +} + +template <class Impl> +void +FullBetaCPU<Impl>::switchOut() +{ + panic("FullBetaCPU does not have a switch out function.\n"); +} + +template <class Impl> +void +FullBetaCPU<Impl>::takeOverFrom(BaseCPU *oldCPU) +{ + BaseCPU::takeOverFrom(oldCPU); + + assert(!tickEvent.scheduled()); + + // Set all status's to active, schedule the + // CPU's tick event. + for (int i = 0; i < execContexts.size(); ++i) { + ExecContext *xc = execContexts[i]; + if (xc->status() == ExecContext::Active && _status != Running) { + _status = Running; + tickEvent.schedule(curTick); + } + } +} + +template <class Impl> +InstSeqNum +FullBetaCPU<Impl>::getAndIncrementInstSeq() +{ + // Hopefully this works right. + return globalSeqNum++; +} + +template <class Impl> +uint64_t +FullBetaCPU<Impl>::readIntReg(int reg_idx) +{ + return regFile.readIntReg(reg_idx); +} + +template <class Impl> +float +FullBetaCPU<Impl>::readFloatRegSingle(int reg_idx) +{ + return regFile.readFloatRegSingle(reg_idx); +} + +template <class Impl> +double +FullBetaCPU<Impl>::readFloatRegDouble(int reg_idx) +{ + return regFile.readFloatRegDouble(reg_idx); +} + +template <class Impl> +uint64_t +FullBetaCPU<Impl>::readFloatRegInt(int reg_idx) +{ + return regFile.readFloatRegInt(reg_idx); +} + +template <class Impl> +void +FullBetaCPU<Impl>::setIntReg(int reg_idx, uint64_t val) +{ + regFile.setIntReg(reg_idx, val); +} + +template <class Impl> +void +FullBetaCPU<Impl>::setFloatRegSingle(int reg_idx, float val) +{ + regFile.setFloatRegSingle(reg_idx, val); +} + +template <class Impl> +void +FullBetaCPU<Impl>::setFloatRegDouble(int reg_idx, double val) +{ + regFile.setFloatRegDouble(reg_idx, val); +} + +template <class Impl> +void +FullBetaCPU<Impl>::setFloatRegInt(int reg_idx, uint64_t val) +{ + regFile.setFloatRegInt(reg_idx, val); +} + +template <class Impl> +uint64_t +FullBetaCPU<Impl>::readPC() +{ + return regFile.readPC(); +} + +template <class Impl> +void +FullBetaCPU<Impl>::setNextPC(uint64_t val) +{ + regFile.setNextPC(val); +} + +template <class Impl> +void +FullBetaCPU<Impl>::setPC(Addr new_PC) +{ + regFile.setPC(new_PC); +} + +template <class Impl> +void +FullBetaCPU<Impl>::addInst(DynInstPtr &inst) +{ + instList.push_back(inst); +} + +template <class Impl> +void +FullBetaCPU<Impl>::instDone() +{ + // Keep an instruction count. + numInsts++; + + // Check for instruction-count-based events. + comInstEventQueue[0]->serviceEvents(numInsts); +} + +template <class Impl> +void +FullBetaCPU<Impl>::removeBackInst(DynInstPtr &inst) +{ + DynInstPtr inst_to_delete; + + // Walk through the instruction list, removing any instructions + // that were inserted after the given instruction, inst. + while (instList.back() != inst) + { + assert(!instList.empty()); + + // Obtain the pointer to the instruction. + inst_to_delete = instList.back(); + + DPRINTF(FullCPU, "FullCPU: Removing instruction %i, PC %#x\n", + inst_to_delete->seqNum, inst_to_delete->readPC()); + + // Remove the instruction from the list. + instList.pop_back(); + + // Mark it as squashed. + inst_to_delete->setSquashed(); + } +} + +template <class Impl> +void +FullBetaCPU<Impl>::removeFrontInst(DynInstPtr &inst) +{ + DynInstPtr inst_to_remove; + + // The front instruction should be the same one being asked to be removed. + assert(instList.front() == inst); + + // Remove the front instruction. + inst_to_remove = inst; + instList.pop_front(); + + DPRINTF(FullCPU, "FullCPU: Removing committed instruction %#x, PC %#x\n", + inst_to_remove, inst_to_remove->readPC()); +} + +template <class Impl> +void +FullBetaCPU<Impl>::removeInstsNotInROB() +{ + DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction " + "list.\n"); + + DynInstPtr rob_tail = rob.readTailInst(); + + removeBackInst(rob_tail); +} + +template <class Impl> +void +FullBetaCPU<Impl>::removeInstsUntil(const InstSeqNum &seq_num) +{ + DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction " + "list.\n"); + + DynInstPtr inst_to_delete; + + while (instList.back()->seqNum > seq_num) { + assert(!instList.empty()); + + // Obtain the pointer to the instruction. + inst_to_delete = instList.back(); + + DPRINTF(FullCPU, "FullCPU: Removing instruction %i, PC %#x\n", + inst_to_delete->seqNum, inst_to_delete->readPC()); + + // Remove the instruction from the list. + instList.back() = NULL; + instList.pop_back(); + + // Mark it as squashed. + inst_to_delete->setSquashed(); + } + +} + +template <class Impl> +void +FullBetaCPU<Impl>::removeAllInsts() +{ + instList.clear(); +} + +template <class Impl> +void +FullBetaCPU<Impl>::dumpInsts() +{ + int num = 0; + typename list<DynInstPtr>::iterator inst_list_it = instList.begin(); + + while (inst_list_it != instList.end()) + { + cprintf("Instruction:%i\nPC:%#x\nSN:%lli\nIssued:%i\nSquashed:%i\n\n", + num, (*inst_list_it)->readPC(), (*inst_list_it)->seqNum, + (*inst_list_it)->isIssued(), (*inst_list_it)->isSquashed()); + inst_list_it++; + ++num; + } +} + +template <class Impl> +void +FullBetaCPU<Impl>::wakeDependents(DynInstPtr &inst) +{ + iew.wakeDependents(inst); +} + +// Forward declaration of FullBetaCPU. +template class FullBetaCPU<AlphaSimpleImpl>; |