gem5  v22.1.0.0
pipeline.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2014, 2020 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 
38 #include "cpu/minor/pipeline.hh"
39 
40 #include <algorithm>
41 
42 #include "cpu/minor/decode.hh"
43 #include "cpu/minor/execute.hh"
44 #include "cpu/minor/fetch1.hh"
45 #include "cpu/minor/fetch2.hh"
46 #include "debug/Drain.hh"
47 #include "debug/MinorCPU.hh"
48 #include "debug/MinorTrace.hh"
49 #include "debug/Quiesce.hh"
50 
51 namespace gem5
52 {
53 
55 namespace minor
56 {
57 
58 Pipeline::Pipeline(MinorCPU &cpu_, const BaseMinorCPUParams &params) :
59  Ticked(cpu_, &(cpu_.BaseCPU::baseStats.numCycles)),
60  cpu(cpu_),
61  allow_idling(params.enableIdling),
62  f1ToF2(cpu.name() + ".f1ToF2", "lines",
63  params.fetch1ToFetch2ForwardDelay),
64  f2ToF1(cpu.name() + ".f2ToF1", "prediction",
65  params.fetch1ToFetch2BackwardDelay, true),
66  f2ToD(cpu.name() + ".f2ToD", "insts",
67  params.fetch2ToDecodeForwardDelay),
68  dToE(cpu.name() + ".dToE", "insts",
69  params.decodeToExecuteForwardDelay),
70  eToF1(cpu.name() + ".eToF1", "branch",
71  params.executeBranchDelay),
72  execute(cpu.name() + ".execute", cpu, params,
73  dToE.output(), eToF1.input()),
74  decode(cpu.name() + ".decode", cpu, params,
75  f2ToD.output(), dToE.input(), execute.inputBuffer),
76  fetch2(cpu.name() + ".fetch2", cpu, params,
77  f1ToF2.output(), eToF1.output(), f2ToF1.input(), f2ToD.input(),
78  decode.inputBuffer),
79  fetch1(cpu.name() + ".fetch1", cpu, params,
80  eToF1.output(), f1ToF2.input(), f2ToF1.output(), fetch2.inputBuffer),
81  activityRecorder(cpu.name() + ".activity", Num_StageId,
82  /* The max depth of inter-stage FIFOs */
83  std::max(params.fetch1ToFetch2ForwardDelay,
84  std::max(params.fetch2ToDecodeForwardDelay,
85  std::max(params.decodeToExecuteForwardDelay,
86  params.executeBranchDelay)))),
87  needToSignalDrained(false)
88 {
89  if (params.fetch1ToFetch2ForwardDelay < 1) {
90  fatal("%s: fetch1ToFetch2ForwardDelay must be >= 1 (%d)\n",
91  cpu.name(), params.fetch1ToFetch2ForwardDelay);
92  }
93 
94  if (params.fetch2ToDecodeForwardDelay < 1) {
95  fatal("%s: fetch2ToDecodeForwardDelay must be >= 1 (%d)\n",
96  cpu.name(), params.fetch2ToDecodeForwardDelay);
97  }
98 
99  if (params.decodeToExecuteForwardDelay < 1) {
100  fatal("%s: decodeToExecuteForwardDelay must be >= 1 (%d)\n",
101  cpu.name(), params.decodeToExecuteForwardDelay);
102  }
103 
104  if (params.executeBranchDelay < 1) {
105  fatal("%s: executeBranchDelay must be >= 1\n",
106  cpu.name(), params.executeBranchDelay);
107  }
108 }
109 
110 void
112 {
113  fetch1.minorTrace();
114  f1ToF2.minorTrace();
115  f2ToF1.minorTrace();
116  fetch2.minorTrace();
117  f2ToD.minorTrace();
118  decode.minorTrace();
119  dToE.minorTrace();
121  eToF1.minorTrace();
123 }
124 
125 void
127 {
129  cpu.tick();
130 
131  /* Note that it's important to evaluate the stages in order to allow
132  * 'immediate', 0-time-offset TimeBuffer activity to be visible from
133  * later stages to earlier ones in the same cycle */
134  execute.evaluate();
135  decode.evaluate();
136  fetch2.evaluate();
137  fetch1.evaluate();
138 
139  if (debug::MinorTrace)
140  minorTrace();
141 
142  /* Update the time buffers after the stages */
143  f1ToF2.evaluate();
144  f2ToF1.evaluate();
145  f2ToD.evaluate();
146  dToE.evaluate();
147  eToF1.evaluate();
148 
149  /* The activity recorder must be be called after all the stages and
150  * before the idler (which acts on the advice of the activity recorder */
152 
153  if (allow_idling) {
154  /* Become idle if we can but are not draining */
156  DPRINTF(Quiesce, "Suspending as the processor is idle\n");
157  stop();
158  }
159 
160  /* Deactivate all stages. Note that the stages *could*
161  * activate and deactivate themselves but that's fraught
162  * with additional difficulty.
163  * As organised herre */
169  }
170 
171  if (needToSignalDrained) /* Must be draining */
172  {
173  DPRINTF(Drain, "Still draining\n");
174  if (isDrained()) {
175  DPRINTF(Drain, "Signalling end of draining\n");
177  needToSignalDrained = false;
178  stop();
179  }
180  }
181 }
182 
185 {
186  return fetch1.getIcachePort();
187 }
188 
191 {
192  return execute.getDcachePort();
193 }
194 
195 void
197 {
198  fetch1.wakeupFetch(tid);
199 }
200 
201 bool
203 {
204  DPRINTF(MinorCPU, "Draining pipeline by halting inst fetches. "
205  " Execution should drain naturally\n");
206 
207  execute.drain();
208 
209  /* Make sure that needToSignalDrained isn't accidentally set if we
210  * are 'pre-drained' */
211  bool drained = isDrained();
212  needToSignalDrained = !drained;
213 
214  return drained;
215 }
216 
217 void
219 {
220  DPRINTF(Drain, "Drain resume\n");
221 
222  for (ThreadID tid = 0; tid < cpu.numThreads; tid++) {
223  fetch1.wakeupFetch(tid);
224  }
225 
227 }
228 
229 bool
231 {
232  bool fetch1_drained = fetch1.isDrained();
233  bool fetch2_drained = fetch2.isDrained();
234  bool decode_drained = decode.isDrained();
235  bool execute_drained = execute.isDrained();
236 
237  bool f1_to_f2_drained = f1ToF2.empty();
238  bool f2_to_f1_drained = f2ToF1.empty();
239  bool f2_to_d_drained = f2ToD.empty();
240  bool d_to_e_drained = dToE.empty();
241 
242  bool ret = fetch1_drained && fetch2_drained &&
243  decode_drained && execute_drained &&
244  f1_to_f2_drained && f2_to_f1_drained &&
245  f2_to_d_drained && d_to_e_drained;
246 
247  DPRINTF(MinorCPU, "Pipeline undrained stages state:%s%s%s%s%s%s%s%s\n",
248  (fetch1_drained ? "" : " Fetch1"),
249  (fetch2_drained ? "" : " Fetch2"),
250  (decode_drained ? "" : " Decode"),
251  (execute_drained ? "" : " Execute"),
252  (f1_to_f2_drained ? "" : " F1->F2"),
253  (f2_to_f1_drained ? "" : " F2->F1"),
254  (f2_to_d_drained ? "" : " F2->D"),
255  (d_to_e_drained ? "" : " D->E")
256  );
257 
258  return ret;
259 }
260 
261 } // namespace minor
262 } // namespace gem5
#define DPRINTF(x,...)
Definition: trace.hh:186
void deactivateStage(const int idx)
Deactivates a stage.
Definition: activity.cc:108
bool active()
Returns if the CPU should be active.
Definition: activity.hh:91
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
Definition: base.hh:367
Provide a non-protected base class for Minor's Ports as derived classes are created by Fetch1 and Exe...
Definition: cpu.hh:107
MinorCPU is an in-order CPU model with four fixed pipeline stages:
Definition: cpu.hh:86
void signalDrainDone()
Signal from Pipeline that MinorCPU should signal that a drain is complete and set its drainState.
Definition: cpu.cc:189
void tick()
The tick method in the MinorCPU is simply updating the cycle counters as the ticking of the pipeline ...
Definition: cpu.hh:199
virtual std::string name() const
Definition: named.hh:47
Ticked attaches gem5's event queue/scheduler to evaluate calls and provides a start/stop interface to...
void stop()
Cancel the next tick event and issue no more.
void evaluate()
Pass on input/buffer data to the output if you can.
Definition: decode.cc:128
void minorTrace() const
Definition: decode.cc:342
bool isDrained()
Is this stage drained? For Decoed, draining is initiated by Execute halting Fetch1 causing Fetch2 to ...
Definition: decode.cc:331
void evaluate()
Pass on input/buffer data to the output if you can.
Definition: execute.cc:1459
unsigned int drain()
Like the drain interface on SimObject.
Definition: execute.cc:1863
MinorCPU::MinorCPUPort & getDcachePort()
Returns the DcachePort owned by this Execute to pass upwards.
Definition: execute.cc:1928
void minorTrace() const
Definition: execute.cc:1692
bool isDrained()
After thread suspension, has Execute been drained of in-flight instructions and memory accesses.
Definition: execute.cc:1885
MinorCPU::MinorCPUPort & getIcachePort()
Returns the IcachePort owned by this Fetch1.
Definition: fetch1.hh:397
void wakeupFetch(ThreadID tid)
Initiate fetch1 fetching.
Definition: fetch1.cc:718
bool isDrained()
Is this stage drained? For Fetch1, draining is initiated by Execute signalling a branch with the reas...
Definition: fetch1.cc:732
void evaluate()
Pass on input/buffer data to the output if you can.
Definition: fetch1.cc:577
void minorTrace() const
Definition: fetch1.cc:766
void evaluate()
Pass on input/buffer data to the output if you can.
Definition: fetch2.cc:240
bool isDrained()
Is this stage drained? For Fetch2, draining is initiated by Execute halting Fetch1 causing Fetch2 to ...
Definition: fetch2.cc:591
void minorTrace() const
Definition: fetch2.cc:632
void evaluate()
Ticked interface.
Definition: activity.hh:62
Latch< BranchData > f2ToF1
Definition: pipeline.hh:82
Pipeline(MinorCPU &cpu_, const BaseMinorCPUParams &params)
Definition: pipeline.cc:58
Latch< ForwardLineData > f1ToF2
Definition: pipeline.hh:81
void minorTrace() const
Definition: pipeline.cc:111
MinorCPU::MinorCPUPort & getDataPort()
Return the DcachePort belonging to Execute for the CPU.
Definition: pipeline.cc:190
bool allow_idling
Allow cycles to be skipped when the pipeline is idle.
Definition: pipeline.hh:79
bool needToSignalDrained
True after drain is called but draining isn't complete.
Definition: pipeline.hh:109
MinorActivityRecorder activityRecorder
Activity recording for the pipeline.
Definition: pipeline.hh:95
void evaluate() override
A custom evaluate allows report in the right place (between stages and pipeline advance)
Definition: pipeline.cc:126
MinorCPU::MinorCPUPort & getInstPort()
Functions below here are BaseCPU operations passed on to pipeline stages.
Definition: pipeline.cc:184
void wakeupFetch(ThreadID tid)
Wake up the Fetch unit.
Definition: pipeline.cc:196
Latch< BranchData > eToF1
Definition: pipeline.hh:85
Latch< ForwardInstData > dToE
Definition: pipeline.hh:84
bool drain()
Try to drain the CPU.
Definition: pipeline.cc:202
Latch< ForwardInstData > f2ToD
Definition: pipeline.hh:83
bool isDrained()
Test to see if the CPU is drained.
Definition: pipeline.cc:230
All the fun of executing instructions from Decode and sending branch/new instruction stream info.
Fetch1 is responsible for fetching "lines" from memory and passing them to Fetch2.
Fetch2 receives lines of data from Fetch1, separates them into instructions and passes them to Decode...
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:190
Decode collects macro-ops from Fetch2 and splits them into micro-ops passed to Execute.
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:235
static void output(const char *filename)
Definition: debug.cc:60
GEM5_DEPRECATED_NAMESPACE(GuestABI, guest_abi)
Minor contains all the definitions within the MinorCPU apart from the CPU class itself.
Overload hash function for BasicBlockRange type.
Definition: misc.hh:2826
The constructed pipeline.
const std::string & name()
Definition: trace.cc:49

Generated on Wed Dec 21 2022 10:22:30 for gem5 by doxygen 1.9.1