pipeline.cc revision 13966:3189413c5894
12SN/A/* 210911Sandreas.sandberg@arm.com * Copyright (c) 2013-2014 ARM Limited 310911Sandreas.sandberg@arm.com * All rights reserved 410911Sandreas.sandberg@arm.com * 510911Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall 610911Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual 710911Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating 810911Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software 910911Sandreas.sandberg@arm.com * licensed hereunder. You may use the software subject to the license 1010911Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated 1110911Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software, 1210911Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form. 1310911Sandreas.sandberg@arm.com * 141762SN/A * Redistribution and use in source and binary forms, with or without 157534Ssteve.reinhardt@amd.com * modification, are permitted provided that the following conditions are 162SN/A * met: redistributions of source code must retain the above copyright 172SN/A * notice, this list of conditions and the following disclaimer; 182SN/A * redistributions in binary form must reproduce the above copyright 192SN/A * notice, this list of conditions and the following disclaimer in the 202SN/A * documentation and/or other materials provided with the distribution; 212SN/A * neither the name of the copyright holders nor the names of its 222SN/A * contributors may be used to endorse or promote products derived from 232SN/A * this software without specific prior written permission. 242SN/A * 252SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 262SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 272SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 282SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 302SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 312SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 322SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 332SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 342SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 352SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 362SN/A * 372SN/A * Authors: Andrew Bardsley 382SN/A */ 392SN/A 402665Ssaidi@eecs.umich.edu#include "cpu/minor/pipeline.hh" 412665Ssaidi@eecs.umich.edu 422665Ssaidi@eecs.umich.edu#include <algorithm> 432SN/A 442SN/A#include "cpu/minor/decode.hh" 452SN/A#include "cpu/minor/execute.hh" 462SN/A#include "cpu/minor/fetch1.hh" 472SN/A#include "cpu/minor/fetch2.hh" 482SN/A#include "debug/Drain.hh" 492SN/A#include "debug/MinorCPU.hh" 502SN/A#include "debug/MinorTrace.hh" 512SN/A#include "debug/Quiesce.hh" 525491Sgblack@eecs.umich.edu 535491Sgblack@eecs.umich.edunamespace Minor 542SN/A{ 555491Sgblack@eecs.umich.edu 562SN/APipeline::Pipeline(MinorCPU &cpu_, MinorCPUParams ¶ms) : 572SN/A Ticked(cpu_, &(cpu_.BaseCPU::numCycles)), 588737Skoansin.tan@gmail.com cpu(cpu_), 594762Snate@binkert.org allow_idling(params.enableIdling), 609342SAndreas.Sandberg@arm.com f1ToF2(cpu.name() + ".f1ToF2", "lines", 619356Snilay@cs.wisc.edu params.fetch1ToFetch2ForwardDelay), 6256SN/A f2ToF1(cpu.name() + ".f2ToF1", "prediction", 632SN/A params.fetch1ToFetch2BackwardDelay, true), 642797Sktlim@umich.edu f2ToD(cpu.name() + ".f2ToD", "insts", 652797Sktlim@umich.edu params.fetch2ToDecodeForwardDelay), 6610023Smatt.horsnell@ARM.com dToE(cpu.name() + ".dToE", "insts", 679196SAndreas.Sandberg@arm.com params.decodeToExecuteForwardDelay), 682SN/A eToF1(cpu.name() + ".eToF1", "branch", 692SN/A params.executeBranchDelay), 702SN/A execute(cpu.name() + ".execute", cpu, params, 719196SAndreas.Sandberg@arm.com dToE.output(), eToF1.input()), 729196SAndreas.Sandberg@arm.com decode(cpu.name() + ".decode", cpu, params, 739196SAndreas.Sandberg@arm.com f2ToD.output(), dToE.input(), execute.inputBuffer), 749196SAndreas.Sandberg@arm.com fetch2(cpu.name() + ".fetch2", cpu, params, 759196SAndreas.Sandberg@arm.com f1ToF2.output(), eToF1.output(), f2ToF1.input(), f2ToD.input(), 769196SAndreas.Sandberg@arm.com decode.inputBuffer), 779196SAndreas.Sandberg@arm.com fetch1(cpu.name() + ".fetch1", cpu, params, 789196SAndreas.Sandberg@arm.com eToF1.output(), f1ToF2.input(), f2ToF1.output(), fetch2.inputBuffer), 799196SAndreas.Sandberg@arm.com activityRecorder(cpu.name() + ".activity", Num_StageId, 809196SAndreas.Sandberg@arm.com /* The max depth of inter-stage FIFOs */ 819196SAndreas.Sandberg@arm.com std::max(params.fetch1ToFetch2ForwardDelay, 829196SAndreas.Sandberg@arm.com std::max(params.fetch2ToDecodeForwardDelay, 839196SAndreas.Sandberg@arm.com std::max(params.decodeToExecuteForwardDelay, 849196SAndreas.Sandberg@arm.com params.executeBranchDelay)))), 859196SAndreas.Sandberg@arm.com needToSignalDrained(false) 869196SAndreas.Sandberg@arm.com{ 879196SAndreas.Sandberg@arm.com if (params.fetch1ToFetch2ForwardDelay < 1) { 889342SAndreas.Sandberg@arm.com fatal("%s: fetch1ToFetch2ForwardDelay must be >= 1 (%d)\n", 899196SAndreas.Sandberg@arm.com cpu.name(), params.fetch1ToFetch2ForwardDelay); 909196SAndreas.Sandberg@arm.com } 919196SAndreas.Sandberg@arm.com 929196SAndreas.Sandberg@arm.com if (params.fetch2ToDecodeForwardDelay < 1) { 939196SAndreas.Sandberg@arm.com fatal("%s: fetch2ToDecodeForwardDelay must be >= 1 (%d)\n", 949196SAndreas.Sandberg@arm.com cpu.name(), params.fetch2ToDecodeForwardDelay); 959196SAndreas.Sandberg@arm.com } 962SN/A 979342SAndreas.Sandberg@arm.com if (params.decodeToExecuteForwardDelay < 1) { 982SN/A fatal("%s: decodeToExecuteForwardDelay must be >= 1 (%d)\n", 992SN/A cpu.name(), params.decodeToExecuteForwardDelay); 1002SN/A } 1012SN/A 1029196SAndreas.Sandberg@arm.com if (params.executeBranchDelay < 1) { 1032SN/A fatal("%s: executeBranchDelay must be >= 1\n", 1042SN/A cpu.name(), params.executeBranchDelay); 10510023Smatt.horsnell@ARM.com } 10610023Smatt.horsnell@ARM.com} 10710023Smatt.horsnell@ARM.com 1084762Snate@binkert.orgvoid 1099196SAndreas.Sandberg@arm.comPipeline::regStats() 1104762Snate@binkert.org{ 1114762Snate@binkert.org Ticked::regStats(); 1122SN/A 1134762Snate@binkert.org fetch2.regStats(); 1144762Snate@binkert.org} 1154762Snate@binkert.org 11610422Sandreas.hansson@arm.comvoid 1172SN/APipeline::minorTrace() const 1185034Smilesck@eecs.umich.edu{ 1195034Smilesck@eecs.umich.edu fetch1.minorTrace(); 1201553SN/A f1ToF2.minorTrace(); 121265SN/A f2ToF1.minorTrace(); 1227532Ssteve.reinhardt@amd.com fetch2.minorTrace(); 1237532Ssteve.reinhardt@amd.com f2ToD.minorTrace(); 1247532Ssteve.reinhardt@amd.com decode.minorTrace(); 1257532Ssteve.reinhardt@amd.com dToE.minorTrace(); 1267532Ssteve.reinhardt@amd.com execute.minorTrace(); 1277532Ssteve.reinhardt@amd.com eToF1.minorTrace(); 128465SN/A activityRecorder.minorTrace(); 129465SN/A} 1307532Ssteve.reinhardt@amd.com 1317532Ssteve.reinhardt@amd.comvoid 1327532Ssteve.reinhardt@amd.comPipeline::evaluate() 1337532Ssteve.reinhardt@amd.com{ 1347532Ssteve.reinhardt@amd.com /* Note that it's important to evaluate the stages in order to allow 1357532Ssteve.reinhardt@amd.com * 'immediate', 0-time-offset TimeBuffer activity to be visible from 1367532Ssteve.reinhardt@amd.com * later stages to earlier ones in the same cycle */ 1377532Ssteve.reinhardt@amd.com execute.evaluate(); 1389196SAndreas.Sandberg@arm.com decode.evaluate(); 1399196SAndreas.Sandberg@arm.com fetch2.evaluate(); 1407532Ssteve.reinhardt@amd.com fetch1.evaluate(); 14110905Sandreas.sandberg@arm.com 1427532Ssteve.reinhardt@amd.com if (DTRACE(MinorTrace)) 1437532Ssteve.reinhardt@amd.com minorTrace(); 1447532Ssteve.reinhardt@amd.com 1457532Ssteve.reinhardt@amd.com /* Update the time buffers after the stages */ 1467532Ssteve.reinhardt@amd.com f1ToF2.evaluate(); 1477532Ssteve.reinhardt@amd.com f2ToF1.evaluate(); 1487532Ssteve.reinhardt@amd.com f2ToD.evaluate(); 1497532Ssteve.reinhardt@amd.com dToE.evaluate(); 1509196SAndreas.Sandberg@arm.com eToF1.evaluate(); 1519196SAndreas.Sandberg@arm.com 1529196SAndreas.Sandberg@arm.com /* The activity recorder must be be called after all the stages and 1532SN/A * before the idler (which acts on the advice of the activity recorder */ 1549196SAndreas.Sandberg@arm.com activityRecorder.evaluate(); 1559196SAndreas.Sandberg@arm.com 1569196SAndreas.Sandberg@arm.com if (allow_idling) { 1579196SAndreas.Sandberg@arm.com /* Become idle if we can but are not draining */ 158330SN/A if (!activityRecorder.active() && !needToSignalDrained) { 1592SN/A DPRINTF(Quiesce, "Suspending as the processor is idle\n"); 1607532Ssteve.reinhardt@amd.com stop(); 16110023Smatt.horsnell@ARM.com } 16210023Smatt.horsnell@ARM.com 16310023Smatt.horsnell@ARM.com /* Deactivate all stages. Note that the stages *could* 16410023Smatt.horsnell@ARM.com * activate and deactivate themselves but that's fraught 16510023Smatt.horsnell@ARM.com * with additional difficulty. 16610023Smatt.horsnell@ARM.com * As organised herre */ 16710023Smatt.horsnell@ARM.com activityRecorder.deactivateStage(Pipeline::CPUStageId); 16810023Smatt.horsnell@ARM.com activityRecorder.deactivateStage(Pipeline::Fetch1StageId); 16910023Smatt.horsnell@ARM.com activityRecorder.deactivateStage(Pipeline::Fetch2StageId); 17010023Smatt.horsnell@ARM.com activityRecorder.deactivateStage(Pipeline::DecodeStageId); 17110023Smatt.horsnell@ARM.com activityRecorder.deactivateStage(Pipeline::ExecuteStageId); 17210023Smatt.horsnell@ARM.com } 17310023Smatt.horsnell@ARM.com 17410023Smatt.horsnell@ARM.com if (needToSignalDrained) /* Must be draining */ 17510023Smatt.horsnell@ARM.com { 1767532Ssteve.reinhardt@amd.com DPRINTF(Drain, "Still draining\n"); 1777532Ssteve.reinhardt@amd.com if (isDrained()) { 1787823Ssteve.reinhardt@amd.com DPRINTF(Drain, "Signalling end of draining\n"); 1797532Ssteve.reinhardt@amd.com cpu.signalDrainDone(); 1807532Ssteve.reinhardt@amd.com needToSignalDrained = false; 1817492Ssteve.reinhardt@amd.com stop(); 182330SN/A } 1839196SAndreas.Sandberg@arm.com } 18410913Sandreas.sandberg@arm.com} 18510913Sandreas.sandberg@arm.com 1869342SAndreas.Sandberg@arm.comMinorCPU::MinorCPUPort & 18710913Sandreas.sandberg@arm.comPipeline::getInstPort() 1889342SAndreas.Sandberg@arm.com{ 18910911Sandreas.sandberg@arm.com return fetch1.getIcachePort(); 19010911Sandreas.sandberg@arm.com} 19110911Sandreas.sandberg@arm.com 19210911Sandreas.sandberg@arm.comMinorCPU::MinorCPUPort & 19310911Sandreas.sandberg@arm.comPipeline::getDataPort() 19410911Sandreas.sandberg@arm.com{ 19510911Sandreas.sandberg@arm.com return execute.getDcachePort(); 19610911Sandreas.sandberg@arm.com} 19710911Sandreas.sandberg@arm.com 19810911Sandreas.sandberg@arm.comvoid 19910911Sandreas.sandberg@arm.comPipeline::wakeupFetch(ThreadID tid) 20010911Sandreas.sandberg@arm.com{ 20110911Sandreas.sandberg@arm.com fetch1.wakeupFetch(tid); 20210911Sandreas.sandberg@arm.com} 20310911Sandreas.sandberg@arm.com 20410911Sandreas.sandberg@arm.combool 20510911Sandreas.sandberg@arm.comPipeline::drain() 20610911Sandreas.sandberg@arm.com{ 20710911Sandreas.sandberg@arm.com DPRINTF(MinorCPU, "Draining pipeline by halting inst fetches. " 20810911Sandreas.sandberg@arm.com " Execution should drain naturally\n"); 20910911Sandreas.sandberg@arm.com 21010911Sandreas.sandberg@arm.com execute.drain(); 21110905Sandreas.sandberg@arm.com 21210905Sandreas.sandberg@arm.com /* Make sure that needToSignalDrained isn't accidentally set if we 21310905Sandreas.sandberg@arm.com * are 'pre-drained' */ 21410905Sandreas.sandberg@arm.com bool drained = isDrained(); 2159342SAndreas.Sandberg@arm.com needToSignalDrained = !drained; 2169196SAndreas.Sandberg@arm.com 2179196SAndreas.Sandberg@arm.com return drained; 21810905Sandreas.sandberg@arm.com} 219938SN/A 2201031SN/Avoid 2211031SN/APipeline::drainResume() 2221031SN/A{ 2231031SN/A DPRINTF(Drain, "Drain resume\n"); 2241031SN/A 2251031SN/A for (ThreadID tid = 0; tid < cpu.numThreads; tid++) { 2265314Sstever@gmail.com fetch1.wakeupFetch(tid); 2275314Sstever@gmail.com } 2285315Sstever@gmail.com 2295314Sstever@gmail.com execute.drainResume(); 2305314Sstever@gmail.com} 2315314Sstever@gmail.com 2322SN/Abool 2332SN/APipeline::isDrained() 23411067Sandreas.sandberg@arm.com{ 23511067Sandreas.sandberg@arm.com bool fetch1_drained = fetch1.isDrained(); 23611067Sandreas.sandberg@arm.com bool fetch2_drained = fetch2.isDrained(); 23711067Sandreas.sandberg@arm.com bool decode_drained = decode.isDrained(); 23811067Sandreas.sandberg@arm.com bool execute_drained = execute.isDrained(); 23911067Sandreas.sandberg@arm.com 24011067Sandreas.sandberg@arm.com bool f1_to_f2_drained = f1ToF2.empty(); 24111067Sandreas.sandberg@arm.com bool f2_to_f1_drained = f2ToF1.empty(); 24211067Sandreas.sandberg@arm.com bool f2_to_d_drained = f2ToD.empty(); 24311067Sandreas.sandberg@arm.com bool d_to_e_drained = dToE.empty(); 24411067Sandreas.sandberg@arm.com 24511067Sandreas.sandberg@arm.com bool ret = fetch1_drained && fetch2_drained && 24611067Sandreas.sandberg@arm.com decode_drained && execute_drained && 24711067Sandreas.sandberg@arm.com f1_to_f2_drained && f2_to_f1_drained && 24811067Sandreas.sandberg@arm.com f2_to_d_drained && d_to_e_drained; 2499554Sandreas.hansson@arm.com 2509554Sandreas.hansson@arm.com DPRINTF(MinorCPU, "Pipeline undrained stages state:%s%s%s%s%s%s%s%s\n", 2519554Sandreas.hansson@arm.com (fetch1_drained ? "" : " Fetch1"), 2529554Sandreas.hansson@arm.com (fetch2_drained ? "" : " Fetch2"), 2532SN/A (decode_drained ? "" : " Decode"), 254 (execute_drained ? "" : " Execute"), 255 (f1_to_f2_drained ? "" : " F1->F2"), 256 (f2_to_f1_drained ? "" : " F2->F1"), 257 (f2_to_d_drained ? "" : " F2->D"), 258 (d_to_e_drained ? "" : " D->E") 259 ); 260 261 return ret; 262} 263 264} 265