fetch1.hh revision 11567
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/** 41 * @file 42 * 43 * Fetch1 is responsible for fetching "lines" from memory and passing 44 * them to Fetch2 45 */ 46 47#ifndef __CPU_MINOR_FETCH1_HH__ 48#define __CPU_MINOR_FETCH1_HH__ 49 50#include "cpu/minor/buffers.hh" 51#include "cpu/minor/cpu.hh" 52#include "cpu/minor/pipe_data.hh" 53#include "cpu/base.hh" 54#include "mem/packet.hh" 55 56namespace Minor 57{ 58 59/** A stage responsible for fetching "lines" from memory and passing 60 * them to Fetch2 */ 61class Fetch1 : public Named 62{ 63 protected: 64 /** Exposable fetch port */ 65 class IcachePort : public MinorCPU::MinorCPUPort 66 { 67 protected: 68 /** My owner */ 69 Fetch1 &fetch; 70 71 public: 72 IcachePort(std::string name, Fetch1 &fetch_, MinorCPU &cpu) : 73 MinorCPU::MinorCPUPort(name, cpu), fetch(fetch_) 74 { } 75 76 protected: 77 bool recvTimingResp(PacketPtr pkt) 78 { return fetch.recvTimingResp(pkt); } 79 80 void recvReqRetry() { fetch.recvReqRetry(); } 81 }; 82 83 /** Memory access queuing. 84 * 85 * A request can be submitted by pushing it onto the requests queue after 86 * issuing an ITLB lookup (state becomes InTranslation) with a 87 * FetchSenderState senderState containing the current lineSeqNum and 88 * stream/predictionSeqNum. 89 * 90 * Translated packets (state becomes Translation) are then passed to the 91 * memory system and the transfers queue (state becomes RequestIssuing). 92 * Retries are handled by leaving the packet on the requests queue and 93 * changing the state to IcacheNeedsRetry). 94 * 95 * Responses from the memory system alter the request object (state 96 * become Complete). Responses can be picked up from the head of the 97 * transfers queue to pass on to Fetch2. */ 98 99 /** Structure to hold SenderState info through 100 * translation and memory accesses. */ 101 class FetchRequest : 102 public BaseTLB::Translation, /* For TLB lookups */ 103 public Packet::SenderState /* For packing into a Packet */ 104 { 105 protected: 106 /** Owning fetch unit */ 107 Fetch1 &fetch; 108 109 public: 110 /** Progress of this request through address translation and 111 * memory */ 112 enum FetchRequestState 113 { 114 NotIssued, /* Just been made */ 115 InTranslation, /* Issued to ITLB, must wait for reqply */ 116 Translated, /* Translation complete */ 117 RequestIssuing, /* Issued to memory, must wait for response */ 118 Complete /* Complete. Either a fault, or a fetched line */ 119 }; 120 121 FetchRequestState state; 122 123 /** Identity of the line that this request will generate */ 124 InstId id; 125 126 /** FetchRequests carry packets while they're in the requests and 127 * transfers responses queues. When a Packet returns from the memory 128 * system, its request needs to have its packet updated as this may 129 * have changed in flight */ 130 PacketPtr packet; 131 132 /** The underlying request that this fetch represents */ 133 Request request; 134 135 /** PC to fixup with line address */ 136 TheISA::PCState pc; 137 138 /** Fill in a fault if one happens during fetch, check this by 139 * picking apart the response packet */ 140 Fault fault; 141 142 /** Make a packet to use with the memory transaction */ 143 void makePacket(); 144 145 /** Report interface */ 146 void reportData(std::ostream &os) const; 147 148 /** Is this line out of date with the current stream/prediction 149 * sequence and can it be discarded without orphaning in flight 150 * TLB lookups/memory accesses? */ 151 bool isDiscardable() const; 152 153 /** Is this a complete read line or fault */ 154 bool isComplete() const { return state == Complete; } 155 156 protected: 157 /** BaseTLB::Translation interface */ 158 159 /** Interface for ITLB responses. We can handle delay, so don't 160 * do anything */ 161 void markDelayed() { } 162 163 /** Interface for ITLB responses. Populates self and then passes 164 * the request on to the ports' handleTLBResponse member 165 * function */ 166 void finish(const Fault &fault_, RequestPtr request_, 167 ThreadContext *tc, BaseTLB::Mode mode); 168 169 public: 170 FetchRequest(Fetch1 &fetch_, InstId id_, TheISA::PCState pc_) : 171 SenderState(), 172 fetch(fetch_), 173 state(NotIssued), 174 id(id_), 175 packet(NULL), 176 request(), 177 pc(pc_), 178 fault(NoFault) 179 { } 180 181 ~FetchRequest(); 182 }; 183 184 typedef FetchRequest *FetchRequestPtr; 185 186 protected: 187 /** Construction-assigned data members */ 188 189 /** Pointer back to the containing CPU */ 190 MinorCPU &cpu; 191 192 /** Input port carrying branch requests from Execute */ 193 Latch<BranchData>::Output inp; 194 /** Output port carrying read lines to Fetch2 */ 195 Latch<ForwardLineData>::Input out; 196 /** Input port carrying branch predictions from Fetch2 */ 197 Latch<BranchData>::Output prediction; 198 199 /** Interface to reserve space in the next stage */ 200 std::vector<InputBuffer<ForwardLineData>> &nextStageReserve; 201 202 /** IcachePort to pass to the CPU. Fetch1 is the only module that uses 203 * it. */ 204 IcachePort icachePort; 205 206 /** Line snap size in bytes. All fetches clip to make their ends not 207 * extend beyond this limit. Setting this to the machine L1 cache line 208 * length will result in fetches never crossing line boundaries. */ 209 unsigned int lineSnap; 210 211 /** Maximum fetch width in bytes. Setting this (and lineSnap) to the 212 * machine L1 cache line length will result in fetches of whole cache 213 * lines. Setting this to sizeof(MachInst) will result it fetches of 214 * single instructions (except near the end of lineSnap lines) */ 215 unsigned int maxLineWidth; 216 217 /** Maximum number of fetches allowed in flight (in queues or memory) */ 218 unsigned int fetchLimit; 219 220 protected: 221 /** Cycle-by-cycle state */ 222 223 /** State of memory access for head instruction fetch */ 224 enum FetchState 225 { 226 FetchHalted, /* Not fetching, waiting to be woken by transition 227 to FetchWaitingForPC. The PC is not valid in this state */ 228 FetchWaitingForPC, /* Not fetching, waiting for stream change. 229 This doesn't stop issued fetches from being returned and 230 processed or for branches to change the state to Running. */ 231 FetchRunning /* Try to fetch, when possible */ 232 }; 233 234 /** Stage cycle-by-cycle state */ 235 236 struct Fetch1ThreadInfo { 237 238 /** Consturctor to initialize all fields. */ 239 Fetch1ThreadInfo() : 240 state(FetchWaitingForPC), 241 pc(TheISA::PCState(0)), 242 streamSeqNum(InstId::firstStreamSeqNum), 243 predictionSeqNum(InstId::firstPredictionSeqNum), 244 blocked(false), 245 wakeupGuard(false) 246 { } 247 248 Fetch1ThreadInfo(const Fetch1ThreadInfo& other) : 249 state(other.state), 250 pc(other.pc), 251 streamSeqNum(other.streamSeqNum), 252 predictionSeqNum(other.predictionSeqNum), 253 blocked(other.blocked) 254 { } 255 256 FetchState state; 257 258 /** Fetch PC value. This is updated by branches from Execute, branch 259 * prediction targets from Fetch2 and by incrementing it as we fetch 260 * lines subsequent to those two sources. */ 261 TheISA::PCState pc; 262 263 /** Stream sequence number. This changes on request from Execute and is 264 * used to tag instructions by the fetch stream to which they belong. 265 * Execute originates new prediction sequence numbers. */ 266 InstSeqNum streamSeqNum; 267 268 /** Prediction sequence number. This changes when requests from Execute 269 * or Fetch2 ask for a change of fetch address and is used to tag lines 270 * by the prediction to which they belong. Fetch2 originates 271 * prediction sequence numbers. */ 272 InstSeqNum predictionSeqNum; 273 274 /** Blocked indication for report */ 275 bool blocked; 276 277 /** Signal to guard against sleeping first cycle of wakeup */ 278 bool wakeupGuard; 279 }; 280 281 std::vector<Fetch1ThreadInfo> fetchInfo; 282 ThreadID threadPriority; 283 284 /** State of memory access for head instruction fetch */ 285 enum IcacheState 286 { 287 IcacheRunning, /* Default. Step icache queues when possible */ 288 IcacheNeedsRetry /* Request rejected, will be asked to retry */ 289 }; 290 291 typedef Queue<FetchRequestPtr, 292 ReportTraitsPtrAdaptor<FetchRequestPtr>, 293 NoBubbleTraits<FetchRequestPtr> > 294 FetchQueue; 295 296 /** Queue of address translated requests from Fetch1 */ 297 FetchQueue requests; 298 299 /** Queue of in-memory system requests and responses */ 300 FetchQueue transfers; 301 302 /** Retry state of icache_port */ 303 IcacheState icacheState; 304 305 /** Sequence number for line fetch used for ordering lines to flush */ 306 InstSeqNum lineSeqNum; 307 308 /** Count of the number fetches which have left the transfers queue 309 * and are in the 'wild' in the memory system. Try not to rely on 310 * this value, it's better to code without knowledge of the number 311 * of outstanding accesses */ 312 unsigned int numFetchesInMemorySystem; 313 /** Number of requests inside the ITLB rather than in the queues. 314 * All requests so located *must* have reserved space in the 315 * transfers queue */ 316 unsigned int numFetchesInITLB; 317 318 protected: 319 friend std::ostream &operator <<(std::ostream &os, 320 Fetch1::FetchState state); 321 322 /** Start fetching from a new address. */ 323 void changeStream(const BranchData &branch); 324 325 /** Update streamSeqNum and predictionSeqNum from the given branch (and 326 * assume these have changed and discard (on delivery) all lines in 327 * flight) */ 328 void updateExpectedSeqNums(const BranchData &branch); 329 330 /** Convert a response to a ForwardLineData */ 331 void processResponse(FetchRequestPtr response, 332 ForwardLineData &line); 333 334 friend std::ostream &operator <<(std::ostream &os, 335 IcacheState state); 336 337 338 /** Use the current threading policy to determine the next thread to 339 * fetch from. */ 340 ThreadID getScheduledThread(); 341 342 /** Insert a line fetch into the requests. This can be a partial 343 * line request where the given address has a non-0 offset into a 344 * line. */ 345 void fetchLine(ThreadID tid); 346 347 /** Try and issue a fetch for a translated request at the 348 * head of the requests queue. Also tries to move the request 349 * between queues */ 350 void tryToSendToTransfers(FetchRequestPtr request); 351 352 /** Try to send (or resend) a memory request's next/only packet to 353 * the memory system. Returns true if the fetch was successfully 354 * sent to memory */ 355 bool tryToSend(FetchRequestPtr request); 356 357 /** Move a request between queues */ 358 void moveFromRequestsToTransfers(FetchRequestPtr request); 359 360 /** Step requests along between requests and transfers queues */ 361 void stepQueues(); 362 363 /** Pop a request from the given queue and correctly deallocate and 364 * discard it. */ 365 void popAndDiscard(FetchQueue &queue); 366 367 /** Handle pushing a TLB response onto the right queue */ 368 void handleTLBResponse(FetchRequestPtr response); 369 370 /** Returns the total number of queue occupancy, in-ITLB and 371 * in-memory system fetches */ 372 unsigned int numInFlightFetches(); 373 374 /** Print the appropriate MinorLine line for a fetch response */ 375 void minorTraceResponseLine(const std::string &name, 376 FetchRequestPtr response) const; 377 378 /** Memory interface */ 379 virtual bool recvTimingResp(PacketPtr pkt); 380 virtual void recvReqRetry(); 381 382 public: 383 Fetch1(const std::string &name_, 384 MinorCPU &cpu_, 385 MinorCPUParams ¶ms, 386 Latch<BranchData>::Output inp_, 387 Latch<ForwardLineData>::Input out_, 388 Latch<BranchData>::Output prediction_, 389 std::vector<InputBuffer<ForwardLineData>> &next_stage_input_buffer); 390 391 public: 392 /** Returns the IcachePort owned by this Fetch1 */ 393 MinorCPU::MinorCPUPort &getIcachePort() { return icachePort; } 394 395 /** Pass on input/buffer data to the output if you can */ 396 void evaluate(); 397 398 /** Initiate fetch1 fetching */ 399 void wakeupFetch(ThreadID tid); 400 401 void minorTrace() const; 402 403 /** Is this stage drained? For Fetch1, draining is initiated by 404 * Execute signalling a branch with the reason HaltFetch */ 405 bool isDrained(); 406}; 407 408} 409 410#endif /* __CPU_MINOR_FETCH1_HH__ */ 411