gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
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"
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
80namespace gem5
81{
82
83BaseSimpleCPU::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
122void
124{
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
134void
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
150void
152{
154
156 t_info.numInst++;
157 }
158 t_info.numOp++;
159}
160
161void
163{
165
167 // increment thread level numInsts fetched count
168 fetchStats[t_info.thread->threadId()]->numInsts++;
169 }
170 // increment thread level numOps fetched count
171 fetchStats[t_info.thread->threadId()]->numOps++;
172}
173
174void
176{
178
180 // increment thread level and core level numInsts count
181 commitStats[t_info.thread->threadId()]->numInsts++;
183 }
184 // increment thread level numOps count
185 commitStats[t_info.thread->threadId()]->numOps++;
186}
187
190{
191 Counter total_inst = 0;
192 for (auto& t_info : threadInfo) {
193 total_inst += t_info->numInst;
194 }
195
196 return total_inst;
197}
198
201{
202 Counter total_op = 0;
203 for (auto& t_info : threadInfo) {
204 total_op += t_info->numOp;
205 }
206
207 return total_op;
208}
209
213
214void
216{
217 // for now, these are equivalent
218 suspendContext(thread_num);
220}
221
222void
224{
226 for (auto &thread_info : threadInfo) {
227 thread_info->execContextStats.notIdleFraction = (_status != Idle);
228 }
229}
230
231void
233{
234 assert(_status == Idle || _status == Running);
235
236 threadInfo[tid]->thread->serialize(cp);
237}
238
239void
241{
242 threadInfo[tid]->thread->unserialize(cp);
243}
244
245void
249
250void
252{
253 getCpuAddrMonitor(tid)->gotWakeup = true;
254
255 if (threadInfo[tid]->thread->status() == ThreadContext::Suspended) {
256 DPRINTF(Quiesce,"[tid:%d] Suspended Processor awoke\n", tid);
257 threadInfo[tid]->thread->activate();
258 }
259}
260
261void
263{
264 if (debug::ExecFaulting) {
265 traceData->setFaulting(true);
266 } else {
267 delete traceData;
268 traceData = NULL;
269 }
270}
271
272void
274{
276 SimpleThread* thread = t_info.thread;
277 ThreadContext* tc = thread->getTC();
278
280 Fault interrupt = interrupts[curThread]->getInterrupt();
281
282 if (interrupt != NoFault) {
283 // hardware transactional memory
284 // Postpone taking interrupts while executing transactions.
285 assert(!std::dynamic_pointer_cast<GenericHtmFailureFault>(
286 interrupt));
287 if (t_info.inHtmTransactionalState()) {
288 DPRINTF(HtmCpu, "Deferring pending interrupt - %s -"
289 "due to transactional state\n",
290 interrupt->name());
291 return;
292 }
293
294 t_info.fetchOffset = 0;
295 interrupts[curThread]->updateIntrInfo();
296 interrupt->invoke(tc);
297 thread->decoder->reset();
298 }
299 }
300}
301
302
303void
305{
307 SimpleThread* thread = t_info.thread;
308
309 auto &decoder = thread->decoder;
310 Addr instAddr = thread->pcState().instAddr();
311 Addr fetchPC = (instAddr & decoder->pcMask()) + t_info.fetchOffset;
312
313 // set up memory request for instruction fetch
314 DPRINTF(Fetch, "Fetch: Inst PC:%08p, Fetch PC:%08p\n", instAddr, fetchPC);
315
316 req->setVirt(fetchPC, decoder->moreBytesSize(), Request::INST_FETCH,
317 instRequestorId(), instAddr);
318}
319
320void
326
327void
329{
331 SimpleThread* thread = t_info.thread;
332
333 // resets predicates
334 t_info.setPredicate(true);
335 t_info.setMemAccPredicate(true);
336
337 // decode the instruction
338 set(preExecuteTempPC, thread->pcState());
339 auto &pc_state = *preExecuteTempPC;
340
341 auto &decoder = thread->decoder;
342
343 if (isRomMicroPC(pc_state.microPC())) {
344 t_info.stayAtPC = false;
345 curStaticInst = decoder->fetchRomMicroop(
346 pc_state.microPC(), curMacroStaticInst);
347 } else if (!curMacroStaticInst) {
348 //We're not in the middle of a macro instruction
349 StaticInstPtr instPtr = NULL;
350
351 //Predecode, ie bundle up an ExtMachInst
352 //If more fetch data is needed, pass it in.
353 Addr fetch_pc =
354 (pc_state.instAddr() & decoder->pcMask()) + t_info.fetchOffset;
355
356 decoder->moreBytes(pc_state, fetch_pc);
357
358 //Decode an instruction if one is ready. Otherwise, we'll have to
359 //fetch beyond the MachInst at the current pc.
360 instPtr = decoder->decode(pc_state);
361 if (instPtr) {
362 t_info.stayAtPC = false;
363 thread->pcState(pc_state);
364 } else {
365 t_info.stayAtPC = true;
366 t_info.fetchOffset += decoder->moreBytesSize();
367 }
368
369 //If we decoded an instruction and it's microcoded, start pulling
370 //out micro ops
371 if (instPtr && instPtr->isMacroop()) {
372 curMacroStaticInst = instPtr;
374 curMacroStaticInst->fetchMicroop(pc_state.microPC());
375 } else {
376 curStaticInst = instPtr;
377 }
378 } else {
379 //Read the next micro op from the macro op
380 curStaticInst = curMacroStaticInst->fetchMicroop(pc_state.microPC());
381 }
382
383 //If we decoded an instruction this "tick", record information about it.
384 if (curStaticInst) {
385#if TRACING_ON
388#endif // TRACING_ON
389 }
390
391 if (branchPred && curStaticInst &&
393 // Use a fake sequence number since we only have one
394 // instruction in flight at the same time.
395 const InstSeqNum cur_sn(0);
396 set(t_info.predPC, thread->pcState());
397 const bool predict_taken(
398 branchPred->predict(curStaticInst, cur_sn, *t_info.predPC,
399 curThread));
400
401 if (predict_taken)
403 }
404
405 // increment the fetch instruction stat counters
406 if (curStaticInst) {
408 }
409}
410
411void
413{
415
416 assert(curStaticInst);
417
418 Addr instAddr = threadContexts[curThread]->pcState().instAddr();
419
420 if (curStaticInst->isMemRef()) {
421 executeStats[t_info.thread->threadId()]->numMemRefs++;
422 }
423
424 if (curStaticInst->isLoad()) {
425 ++t_info.numLoad;
426 }
427
428 if (curStaticInst->isControl()) {
429 ++fetchStats[t_info.thread->threadId()]->numBranches;
430 }
431
432 /* Power model statistics */
433 //integer alu accesses
434 if (curStaticInst->isInteger()){
435 executeStats[t_info.thread->threadId()]->numIntAluAccesses++;
436 commitStats[t_info.thread->threadId()]->numIntInsts++;
437 }
438
439 //float alu accesses
441 executeStats[t_info.thread->threadId()]->numFpAluAccesses++;
442 commitStats[t_info.thread->threadId()]->numFpInsts++;
443 }
444
445 //vector alu accesses
446 if (curStaticInst->isVector()){
447 executeStats[t_info.thread->threadId()]->numVecAluAccesses++;
448 commitStats[t_info.thread->threadId()]->numVecInsts++;
449 }
450
451 //Matrix alu accesses
452 if (curStaticInst->isMatrix()){
455 }
456
457 //number of function calls/returns to get window accesses
460 }
461
462 //result bus acceses
463 if (curStaticInst->isLoad()){
464 commitStats[t_info.thread->threadId()]->numLoadInsts++;
465 }
466
468 commitStats[t_info.thread->threadId()]->numStoreInsts++;
469 }
470 /* End power model statistics */
471
472 commitStats[t_info.thread->threadId()]
473 ->committedInstType[curStaticInst->opClass()]++;
474 commitStats[t_info.thread->threadId()]->updateComCtrlStats(curStaticInst);
475
476 /* increment the committed numInsts and numOps stats */
478
479 if (FullSystem)
480 traceFunctions(instAddr);
481
482 if (traceData) {
483 traceData->dump();
484 delete traceData;
485 traceData = NULL;
486 }
487
488 // Call CPU instruction commit probes
490}
491
492void
494{
496 SimpleThread* thread = t_info.thread;
497
498 const bool branching = thread->pcState().branching();
499
500 //Since we're moving to a new pc, zero out the offset
501 t_info.fetchOffset = 0;
502 if (fault != NoFault) {
504 fault->invoke(threadContexts[curThread], curStaticInst);
505 thread->decoder->reset();
506 } else {
507 if (curStaticInst) {
510 curStaticInst->advancePC(thread);
511 }
512 }
513
515 // Use a fake sequence number since we only have one
516 // instruction in flight at the same time.
517 const InstSeqNum cur_sn(0);
518
519 if (*t_info.predPC == thread->pcState()) {
520 // Correctly predicted branch
521 branchPred->update(cur_sn, curThread);
522 } else {
523 // Mis-predicted branch
524 branchPred->squash(cur_sn, thread->pcState(), branching,
525 curThread);
527 }
528 }
529}
530
531} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
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:195
trace::InstTracer * tracer
Definition base.hh:262
AddressMonitor * getCpuAddrMonitor(ThreadID tid)
Definition base.hh:656
void updateCycleCounters(CPUState state)
base method keeping track of cycle progression
Definition base.hh:561
@ CPU_STATE_SLEEP
Definition base.hh:552
std::vector< std::unique_ptr< CommitCPUStats > > commitStats
Definition base.hh:821
virtual void suspendContext(ThreadID thread_num)
Notify the CPU that the indicated context is now suspended.
Definition base.cc:550
gem5::BaseCPU::BaseCPUStats baseStats
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
Definition base.hh:390
std::vector< std::unique_ptr< ExecuteCPUStats > > executeStats
Definition base.hh:820
bool checkInterrupts(ThreadID tid) const
Definition base.hh:254
std::vector< BaseInterrupts * > interrupts
Definition base.hh:224
void traceFunctions(Addr pc)
Definition base.hh:601
std::vector< std::unique_ptr< FetchCPUStats > > fetchStats
Definition base.hh:819
std::vector< ThreadContext * > threadContexts
Definition base.hh:260
virtual void probeInstCommit(const StaticInstPtr &inst, Addr pc)
Helper method to trigger PMU probes for a committed instruction.
Definition base.cc:390
void preExecute()
Definition base.cc:328
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:232
void resetStats() override
Callback to reset stats.
Definition base.cc:223
branch_prediction::BPredUnit * branchPred
Definition base.hh:87
virtual ~BaseSimpleCPU()
Definition base.cc:210
ThreadID curThread
Definition base.hh:86
void unserializeThread(CheckpointIn &cp, ThreadID tid) override
Unserialize one thread.
Definition base.cc:240
void wakeup(ThreadID tid) override
Definition base.cc:251
StaticInstPtr curMacroStaticInst
Definition base.hh:105
void checkForInterrupts()
Definition base.cc:273
void traceFault()
Handler used when encountering a fault; its purpose is to tear down the InstRecord.
Definition base.cc:262
void advancePC(const Fault &fault)
Definition base.cc:493
void swapActiveThread()
Definition base.cc:135
void setupFetchRequest(const RequestPtr &req)
Definition base.cc:304
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:200
StaticInstPtr curStaticInst
Current instruction.
Definition base.hh:104
Counter totalInsts() const override
Definition base.cc:189
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:215
void postExecute()
Definition base.cc:412
void countCommitInst()
Definition base.cc:175
trace::InstRecord * traceData
Definition base.hh:97
void countFetchInst()
Definition base.cc:162
void serviceInstCountEvents()
Definition base.cc:321
CheckerCPU class.
Definition cpu.hh:85
void setSystem(System *system)
Definition cpu.cc:96
SimpleThread * thread
Definition cpu.hh:150
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:108
@ INST_FETCH
The request was an instruction fetch.
Definition request.hh:115
Counter numInst
PER-THREAD STATS.
void setMemAccPredicate(bool val) override
void setPredicate(bool val) override
std::unique_ptr< PCStateBase > predPC
bool inHtmTransactionalState() const override
gem5::SimpleExecContext::ExecContextStats execContextStats
The SimpleThread object provides a combination of the ThreadState object and the ThreadContext interf...
int threadId() const override
EventQueue comInstEventQueue
An instruction-based event queue.
const PCStateBase & pcState() const override
ThreadContext * getTC()
Returns the pointer to this SimpleThread's ThreadContext.
InstDecoder * decoder
bool isInteger() const
virtual StaticInstPtr fetchMicroop(MicroPC upc) const
Return the microop that goes with a particular micropc.
OpClass opClass() const
Operation class. Used to select appropriate function unit in issue.
bool isLoad() const
bool isMatrix() const
virtual void advancePC(PCStateBase &pc_state) const =0
bool isFloating() const
bool isMacroop() const
bool isReturn() const
bool isMemRef() const
bool isVector() const
bool isLastMicroop() const
bool isStore() const
bool isAtomic() const
bool isMicroop() const
bool isCall() const
bool isDelayedCommit() const
bool isControl() const
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.
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:99
void squash(const InstSeqNum &squashed_sn, ThreadID tid)
Squashes all outstanding updates until a given sequence number.
void setFaulting(bool val)
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:869
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:200
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
Bitfield< 3, 0 > priority
Bitfield< 4 > pc
Bitfield< 0 > p
double Counter
All counters are of 64-bit values.
Definition types.hh:46
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
std::shared_ptr< FaultBase > Fault
Definition types.hh:249
int16_t ThreadID
Thread index/ID type.
Definition types.hh:235
std::shared_ptr< Request > RequestPtr
Definition request.hh:94
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
static void activate(const char *expr)
Definition debug.cc:71
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:246
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 numInsts
Definition base.hh:637
statistics::Scalar numBranchMispred
Number of misprediced branches.

Generated on Tue Jun 18 2024 16:24:01 for gem5 by doxygen 1.11.0