fetch1.hh (11567:560d7fbbddd1) fetch1.hh (12749:223c83ed9979)
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 */
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;
133 RequestPtr 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 */
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_,
166 void finish(const Fault &fault_, const 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)
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 { }
179 {
180 request = std::make_shared<Request>();
181 }
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 &params,
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__ */
182
183 ~FetchRequest();
184 };
185
186 typedef FetchRequest *FetchRequestPtr;
187
188 protected:
189 /** Construction-assigned data members */
190
191 /** Pointer back to the containing CPU */
192 MinorCPU &cpu;
193
194 /** Input port carrying branch requests from Execute */
195 Latch<BranchData>::Output inp;
196 /** Output port carrying read lines to Fetch2 */
197 Latch<ForwardLineData>::Input out;
198 /** Input port carrying branch predictions from Fetch2 */
199 Latch<BranchData>::Output prediction;
200
201 /** Interface to reserve space in the next stage */
202 std::vector<InputBuffer<ForwardLineData>> &nextStageReserve;
203
204 /** IcachePort to pass to the CPU. Fetch1 is the only module that uses
205 * it. */
206 IcachePort icachePort;
207
208 /** Line snap size in bytes. All fetches clip to make their ends not
209 * extend beyond this limit. Setting this to the machine L1 cache line
210 * length will result in fetches never crossing line boundaries. */
211 unsigned int lineSnap;
212
213 /** Maximum fetch width in bytes. Setting this (and lineSnap) to the
214 * machine L1 cache line length will result in fetches of whole cache
215 * lines. Setting this to sizeof(MachInst) will result it fetches of
216 * single instructions (except near the end of lineSnap lines) */
217 unsigned int maxLineWidth;
218
219 /** Maximum number of fetches allowed in flight (in queues or memory) */
220 unsigned int fetchLimit;
221
222 protected:
223 /** Cycle-by-cycle state */
224
225 /** State of memory access for head instruction fetch */
226 enum FetchState
227 {
228 FetchHalted, /* Not fetching, waiting to be woken by transition
229 to FetchWaitingForPC. The PC is not valid in this state */
230 FetchWaitingForPC, /* Not fetching, waiting for stream change.
231 This doesn't stop issued fetches from being returned and
232 processed or for branches to change the state to Running. */
233 FetchRunning /* Try to fetch, when possible */
234 };
235
236 /** Stage cycle-by-cycle state */
237
238 struct Fetch1ThreadInfo {
239
240 /** Consturctor to initialize all fields. */
241 Fetch1ThreadInfo() :
242 state(FetchWaitingForPC),
243 pc(TheISA::PCState(0)),
244 streamSeqNum(InstId::firstStreamSeqNum),
245 predictionSeqNum(InstId::firstPredictionSeqNum),
246 blocked(false),
247 wakeupGuard(false)
248 { }
249
250 Fetch1ThreadInfo(const Fetch1ThreadInfo& other) :
251 state(other.state),
252 pc(other.pc),
253 streamSeqNum(other.streamSeqNum),
254 predictionSeqNum(other.predictionSeqNum),
255 blocked(other.blocked)
256 { }
257
258 FetchState state;
259
260 /** Fetch PC value. This is updated by branches from Execute, branch
261 * prediction targets from Fetch2 and by incrementing it as we fetch
262 * lines subsequent to those two sources. */
263 TheISA::PCState pc;
264
265 /** Stream sequence number. This changes on request from Execute and is
266 * used to tag instructions by the fetch stream to which they belong.
267 * Execute originates new prediction sequence numbers. */
268 InstSeqNum streamSeqNum;
269
270 /** Prediction sequence number. This changes when requests from Execute
271 * or Fetch2 ask for a change of fetch address and is used to tag lines
272 * by the prediction to which they belong. Fetch2 originates
273 * prediction sequence numbers. */
274 InstSeqNum predictionSeqNum;
275
276 /** Blocked indication for report */
277 bool blocked;
278
279 /** Signal to guard against sleeping first cycle of wakeup */
280 bool wakeupGuard;
281 };
282
283 std::vector<Fetch1ThreadInfo> fetchInfo;
284 ThreadID threadPriority;
285
286 /** State of memory access for head instruction fetch */
287 enum IcacheState
288 {
289 IcacheRunning, /* Default. Step icache queues when possible */
290 IcacheNeedsRetry /* Request rejected, will be asked to retry */
291 };
292
293 typedef Queue<FetchRequestPtr,
294 ReportTraitsPtrAdaptor<FetchRequestPtr>,
295 NoBubbleTraits<FetchRequestPtr> >
296 FetchQueue;
297
298 /** Queue of address translated requests from Fetch1 */
299 FetchQueue requests;
300
301 /** Queue of in-memory system requests and responses */
302 FetchQueue transfers;
303
304 /** Retry state of icache_port */
305 IcacheState icacheState;
306
307 /** Sequence number for line fetch used for ordering lines to flush */
308 InstSeqNum lineSeqNum;
309
310 /** Count of the number fetches which have left the transfers queue
311 * and are in the 'wild' in the memory system. Try not to rely on
312 * this value, it's better to code without knowledge of the number
313 * of outstanding accesses */
314 unsigned int numFetchesInMemorySystem;
315 /** Number of requests inside the ITLB rather than in the queues.
316 * All requests so located *must* have reserved space in the
317 * transfers queue */
318 unsigned int numFetchesInITLB;
319
320 protected:
321 friend std::ostream &operator <<(std::ostream &os,
322 Fetch1::FetchState state);
323
324 /** Start fetching from a new address. */
325 void changeStream(const BranchData &branch);
326
327 /** Update streamSeqNum and predictionSeqNum from the given branch (and
328 * assume these have changed and discard (on delivery) all lines in
329 * flight) */
330 void updateExpectedSeqNums(const BranchData &branch);
331
332 /** Convert a response to a ForwardLineData */
333 void processResponse(FetchRequestPtr response,
334 ForwardLineData &line);
335
336 friend std::ostream &operator <<(std::ostream &os,
337 IcacheState state);
338
339
340 /** Use the current threading policy to determine the next thread to
341 * fetch from. */
342 ThreadID getScheduledThread();
343
344 /** Insert a line fetch into the requests. This can be a partial
345 * line request where the given address has a non-0 offset into a
346 * line. */
347 void fetchLine(ThreadID tid);
348
349 /** Try and issue a fetch for a translated request at the
350 * head of the requests queue. Also tries to move the request
351 * between queues */
352 void tryToSendToTransfers(FetchRequestPtr request);
353
354 /** Try to send (or resend) a memory request's next/only packet to
355 * the memory system. Returns true if the fetch was successfully
356 * sent to memory */
357 bool tryToSend(FetchRequestPtr request);
358
359 /** Move a request between queues */
360 void moveFromRequestsToTransfers(FetchRequestPtr request);
361
362 /** Step requests along between requests and transfers queues */
363 void stepQueues();
364
365 /** Pop a request from the given queue and correctly deallocate and
366 * discard it. */
367 void popAndDiscard(FetchQueue &queue);
368
369 /** Handle pushing a TLB response onto the right queue */
370 void handleTLBResponse(FetchRequestPtr response);
371
372 /** Returns the total number of queue occupancy, in-ITLB and
373 * in-memory system fetches */
374 unsigned int numInFlightFetches();
375
376 /** Print the appropriate MinorLine line for a fetch response */
377 void minorTraceResponseLine(const std::string &name,
378 FetchRequestPtr response) const;
379
380 /** Memory interface */
381 virtual bool recvTimingResp(PacketPtr pkt);
382 virtual void recvReqRetry();
383
384 public:
385 Fetch1(const std::string &name_,
386 MinorCPU &cpu_,
387 MinorCPUParams &params,
388 Latch<BranchData>::Output inp_,
389 Latch<ForwardLineData>::Input out_,
390 Latch<BranchData>::Output prediction_,
391 std::vector<InputBuffer<ForwardLineData>> &next_stage_input_buffer);
392
393 public:
394 /** Returns the IcachePort owned by this Fetch1 */
395 MinorCPU::MinorCPUPort &getIcachePort() { return icachePort; }
396
397 /** Pass on input/buffer data to the output if you can */
398 void evaluate();
399
400 /** Initiate fetch1 fetching */
401 void wakeupFetch(ThreadID tid);
402
403 void minorTrace() const;
404
405 /** Is this stage drained? For Fetch1, draining is initiated by
406 * Execute signalling a branch with the reason HaltFetch */
407 bool isDrained();
408};
409
410}
411
412#endif /* __CPU_MINOR_FETCH1_HH__ */