pipeline.cc revision 10913
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 4010259SAndrew.Bardsley@arm.com#include <algorithm> 4110259SAndrew.Bardsley@arm.com 4210259SAndrew.Bardsley@arm.com#include "cpu/minor/decode.hh" 4310259SAndrew.Bardsley@arm.com#include "cpu/minor/execute.hh" 4410259SAndrew.Bardsley@arm.com#include "cpu/minor/fetch1.hh" 4510259SAndrew.Bardsley@arm.com#include "cpu/minor/fetch2.hh" 4610259SAndrew.Bardsley@arm.com#include "cpu/minor/pipeline.hh" 4710259SAndrew.Bardsley@arm.com#include "debug/Drain.hh" 4810259SAndrew.Bardsley@arm.com#include "debug/MinorCPU.hh" 4910259SAndrew.Bardsley@arm.com#include "debug/MinorTrace.hh" 5010259SAndrew.Bardsley@arm.com#include "debug/Quiesce.hh" 5110259SAndrew.Bardsley@arm.com 5210259SAndrew.Bardsley@arm.comnamespace Minor 5310259SAndrew.Bardsley@arm.com{ 5410259SAndrew.Bardsley@arm.com 5510259SAndrew.Bardsley@arm.comPipeline::Pipeline(MinorCPU &cpu_, MinorCPUParams ¶ms) : 5610259SAndrew.Bardsley@arm.com Ticked(cpu_, &(cpu_.BaseCPU::numCycles)), 5710259SAndrew.Bardsley@arm.com cpu(cpu_), 5810259SAndrew.Bardsley@arm.com allow_idling(params.enableIdling), 5910259SAndrew.Bardsley@arm.com f1ToF2(cpu.name() + ".f1ToF2", "lines", 6010259SAndrew.Bardsley@arm.com params.fetch1ToFetch2ForwardDelay), 6110259SAndrew.Bardsley@arm.com f2ToF1(cpu.name() + ".f2ToF1", "prediction", 6210259SAndrew.Bardsley@arm.com params.fetch1ToFetch2BackwardDelay, true), 6310259SAndrew.Bardsley@arm.com f2ToD(cpu.name() + ".f2ToD", "insts", 6410259SAndrew.Bardsley@arm.com params.fetch2ToDecodeForwardDelay), 6510259SAndrew.Bardsley@arm.com dToE(cpu.name() + ".dToE", "insts", 6610259SAndrew.Bardsley@arm.com params.decodeToExecuteForwardDelay), 6710259SAndrew.Bardsley@arm.com eToF1(cpu.name() + ".eToF1", "branch", 6810259SAndrew.Bardsley@arm.com params.executeBranchDelay), 6910259SAndrew.Bardsley@arm.com execute(cpu.name() + ".execute", cpu, params, 7010259SAndrew.Bardsley@arm.com dToE.output(), eToF1.input()), 7110259SAndrew.Bardsley@arm.com decode(cpu.name() + ".decode", cpu, params, 7210259SAndrew.Bardsley@arm.com f2ToD.output(), dToE.input(), execute.inputBuffer), 7310259SAndrew.Bardsley@arm.com fetch2(cpu.name() + ".fetch2", cpu, params, 7410259SAndrew.Bardsley@arm.com f1ToF2.output(), eToF1.output(), f2ToF1.input(), f2ToD.input(), 7510259SAndrew.Bardsley@arm.com decode.inputBuffer), 7610259SAndrew.Bardsley@arm.com fetch1(cpu.name() + ".fetch1", cpu, params, 7710259SAndrew.Bardsley@arm.com eToF1.output(), f1ToF2.input(), f2ToF1.output(), fetch2.inputBuffer), 7810259SAndrew.Bardsley@arm.com activityRecorder(cpu.name() + ".activity", Num_StageId, 7910259SAndrew.Bardsley@arm.com /* The max depth of inter-stage FIFOs */ 8010259SAndrew.Bardsley@arm.com std::max(params.fetch1ToFetch2ForwardDelay, 8110259SAndrew.Bardsley@arm.com std::max(params.fetch2ToDecodeForwardDelay, 8210259SAndrew.Bardsley@arm.com std::max(params.decodeToExecuteForwardDelay, 8310259SAndrew.Bardsley@arm.com params.executeBranchDelay)))), 8410259SAndrew.Bardsley@arm.com needToSignalDrained(false) 8510259SAndrew.Bardsley@arm.com{ 8610259SAndrew.Bardsley@arm.com if (params.fetch1ToFetch2ForwardDelay < 1) { 8710259SAndrew.Bardsley@arm.com fatal("%s: fetch1ToFetch2ForwardDelay must be >= 1 (%d)\n", 8810259SAndrew.Bardsley@arm.com cpu.name(), params.fetch1ToFetch2ForwardDelay); 8910259SAndrew.Bardsley@arm.com } 9010259SAndrew.Bardsley@arm.com 9110259SAndrew.Bardsley@arm.com if (params.fetch2ToDecodeForwardDelay < 1) { 9210259SAndrew.Bardsley@arm.com fatal("%s: fetch2ToDecodeForwardDelay must be >= 1 (%d)\n", 9310259SAndrew.Bardsley@arm.com cpu.name(), params.fetch2ToDecodeForwardDelay); 9410259SAndrew.Bardsley@arm.com } 9510259SAndrew.Bardsley@arm.com 9610259SAndrew.Bardsley@arm.com if (params.decodeToExecuteForwardDelay < 1) { 9710259SAndrew.Bardsley@arm.com fatal("%s: decodeToExecuteForwardDelay must be >= 1 (%d)\n", 9810259SAndrew.Bardsley@arm.com cpu.name(), params.decodeToExecuteForwardDelay); 9910259SAndrew.Bardsley@arm.com } 10010259SAndrew.Bardsley@arm.com 10110259SAndrew.Bardsley@arm.com if (params.executeBranchDelay < 1) { 10210259SAndrew.Bardsley@arm.com fatal("%s: executeBranchDelay must be >= 1\n", 10310259SAndrew.Bardsley@arm.com cpu.name(), params.executeBranchDelay); 10410259SAndrew.Bardsley@arm.com } 10510259SAndrew.Bardsley@arm.com} 10610259SAndrew.Bardsley@arm.com 10710259SAndrew.Bardsley@arm.comvoid 10810259SAndrew.Bardsley@arm.comPipeline::minorTrace() const 10910259SAndrew.Bardsley@arm.com{ 11010259SAndrew.Bardsley@arm.com fetch1.minorTrace(); 11110259SAndrew.Bardsley@arm.com f1ToF2.minorTrace(); 11210259SAndrew.Bardsley@arm.com f2ToF1.minorTrace(); 11310259SAndrew.Bardsley@arm.com fetch2.minorTrace(); 11410259SAndrew.Bardsley@arm.com f2ToD.minorTrace(); 11510259SAndrew.Bardsley@arm.com decode.minorTrace(); 11610259SAndrew.Bardsley@arm.com dToE.minorTrace(); 11710259SAndrew.Bardsley@arm.com execute.minorTrace(); 11810259SAndrew.Bardsley@arm.com eToF1.minorTrace(); 11910259SAndrew.Bardsley@arm.com activityRecorder.minorTrace(); 12010259SAndrew.Bardsley@arm.com} 12110259SAndrew.Bardsley@arm.com 12210259SAndrew.Bardsley@arm.comvoid 12310259SAndrew.Bardsley@arm.comPipeline::evaluate() 12410259SAndrew.Bardsley@arm.com{ 12510259SAndrew.Bardsley@arm.com /* Note that it's important to evaluate the stages in order to allow 12610259SAndrew.Bardsley@arm.com * 'immediate', 0-time-offset TimeBuffer activity to be visible from 12710259SAndrew.Bardsley@arm.com * later stages to earlier ones in the same cycle */ 12810259SAndrew.Bardsley@arm.com execute.evaluate(); 12910259SAndrew.Bardsley@arm.com decode.evaluate(); 13010259SAndrew.Bardsley@arm.com fetch2.evaluate(); 13110259SAndrew.Bardsley@arm.com fetch1.evaluate(); 13210259SAndrew.Bardsley@arm.com 13310259SAndrew.Bardsley@arm.com if (DTRACE(MinorTrace)) 13410259SAndrew.Bardsley@arm.com minorTrace(); 13510259SAndrew.Bardsley@arm.com 13610259SAndrew.Bardsley@arm.com /* Update the time buffers after the stages */ 13710259SAndrew.Bardsley@arm.com f1ToF2.evaluate(); 13810259SAndrew.Bardsley@arm.com f2ToF1.evaluate(); 13910259SAndrew.Bardsley@arm.com f2ToD.evaluate(); 14010259SAndrew.Bardsley@arm.com dToE.evaluate(); 14110259SAndrew.Bardsley@arm.com eToF1.evaluate(); 14210259SAndrew.Bardsley@arm.com 14310259SAndrew.Bardsley@arm.com /* The activity recorder must be be called after all the stages and 14410259SAndrew.Bardsley@arm.com * before the idler (which acts on the advice of the activity recorder */ 14510259SAndrew.Bardsley@arm.com activityRecorder.evaluate(); 14610259SAndrew.Bardsley@arm.com 14710259SAndrew.Bardsley@arm.com if (allow_idling) { 14810259SAndrew.Bardsley@arm.com /* Become idle if we can but are not draining */ 14910259SAndrew.Bardsley@arm.com if (!activityRecorder.active() && !needToSignalDrained) { 15010259SAndrew.Bardsley@arm.com DPRINTF(Quiesce, "Suspending as the processor is idle\n"); 15110259SAndrew.Bardsley@arm.com stop(); 15210259SAndrew.Bardsley@arm.com } 15310259SAndrew.Bardsley@arm.com 15410259SAndrew.Bardsley@arm.com /* Deactivate all stages. Note that the stages *could* 15510259SAndrew.Bardsley@arm.com * activate and deactivate themselves but that's fraught 15610259SAndrew.Bardsley@arm.com * with additional difficulty. 15710259SAndrew.Bardsley@arm.com * As organised herre */ 15810259SAndrew.Bardsley@arm.com activityRecorder.deactivateStage(Pipeline::CPUStageId); 15910259SAndrew.Bardsley@arm.com activityRecorder.deactivateStage(Pipeline::Fetch1StageId); 16010259SAndrew.Bardsley@arm.com activityRecorder.deactivateStage(Pipeline::Fetch2StageId); 16110259SAndrew.Bardsley@arm.com activityRecorder.deactivateStage(Pipeline::DecodeStageId); 16210259SAndrew.Bardsley@arm.com activityRecorder.deactivateStage(Pipeline::ExecuteStageId); 16310259SAndrew.Bardsley@arm.com } 16410259SAndrew.Bardsley@arm.com 16510259SAndrew.Bardsley@arm.com if (needToSignalDrained) /* Must be draining */ 16610259SAndrew.Bardsley@arm.com { 16710259SAndrew.Bardsley@arm.com DPRINTF(Drain, "Still draining\n"); 16810259SAndrew.Bardsley@arm.com if (isDrained()) { 16910259SAndrew.Bardsley@arm.com DPRINTF(Drain, "Signalling end of draining\n"); 17010259SAndrew.Bardsley@arm.com cpu.signalDrainDone(); 17110259SAndrew.Bardsley@arm.com needToSignalDrained = false; 17210259SAndrew.Bardsley@arm.com stop(); 17310259SAndrew.Bardsley@arm.com } 17410259SAndrew.Bardsley@arm.com } 17510259SAndrew.Bardsley@arm.com} 17610259SAndrew.Bardsley@arm.com 17710259SAndrew.Bardsley@arm.comMinorCPU::MinorCPUPort & 17810259SAndrew.Bardsley@arm.comPipeline::getInstPort() 17910259SAndrew.Bardsley@arm.com{ 18010259SAndrew.Bardsley@arm.com return fetch1.getIcachePort(); 18110259SAndrew.Bardsley@arm.com} 18210259SAndrew.Bardsley@arm.com 18310259SAndrew.Bardsley@arm.comMinorCPU::MinorCPUPort & 18410259SAndrew.Bardsley@arm.comPipeline::getDataPort() 18510259SAndrew.Bardsley@arm.com{ 18610259SAndrew.Bardsley@arm.com return execute.getDcachePort(); 18710259SAndrew.Bardsley@arm.com} 18810259SAndrew.Bardsley@arm.com 18910259SAndrew.Bardsley@arm.comvoid 19010259SAndrew.Bardsley@arm.comPipeline::wakeupFetch() 19110259SAndrew.Bardsley@arm.com{ 19210259SAndrew.Bardsley@arm.com execute.wakeupFetch(); 19310259SAndrew.Bardsley@arm.com} 19410259SAndrew.Bardsley@arm.com 19510913Sandreas.sandberg@arm.combool 19610913Sandreas.sandberg@arm.comPipeline::drain() 19710259SAndrew.Bardsley@arm.com{ 19810259SAndrew.Bardsley@arm.com DPRINTF(MinorCPU, "Draining pipeline by halting inst fetches. " 19910259SAndrew.Bardsley@arm.com " Execution should drain naturally\n"); 20010259SAndrew.Bardsley@arm.com 20110259SAndrew.Bardsley@arm.com execute.drain(); 20210259SAndrew.Bardsley@arm.com 20310259SAndrew.Bardsley@arm.com /* Make sure that needToSignalDrained isn't accidentally set if we 20410259SAndrew.Bardsley@arm.com * are 'pre-drained' */ 20510259SAndrew.Bardsley@arm.com bool drained = isDrained(); 20610259SAndrew.Bardsley@arm.com needToSignalDrained = !drained; 20710259SAndrew.Bardsley@arm.com 20810913Sandreas.sandberg@arm.com return drained; 20910259SAndrew.Bardsley@arm.com} 21010259SAndrew.Bardsley@arm.com 21110259SAndrew.Bardsley@arm.comvoid 21210259SAndrew.Bardsley@arm.comPipeline::drainResume() 21310259SAndrew.Bardsley@arm.com{ 21410259SAndrew.Bardsley@arm.com DPRINTF(Drain, "Drain resume\n"); 21510259SAndrew.Bardsley@arm.com execute.drainResume(); 21610259SAndrew.Bardsley@arm.com} 21710259SAndrew.Bardsley@arm.com 21810259SAndrew.Bardsley@arm.combool 21910259SAndrew.Bardsley@arm.comPipeline::isDrained() 22010259SAndrew.Bardsley@arm.com{ 22110259SAndrew.Bardsley@arm.com bool fetch1_drained = fetch1.isDrained(); 22210259SAndrew.Bardsley@arm.com bool fetch2_drained = fetch2.isDrained(); 22310259SAndrew.Bardsley@arm.com bool decode_drained = decode.isDrained(); 22410259SAndrew.Bardsley@arm.com bool execute_drained = execute.isDrained(); 22510259SAndrew.Bardsley@arm.com 22610259SAndrew.Bardsley@arm.com bool f1_to_f2_drained = f1ToF2.empty(); 22710259SAndrew.Bardsley@arm.com bool f2_to_f1_drained = f2ToF1.empty(); 22810259SAndrew.Bardsley@arm.com bool f2_to_d_drained = f2ToD.empty(); 22910259SAndrew.Bardsley@arm.com bool d_to_e_drained = dToE.empty(); 23010259SAndrew.Bardsley@arm.com 23110259SAndrew.Bardsley@arm.com bool ret = fetch1_drained && fetch2_drained && 23210259SAndrew.Bardsley@arm.com decode_drained && execute_drained && 23310259SAndrew.Bardsley@arm.com f1_to_f2_drained && f2_to_f1_drained && 23410259SAndrew.Bardsley@arm.com f2_to_d_drained && d_to_e_drained; 23510259SAndrew.Bardsley@arm.com 23610259SAndrew.Bardsley@arm.com DPRINTF(MinorCPU, "Pipeline undrained stages state:%s%s%s%s%s%s%s%s\n", 23710259SAndrew.Bardsley@arm.com (fetch1_drained ? "" : " Fetch1"), 23810259SAndrew.Bardsley@arm.com (fetch2_drained ? "" : " Fetch2"), 23910259SAndrew.Bardsley@arm.com (decode_drained ? "" : " Decode"), 24010259SAndrew.Bardsley@arm.com (execute_drained ? "" : " Execute"), 24110259SAndrew.Bardsley@arm.com (f1_to_f2_drained ? "" : " F1->F2"), 24210259SAndrew.Bardsley@arm.com (f2_to_f1_drained ? "" : " F2->F1"), 24310259SAndrew.Bardsley@arm.com (f2_to_d_drained ? "" : " F2->D"), 24410259SAndrew.Bardsley@arm.com (d_to_e_drained ? "" : " D->E") 24510259SAndrew.Bardsley@arm.com ); 24610259SAndrew.Bardsley@arm.com 24710259SAndrew.Bardsley@arm.com return ret; 24810259SAndrew.Bardsley@arm.com} 24910259SAndrew.Bardsley@arm.com 25010259SAndrew.Bardsley@arm.com} 251