1/* 2 * Copyright (c) 2013-2014 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Andrew Bardsley 38 */ 39 40#include "cpu/minor/pipeline.hh" 41 42#include <algorithm> 43 44#include "cpu/minor/decode.hh" 45#include "cpu/minor/execute.hh" 46#include "cpu/minor/fetch1.hh" 47#include "cpu/minor/fetch2.hh" 48#include "debug/Drain.hh" 49#include "debug/MinorCPU.hh" 50#include "debug/MinorTrace.hh" 51#include "debug/Quiesce.hh" 52 53namespace Minor 54{ 55 56Pipeline::Pipeline(MinorCPU &cpu_, MinorCPUParams ¶ms) : 57 Ticked(cpu_, &(cpu_.BaseCPU::numCycles)), 58 cpu(cpu_), 59 allow_idling(params.enableIdling), 60 f1ToF2(cpu.name() + ".f1ToF2", "lines", 61 params.fetch1ToFetch2ForwardDelay), 62 f2ToF1(cpu.name() + ".f2ToF1", "prediction", 63 params.fetch1ToFetch2BackwardDelay, true), 64 f2ToD(cpu.name() + ".f2ToD", "insts", 65 params.fetch2ToDecodeForwardDelay), 66 dToE(cpu.name() + ".dToE", "insts", 67 params.decodeToExecuteForwardDelay), 68 eToF1(cpu.name() + ".eToF1", "branch", 69 params.executeBranchDelay), 70 execute(cpu.name() + ".execute", cpu, params, 71 dToE.output(), eToF1.input()), 72 decode(cpu.name() + ".decode", cpu, params, 73 f2ToD.output(), dToE.input(), execute.inputBuffer), 74 fetch2(cpu.name() + ".fetch2", cpu, params, 75 f1ToF2.output(), eToF1.output(), f2ToF1.input(), f2ToD.input(), 76 decode.inputBuffer), 77 fetch1(cpu.name() + ".fetch1", cpu, params, 78 eToF1.output(), f1ToF2.input(), f2ToF1.output(), fetch2.inputBuffer), 79 activityRecorder(cpu.name() + ".activity", Num_StageId, 80 /* The max depth of inter-stage FIFOs */ 81 std::max(params.fetch1ToFetch2ForwardDelay, 82 std::max(params.fetch2ToDecodeForwardDelay, 83 std::max(params.decodeToExecuteForwardDelay, 84 params.executeBranchDelay)))), 85 needToSignalDrained(false) 86{ 87 if (params.fetch1ToFetch2ForwardDelay < 1) { 88 fatal("%s: fetch1ToFetch2ForwardDelay must be >= 1 (%d)\n", 89 cpu.name(), params.fetch1ToFetch2ForwardDelay); 90 } 91 92 if (params.fetch2ToDecodeForwardDelay < 1) { 93 fatal("%s: fetch2ToDecodeForwardDelay must be >= 1 (%d)\n", 94 cpu.name(), params.fetch2ToDecodeForwardDelay); 95 } 96 97 if (params.decodeToExecuteForwardDelay < 1) { 98 fatal("%s: decodeToExecuteForwardDelay must be >= 1 (%d)\n", 99 cpu.name(), params.decodeToExecuteForwardDelay); 100 } 101 102 if (params.executeBranchDelay < 1) { 103 fatal("%s: executeBranchDelay must be >= 1\n", 104 cpu.name(), params.executeBranchDelay); 105 } 106} 107 108void 109Pipeline::regStats() 110{ 111 Ticked::regStats(); 112 113 fetch2.regStats(); 114} 115 116void 117Pipeline::minorTrace() const 118{ 119 fetch1.minorTrace(); 120 f1ToF2.minorTrace(); 121 f2ToF1.minorTrace(); 122 fetch2.minorTrace(); 123 f2ToD.minorTrace(); 124 decode.minorTrace(); 125 dToE.minorTrace(); 126 execute.minorTrace(); 127 eToF1.minorTrace(); 128 activityRecorder.minorTrace(); 129} 130 131void 132Pipeline::evaluate() 133{ 134 /* Note that it's important to evaluate the stages in order to allow 135 * 'immediate', 0-time-offset TimeBuffer activity to be visible from 136 * later stages to earlier ones in the same cycle */ 137 execute.evaluate(); 138 decode.evaluate(); 139 fetch2.evaluate(); 140 fetch1.evaluate(); 141 142 if (DTRACE(MinorTrace)) 143 minorTrace(); 144 145 /* Update the time buffers after the stages */ 146 f1ToF2.evaluate(); 147 f2ToF1.evaluate(); 148 f2ToD.evaluate(); 149 dToE.evaluate(); 150 eToF1.evaluate(); 151 152 /* The activity recorder must be be called after all the stages and 153 * before the idler (which acts on the advice of the activity recorder */ 154 activityRecorder.evaluate(); 155 156 if (allow_idling) { 157 /* Become idle if we can but are not draining */ 158 if (!activityRecorder.active() && !needToSignalDrained) { 159 DPRINTF(Quiesce, "Suspending as the processor is idle\n"); 160 stop(); 161 } 162 163 /* Deactivate all stages. Note that the stages *could* 164 * activate and deactivate themselves but that's fraught 165 * with additional difficulty. 166 * As organised herre */ 167 activityRecorder.deactivateStage(Pipeline::CPUStageId); 168 activityRecorder.deactivateStage(Pipeline::Fetch1StageId); 169 activityRecorder.deactivateStage(Pipeline::Fetch2StageId); 170 activityRecorder.deactivateStage(Pipeline::DecodeStageId); 171 activityRecorder.deactivateStage(Pipeline::ExecuteStageId); 172 } 173 174 if (needToSignalDrained) /* Must be draining */ 175 { 176 DPRINTF(Drain, "Still draining\n"); 177 if (isDrained()) { 178 DPRINTF(Drain, "Signalling end of draining\n"); 179 cpu.signalDrainDone(); 180 needToSignalDrained = false; 181 stop(); 182 } 183 } 184} 185 186MinorCPU::MinorCPUPort & 187Pipeline::getInstPort() 188{ 189 return fetch1.getIcachePort(); 190} 191 192MinorCPU::MinorCPUPort & 193Pipeline::getDataPort() 194{ 195 return execute.getDcachePort(); 196} 197 198void 199Pipeline::wakeupFetch(ThreadID tid) 200{ 201 fetch1.wakeupFetch(tid); 202} 203 204bool 205Pipeline::drain() 206{ 207 DPRINTF(MinorCPU, "Draining pipeline by halting inst fetches. " 208 " Execution should drain naturally\n"); 209 210 execute.drain(); 211 212 /* Make sure that needToSignalDrained isn't accidentally set if we 213 * are 'pre-drained' */ 214 bool drained = isDrained(); 215 needToSignalDrained = !drained; 216 217 return drained; 218} 219 220void 221Pipeline::drainResume() 222{ 223 DPRINTF(Drain, "Drain resume\n"); 224 225 for (ThreadID tid = 0; tid < cpu.numThreads; tid++) { 226 fetch1.wakeupFetch(tid); 227 } 228 229 execute.drainResume(); 230} 231 232bool 233Pipeline::isDrained() 234{ 235 bool fetch1_drained = fetch1.isDrained(); 236 bool fetch2_drained = fetch2.isDrained(); 237 bool decode_drained = decode.isDrained(); 238 bool execute_drained = execute.isDrained(); 239 240 bool f1_to_f2_drained = f1ToF2.empty(); 241 bool f2_to_f1_drained = f2ToF1.empty(); 242 bool f2_to_d_drained = f2ToD.empty(); 243 bool d_to_e_drained = dToE.empty(); 244 245 bool ret = fetch1_drained && fetch2_drained && 246 decode_drained && execute_drained && 247 f1_to_f2_drained && f2_to_f1_drained && 248 f2_to_d_drained && d_to_e_drained; 249 250 DPRINTF(MinorCPU, "Pipeline undrained stages state:%s%s%s%s%s%s%s%s\n", 251 (fetch1_drained ? "" : " Fetch1"), 252 (fetch2_drained ? "" : " Fetch2"), 253 (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