From ec9b2ec25151bd857ad0557befc37f00bc61d1c7 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sat, 12 Feb 2011 10:14:40 -0500 Subject: inorder: stage scheduler for front/back end schedule creation add a stage scheduler class to replace InstStage in pipeline_traits.cc use that class to define a default front-end, resource schedule that all instructions will follow. This will also replace the back end schedule in pipeline_traits.cc. The reason for adding this is so that we can cache instruction schedules in the future instead of calling the same function over/over again as well as constantly dynamically alllocating memory on every instruction to try to figure out it's schedule --- src/cpu/inorder/cpu.cc | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) (limited to 'src/cpu/inorder/cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 39357cd30..0591b0510 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -341,6 +341,7 @@ InOrderCPU::InOrderCPU(Params *params) dummyBufferInst->resetInstCount(); endOfSkedIt = skedCache.end(); + frontEndSked = createFrontEndSked(); lastRunningCycle = curTick(); @@ -364,6 +365,102 @@ InOrderCPU::~InOrderCPU() std::map InOrderCPU::skedCache; +RSkedPtr +InOrderCPU::createFrontEndSked() +{ + RSkedPtr res_sked = NULL; + int stage_num = 0; + StageScheduler F(res_sked, stage_num++); + StageScheduler D(res_sked, stage_num++); + + // FETCH + F.needs(FetchSeq, FetchSeqUnit::AssignNextPC); + F.needs(ICache, FetchUnit::InitiateFetch); + + // DECODE + D.needs(ICache, FetchUnit::CompleteFetch); + D.needs(Decode, DecodeUnit::DecodeInst); + D.needs(BPred, BranchPredictor::PredictBranch); + D.needs(FetchSeq, FetchSeqUnit::UpdateTargetPC); + + return res_sked; +} + +RSkedPtr +InOrderCPU::createBackEndSked(DynInstPtr inst) +{ + RSkedPtr res_sked = lookupSked(inst); + if (res_sked != NULL) { + return res_sked; + } + + int stage_num = ThePipeline::BackEndStartStage; + StageScheduler X(res_sked, stage_num++); + StageScheduler M(res_sked, stage_num++); + StageScheduler W(res_sked, stage_num++); + + if (!inst->staticInst) { + warn_once("Static Instruction Object Not Set. Can't Create" + " Back End Schedule"); + return false; + } + + // EXECUTE + for (int idx=0; idx < inst->numSrcRegs(); idx++) { + if (!idx || !inst->isStore()) { + X.needs(RegManager, UseDefUnit::ReadSrcReg, idx); + } + } + + if ( inst->isNonSpeculative() ) { + // skip execution of non speculative insts until later + } else if ( inst->isMemRef() ) { + if ( inst->isLoad() ) { + X.needs(AGEN, AGENUnit::GenerateAddr); + } + } else if (inst->opClass() == IntMultOp || inst->opClass() == IntDivOp) { + X.needs(MDU, MultDivUnit::StartMultDiv); + } else { + X.needs(ExecUnit, ExecutionUnit::ExecuteInst); + } + + if (inst->opClass() == IntMultOp || inst->opClass() == IntDivOp) { + X.needs(MDU, MultDivUnit::EndMultDiv); + } + + // MEMORY + if ( inst->isLoad() ) { + M.needs(DCache, CacheUnit::InitiateReadData); + } else if ( inst->isStore() ) { + if ( inst->numSrcRegs() >= 2 ) { + M.needs(RegManager, UseDefUnit::ReadSrcReg, 1); + } + M.needs(AGEN, AGENUnit::GenerateAddr); + M.needs(DCache, CacheUnit::InitiateWriteData); + } + + + // WRITEBACK + if ( inst->isLoad() ) { + W.needs(DCache, CacheUnit::CompleteReadData); + } else if ( inst->isStore() ) { + W.needs(DCache, CacheUnit::CompleteWriteData); + } + + if ( inst->isNonSpeculative() ) { + if ( inst->isMemRef() ) fatal("Non-Speculative Memory Instruction"); + W.needs(ExecUnit, ExecutionUnit::ExecuteInst); + } + + for (int idx=0; idx < inst->numDestRegs(); idx++) { + W.needs(RegManager, UseDefUnit::WriteDestReg, idx); + } + + W.needs(Grad, GraduationUnit::GraduateInst); + + return res_sked; +} + void InOrderCPU::regStats() { -- cgit v1.2.3