pipeline.cc revision 12324
110259SAndrew.Bardsley@arm.com/* 210259SAndrew.Bardsley@arm.com * Copyright (c) 2013-2014 ARM Limited 310259SAndrew.Bardsley@arm.com * All rights reserved 410259SAndrew.Bardsley@arm.com * 510259SAndrew.Bardsley@arm.com * The license below extends only to copyright in the software and shall 610259SAndrew.Bardsley@arm.com * not be construed as granting a license to any other intellectual 710259SAndrew.Bardsley@arm.com * property including but not limited to intellectual property relating 810259SAndrew.Bardsley@arm.com * to a hardware implementation of the functionality of the software 910259SAndrew.Bardsley@arm.com * licensed hereunder. You may use the software subject to the license 1010259SAndrew.Bardsley@arm.com * terms below provided that you ensure that this notice is replicated 1110259SAndrew.Bardsley@arm.com * unmodified and in its entirety in all distributions of the software, 1210259SAndrew.Bardsley@arm.com * modified or unmodified, in source code or in binary form. 1310259SAndrew.Bardsley@arm.com * 1410259SAndrew.Bardsley@arm.com * Redistribution and use in source and binary forms, with or without 1510259SAndrew.Bardsley@arm.com * modification, are permitted provided that the following conditions are 1610259SAndrew.Bardsley@arm.com * met: redistributions of source code must retain the above copyright 1710259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer; 1810259SAndrew.Bardsley@arm.com * redistributions in binary form must reproduce the above copyright 1910259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer in the 2010259SAndrew.Bardsley@arm.com * documentation and/or other materials provided with the distribution; 2110259SAndrew.Bardsley@arm.com * neither the name of the copyright holders nor the names of its 2210259SAndrew.Bardsley@arm.com * contributors may be used to endorse or promote products derived from 2310259SAndrew.Bardsley@arm.com * this software without specific prior written permission. 2410259SAndrew.Bardsley@arm.com * 2510259SAndrew.Bardsley@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610259SAndrew.Bardsley@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710259SAndrew.Bardsley@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810259SAndrew.Bardsley@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910259SAndrew.Bardsley@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010259SAndrew.Bardsley@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110259SAndrew.Bardsley@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210259SAndrew.Bardsley@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310259SAndrew.Bardsley@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410259SAndrew.Bardsley@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510259SAndrew.Bardsley@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610259SAndrew.Bardsley@arm.com * 3710259SAndrew.Bardsley@arm.com * Authors: Andrew Bardsley 3810259SAndrew.Bardsley@arm.com */ 3910259SAndrew.Bardsley@arm.com 4011793Sbrandon.potter@amd.com#include "cpu/minor/pipeline.hh" 4111793Sbrandon.potter@amd.com 4210259SAndrew.Bardsley@arm.com#include <algorithm> 4310259SAndrew.Bardsley@arm.com 4410259SAndrew.Bardsley@arm.com#include "cpu/minor/decode.hh" 4510259SAndrew.Bardsley@arm.com#include "cpu/minor/execute.hh" 4610259SAndrew.Bardsley@arm.com#include "cpu/minor/fetch1.hh" 4710259SAndrew.Bardsley@arm.com#include "cpu/minor/fetch2.hh" 4810259SAndrew.Bardsley@arm.com#include "debug/Drain.hh" 4910259SAndrew.Bardsley@arm.com#include "debug/MinorCPU.hh" 5010259SAndrew.Bardsley@arm.com#include "debug/MinorTrace.hh" 5110259SAndrew.Bardsley@arm.com#include "debug/Quiesce.hh" 5210259SAndrew.Bardsley@arm.com 5310259SAndrew.Bardsley@arm.comnamespace Minor 5410259SAndrew.Bardsley@arm.com{ 5510259SAndrew.Bardsley@arm.com 5610259SAndrew.Bardsley@arm.comPipeline::Pipeline(MinorCPU &cpu_, MinorCPUParams ¶ms) : 5710259SAndrew.Bardsley@arm.com Ticked(cpu_, &(cpu_.BaseCPU::numCycles)), 5810259SAndrew.Bardsley@arm.com cpu(cpu_), 5910259SAndrew.Bardsley@arm.com allow_idling(params.enableIdling), 6010259SAndrew.Bardsley@arm.com f1ToF2(cpu.name() + ".f1ToF2", "lines", 6110259SAndrew.Bardsley@arm.com params.fetch1ToFetch2ForwardDelay), 6210259SAndrew.Bardsley@arm.com f2ToF1(cpu.name() + ".f2ToF1", "prediction", 6310259SAndrew.Bardsley@arm.com params.fetch1ToFetch2BackwardDelay, true), 6410259SAndrew.Bardsley@arm.com f2ToD(cpu.name() + ".f2ToD", "insts", 6510259SAndrew.Bardsley@arm.com params.fetch2ToDecodeForwardDelay), 6610259SAndrew.Bardsley@arm.com dToE(cpu.name() + ".dToE", "insts", 6710259SAndrew.Bardsley@arm.com params.decodeToExecuteForwardDelay), 6810259SAndrew.Bardsley@arm.com eToF1(cpu.name() + ".eToF1", "branch", 6910259SAndrew.Bardsley@arm.com params.executeBranchDelay), 7010259SAndrew.Bardsley@arm.com execute(cpu.name() + ".execute", cpu, params, 7110259SAndrew.Bardsley@arm.com dToE.output(), eToF1.input()), 7210259SAndrew.Bardsley@arm.com decode(cpu.name() + ".decode", cpu, params, 7310259SAndrew.Bardsley@arm.com f2ToD.output(), dToE.input(), execute.inputBuffer), 7410259SAndrew.Bardsley@arm.com fetch2(cpu.name() + ".fetch2", cpu, params, 7510259SAndrew.Bardsley@arm.com f1ToF2.output(), eToF1.output(), f2ToF1.input(), f2ToD.input(), 7610259SAndrew.Bardsley@arm.com decode.inputBuffer), 7710259SAndrew.Bardsley@arm.com fetch1(cpu.name() + ".fetch1", cpu, params, 7810259SAndrew.Bardsley@arm.com eToF1.output(), f1ToF2.input(), f2ToF1.output(), fetch2.inputBuffer), 7910259SAndrew.Bardsley@arm.com activityRecorder(cpu.name() + ".activity", Num_StageId, 8010259SAndrew.Bardsley@arm.com /* The max depth of inter-stage FIFOs */ 8110259SAndrew.Bardsley@arm.com std::max(params.fetch1ToFetch2ForwardDelay, 8210259SAndrew.Bardsley@arm.com std::max(params.fetch2ToDecodeForwardDelay, 8310259SAndrew.Bardsley@arm.com std::max(params.decodeToExecuteForwardDelay, 8410259SAndrew.Bardsley@arm.com params.executeBranchDelay)))), 8510259SAndrew.Bardsley@arm.com needToSignalDrained(false) 8610259SAndrew.Bardsley@arm.com{ 8710259SAndrew.Bardsley@arm.com if (params.fetch1ToFetch2ForwardDelay < 1) { 8810259SAndrew.Bardsley@arm.com fatal("%s: fetch1ToFetch2ForwardDelay must be >= 1 (%d)\n", 8910259SAndrew.Bardsley@arm.com cpu.name(), params.fetch1ToFetch2ForwardDelay); 9010259SAndrew.Bardsley@arm.com } 9110259SAndrew.Bardsley@arm.com 9210259SAndrew.Bardsley@arm.com if (params.fetch2ToDecodeForwardDelay < 1) { 9310259SAndrew.Bardsley@arm.com fatal("%s: fetch2ToDecodeForwardDelay must be >= 1 (%d)\n", 9410259SAndrew.Bardsley@arm.com cpu.name(), params.fetch2ToDecodeForwardDelay); 9510259SAndrew.Bardsley@arm.com } 9610259SAndrew.Bardsley@arm.com 9710259SAndrew.Bardsley@arm.com if (params.decodeToExecuteForwardDelay < 1) { 9810259SAndrew.Bardsley@arm.com fatal("%s: decodeToExecuteForwardDelay must be >= 1 (%d)\n", 9910259SAndrew.Bardsley@arm.com cpu.name(), params.decodeToExecuteForwardDelay); 10010259SAndrew.Bardsley@arm.com } 10110259SAndrew.Bardsley@arm.com 10210259SAndrew.Bardsley@arm.com if (params.executeBranchDelay < 1) { 10310259SAndrew.Bardsley@arm.com fatal("%s: executeBranchDelay must be >= 1\n", 10410259SAndrew.Bardsley@arm.com cpu.name(), params.executeBranchDelay); 10510259SAndrew.Bardsley@arm.com } 10610259SAndrew.Bardsley@arm.com} 10710259SAndrew.Bardsley@arm.com 10810259SAndrew.Bardsley@arm.comvoid 10912324Sdavid.guillen@arm.comPipeline::regStats() 11012324Sdavid.guillen@arm.com{ 11112324Sdavid.guillen@arm.com Ticked::regStats(); 11212324Sdavid.guillen@arm.com 11312324Sdavid.guillen@arm.com fetch2.regStats(); 11412324Sdavid.guillen@arm.com} 11512324Sdavid.guillen@arm.com 11612324Sdavid.guillen@arm.comvoid 11710259SAndrew.Bardsley@arm.comPipeline::minorTrace() const 11810259SAndrew.Bardsley@arm.com{ 11910259SAndrew.Bardsley@arm.com fetch1.minorTrace(); 12010259SAndrew.Bardsley@arm.com f1ToF2.minorTrace(); 12110259SAndrew.Bardsley@arm.com f2ToF1.minorTrace(); 12210259SAndrew.Bardsley@arm.com fetch2.minorTrace(); 12310259SAndrew.Bardsley@arm.com f2ToD.minorTrace(); 12410259SAndrew.Bardsley@arm.com decode.minorTrace(); 12510259SAndrew.Bardsley@arm.com dToE.minorTrace(); 12610259SAndrew.Bardsley@arm.com execute.minorTrace(); 12710259SAndrew.Bardsley@arm.com eToF1.minorTrace(); 12810259SAndrew.Bardsley@arm.com activityRecorder.minorTrace(); 12910259SAndrew.Bardsley@arm.com} 13010259SAndrew.Bardsley@arm.com 13110259SAndrew.Bardsley@arm.comvoid 13210259SAndrew.Bardsley@arm.comPipeline::evaluate() 13310259SAndrew.Bardsley@arm.com{ 13410259SAndrew.Bardsley@arm.com /* Note that it's important to evaluate the stages in order to allow 13510259SAndrew.Bardsley@arm.com * 'immediate', 0-time-offset TimeBuffer activity to be visible from 13610259SAndrew.Bardsley@arm.com * later stages to earlier ones in the same cycle */ 13710259SAndrew.Bardsley@arm.com execute.evaluate(); 13810259SAndrew.Bardsley@arm.com decode.evaluate(); 13910259SAndrew.Bardsley@arm.com fetch2.evaluate(); 14010259SAndrew.Bardsley@arm.com fetch1.evaluate(); 14110259SAndrew.Bardsley@arm.com 14210259SAndrew.Bardsley@arm.com if (DTRACE(MinorTrace)) 14310259SAndrew.Bardsley@arm.com minorTrace(); 14410259SAndrew.Bardsley@arm.com 14510259SAndrew.Bardsley@arm.com /* Update the time buffers after the stages */ 14610259SAndrew.Bardsley@arm.com f1ToF2.evaluate(); 14710259SAndrew.Bardsley@arm.com f2ToF1.evaluate(); 14810259SAndrew.Bardsley@arm.com f2ToD.evaluate(); 14910259SAndrew.Bardsley@arm.com dToE.evaluate(); 15010259SAndrew.Bardsley@arm.com eToF1.evaluate(); 15110259SAndrew.Bardsley@arm.com 15210259SAndrew.Bardsley@arm.com /* The activity recorder must be be called after all the stages and 15310259SAndrew.Bardsley@arm.com * before the idler (which acts on the advice of the activity recorder */ 15410259SAndrew.Bardsley@arm.com activityRecorder.evaluate(); 15510259SAndrew.Bardsley@arm.com 15610259SAndrew.Bardsley@arm.com if (allow_idling) { 15710259SAndrew.Bardsley@arm.com /* Become idle if we can but are not draining */ 15810259SAndrew.Bardsley@arm.com if (!activityRecorder.active() && !needToSignalDrained) { 15910259SAndrew.Bardsley@arm.com DPRINTF(Quiesce, "Suspending as the processor is idle\n"); 16010259SAndrew.Bardsley@arm.com stop(); 16110259SAndrew.Bardsley@arm.com } 16210259SAndrew.Bardsley@arm.com 16310259SAndrew.Bardsley@arm.com /* Deactivate all stages. Note that the stages *could* 16410259SAndrew.Bardsley@arm.com * activate and deactivate themselves but that's fraught 16510259SAndrew.Bardsley@arm.com * with additional difficulty. 16610259SAndrew.Bardsley@arm.com * As organised herre */ 16710259SAndrew.Bardsley@arm.com activityRecorder.deactivateStage(Pipeline::CPUStageId); 16810259SAndrew.Bardsley@arm.com activityRecorder.deactivateStage(Pipeline::Fetch1StageId); 16910259SAndrew.Bardsley@arm.com activityRecorder.deactivateStage(Pipeline::Fetch2StageId); 17010259SAndrew.Bardsley@arm.com activityRecorder.deactivateStage(Pipeline::DecodeStageId); 17110259SAndrew.Bardsley@arm.com activityRecorder.deactivateStage(Pipeline::ExecuteStageId); 17210259SAndrew.Bardsley@arm.com } 17310259SAndrew.Bardsley@arm.com 17410259SAndrew.Bardsley@arm.com if (needToSignalDrained) /* Must be draining */ 17510259SAndrew.Bardsley@arm.com { 17610259SAndrew.Bardsley@arm.com DPRINTF(Drain, "Still draining\n"); 17710259SAndrew.Bardsley@arm.com if (isDrained()) { 17810259SAndrew.Bardsley@arm.com DPRINTF(Drain, "Signalling end of draining\n"); 17910259SAndrew.Bardsley@arm.com cpu.signalDrainDone(); 18010259SAndrew.Bardsley@arm.com needToSignalDrained = false; 18110259SAndrew.Bardsley@arm.com stop(); 18210259SAndrew.Bardsley@arm.com } 18310259SAndrew.Bardsley@arm.com } 18410259SAndrew.Bardsley@arm.com} 18510259SAndrew.Bardsley@arm.com 18610259SAndrew.Bardsley@arm.comMinorCPU::MinorCPUPort & 18710259SAndrew.Bardsley@arm.comPipeline::getInstPort() 18810259SAndrew.Bardsley@arm.com{ 18910259SAndrew.Bardsley@arm.com return fetch1.getIcachePort(); 19010259SAndrew.Bardsley@arm.com} 19110259SAndrew.Bardsley@arm.com 19210259SAndrew.Bardsley@arm.comMinorCPU::MinorCPUPort & 19310259SAndrew.Bardsley@arm.comPipeline::getDataPort() 19410259SAndrew.Bardsley@arm.com{ 19510259SAndrew.Bardsley@arm.com return execute.getDcachePort(); 19610259SAndrew.Bardsley@arm.com} 19710259SAndrew.Bardsley@arm.com 19810259SAndrew.Bardsley@arm.comvoid 19911567Smitch.hayenga@arm.comPipeline::wakeupFetch(ThreadID tid) 20010259SAndrew.Bardsley@arm.com{ 20111567Smitch.hayenga@arm.com fetch1.wakeupFetch(tid); 20210259SAndrew.Bardsley@arm.com} 20310259SAndrew.Bardsley@arm.com 20410913Sandreas.sandberg@arm.combool 20510913Sandreas.sandberg@arm.comPipeline::drain() 20610259SAndrew.Bardsley@arm.com{ 20710259SAndrew.Bardsley@arm.com DPRINTF(MinorCPU, "Draining pipeline by halting inst fetches. " 20810259SAndrew.Bardsley@arm.com " Execution should drain naturally\n"); 20910259SAndrew.Bardsley@arm.com 21010259SAndrew.Bardsley@arm.com execute.drain(); 21110259SAndrew.Bardsley@arm.com 21210259SAndrew.Bardsley@arm.com /* Make sure that needToSignalDrained isn't accidentally set if we 21310259SAndrew.Bardsley@arm.com * are 'pre-drained' */ 21410259SAndrew.Bardsley@arm.com bool drained = isDrained(); 21510259SAndrew.Bardsley@arm.com needToSignalDrained = !drained; 21610259SAndrew.Bardsley@arm.com 21710913Sandreas.sandberg@arm.com return drained; 21810259SAndrew.Bardsley@arm.com} 21910259SAndrew.Bardsley@arm.com 22010259SAndrew.Bardsley@arm.comvoid 22110259SAndrew.Bardsley@arm.comPipeline::drainResume() 22210259SAndrew.Bardsley@arm.com{ 22310259SAndrew.Bardsley@arm.com DPRINTF(Drain, "Drain resume\n"); 22411567Smitch.hayenga@arm.com 22511567Smitch.hayenga@arm.com for (ThreadID tid = 0; tid < cpu.numThreads; tid++) { 22611567Smitch.hayenga@arm.com fetch1.wakeupFetch(tid); 22711567Smitch.hayenga@arm.com } 22811567Smitch.hayenga@arm.com 22910259SAndrew.Bardsley@arm.com execute.drainResume(); 23010259SAndrew.Bardsley@arm.com} 23110259SAndrew.Bardsley@arm.com 23210259SAndrew.Bardsley@arm.combool 23310259SAndrew.Bardsley@arm.comPipeline::isDrained() 23410259SAndrew.Bardsley@arm.com{ 23510259SAndrew.Bardsley@arm.com bool fetch1_drained = fetch1.isDrained(); 23610259SAndrew.Bardsley@arm.com bool fetch2_drained = fetch2.isDrained(); 23710259SAndrew.Bardsley@arm.com bool decode_drained = decode.isDrained(); 23810259SAndrew.Bardsley@arm.com bool execute_drained = execute.isDrained(); 23910259SAndrew.Bardsley@arm.com 24010259SAndrew.Bardsley@arm.com bool f1_to_f2_drained = f1ToF2.empty(); 24110259SAndrew.Bardsley@arm.com bool f2_to_f1_drained = f2ToF1.empty(); 24210259SAndrew.Bardsley@arm.com bool f2_to_d_drained = f2ToD.empty(); 24310259SAndrew.Bardsley@arm.com bool d_to_e_drained = dToE.empty(); 24410259SAndrew.Bardsley@arm.com 24510259SAndrew.Bardsley@arm.com bool ret = fetch1_drained && fetch2_drained && 24610259SAndrew.Bardsley@arm.com decode_drained && execute_drained && 24710259SAndrew.Bardsley@arm.com f1_to_f2_drained && f2_to_f1_drained && 24810259SAndrew.Bardsley@arm.com f2_to_d_drained && d_to_e_drained; 24910259SAndrew.Bardsley@arm.com 25010259SAndrew.Bardsley@arm.com DPRINTF(MinorCPU, "Pipeline undrained stages state:%s%s%s%s%s%s%s%s\n", 25110259SAndrew.Bardsley@arm.com (fetch1_drained ? "" : " Fetch1"), 25210259SAndrew.Bardsley@arm.com (fetch2_drained ? "" : " Fetch2"), 25310259SAndrew.Bardsley@arm.com (decode_drained ? "" : " Decode"), 25410259SAndrew.Bardsley@arm.com (execute_drained ? "" : " Execute"), 25510259SAndrew.Bardsley@arm.com (f1_to_f2_drained ? "" : " F1->F2"), 25610259SAndrew.Bardsley@arm.com (f2_to_f1_drained ? "" : " F2->F1"), 25710259SAndrew.Bardsley@arm.com (f2_to_d_drained ? "" : " F2->D"), 25810259SAndrew.Bardsley@arm.com (d_to_e_drained ? "" : " D->E") 25910259SAndrew.Bardsley@arm.com ); 26010259SAndrew.Bardsley@arm.com 26110259SAndrew.Bardsley@arm.com return ret; 26210259SAndrew.Bardsley@arm.com} 26310259SAndrew.Bardsley@arm.com 26410259SAndrew.Bardsley@arm.com} 265