2 * Copyright (c) 2013-2014 ARM Limited
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.
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.
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.
37 * Authors: Andrew Bardsley
43 * Fetch1 is responsible for fetching "lines" from memory and passing
47 #ifndef __CPU_MINOR_FETCH1_HH__
48 #define __CPU_MINOR_FETCH1_HH__
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"
59 /** A stage responsible for fetching "lines" from memory and passing
61 class Fetch1 : public Named
64 /** Exposable fetch port */
65 class IcachePort : public MinorCPU::MinorCPUPort
72 IcachePort(std::string name, Fetch1 &fetch_, MinorCPU &cpu) :
73 MinorCPU::MinorCPUPort(name, cpu), fetch(fetch_)
77 bool recvTimingResp(PacketPtr pkt)
78 { return fetch.recvTimingResp(pkt); }
80 void recvRetry() { fetch.recvRetry(); }
83 /** Memory access queuing.
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.
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).
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. */
99 /** Structure to hold SenderState info through
100 * translation and memory accesses. */
102 public BaseTLB::Translation, /* For TLB lookups */
103 public Packet::SenderState /* For packing into a Packet */
106 /** Owning fetch unit */
110 /** Progress of this request through address translation and
112 enum FetchRequestState
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 */
121 FetchRequestState state;
123 /** Identity of the line that this request will generate */
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 */
132 /** The underlying request that this fetch represents */
135 /** PC to fixup with line address */
138 /** Fill in a fault if one happens during fetch, check this by
139 * picking apart the response packet */
142 /** Make a packet to use with the memory transaction */
145 /** Report interface */
146 void reportData(std::ostream &os) const;
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;
153 /** Is this a complete read line or fault */
154 bool isComplete() const { return state == Complete; }
157 /** BaseTLB::Translation interface */
159 /** Interface for ITLB responses. We can handle delay, so don't
161 void markDelayed() { }
163 /** Interface for ITLB responses. Populates self and then passes
164 * the request on to the ports' handleTLBResponse member
166 void finish(const Fault &fault_, RequestPtr request_,
167 ThreadContext *tc, BaseTLB::Mode mode);
170 FetchRequest(Fetch1 &fetch_, InstId id_, TheISA::PCState pc_) :
184 typedef FetchRequest *FetchRequestPtr;
187 /** Construction-assigned data members */
189 /** Pointer back to the containing CPU */
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;
199 /** Interface to reserve space in the next stage */
200 Reservable &nextStageReserve;
202 /** IcachePort to pass to the CPU. Fetch1 is the only module that uses
204 IcachePort icachePort;
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;
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;
217 /** Maximum number of fetches allowed in flight (in queues or memory) */
218 unsigned int fetchLimit;
221 /** Cycle-by-cycle state */
223 /** State of memory access for head instruction fetch */
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 */
234 /** Stage cycle-by-cycle state */
238 /** Fetch PC value. This is updated by branches from Execute, branch
239 * prediction targets from Fetch2 and by incrementing it as we fetch
240 * lines subsequent to those two sources. */
243 /** Stream sequence number. This changes on request from Execute and is
244 * used to tag instructions by the fetch stream to which they belong.
245 * Execute originates new prediction sequence numbers. */
246 InstSeqNum streamSeqNum;
248 /** Prediction sequence number. This changes when requests from Execute
249 * or Fetch2 ask for a change of fetch address and is used to tag lines
250 * by the prediction to which they belong. Fetch2 originates
251 * prediction sequence numbers. */
252 InstSeqNum predictionSeqNum;
254 /** Blocked indication for report */
257 /** State of memory access for head instruction fetch */
260 IcacheRunning, /* Default. Step icache queues when possible */
261 IcacheNeedsRetry /* Request rejected, will be asked to retry */
264 typedef Queue<FetchRequestPtr,
265 ReportTraitsPtrAdaptor<FetchRequestPtr>,
266 NoBubbleTraits<FetchRequestPtr> >
269 /** Queue of address translated requests from Fetch1 */
272 /** Queue of in-memory system requests and responses */
273 FetchQueue transfers;
275 /** Retry state of icache_port */
276 IcacheState icacheState;
278 /** Sequence number for line fetch used for ordering lines to flush */
279 InstSeqNum lineSeqNum;
281 /** Count of the number fetches which have left the transfers queue
282 * and are in the 'wild' in the memory system. Try not to rely on
283 * this value, it's better to code without knowledge of the number
284 * of outstanding accesses */
285 unsigned int numFetchesInMemorySystem;
286 /** Number of requests inside the ITLB rather than in the queues.
287 * All requests so located *must* have reserved space in the
289 unsigned int numFetchesInITLB;
292 friend std::ostream &operator <<(std::ostream &os,
293 Fetch1::FetchState state);
295 /** Start fetching from a new address. */
296 void changeStream(const BranchData &branch);
298 /** Update streamSeqNum and predictionSeqNum from the given branch (and
299 * assume these have changed and discard (on delivery) all lines in
301 void updateExpectedSeqNums(const BranchData &branch);
303 /** Convert a response to a ForwardLineData */
304 void processResponse(FetchRequestPtr response,
305 ForwardLineData &line);
307 friend std::ostream &operator <<(std::ostream &os,
310 /** Insert a line fetch into the requests. This can be a partial
311 * line request where the given address has a non-0 offset into a
315 /** Try and issue a fetch for a translated request at the
316 * head of the requests queue. Also tries to move the request
318 void tryToSendToTransfers(FetchRequestPtr request);
320 /** Try to send (or resend) a memory request's next/only packet to
321 * the memory system. Returns true if the fetch was successfully
323 bool tryToSend(FetchRequestPtr request);
325 /** Move a request between queues */
326 void moveFromRequestsToTransfers(FetchRequestPtr request);
328 /** Step requests along between requests and transfers queues */
331 /** Pop a request from the given queue and correctly deallocate and
333 void popAndDiscard(FetchQueue &queue);
335 /** Handle pushing a TLB response onto the right queue */
336 void handleTLBResponse(FetchRequestPtr response);
338 /** Returns the total number of queue occupancy, in-ITLB and
339 * in-memory system fetches */
340 unsigned int numInFlightFetches();
342 /** Print the appropriate MinorLine line for a fetch response */
343 void minorTraceResponseLine(const std::string &name,
344 FetchRequestPtr response) const;
346 /** Memory interface */
347 virtual bool recvTimingResp(PacketPtr pkt);
348 virtual void recvRetry();
351 Fetch1(const std::string &name_,
353 MinorCPUParams ¶ms,
354 Latch<BranchData>::Output inp_,
355 Latch<ForwardLineData>::Input out_,
356 Latch<BranchData>::Output prediction_,
357 Reservable &next_stage_input_buffer);
360 /** Returns the IcachePort owned by this Fetch1 */
361 MinorCPU::MinorCPUPort &getIcachePort() { return icachePort; }
363 /** Pass on input/buffer data to the output if you can */
366 void minorTrace() const;
368 /** Is this stage drained? For Fetch1, draining is initiated by
369 * Execute signalling a branch with the reason HaltFetch */
375 #endif /* __CPU_MINOR_FETCH1_HH__ */