gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
fetch1.cc
Go to the documentation of this file.
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/fetch1.hh"
41 
42 #include <cstring>
43 #include <iomanip>
44 #include <sstream>
45 
46 #include "base/cast.hh"
47 #include "cpu/minor/pipeline.hh"
48 #include "debug/Drain.hh"
49 #include "debug/Fetch.hh"
50 #include "debug/MinorTrace.hh"
51 
52 namespace Minor
53 {
54 
55 Fetch1::Fetch1(const std::string &name_,
56  MinorCPU &cpu_,
57  MinorCPUParams &params,
60  Latch<BranchData>::Output prediction_,
61  std::vector<InputBuffer<ForwardLineData>> &next_stage_input_buffer) :
62  Named(name_),
63  cpu(cpu_),
64  inp(inp_),
65  out(out_),
66  prediction(prediction_),
67  nextStageReserve(next_stage_input_buffer),
68  icachePort(name_ + ".icache_port", *this, cpu_),
69  lineSnap(params.fetch1LineSnapWidth),
70  maxLineWidth(params.fetch1LineWidth),
71  fetchLimit(params.fetch1FetchLimit),
72  fetchInfo(params.numThreads),
73  threadPriority(0),
74  requests(name_ + ".requests", "lines", params.fetch1FetchLimit),
75  transfers(name_ + ".transfers", "lines", params.fetch1FetchLimit),
76  icacheState(IcacheRunning),
77  lineSeqNum(InstId::firstLineSeqNum),
78  numFetchesInMemorySystem(0),
79  numFetchesInITLB(0)
80 {
81  if (lineSnap == 0) {
82  lineSnap = cpu.cacheLineSize();
83  DPRINTF(Fetch, "lineSnap set to cache line size of: %d\n",
84  lineSnap);
85  }
86 
87  if (maxLineWidth == 0) {
88  maxLineWidth = cpu.cacheLineSize();
89  DPRINTF(Fetch, "maxLineWidth set to cache line size of: %d\n",
90  maxLineWidth);
91  }
92 
93  /* These assertions should be copied to the Python config. as well */
94  if ((lineSnap % sizeof(TheISA::MachInst)) != 0) {
95  fatal("%s: fetch1LineSnapWidth must be a multiple "
96  "of sizeof(TheISA::MachInst) (%d)\n", name_,
97  sizeof(TheISA::MachInst));
98  }
99 
100  if (!(maxLineWidth >= lineSnap &&
101  (maxLineWidth % sizeof(TheISA::MachInst)) == 0))
102  {
103  fatal("%s: fetch1LineWidth must be a multiple of"
104  " sizeof(TheISA::MachInst)"
105  " (%d), and >= fetch1LineSnapWidth (%d)\n",
106  name_, sizeof(TheISA::MachInst), lineSnap);
107  }
108 
109  if (fetchLimit < 1) {
110  fatal("%s: fetch1FetchLimit must be >= 1 (%d)\n", name_,
111  fetchLimit);
112  }
113 }
114 
115 inline ThreadID
117 {
118  /* Select thread via policy. */
119  std::vector<ThreadID> priority_list;
120 
121  switch (cpu.threadPolicy) {
122  case Enums::SingleThreaded:
123  priority_list.push_back(0);
124  break;
125  case Enums::RoundRobin:
126  priority_list = cpu.roundRobinPriority(threadPriority);
127  break;
128  case Enums::Random:
129  priority_list = cpu.randomPriority();
130  break;
131  default:
132  panic("Unknown fetch policy");
133  }
134 
135  for (auto tid : priority_list) {
136  if (cpu.getContext(tid)->status() == ThreadContext::Active &&
137  !fetchInfo[tid].blocked &&
138  fetchInfo[tid].state == FetchRunning) {
139  threadPriority = tid;
140  return tid;
141  }
142  }
143 
144  return InvalidThreadID;
145 }
146 
147 void
149 {
150  /* Reference the currently used thread state. */
151  Fetch1ThreadInfo &thread = fetchInfo[tid];
152 
153  /* If line_offset != 0, a request is pushed for the remainder of the
154  * line. */
155  /* Use a lower, sizeof(MachInst) aligned address for the fetch */
156  Addr aligned_pc = thread.pc.instAddr() & ~((Addr) lineSnap - 1);
157  unsigned int line_offset = aligned_pc % lineSnap;
158  unsigned int request_size = maxLineWidth - line_offset;
159 
160  /* Fill in the line's id */
161  InstId request_id(tid,
162  thread.streamSeqNum, thread.predictionSeqNum,
163  lineSeqNum);
164 
165  FetchRequestPtr request = new FetchRequest(*this, request_id, thread.pc);
166 
167  DPRINTF(Fetch, "Inserting fetch into the fetch queue "
168  "%s addr: 0x%x pc: %s line_offset: %d request_size: %d\n",
169  request_id, aligned_pc, thread.pc, line_offset, request_size);
170 
171  request->request.setContext(cpu.threads[tid]->getTC()->contextId());
172  request->request.setVirt(0 /* asid */,
173  aligned_pc, request_size, Request::INST_FETCH, cpu.instMasterId(),
174  /* I've no idea why we need the PC, but give it */
175  thread.pc.instAddr());
176 
177  DPRINTF(Fetch, "Submitting ITLB request\n");
179 
181 
182  /* Reserve space in the queues upstream of requests for results */
183  transfers.reserve();
184  requests.push(request);
185 
186  /* Submit the translation request. The response will come
187  * through finish/markDelayed on this request as it bears
188  * the Translation interface */
189  cpu.threads[request->id.threadId]->itb->translateTiming(
190  &request->request,
191  cpu.getContext(request->id.threadId),
192  request, BaseTLB::Execute);
193 
194  lineSeqNum++;
195 
196  /* Step the PC for the next line onto the line aligned next address.
197  * Note that as instructions can span lines, this PC is only a
198  * reliable 'new' PC if the next line has a new stream sequence number. */
199 #if THE_ISA == ALPHA_ISA
200  /* Restore the low bits of the PC used as address space flags */
201  Addr pc_low_bits = thread.pc.instAddr() &
202  ((Addr) (1 << sizeof(TheISA::MachInst)) - 1);
203 
204  thread.pc.set(aligned_pc + request_size + pc_low_bits);
205 #else
206  thread.pc.set(aligned_pc + request_size);
207 #endif
208 }
209 
210 std::ostream &
211 operator <<(std::ostream &os, Fetch1::IcacheState state)
212 {
213  switch (state) {
215  os << "IcacheRunning";
216  break;
218  os << "IcacheNeedsRetry";
219  break;
220  default:
221  os << "IcacheState-" << static_cast<int>(state);
222  break;
223  }
224  return os;
225 }
226 
227 void
229 {
230  /* Make the necessary packet for a memory transaction */
232  packet->allocate();
233 
234  /* This FetchRequest becomes SenderState to allow the response to be
235  * identified */
236  packet->pushSenderState(this);
237 }
238 
239 void
242 {
243  fault = fault_;
244 
245  state = Translated;
246  fetch.handleTLBResponse(this);
247 
248  /* Let's try and wake up the processor for the next cycle */
249  fetch.cpu.wakeupOnEvent(Pipeline::Fetch1StageId);
250 }
251 
252 void
254 {
256 
257  if (response->fault != NoFault) {
258  DPRINTF(Fetch, "Fault in address ITLB translation: %s, "
259  "paddr: 0x%x, vaddr: 0x%x\n",
260  response->fault->name(),
261  (response->request.hasPaddr() ? response->request.getPaddr() : 0),
262  response->request.getVaddr());
263 
264  if (DTRACE(MinorTrace))
265  minorTraceResponseLine(name(), response);
266  } else {
267  DPRINTF(Fetch, "Got ITLB response\n");
268  }
269 
270  response->state = FetchRequest::Translated;
271 
272  tryToSendToTransfers(response);
273 }
274 
276 {
277  if (packet)
278  delete packet;
279 }
280 
281 void
283 {
284  if (!requests.empty() && requests.front() != request) {
285  DPRINTF(Fetch, "Fetch not at front of requests queue, can't"
286  " issue to memory\n");
287  return;
288  }
289 
290  if (request->state == FetchRequest::InTranslation) {
291  DPRINTF(Fetch, "Fetch still in translation, not issuing to"
292  " memory\n");
293  return;
294  }
295 
296  if (request->isDiscardable() || request->fault != NoFault) {
297  /* Discarded and faulting requests carry on through transfers
298  * as Complete/packet == NULL */
299 
300  request->state = FetchRequest::Complete;
302 
303  /* Wake up the pipeline next cycle as there will be no event
304  * for this queue->queue transfer */
306  } else if (request->state == FetchRequest::Translated) {
307  if (!request->packet)
308  request->makePacket();
309 
310  /* Ensure that the packet won't delete the request */
311  assert(request->packet->needsResponse());
312 
313  if (tryToSend(request))
315  } else {
316  DPRINTF(Fetch, "Not advancing line fetch\n");
317  }
318 }
319 
320 void
322 {
323  assert(!requests.empty() && requests.front() == request);
324 
325  requests.pop();
326  transfers.push(request);
327 }
328 
329 bool
331 {
332  bool ret = false;
333 
334  if (icachePort.sendTimingReq(request->packet)) {
335  /* Invalidate the fetch_requests packet so we don't
336  * accidentally fail to deallocate it (or use it!)
337  * later by overwriting it */
338  request->packet = NULL;
341 
342  ret = true;
343 
344  DPRINTF(Fetch, "Issued fetch request to memory: %s\n",
345  request->id);
346  } else {
347  /* Needs to be resent, wait for that */
349 
350  DPRINTF(Fetch, "Line fetch needs to retry: %s\n",
351  request->id);
352  }
353 
354  return ret;
355 }
356 
357 void
359 {
360  IcacheState old_icache_state = icacheState;
361 
362  switch (icacheState) {
363  case IcacheRunning:
364  /* Move ITLB results on to the memory system */
365  if (!requests.empty()) {
367  }
368  break;
369  case IcacheNeedsRetry:
370  break;
371  }
372 
373  if (icacheState != old_icache_state) {
374  DPRINTF(Fetch, "Step in state %s moving to state %s\n",
375  old_icache_state, icacheState);
376  }
377 }
378 
379 void
381 {
382  if (!queue.empty()) {
383  delete queue.front();
384  queue.pop();
385  }
386 }
387 
388 unsigned int
390 {
391  return requests.occupiedSpace() +
393 }
394 
396 void
398  Fetch1::FetchRequestPtr response) const
399 {
400  Request &request M5_VAR_USED = response->request;
401 
402  if (response->packet && response->packet->isError()) {
403  MINORLINE(this, "id=F;%s vaddr=0x%x fault=\"error packet\"\n",
404  response->id, request.getVaddr());
405  } else if (response->fault != NoFault) {
406  MINORLINE(this, "id=F;%s vaddr=0x%x fault=\"%s\"\n",
407  response->id, request.getVaddr(), response->fault->name());
408  } else {
409  MINORLINE(this, "id=%s size=%d vaddr=0x%x paddr=0x%x\n",
410  response->id, request.getSize(),
411  request.getVaddr(), request.getPaddr());
412  }
413 }
414 
415 bool
417 {
418  DPRINTF(Fetch, "recvTimingResp %d\n", numFetchesInMemorySystem);
419 
420  /* Only push the response if we didn't change stream? No, all responses
421  * should hit the responses queue. It's the job of 'step' to throw them
422  * away. */
423  FetchRequestPtr fetch_request = safe_cast<FetchRequestPtr>
424  (response->popSenderState());
425 
426  /* Fixup packet in fetch_request as this may have changed */
427  assert(!fetch_request->packet);
428  fetch_request->packet = response;
429 
431  fetch_request->state = FetchRequest::Complete;
432 
433  if (DTRACE(MinorTrace))
434  minorTraceResponseLine(name(), fetch_request);
435 
436  if (response->isError()) {
437  DPRINTF(Fetch, "Received error response packet: %s\n",
438  fetch_request->id);
439  }
440 
441  /* We go to idle even if there are more things to do on the queues as
442  * it's the job of step to actually step us on to the next transaction */
443 
444  /* Let's try and wake up the processor for the next cycle to move on
445  * queues */
447 
448  /* Never busy */
449  return true;
450 }
451 
452 void
454 {
455  DPRINTF(Fetch, "recvRetry\n");
456  assert(icacheState == IcacheNeedsRetry);
457  assert(!requests.empty());
458 
459  FetchRequestPtr retryRequest = requests.front();
460 
462 
463  if (tryToSend(retryRequest))
464  moveFromRequestsToTransfers(retryRequest);
465 }
466 
467 std::ostream &
468 operator <<(std::ostream &os, Fetch1::FetchState state)
469 {
470  switch (state) {
471  case Fetch1::FetchHalted:
472  os << "FetchHalted";
473  break;
475  os << "FetchWaitingForPC";
476  break;
478  os << "FetchRunning";
479  break;
480  default:
481  os << "FetchState-" << static_cast<int>(state);
482  break;
483  }
484  return os;
485 }
486 
487 void
489 {
490  Fetch1ThreadInfo &thread = fetchInfo[branch.threadId];
491 
492  updateExpectedSeqNums(branch);
493 
494  /* Start fetching again if we were stopped */
495  switch (branch.reason) {
497  {
498  if (thread.wakeupGuard) {
499  DPRINTF(Fetch, "Not suspending fetch due to guard: %s\n",
500  branch);
501  } else {
502  DPRINTF(Fetch, "Suspending fetch: %s\n", branch);
503  thread.state = FetchWaitingForPC;
504  }
505  }
506  break;
508  DPRINTF(Fetch, "Halting fetch\n");
509  thread.state = FetchHalted;
510  break;
511  default:
512  DPRINTF(Fetch, "Changing stream on branch: %s\n", branch);
513  thread.state = FetchRunning;
514  break;
515  }
516  thread.pc = branch.target;
517 }
518 
519 void
521 {
522  Fetch1ThreadInfo &thread = fetchInfo[branch.threadId];
523 
524  DPRINTF(Fetch, "Updating streamSeqNum from: %d to %d,"
525  " predictionSeqNum from: %d to %d\n",
526  thread.streamSeqNum, branch.newStreamSeqNum,
527  thread.predictionSeqNum, branch.newPredictionSeqNum);
528 
529  /* Change the stream */
530  thread.streamSeqNum = branch.newStreamSeqNum;
531  /* Update the prediction. Note that it's possible for this to
532  * actually set the prediction to an *older* value if new
533  * predictions have been discarded by execute */
534  thread.predictionSeqNum = branch.newPredictionSeqNum;
535 }
536 
537 void
539  ForwardLineData &line)
540 {
541  Fetch1ThreadInfo &thread = fetchInfo[response->id.threadId];
542  PacketPtr packet = response->packet;
543 
544  /* Pass the prefetch abort (if any) on to Fetch2 in a ForwardLineData
545  * structure */
546  line.setFault(response->fault);
547  /* Make sequence numbers valid in return */
548  line.id = response->id;
549  /* Set PC to virtual address */
550  line.pc = response->pc;
551  /* Set the lineBase, which is a sizeof(MachInst) aligned address <=
552  * pc.instAddr() */
553  line.lineBaseAddr = response->request.getVaddr();
554 
555  if (response->fault != NoFault) {
556  /* Stop fetching if there was a fault */
557  /* Should probably try to flush the queues as well, but we
558  * can't be sure that this fault will actually reach Execute, and we
559  * can't (currently) selectively remove this stream from the queues */
560  DPRINTF(Fetch, "Stopping line fetch because of fault: %s\n",
561  response->fault->name());
563  } else {
564  line.adoptPacketData(packet);
565  /* Null the response's packet to prevent the response from trying to
566  * deallocate the packet */
567  response->packet = NULL;
568  }
569 }
570 
571 void
573 {
574  const BranchData &execute_branch = *inp.outputWire;
575  const BranchData &fetch2_branch = *prediction.outputWire;
576  ForwardLineData &line_out = *out.inputWire;
577 
578  assert(line_out.isBubble());
579 
580  for (ThreadID tid = 0; tid < cpu.numThreads; tid++)
581  fetchInfo[tid].blocked = !nextStageReserve[tid].canReserve();
582 
584  if (execute_branch.threadId != InvalidThreadID &&
585  execute_branch.threadId == fetch2_branch.threadId) {
586 
587  Fetch1ThreadInfo &thread = fetchInfo[execute_branch.threadId];
588 
589  /* Are we changing stream? Look to the Execute branches first, then
590  * to predicted changes of stream from Fetch2 */
591  if (execute_branch.isStreamChange()) {
592  if (thread.state == FetchHalted) {
593  DPRINTF(Fetch, "Halted, ignoring branch: %s\n", execute_branch);
594  } else {
595  changeStream(execute_branch);
596  }
597 
598  if (!fetch2_branch.isBubble()) {
599  DPRINTF(Fetch, "Ignoring simultaneous prediction: %s\n",
600  fetch2_branch);
601  }
602 
603  /* The streamSeqNum tagging in request/response ->req should handle
604  * discarding those requests when we get to them. */
605  } else if (thread.state != FetchHalted && fetch2_branch.isStreamChange()) {
606  /* Handle branch predictions by changing the instruction source
607  * if we're still processing the same stream (as set by streamSeqNum)
608  * as the one of the prediction.
609  */
610  if (fetch2_branch.newStreamSeqNum != thread.streamSeqNum) {
611  DPRINTF(Fetch, "Not changing stream on prediction: %s,"
612  " streamSeqNum mismatch\n",
613  fetch2_branch);
614  } else {
615  changeStream(fetch2_branch);
616  }
617  }
618  } else {
619  /* Fetch2 and Execute branches are for different threads */
620  if (execute_branch.threadId != InvalidThreadID &&
621  execute_branch.isStreamChange()) {
622 
623  if (fetchInfo[execute_branch.threadId].state == FetchHalted) {
624  DPRINTF(Fetch, "Halted, ignoring branch: %s\n", execute_branch);
625  } else {
626  changeStream(execute_branch);
627  }
628  }
629 
630  if (fetch2_branch.threadId != InvalidThreadID &&
631  fetch2_branch.isStreamChange()) {
632 
633  if (fetchInfo[fetch2_branch.threadId].state == FetchHalted) {
634  DPRINTF(Fetch, "Halted, ignoring branch: %s\n", fetch2_branch);
635  } else if (fetch2_branch.newStreamSeqNum != fetchInfo[fetch2_branch.threadId].streamSeqNum) {
636  DPRINTF(Fetch, "Not changing stream on prediction: %s,"
637  " streamSeqNum mismatch\n", fetch2_branch);
638  } else {
639  changeStream(fetch2_branch);
640  }
641  }
642  }
643 
644  if (numInFlightFetches() < fetchLimit) {
645  ThreadID fetch_tid = getScheduledThread();
646 
647  if (fetch_tid != InvalidThreadID) {
648  DPRINTF(Fetch, "Fetching from thread %d\n", fetch_tid);
649 
650  /* Generate fetch to selected thread */
651  fetchLine(fetch_tid);
652  /* Take up a slot in the fetch queue */
653  nextStageReserve[fetch_tid].reserve();
654  } else {
655  DPRINTF(Fetch, "No active threads available to fetch from\n");
656  }
657  }
658 
659 
660  /* Halting shouldn't prevent fetches in flight from being processed */
661  /* Step fetches through the icachePort queues and memory system */
662  stepQueues();
663 
664  /* As we've thrown away early lines, if there is a line, it must
665  * be from the right stream */
666  if (!transfers.empty() &&
668  {
670 
671  if (response->isDiscardable()) {
672  nextStageReserve[response->id.threadId].freeReservation();
673 
674  DPRINTF(Fetch, "Discarding translated fetch as it's for"
675  " an old stream\n");
676 
677  /* Wake up next cycle just in case there was some other
678  * action to do */
680  } else {
681  DPRINTF(Fetch, "Processing fetched line: %s\n",
682  response->id);
683 
684  processResponse(response, line_out);
685  }
686 
688  }
689 
690  /* If we generated output, and mark the stage as being active
691  * to encourage that output on to the next stage */
692  if (!line_out.isBubble())
694 
695  /* Fetch1 has no inputBuffer so the only activity we can have is to
696  * generate a line output (tested just above) or to initiate a memory
697  * fetch which will signal activity when it returns/needs stepping
698  * between queues */
699 
700 
701  /* This looks hackish. And it is, but there doesn't seem to be a better
702  * way to do this. The signal from commit to suspend fetch takes 1
703  * clock cycle to propagate to fetch. However, a legitimate wakeup
704  * may occur between cycles from the memory system. Thus wakeup guard
705  * prevents us from suspending in that case. */
706 
707  for (auto& thread : fetchInfo) {
708  thread.wakeupGuard = false;
709  }
710 }
711 
712 void
714 {
715  ThreadContext *thread_ctx = cpu.getContext(tid);
716  Fetch1ThreadInfo &thread = fetchInfo[tid];
717  thread.pc = thread_ctx->pcState();
718  thread.state = FetchRunning;
719  thread.wakeupGuard = true;
720  DPRINTF(Fetch, "[tid:%d]: Changing stream wakeup %s\n",
721  tid, thread_ctx->pcState());
722 
724 }
725 
726 bool
728 {
729  bool drained = numInFlightFetches() == 0 && (*out.inputWire).isBubble();
730  for (ThreadID tid = 0; tid < cpu.numThreads; tid++) {
731  Fetch1ThreadInfo &thread = fetchInfo[tid];
732  DPRINTF(Drain, "isDrained[tid:%d]: %s %s%s\n",
733  tid,
734  thread.state == FetchHalted,
735  (numInFlightFetches() == 0 ? "" : "inFlightFetches "),
736  ((*out.inputWire).isBubble() ? "" : "outputtingLine"));
737 
738  drained = drained && (thread.state != FetchRunning);
739  }
740 
741  return drained;
742 }
743 
744 void
746 {
747  os << id;
748 }
749 
751 {
752  Fetch1ThreadInfo &thread = fetch.fetchInfo[id.threadId];
753 
754  /* Can't discard lines in TLB/memory */
755  return state != InTranslation && state != RequestIssuing &&
756  (id.streamSeqNum != thread.streamSeqNum ||
757  id.predictionSeqNum != thread.predictionSeqNum);
758 }
759 
760 void
762 {
763  // TODO: Un-bork minorTrace for THREADS
764  // bork bork bork
765  const Fetch1ThreadInfo &thread = fetchInfo[0];
766 
767  std::ostringstream data;
768 
769  if (thread.blocked)
770  data << 'B';
771  else
772  (*out.inputWire).reportData(data);
773 
774  MINORTRACE("state=%s icacheState=%s in_tlb_mem=%s/%s"
775  " streamSeqNum=%d lines=%s\n", thread.state, icacheState,
777  thread.streamSeqNum, data.str());
780 }
781 
782 }
#define DPRINTF(x,...)
Definition: trace.hh:212
ThreadID threadPriority
Definition: fetch1.hh:282
void processResponse(FetchRequestPtr response, ForwardLineData &line)
Convert a response to a ForwardLineData.
Definition: fetch1.cc:538
std::ostream & operator<<(std::ostream &os, const InstId &id)
Print this id in the usual slash-separated format expected by MinorTrace.
Definition: dyn_inst.cc:63
std::vector< Fetch1ThreadInfo > fetchInfo
Definition: fetch1.hh:281
IcacheState
State of memory access for head instruction fetch.
Definition: fetch1.hh:285
InstSeqNum predictionSeqNum
Prediction sequence number.
Definition: fetch1.hh:272
const std::string & name() const
Definition: trace.hh:149
decltype(nullptr) constexpr NoFault
Definition: types.hh:189
void pop()
Pop the head item.
Definition: buffers.hh:497
void fetchLine(ThreadID tid)
Insert a line fetch into the requests.
Definition: fetch1.cc:148
Like a Queue but with a restricted interface and a setTail function which, when the queue is empty...
Definition: buffers.hh:563
void stepQueues()
Step requests along between requests and transfers queues.
Definition: fetch1.cc:358
#define panic(...)
Definition: misc.hh:153
Memory access queuing.
Definition: fetch1.hh:101
bool tryToSend(FetchRequestPtr request)
Try to send (or resend) a memory request's next/only packet to the memory system. ...
Definition: fetch1.cc:330
Addr lineBaseAddr
First byte address in the line.
Definition: pipe_data.hh:183
static bool isStreamChange(const BranchData::Reason reason)
Is a request with this reason actually a request to change the PC rather than a bubble or branch pred...
Definition: pipe_data.cc:83
std::vector< InputBuffer< ForwardLineData > > & nextStageReserve
Interface to reserve space in the next stage.
Definition: fetch1.hh:200
ThreadID threadId
ThreadID associated with branch.
Definition: pipe_data.hh:114
unsigned int lineSnap
Line snap size in bytes.
Definition: fetch1.hh:209
unsigned int numFetchesInMemorySystem
Count of the number fetches which have left the transfers queue and are in the 'wild' in the memory s...
Definition: fetch1.hh:312
InstId id
Identity of the line that this request will generate.
Definition: fetch1.hh:124
void wakeupOnEvent(unsigned int stage_id)
Interface for stages to signal that they have become active after a callback or eventq event where th...
Definition: cpu.cc:305
bool isBubble() const
Definition: pipe_data.hh:243
void popAndDiscard(FetchQueue &queue)
Pop a request from the given queue and correctly deallocate and discard it.
Definition: fetch1.cc:380
void changeStream(const BranchData &branch)
Start fetching from a new address.
Definition: fetch1.cc:488
void updateExpectedSeqNums(const BranchData &branch)
Update streamSeqNum and predictionSeqNum from the given branch (and assume these have changed and dis...
Definition: fetch1.cc:520
Line fetch data in the forward direction.
Definition: pipe_data.hh:173
Reason reason
Explanation for this branch.
Definition: pipe_data.hh:111
Stage cycle-by-cycle state.
Definition: fetch1.hh:236
void activity()
Records that there is activity this cycle.
Definition: activity.cc:56
bool isDiscardable() const
Is this line out of date with the current stream/prediction sequence and can it be discarded without ...
Definition: fetch1.cc:750
IcacheState icacheState
Retry state of icache_port.
Definition: fetch1.hh:303
TheISA::PCState pc
PC to fixup with line address.
Definition: fetch1.hh:136
Id for lines and instructions.
Definition: dyn_inst.hh:70
void setContext(ContextID context_id)
Set up Context numbers.
Definition: request.hh:449
InstSeqNum newStreamSeqNum
Sequence number of new stream/prediction to be adopted.
Definition: pipe_data.hh:117
TheISA::PCState pc
PC of the first requested inst within this line.
Definition: pipe_data.hh:186
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the slave port by calling its corresponding receive function...
Definition: port.cc:180
virtual TheISA::PCState pcState()=0
Fetch1(const std::string &name_, MinorCPU &cpu_, MinorCPUParams &params, Latch< BranchData >::Output inp_, Latch< ForwardLineData >::Input out_, Latch< BranchData >::Output prediction_, std::vector< InputBuffer< ForwardLineData >> &next_stage_input_buffer)
Definition: fetch1.cc:55
Latch< BranchData >::Output inp
Input port carrying branch requests from Execute.
Definition: fetch1.hh:193
Bitfield< 4, 0 > mode
Definition: miscregs.hh:1385
ThreadContext is the external interface to all thread state for anything outside of the CPU...
Bitfield< 17 > os
Definition: misc.hh:804
STL vector class.
Definition: stl.hh:40
void reserve()
Reserve space in the queue for future pushes.
Definition: buffers.hh:452
void handleTLBResponse(FetchRequestPtr response)
Handle pushing a TLB response onto the right queue.
Definition: fetch1.cc:253
MinorCPU & cpu
Construction-assigned data members.
Definition: fetch1.hh:190
uint32_t MachInst
Definition: types.hh:40
const char data[]
Definition: circlebuf.cc:43
bool blocked
Blocked indication for report.
Definition: fetch1.hh:275
Definition: trace.hh:140
void minorTrace() const
Definition: fetch1.cc:761
bool empty() const
Is the queue empty?
Definition: buffers.hh:500
#define DTRACE(x)
Definition: trace.hh:210
ElemType & front()
Head value.
Definition: buffers.hh:492
void reportData(std::ostream &os) const
Report interface.
Definition: fetch1.cc:745
bool wakeupGuard
Signal to guard against sleeping first cycle of wakeup.
Definition: fetch1.hh:278
std::vector< ThreadID > randomPriority()
Definition: cpu.hh:178
Latch< BranchData >::Output prediction
Input port carrying branch predictions from Fetch2.
Definition: fetch1.hh:197
bool isComplete() const
Is this a complete read line or fault.
Definition: fetch1.hh:154
Addr getPaddr() const
Definition: request.hh:519
#define fatal(...)
Definition: misc.hh:163
FetchQueue requests
Queue of address translated requests from Fetch1.
Definition: fetch1.hh:297
void moveFromRequestsToTransfers(FetchRequestPtr request)
Move a request between queues.
Definition: fetch1.cc:321
Minor::MinorActivityRecorder * activityRecorder
Activity recording for pipeline.
Definition: cpu.hh:90
bool needsResponse() const
Definition: packet.hh:516
Request request
The underlying request that this fetch represents.
Definition: fetch1.hh:133
InstId id
Thread, stream, prediction ...
Definition: pipe_data.hh:197
Latch< ForwardLineData >::Input out
Output port carrying read lines to Fetch2.
Definition: fetch1.hh:195
unsigned int numFetchesInITLB
Number of requests inside the ITLB rather than in the queues.
Definition: fetch1.hh:316
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
unsigned int numInFlightFetches()
Returns the total number of queue occupancy, in-ITLB and in-memory system fetches.
Definition: fetch1.cc:389
void makePacket()
Make a packet to use with the memory transaction.
Definition: fetch1.cc:228
T safe_cast(U ptr)
Definition: cast.hh:61
InstSeqNum streamSeqNum
Stream sequence number.
Definition: fetch1.hh:266
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:245
FetchState
Cycle-by-cycle state.
Definition: fetch1.hh:224
std::vector< ThreadID > roundRobinPriority(ThreadID priority)
Thread scheduling utility functions.
Definition: cpu.hh:169
Fault fault
Fill in a fault if one happens during fetch, check this by picking apart the response packet...
Definition: fetch1.hh:140
const ThreadID InvalidThreadID
Definition: types.hh:172
Fetch1 is responsible for fetching "lines" from memory and passing them to Fetch2.
static const int NumArgumentRegs M5_VAR_USED
Definition: process.cc:83
unsigned int maxLineWidth
Maximum fetch width in bytes.
Definition: fetch1.hh:215
FetchRequestState state
Definition: fetch1.hh:121
Mode
Definition: tlb.hh:61
friend std::ostream & operator<<(std::ostream &os, Fetch1::FetchState state)
Definition: fetch1.cc:468
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:171
Forward data betwen Execute and Fetch1 carrying change-of-address/stream information.
Definition: pipe_data.hh:64
void finish(const Fault &fault_, RequestPtr request_, ThreadContext *tc, BaseTLB::Mode mode)
Interface for ITLB responses.
Definition: fetch1.cc:240
Enums::ThreadPolicy threadPolicy
Thread Scheduling Policy (RoundRobin, Random, etc)
Definition: cpu.hh:114
TheISA::PCState pc
Fetch PC value.
Definition: fetch1.hh:261
bool isError() const
Definition: packet.hh:528
virtual bool recvTimingResp(PacketPtr pkt)
Memory interface.
Definition: fetch1.cc:416
The request was an instruction fetch.
Definition: request.hh:104
Addr getVaddr() const
Definition: request.hh:616
void setVirt(int asid, Addr vaddr, unsigned size, Flags flags, MasterID mid, Addr pc)
Set up a virtual (e.g., CPU) request in a previously allocated Request object.
Definition: request.hh:460
std::vector< Minor::MinorThread * > threads
These are thread state-representing objects for this CPU.
Definition: cpu.hh:95
InstSeqNum newPredictionSeqNum
Definition: pipe_data.hh:118
void push(ElemType &data)
Push an element into the buffer if it isn't a bubble.
Definition: buffers.hh:424
#define MINORTRACE(...)
DPRINTFN for MinorTrace reporting.
Definition: trace.hh:62
The constructed pipeline.
void wakeupFetch(ThreadID tid)
Initiate fetch1 fetching.
Definition: fetch1.cc:713
void tryToSendToTransfers(FetchRequestPtr request)
Try and issue a fetch for a translated request at the head of the requests queue. ...
Definition: fetch1.cc:282
void pushSenderState(SenderState *sender_state)
Push a new sender state to the packet and make the current sender state the predecessor of the new on...
Definition: packet.cc:329
bool isDrained()
Is this stage drained? For Fetch1, draining is initiated by Execute signalling a branch with the reas...
Definition: fetch1.cc:727
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
Definition: packet.cc:337
bool isBubble() const
Definition: pipe_data.hh:150
#define MINORLINE(sim_object,...)
DPRINTFN for MinorTrace MinorLine line reporting.
Definition: trace.hh:70
InstSeqNum lineSeqNum
Sequence number for line fetch used for ordering lines to flush.
Definition: fetch1.hh:306
void minorTrace() const
Definition: buffers.hh:503
PacketPtr packet
FetchRequests carry packets while they're in the requests and transfers responses queues...
Definition: fetch1.hh:130
void setFault(Fault fault_)
Set fault and possible clear the bubble flag.
Definition: pipe_data.cc:165
MinorCPU is an in-order CPU model with four fixed pipeline stages:
Definition: cpu.hh:79
void evaluate()
Pass on input/buffer data to the output if you can.
Definition: fetch1.cc:572
Encapsulate wires on either input or output of the latch.
Definition: buffers.hh:243
Bitfield< 11 > id
Definition: miscregs.hh:124
TheISA::PCState target
Starting PC of that stream.
Definition: pipe_data.hh:121
void adoptPacketData(Packet *packet)
Use the data from a packet as line instead of allocating new space.
Definition: pipe_data.cc:185
FetchQueue transfers
Queue of in-memory system requests and responses.
Definition: fetch1.hh:300
unsigned int occupiedSpace() const
Number of slots already occupied in this buffer.
Definition: buffers.hh:467
IcachePort icachePort
IcachePort to pass to the CPU.
Definition: fetch1.hh:204
std::shared_ptr< FaultBase > Fault
Definition: types.hh:184
unsigned int fetchLimit
Maximum number of fetches allowed in flight (in queues or memory)
Definition: fetch1.hh:218
ThreadID threadId
The thread to which this line/instruction belongs.
Definition: dyn_inst.hh:83
void minorTraceResponseLine(const std::string &name, FetchRequestPtr response) const
Print the appropriate MinorLine line for a fetch response.
Definition: fetch1.cc:397
void allocate()
Allocate memory for the packet.
Definition: packet.hh:1082
bool hasPaddr() const
Accessor for paddr.
Definition: request.hh:513
ProbePointArg< PacketInfo > Packet
Packet probe point.
Definition: mem.hh:102
ThreadID getScheduledThread()
Use the current threading policy to determine the next thread to fetch from.
Definition: fetch1.cc:116
virtual void recvReqRetry()
Definition: fetch1.cc:453

Generated on Fri Jun 9 2017 13:03:42 for gem5 by doxygen 1.8.6