gem5  v22.1.0.0
base.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2012, 2015, 2017, 2018, 2020 ARM Limited
3  * Copyright (c) 2013 Advanced Micro Devices, Inc.
4  * All rights reserved
5  *
6  * The license below extends only to copyright in the software and shall
7  * not be construed as granting a license to any other intellectual
8  * property including but not limited to intellectual property relating
9  * to a hardware implementation of the functionality of the software
10  * licensed hereunder. You may use the software subject to the license
11  * terms below provided that you ensure that this notice is replicated
12  * unmodified and in its entirety in all distributions of the software,
13  * modified or unmodified, in source code or in binary form.
14  *
15  * Copyright (c) 2002-2005 The Regents of The University of Michigan
16  * All rights reserved.
17  *
18  * Redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions are
20  * met: redistributions of source code must retain the above copyright
21  * notice, this list of conditions and the following disclaimer;
22  * redistributions in binary form must reproduce the above copyright
23  * notice, this list of conditions and the following disclaimer in the
24  * documentation and/or other materials provided with the distribution;
25  * neither the name of the copyright holders nor the names of its
26  * contributors may be used to endorse or promote products derived from
27  * this software without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  */
41 
42 #include "cpu/simple/base.hh"
43 
44 #include "arch/generic/decoder.hh"
45 #include "base/cprintf.hh"
46 #include "base/inifile.hh"
47 #include "base/loader/symtab.hh"
48 #include "base/logging.hh"
49 #include "base/pollevent.hh"
50 #include "base/trace.hh"
51 #include "base/types.hh"
52 #include "cpu/base.hh"
53 #include "cpu/checker/cpu.hh"
55 #include "cpu/exetrace.hh"
56 #include "cpu/null_static_inst.hh"
57 #include "cpu/pred/bpred_unit.hh"
59 #include "cpu/simple_thread.hh"
60 #include "cpu/smt.hh"
61 #include "cpu/static_inst.hh"
62 #include "cpu/thread_context.hh"
63 #include "debug/Decode.hh"
64 #include "debug/ExecFaulting.hh"
65 #include "debug/Fetch.hh"
66 #include "debug/HtmCpu.hh"
67 #include "debug/Quiesce.hh"
68 #include "mem/packet.hh"
69 #include "mem/request.hh"
70 #include "params/BaseSimpleCPU.hh"
71 #include "sim/byteswap.hh"
72 #include "sim/debug.hh"
73 #include "sim/faults.hh"
74 #include "sim/full_system.hh"
75 #include "sim/sim_events.hh"
76 #include "sim/sim_object.hh"
77 #include "sim/stats.hh"
78 #include "sim/system.hh"
79 
80 namespace gem5
81 {
82 
83 BaseSimpleCPU::BaseSimpleCPU(const BaseSimpleCPUParams &p)
84  : BaseCPU(p),
85  curThread(0),
86  branchPred(p.branchPred),
87  traceData(NULL),
88  _status(Idle)
89 {
90  SimpleThread *thread;
91 
92  for (unsigned i = 0; i < numThreads; i++) {
93  if (FullSystem) {
94  thread = new SimpleThread(
95  this, i, p.system, p.mmu, p.isa[i], p.decoder[i]);
96  } else {
97  thread = new SimpleThread(
98  this, i, p.system, p.workload[i], p.mmu, p.isa[i],
99  p.decoder[i]);
100  }
101  threadInfo.push_back(new SimpleExecContext(this, thread));
102  ThreadContext *tc = thread->getTC();
103  threadContexts.push_back(tc);
104  }
105 
106  if (p.checker) {
107  if (numThreads != 1)
108  fatal("Checker currently does not support SMT");
109 
110  BaseCPU *temp_checker = p.checker;
111  checker = dynamic_cast<CheckerCPU *>(temp_checker);
112  checker->setSystem(p.system);
113  // Manipulate thread context
114  ThreadContext *cpu_tc = threadContexts[0];
116  cpu_tc, this->checker);
117  } else {
118  checker = NULL;
119  }
120 }
121 
122 void
124 {
125  Addr oldpc, pc = threadInfo[curThread]->thread->pcState().instAddr();
126  do {
127  oldpc = pc;
128  threadInfo[curThread]->thread->pcEventQueue.service(
129  oldpc, threadContexts[curThread]);
130  pc = threadInfo[curThread]->thread->pcState().instAddr();
131  } while (oldpc != pc);
132 }
133 
134 void
136 {
137  if (numThreads > 1) {
139  !threadInfo[curThread]->stayAtPC) {
140  // Swap active threads
141  if (!activeThreads.empty()) {
142  curThread = activeThreads.front();
143  activeThreads.pop_front();
144  activeThreads.push_back(curThread);
145  }
146  }
147  }
148 }
149 
150 void
152 {
154 
156  t_info.numInst++;
157  t_info.execContextStats.numInsts++;
158  }
159  t_info.numOp++;
160  t_info.execContextStats.numOps++;
161 }
162 
163 Counter
165 {
166  Counter total_inst = 0;
167  for (auto& t_info : threadInfo) {
168  total_inst += t_info->numInst;
169  }
170 
171  return total_inst;
172 }
173 
174 Counter
176 {
177  Counter total_op = 0;
178  for (auto& t_info : threadInfo) {
179  total_op += t_info->numOp;
180  }
181 
182  return total_op;
183 }
184 
186 {
187 }
188 
189 void
191 {
192  // for now, these are equivalent
193  suspendContext(thread_num);
195 }
196 
197 void
199 {
201  for (auto &thread_info : threadInfo) {
202  thread_info->execContextStats.notIdleFraction = (_status != Idle);
203  }
204 }
205 
206 void
208 {
209  assert(_status == Idle || _status == Running);
210 
211  threadInfo[tid]->thread->serialize(cp);
212 }
213 
214 void
216 {
217  threadInfo[tid]->thread->unserialize(cp);
218 }
219 
220 void
221 change_thread_state(ThreadID tid, int activate, int priority)
222 {
223 }
224 
225 void
227 {
228  getCpuAddrMonitor(tid)->gotWakeup = true;
229 
230  if (threadInfo[tid]->thread->status() == ThreadContext::Suspended) {
231  DPRINTF(Quiesce,"[tid:%d] Suspended Processor awoke\n", tid);
232  threadInfo[tid]->thread->activate();
233  }
234 }
235 
236 void
238 {
239  if (debug::ExecFaulting) {
240  traceData->setFaulting(true);
241  } else {
242  delete traceData;
243  traceData = NULL;
244  }
245 }
246 
247 void
249 {
251  SimpleThread* thread = t_info.thread;
252  ThreadContext* tc = thread->getTC();
253 
254  if (checkInterrupts(curThread)) {
255  Fault interrupt = interrupts[curThread]->getInterrupt();
256 
257  if (interrupt != NoFault) {
258  // hardware transactional memory
259  // Postpone taking interrupts while executing transactions.
260  assert(!std::dynamic_pointer_cast<GenericHtmFailureFault>(
261  interrupt));
262  if (t_info.inHtmTransactionalState()) {
263  DPRINTF(HtmCpu, "Deferring pending interrupt - %s -"
264  "due to transactional state\n",
265  interrupt->name());
266  return;
267  }
268 
269  t_info.fetchOffset = 0;
270  interrupts[curThread]->updateIntrInfo();
271  interrupt->invoke(tc);
272  thread->decoder->reset();
273  }
274  }
275 }
276 
277 
278 void
280 {
282  SimpleThread* thread = t_info.thread;
283 
284  auto &decoder = thread->decoder;
285  Addr instAddr = thread->pcState().instAddr();
286  Addr fetchPC = (instAddr & decoder->pcMask()) + t_info.fetchOffset;
287 
288  // set up memory request for instruction fetch
289  DPRINTF(Fetch, "Fetch: Inst PC:%08p, Fetch PC:%08p\n", instAddr, fetchPC);
290 
291  req->setVirt(fetchPC, decoder->moreBytesSize(), Request::INST_FETCH,
292  instRequestorId(), instAddr);
293 }
294 
295 void
297 {
300 }
301 
302 void
304 {
306  SimpleThread* thread = t_info.thread;
307 
308  // resets predicates
309  t_info.setPredicate(true);
310  t_info.setMemAccPredicate(true);
311 
312  // decode the instruction
313  set(preExecuteTempPC, thread->pcState());
314  auto &pc_state = *preExecuteTempPC;
315 
316  auto &decoder = thread->decoder;
317 
318  if (isRomMicroPC(pc_state.microPC())) {
319  t_info.stayAtPC = false;
320  curStaticInst = decoder->fetchRomMicroop(
321  pc_state.microPC(), curMacroStaticInst);
322  } else if (!curMacroStaticInst) {
323  //We're not in the middle of a macro instruction
324  StaticInstPtr instPtr = NULL;
325 
326  //Predecode, ie bundle up an ExtMachInst
327  //If more fetch data is needed, pass it in.
328  Addr fetch_pc =
329  (pc_state.instAddr() & decoder->pcMask()) + t_info.fetchOffset;
330 
331  decoder->moreBytes(pc_state, fetch_pc);
332 
333  //Decode an instruction if one is ready. Otherwise, we'll have to
334  //fetch beyond the MachInst at the current pc.
335  instPtr = decoder->decode(pc_state);
336  if (instPtr) {
337  t_info.stayAtPC = false;
338  thread->pcState(pc_state);
339  } else {
340  t_info.stayAtPC = true;
341  t_info.fetchOffset += decoder->moreBytesSize();
342  }
343 
344  //If we decoded an instruction and it's microcoded, start pulling
345  //out micro ops
346  if (instPtr && instPtr->isMacroop()) {
347  curMacroStaticInst = instPtr;
348  curStaticInst =
349  curMacroStaticInst->fetchMicroop(pc_state.microPC());
350  } else {
351  curStaticInst = instPtr;
352  }
353  } else {
354  //Read the next micro op from the macro op
355  curStaticInst = curMacroStaticInst->fetchMicroop(pc_state.microPC());
356  }
357 
358  //If we decoded an instruction this "tick", record information about it.
359  if (curStaticInst) {
360 #if TRACING_ON
361  traceData = tracer->getInstRecord(curTick(), thread->getTC(),
363 #endif // TRACING_ON
364  }
365 
366  if (branchPred && curStaticInst &&
368  // Use a fake sequence number since we only have one
369  // instruction in flight at the same time.
370  const InstSeqNum cur_sn(0);
371  set(t_info.predPC, thread->pcState());
372  const bool predict_taken(
373  branchPred->predict(curStaticInst, cur_sn, *t_info.predPC,
374  curThread));
375 
376  if (predict_taken)
378  }
379 }
380 
381 void
383 {
385 
386  assert(curStaticInst);
387 
388  Addr instAddr = threadContexts[curThread]->pcState().instAddr();
389 
390  if (curStaticInst->isMemRef()) {
391  t_info.execContextStats.numMemRefs++;
392  }
393 
394  if (curStaticInst->isLoad()) {
395  ++t_info.numLoad;
396  }
397 
398  if (curStaticInst->isControl()) {
399  ++t_info.execContextStats.numBranches;
400  }
401 
402  /* Power model statistics */
403  //integer alu accesses
404  if (curStaticInst->isInteger()){
406  t_info.execContextStats.numIntInsts++;
407  }
408 
409  //float alu accesses
410  if (curStaticInst->isFloating()){
412  t_info.execContextStats.numFpInsts++;
413  }
414 
415  //vector alu accesses
416  if (curStaticInst->isVector()){
418  t_info.execContextStats.numVecInsts++;
419  }
420 
421  //number of function calls/returns to get window accesses
424  }
425 
426  //the number of branch predictions that will be made
427  if (curStaticInst->isCondCtrl()){
429  }
430 
431  //result bus acceses
432  if (curStaticInst->isLoad()){
434  }
435 
438  }
439  /* End power model statistics */
440 
442 
443  if (FullSystem)
444  traceFunctions(instAddr);
445 
446  if (traceData) {
447  traceData->dump();
448  delete traceData;
449  traceData = NULL;
450  }
451 
452  // Call CPU instruction commit probes
453  probeInstCommit(curStaticInst, instAddr);
454 }
455 
456 void
458 {
460  SimpleThread* thread = t_info.thread;
461 
462  const bool branching = thread->pcState().branching();
463 
464  //Since we're moving to a new pc, zero out the offset
465  t_info.fetchOffset = 0;
466  if (fault != NoFault) {
468  fault->invoke(threadContexts[curThread], curStaticInst);
469  thread->decoder->reset();
470  } else {
471  if (curStaticInst) {
474  curStaticInst->advancePC(thread);
475  }
476  }
477 
479  // Use a fake sequence number since we only have one
480  // instruction in flight at the same time.
481  const InstSeqNum cur_sn(0);
482 
483  if (*t_info.predPC == thread->pcState()) {
484  // Correctly predicted branch
485  branchPred->update(cur_sn, curThread);
486  } else {
487  // Mis-predicted branch
488  branchPred->squash(cur_sn, thread->pcState(), branching,
489  curThread);
491  }
492  }
493 }
494 
495 } // namespace gem5
#define DPRINTF(x,...)
Definition: trace.hh:186
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
RequestorID instRequestorId() const
Reads this CPU's unique instruction requestor ID.
Definition: base.hh:191
trace::InstTracer * tracer
Definition: base.hh:258
AddressMonitor * getCpuAddrMonitor(ThreadID tid)
Definition: base.hh:633
void updateCycleCounters(CPUState state)
base method keeping track of cycle progression
Definition: base.hh:544
@ CPU_STATE_SLEEP
Definition: base.hh:535
virtual void suspendContext(ThreadID thread_num)
Notify the CPU that the indicated context is now suspended.
Definition: base.cc:494
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
Definition: base.hh:367
bool checkInterrupts(ThreadID tid) const
Definition: base.hh:250
std::vector< BaseInterrupts * > interrupts
Definition: base.hh:220
void traceFunctions(Addr pc)
Definition: base.hh:584
std::vector< ThreadContext * > threadContexts
Definition: base.hh:256
virtual void probeInstCommit(const StaticInstPtr &inst, Addr pc)
Helper method to trigger PMU probes for a committed instruction.
Definition: base.cc:353
void preExecute()
Definition: base.cc:303
void checkPcEventQueue()
Definition: base.cc:123
BaseSimpleCPU(const BaseSimpleCPUParams &params)
Definition: base.cc:83
void serializeThread(CheckpointOut &cp, ThreadID tid) const override
Serialize a single thread.
Definition: base.cc:207
void resetStats() override
Callback to reset stats.
Definition: base.cc:198
branch_prediction::BPredUnit * branchPred
Definition: base.hh:87
virtual ~BaseSimpleCPU()
Definition: base.cc:185
ThreadID curThread
Definition: base.hh:86
void unserializeThread(CheckpointIn &cp, ThreadID tid) override
Unserialize one thread.
Definition: base.cc:215
void wakeup(ThreadID tid) override
Definition: base.cc:226
StaticInstPtr curMacroStaticInst
Definition: base.hh:105
void checkForInterrupts()
Definition: base.cc:248
void traceFault()
Handler used when encountering a fault; its purpose is to tear down the InstRecord.
Definition: base.cc:237
void advancePC(const Fault &fault)
Definition: base.cc:457
void swapActiveThread()
Definition: base.cc:135
void setupFetchRequest(const RequestPtr &req)
Definition: base.cc:279
std::unique_ptr< PCStateBase > preExecuteTempPC
Definition: base.hh:133
std::list< ThreadID > activeThreads
Definition: base.hh:101
std::vector< SimpleExecContext * > threadInfo
Definition: base.hh:100
Counter totalOps() const override
Definition: base.cc:175
StaticInstPtr curStaticInst
Current instruction.
Definition: base.hh:104
Status _status
Definition: base.hh:123
Counter totalInsts() const override
Definition: base.cc:164
CheckerCPU * checker
Definition: base.hh:98
void haltContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now halted.
Definition: base.cc:190
void postExecute()
Definition: base.cc:382
trace::InstRecord * traceData
Definition: base.hh:97
void serviceInstCountEvents()
Definition: base.cc:296
void countInst()
Definition: base.cc:151
CheckerCPU class.
Definition: cpu.hh:85
void setSystem(System *system)
Definition: cpu.cc:96
Derived ThreadContext class for use with the Checker.
virtual void reset()
Definition: decoder.hh:63
virtual bool branching() const =0
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
Definition: pcstate.hh:107
@ INST_FETCH
The request was an instruction fetch.
Definition: request.hh:115
Counter numInst
PER-THREAD STATS.
Definition: exec_context.hh:74
void setMemAccPredicate(bool val) override
void setPredicate(bool val) override
std::unique_ptr< PCStateBase > predPC
Definition: exec_context.hh:71
bool inHtmTransactionalState() const override
gem5::SimpleExecContext::ExecContextStats execContextStats
SimpleThread * thread
Definition: exec_context.hh:62
The SimpleThread object provides a combination of the ThreadState object and the ThreadContext interf...
ThreadContext * getTC()
Returns the pointer to this SimpleThread's ThreadContext.
const PCStateBase & pcState() const override
EventQueue comInstEventQueue
An instruction-based event queue.
InstDecoder * decoder
bool isInteger() const
Definition: static_inst.hh:156
virtual StaticInstPtr fetchMicroop(MicroPC upc) const
Return the microop that goes with a particular micropc.
Definition: static_inst.cc:39
OpClass opClass() const
Operation class. Used to select appropriate function unit in issue.
Definition: static_inst.hh:210
bool isLoad() const
Definition: static_inst.hh:147
virtual void advancePC(PCStateBase &pc_state) const =0
bool isFloating() const
Definition: static_inst.hh:157
bool isMacroop() const
Definition: static_inst.hh:185
bool isReturn() const
Definition: static_inst.hh:162
bool isMemRef() const
Definition: static_inst.hh:143
bool isVector() const
Definition: static_inst.hh:158
bool isLastMicroop() const
Definition: static_inst.hh:188
bool isStore() const
Definition: static_inst.hh:148
bool isAtomic() const
Definition: static_inst.hh:149
bool isMicroop() const
Definition: static_inst.hh:186
bool isCall() const
Definition: static_inst.hh:161
bool isCondCtrl() const
Definition: static_inst.hh:165
bool isDelayedCommit() const
Definition: static_inst.hh:187
bool isControl() const
Definition: static_inst.hh:160
ThreadContext is the external interface to all thread state for anything outside of the CPU.
@ Suspended
Temporarily inactive.
void update(const InstSeqNum &done_sn, ThreadID tid)
Tells the branch predictor to commit any updates until the given sequence number.
Definition: bpred_unit.cc:310
bool predict(const StaticInstPtr &inst, const InstSeqNum &seqNum, PCStateBase &pc, ThreadID tid)
Predicts whether or not the instruction is a taken branch, and the target of the branch if it is take...
Definition: bpred_unit.cc:132
void squash(const InstSeqNum &squashed_sn, ThreadID tid)
Squashes all outstanding updates until a given sequence number.
Definition: bpred_unit.cc:333
void setFaulting(bool val)
Definition: insttracer.hh:260
virtual void dump()=0
virtual InstRecord * getInstRecord(Tick when, ThreadContext *tc, const StaticInstPtr staticInst, const PCStateBase &pc, const StaticInstPtr macroStaticInst=nullptr)=0
void serviceEvents(Tick when)
process all events up to the given timestamp.
Definition: eventq.hh:876
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:190
virtual void resetStats()
Callback to reset stats.
Definition: group.cc:86
Declaration of IniFile object.
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 12, 11 > set
Definition: misc_types.hh:709
Bitfield< 4 > pc
Bitfield< 54 > p
Definition: pagetable.hh:70
double Counter
All counters are of 64-bit values.
Definition: types.hh:47
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::shared_ptr< FaultBase > Fault
Definition: types.hh:248
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:235
std::shared_ptr< Request > RequestPtr
Definition: request.hh:92
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
std::ostream CheckpointOut
Definition: serialize.hh:66
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:220
static bool isRomMicroPC(MicroPC upc)
Definition: types.hh:166
void change_thread_state(ThreadID tid, int activate, int priority)
Changes the status and priority of the thread with the given number.
Definition: base.cc:221
const StaticInstPtr nullStaticInstPtr
Statically allocated null StaticInstPtr.
constexpr decltype(nullptr) NoFault
Definition: types.hh:253
uint64_t InstSeqNum
Definition: inst_seq.hh:40
output decoder
Definition: nop.cc:61
Declaration of the Packet class.
Declaration of a request, the overall memory request consisting of the parts of the request that are ...
Defines SMT_MAX_THREADS.
statistics::Scalar numBranchMispred
Number of misprediced branches.
statistics::Scalar numPredictedBranches
Number of branches predicted as taken.

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