cpu.hh (2690:f4337c0d9e6f) cpu.hh (2698:d5f35d41e017)
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Kevin Lim
29 */
30
31#ifndef __CPU_O3_CPU_HH__
32#define __CPU_O3_CPU_HH__
33
34#include <iostream>
35#include <list>
36#include <queue>
37#include <set>
38#include <vector>
39
40#include "arch/isa_traits.hh"
41#include "base/statistics.hh"
42#include "base/timebuf.hh"
43#include "config/full_system.hh"
44#include "cpu/activity.hh"
45#include "cpu/base.hh"
46#include "cpu/simple_thread.hh"
47#include "cpu/o3/comm.hh"
48#include "cpu/o3/cpu_policy.hh"
49#include "cpu/o3/scoreboard.hh"
50#include "cpu/o3/thread_state.hh"
51#include "sim/process.hh"
52
53template <class>
54class Checker;
55class ThreadContext;
56class MemObject;
57class Process;
58
59class BaseFullCPU : public BaseCPU
60{
61 //Stuff that's pretty ISA independent will go here.
62 public:
63 typedef BaseCPU::Params Params;
64
65 BaseFullCPU(Params *params);
66
67 void regStats();
68
69 int readCpuId() { return cpu_id; }
70
71 protected:
72 int cpu_id;
73};
74
75/**
76 * FullO3CPU class, has each of the stages (fetch through commit)
77 * within it, as well as all of the time buffers between stages. The
78 * tick() function for the CPU is defined here.
79 */
80template <class Impl>
81class FullO3CPU : public BaseFullCPU
82{
83 public:
84 typedef TheISA::FloatReg FloatReg;
85 typedef TheISA::FloatRegBits FloatRegBits;
86
87 // Typedefs from the Impl here.
88 typedef typename Impl::CPUPol CPUPolicy;
89 typedef typename Impl::Params Params;
90 typedef typename Impl::DynInstPtr DynInstPtr;
91
92 typedef O3ThreadState<Impl> Thread;
93
94 typedef typename std::list<DynInstPtr>::iterator ListIt;
95
96 public:
97 enum Status {
98 Running,
99 Idle,
100 Halted,
101 Blocked,
102 SwitchedOut
103 };
104
105 /** Overall CPU status. */
106 Status _status;
107
108 private:
109 class TickEvent : public Event
110 {
111 private:
112 /** Pointer to the CPU. */
113 FullO3CPU<Impl> *cpu;
114
115 public:
116 /** Constructs a tick event. */
117 TickEvent(FullO3CPU<Impl> *c);
118
119 /** Processes a tick event, calling tick() on the CPU. */
120 void process();
121 /** Returns the description of the tick event. */
122 const char *description();
123 };
124
125 /** The tick event used for scheduling CPU ticks. */
126 TickEvent tickEvent;
127
128 /** Schedule tick event, regardless of its current state. */
129 void scheduleTickEvent(int delay)
130 {
131 if (tickEvent.squashed())
132 tickEvent.reschedule(curTick + cycles(delay));
133 else if (!tickEvent.scheduled())
134 tickEvent.schedule(curTick + cycles(delay));
135 }
136
137 /** Unschedule tick event, regardless of its current state. */
138 void unscheduleTickEvent()
139 {
140 if (tickEvent.scheduled())
141 tickEvent.squash();
142 }
143
144 public:
145 /** Constructs a CPU with the given parameters. */
146 FullO3CPU(Params *params);
147 /** Destructor. */
148 ~FullO3CPU();
149
150 /** Registers statistics. */
151 void fullCPURegStats();
152
153 /** Ticks CPU, calling tick() on each stage, and checking the overall
154 * activity to see if the CPU should deschedule itself.
155 */
156 void tick();
157
158 /** Initialize the CPU */
159 void init();
160
161 /** Setup CPU to insert a thread's context */
162 void insertThread(unsigned tid);
163
164 /** Remove all of a thread's context from CPU */
165 void removeThread(unsigned tid);
166
167 /** Count the Total Instructions Committed in the CPU. */
168 virtual Counter totalInstructions() const
169 {
170 Counter total(0);
171
172 for (int i=0; i < thread.size(); i++)
173 total += thread[i]->numInst;
174
175 return total;
176 }
177
178 /** Add Thread to Active Threads List. */
179 void activateContext(int tid, int delay);
180
181 /** Remove Thread from Active Threads List */
182 void suspendContext(int tid);
183
184 /** Remove Thread from Active Threads List &&
185 * Remove Thread Context from CPU.
186 */
187 void deallocateContext(int tid);
188
189 /** Remove Thread from Active Threads List &&
190 * Remove Thread Context from CPU.
191 */
192 void haltContext(int tid);
193
194 /** Activate a Thread When CPU Resources are Available. */
195 void activateWhenReady(int tid);
196
197 /** Add or Remove a Thread Context in the CPU. */
198 void doContextSwitch();
199
200 /** Update The Order In Which We Process Threads. */
201 void updateThreadPriority();
202
203 /** Executes a syscall on this cycle.
204 * ---------------------------------------
205 * Note: this is a virtual function. CPU-Specific
206 * functionality defined in derived classes
207 */
208 virtual void syscall(int tid) { panic("Unimplemented!"); }
209
210 /** Switches out this CPU. */
211 void switchOut(Sampler *sampler);
212
213 /** Signals to this CPU that a stage has completed switching out. */
214 void signalSwitched();
215
216 /** Takes over from another CPU. */
217 void takeOverFrom(BaseCPU *oldCPU);
218
219 /** Get the current instruction sequence number, and increment it. */
220 InstSeqNum getAndIncrementInstSeq()
221 { return globalSeqNum++; }
222
223#if FULL_SYSTEM
224 /** Check if this address is a valid instruction address. */
225 bool validInstAddr(Addr addr) { return true; }
226
227 /** Check if this address is a valid data address. */
228 bool validDataAddr(Addr addr) { return true; }
229
230 /** Get instruction asid. */
231 int getInstAsid(unsigned tid)
232 { return regFile.miscRegs[tid].getInstAsid(); }
233
234 /** Get data asid. */
235 int getDataAsid(unsigned tid)
236 { return regFile.miscRegs[tid].getDataAsid(); }
237#else
238 /** Get instruction asid. */
239 int getInstAsid(unsigned tid)
240 { return thread[tid]->getInstAsid(); }
241
242 /** Get data asid. */
243 int getDataAsid(unsigned tid)
244 { return thread[tid]->getDataAsid(); }
245
246#endif
247
248 /** Register accessors. Index refers to the physical register index. */
249 uint64_t readIntReg(int reg_idx);
250
251 FloatReg readFloatReg(int reg_idx);
252
253 FloatReg readFloatReg(int reg_idx, int width);
254
255 FloatRegBits readFloatRegBits(int reg_idx);
256
257 FloatRegBits readFloatRegBits(int reg_idx, int width);
258
259 void setIntReg(int reg_idx, uint64_t val);
260
261 void setFloatReg(int reg_idx, FloatReg val);
262
263 void setFloatReg(int reg_idx, FloatReg val, int width);
264
265 void setFloatRegBits(int reg_idx, FloatRegBits val);
266
267 void setFloatRegBits(int reg_idx, FloatRegBits val, int width);
268
269 uint64_t readArchIntReg(int reg_idx, unsigned tid);
270
271 float readArchFloatRegSingle(int reg_idx, unsigned tid);
272
273 double readArchFloatRegDouble(int reg_idx, unsigned tid);
274
275 uint64_t readArchFloatRegInt(int reg_idx, unsigned tid);
276
277 /** Architectural register accessors. Looks up in the commit
278 * rename table to obtain the true physical index of the
279 * architected register first, then accesses that physical
280 * register.
281 */
282 void setArchIntReg(int reg_idx, uint64_t val, unsigned tid);
283
284 void setArchFloatRegSingle(int reg_idx, float val, unsigned tid);
285
286 void setArchFloatRegDouble(int reg_idx, double val, unsigned tid);
287
288 void setArchFloatRegInt(int reg_idx, uint64_t val, unsigned tid);
289
290 /** Reads the commit PC of a specific thread. */
291 uint64_t readPC(unsigned tid);
292
293 /** Sets the commit PC of a specific thread. */
294 void setPC(Addr new_PC, unsigned tid);
295
296 /** Reads the next PC of a specific thread. */
297 uint64_t readNextPC(unsigned tid);
298
299 /** Sets the next PC of a specific thread. */
300 void setNextPC(uint64_t val, unsigned tid);
301
302 /** Function to add instruction onto the head of the list of the
303 * instructions. Used when new instructions are fetched.
304 */
305 ListIt addInst(DynInstPtr &inst);
306
307 /** Function to tell the CPU that an instruction has completed. */
308 void instDone(unsigned tid);
309
310 /** Add Instructions to the CPU Remove List*/
311 void addToRemoveList(DynInstPtr &inst);
312
313 /** Remove an instruction from the front end of the list. There's
314 * no restriction on location of the instruction.
315 */
316 void removeFrontInst(DynInstPtr &inst);
317
318 /** Remove all instructions that are not currently in the ROB. */
319 void removeInstsNotInROB(unsigned tid);
320
321 /** Remove all instructions younger than the given sequence number. */
322 void removeInstsUntil(const InstSeqNum &seq_num,unsigned tid);
323
324 /** Removes the instruction pointed to by the iterator. */
325 inline void squashInstIt(const ListIt &instIt, const unsigned &tid);
326
327 /** Cleans up all instructions on the remove list. */
328 void cleanUpRemovedInsts();
329
330 /** Debug function to print all instructions on the list. */
331 void dumpInsts();
332
333 public:
334 /** List of all the instructions in flight. */
335 std::list<DynInstPtr> instList;
336
337 /** List of all the instructions that will be removed at the end of this
338 * cycle.
339 */
340 std::queue<ListIt> removeList;
341
342#ifdef DEBUG
343 /** Debug structure to keep track of the sequence numbers still in
344 * flight.
345 */
346 std::set<InstSeqNum> snList;
347#endif
348
349 /** Records if instructions need to be removed this cycle due to
350 * being retired or squashed.
351 */
352 bool removeInstsThisCycle;
353
354 protected:
355 /** The fetch stage. */
356 typename CPUPolicy::Fetch fetch;
357
358 /** The decode stage. */
359 typename CPUPolicy::Decode decode;
360
361 /** The dispatch stage. */
362 typename CPUPolicy::Rename rename;
363
364 /** The issue/execute/writeback stages. */
365 typename CPUPolicy::IEW iew;
366
367 /** The commit stage. */
368 typename CPUPolicy::Commit commit;
369
370 /** The register file. */
371 typename CPUPolicy::RegFile regFile;
372
373 /** The free list. */
374 typename CPUPolicy::FreeList freeList;
375
376 /** The rename map. */
377 typename CPUPolicy::RenameMap renameMap[Impl::MaxThreads];
378
379 /** The commit rename map. */
380 typename CPUPolicy::RenameMap commitRenameMap[Impl::MaxThreads];
381
382 /** The re-order buffer. */
383 typename CPUPolicy::ROB rob;
384
385 /** Active Threads List */
386 std::list<unsigned> activeThreads;
387
388 /** Integer Register Scoreboard */
389 Scoreboard scoreboard;
390
391 public:
392 /** Enum to give each stage a specific index, so when calling
393 * activateStage() or deactivateStage(), they can specify which stage
394 * is being activated/deactivated.
395 */
396 enum StageIdx {
397 FetchIdx,
398 DecodeIdx,
399 RenameIdx,
400 IEWIdx,
401 CommitIdx,
402 NumStages };
403
404 /** Typedefs from the Impl to get the structs that each of the
405 * time buffers should use.
406 */
407 typedef typename CPUPolicy::TimeStruct TimeStruct;
408
409 typedef typename CPUPolicy::FetchStruct FetchStruct;
410
411 typedef typename CPUPolicy::DecodeStruct DecodeStruct;
412
413 typedef typename CPUPolicy::RenameStruct RenameStruct;
414
415 typedef typename CPUPolicy::IEWStruct IEWStruct;
416
417 /** The main time buffer to do backwards communication. */
418 TimeBuffer<TimeStruct> timeBuffer;
419
420 /** The fetch stage's instruction queue. */
421 TimeBuffer<FetchStruct> fetchQueue;
422
423 /** The decode stage's instruction queue. */
424 TimeBuffer<DecodeStruct> decodeQueue;
425
426 /** The rename stage's instruction queue. */
427 TimeBuffer<RenameStruct> renameQueue;
428
429 /** The IEW stage's instruction queue. */
430 TimeBuffer<IEWStruct> iewQueue;
431
432 private:
433 /** The activity recorder; used to tell if the CPU has any
434 * activity remaining or if it can go to idle and deschedule
435 * itself.
436 */
437 ActivityRecorder activityRec;
438
439 public:
440 /** Records that there was time buffer activity this cycle. */
441 void activityThisCycle() { activityRec.activity(); }
442
443 /** Changes a stage's status to active within the activity recorder. */
444 void activateStage(const StageIdx idx)
445 { activityRec.activateStage(idx); }
446
447 /** Changes a stage's status to inactive within the activity recorder. */
448 void deactivateStage(const StageIdx idx)
449 { activityRec.deactivateStage(idx); }
450
451 /** Wakes the CPU, rescheduling the CPU if it's not already active. */
452 void wakeCPU();
453
454 /** Gets a free thread id. Use if thread ids change across system. */
455 int getFreeTid();
456
457 public:
458 /** Returns a pointer to a thread context. */
459 ThreadContext *tcBase(unsigned tid)
460 {
461 return thread[tid]->getTC();
462 }
463
464 /** The global sequence number counter. */
465 InstSeqNum globalSeqNum;
466
467 /** Pointer to the checker, which can dynamically verify
468 * instruction results at run time. This can be set to NULL if it
469 * is not being used.
470 */
471 Checker<DynInstPtr> *checker;
472
473#if FULL_SYSTEM
474 /** Pointer to the system. */
475 System *system;
476
477 /** Pointer to physical memory. */
478 PhysicalMemory *physmem;
479#endif
480
481 /** Pointer to memory. */
482 MemObject *mem;
483
484 /** Pointer to the sampler */
485 Sampler *sampler;
486
487 /** Counter of how many stages have completed switching out. */
488 int switchCount;
489
490 /** Pointers to all of the threads in the CPU. */
491 std::vector<Thread *> thread;
492
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Kevin Lim
29 */
30
31#ifndef __CPU_O3_CPU_HH__
32#define __CPU_O3_CPU_HH__
33
34#include <iostream>
35#include <list>
36#include <queue>
37#include <set>
38#include <vector>
39
40#include "arch/isa_traits.hh"
41#include "base/statistics.hh"
42#include "base/timebuf.hh"
43#include "config/full_system.hh"
44#include "cpu/activity.hh"
45#include "cpu/base.hh"
46#include "cpu/simple_thread.hh"
47#include "cpu/o3/comm.hh"
48#include "cpu/o3/cpu_policy.hh"
49#include "cpu/o3/scoreboard.hh"
50#include "cpu/o3/thread_state.hh"
51#include "sim/process.hh"
52
53template <class>
54class Checker;
55class ThreadContext;
56class MemObject;
57class Process;
58
59class BaseFullCPU : public BaseCPU
60{
61 //Stuff that's pretty ISA independent will go here.
62 public:
63 typedef BaseCPU::Params Params;
64
65 BaseFullCPU(Params *params);
66
67 void regStats();
68
69 int readCpuId() { return cpu_id; }
70
71 protected:
72 int cpu_id;
73};
74
75/**
76 * FullO3CPU class, has each of the stages (fetch through commit)
77 * within it, as well as all of the time buffers between stages. The
78 * tick() function for the CPU is defined here.
79 */
80template <class Impl>
81class FullO3CPU : public BaseFullCPU
82{
83 public:
84 typedef TheISA::FloatReg FloatReg;
85 typedef TheISA::FloatRegBits FloatRegBits;
86
87 // Typedefs from the Impl here.
88 typedef typename Impl::CPUPol CPUPolicy;
89 typedef typename Impl::Params Params;
90 typedef typename Impl::DynInstPtr DynInstPtr;
91
92 typedef O3ThreadState<Impl> Thread;
93
94 typedef typename std::list<DynInstPtr>::iterator ListIt;
95
96 public:
97 enum Status {
98 Running,
99 Idle,
100 Halted,
101 Blocked,
102 SwitchedOut
103 };
104
105 /** Overall CPU status. */
106 Status _status;
107
108 private:
109 class TickEvent : public Event
110 {
111 private:
112 /** Pointer to the CPU. */
113 FullO3CPU<Impl> *cpu;
114
115 public:
116 /** Constructs a tick event. */
117 TickEvent(FullO3CPU<Impl> *c);
118
119 /** Processes a tick event, calling tick() on the CPU. */
120 void process();
121 /** Returns the description of the tick event. */
122 const char *description();
123 };
124
125 /** The tick event used for scheduling CPU ticks. */
126 TickEvent tickEvent;
127
128 /** Schedule tick event, regardless of its current state. */
129 void scheduleTickEvent(int delay)
130 {
131 if (tickEvent.squashed())
132 tickEvent.reschedule(curTick + cycles(delay));
133 else if (!tickEvent.scheduled())
134 tickEvent.schedule(curTick + cycles(delay));
135 }
136
137 /** Unschedule tick event, regardless of its current state. */
138 void unscheduleTickEvent()
139 {
140 if (tickEvent.scheduled())
141 tickEvent.squash();
142 }
143
144 public:
145 /** Constructs a CPU with the given parameters. */
146 FullO3CPU(Params *params);
147 /** Destructor. */
148 ~FullO3CPU();
149
150 /** Registers statistics. */
151 void fullCPURegStats();
152
153 /** Ticks CPU, calling tick() on each stage, and checking the overall
154 * activity to see if the CPU should deschedule itself.
155 */
156 void tick();
157
158 /** Initialize the CPU */
159 void init();
160
161 /** Setup CPU to insert a thread's context */
162 void insertThread(unsigned tid);
163
164 /** Remove all of a thread's context from CPU */
165 void removeThread(unsigned tid);
166
167 /** Count the Total Instructions Committed in the CPU. */
168 virtual Counter totalInstructions() const
169 {
170 Counter total(0);
171
172 for (int i=0; i < thread.size(); i++)
173 total += thread[i]->numInst;
174
175 return total;
176 }
177
178 /** Add Thread to Active Threads List. */
179 void activateContext(int tid, int delay);
180
181 /** Remove Thread from Active Threads List */
182 void suspendContext(int tid);
183
184 /** Remove Thread from Active Threads List &&
185 * Remove Thread Context from CPU.
186 */
187 void deallocateContext(int tid);
188
189 /** Remove Thread from Active Threads List &&
190 * Remove Thread Context from CPU.
191 */
192 void haltContext(int tid);
193
194 /** Activate a Thread When CPU Resources are Available. */
195 void activateWhenReady(int tid);
196
197 /** Add or Remove a Thread Context in the CPU. */
198 void doContextSwitch();
199
200 /** Update The Order In Which We Process Threads. */
201 void updateThreadPriority();
202
203 /** Executes a syscall on this cycle.
204 * ---------------------------------------
205 * Note: this is a virtual function. CPU-Specific
206 * functionality defined in derived classes
207 */
208 virtual void syscall(int tid) { panic("Unimplemented!"); }
209
210 /** Switches out this CPU. */
211 void switchOut(Sampler *sampler);
212
213 /** Signals to this CPU that a stage has completed switching out. */
214 void signalSwitched();
215
216 /** Takes over from another CPU. */
217 void takeOverFrom(BaseCPU *oldCPU);
218
219 /** Get the current instruction sequence number, and increment it. */
220 InstSeqNum getAndIncrementInstSeq()
221 { return globalSeqNum++; }
222
223#if FULL_SYSTEM
224 /** Check if this address is a valid instruction address. */
225 bool validInstAddr(Addr addr) { return true; }
226
227 /** Check if this address is a valid data address. */
228 bool validDataAddr(Addr addr) { return true; }
229
230 /** Get instruction asid. */
231 int getInstAsid(unsigned tid)
232 { return regFile.miscRegs[tid].getInstAsid(); }
233
234 /** Get data asid. */
235 int getDataAsid(unsigned tid)
236 { return regFile.miscRegs[tid].getDataAsid(); }
237#else
238 /** Get instruction asid. */
239 int getInstAsid(unsigned tid)
240 { return thread[tid]->getInstAsid(); }
241
242 /** Get data asid. */
243 int getDataAsid(unsigned tid)
244 { return thread[tid]->getDataAsid(); }
245
246#endif
247
248 /** Register accessors. Index refers to the physical register index. */
249 uint64_t readIntReg(int reg_idx);
250
251 FloatReg readFloatReg(int reg_idx);
252
253 FloatReg readFloatReg(int reg_idx, int width);
254
255 FloatRegBits readFloatRegBits(int reg_idx);
256
257 FloatRegBits readFloatRegBits(int reg_idx, int width);
258
259 void setIntReg(int reg_idx, uint64_t val);
260
261 void setFloatReg(int reg_idx, FloatReg val);
262
263 void setFloatReg(int reg_idx, FloatReg val, int width);
264
265 void setFloatRegBits(int reg_idx, FloatRegBits val);
266
267 void setFloatRegBits(int reg_idx, FloatRegBits val, int width);
268
269 uint64_t readArchIntReg(int reg_idx, unsigned tid);
270
271 float readArchFloatRegSingle(int reg_idx, unsigned tid);
272
273 double readArchFloatRegDouble(int reg_idx, unsigned tid);
274
275 uint64_t readArchFloatRegInt(int reg_idx, unsigned tid);
276
277 /** Architectural register accessors. Looks up in the commit
278 * rename table to obtain the true physical index of the
279 * architected register first, then accesses that physical
280 * register.
281 */
282 void setArchIntReg(int reg_idx, uint64_t val, unsigned tid);
283
284 void setArchFloatRegSingle(int reg_idx, float val, unsigned tid);
285
286 void setArchFloatRegDouble(int reg_idx, double val, unsigned tid);
287
288 void setArchFloatRegInt(int reg_idx, uint64_t val, unsigned tid);
289
290 /** Reads the commit PC of a specific thread. */
291 uint64_t readPC(unsigned tid);
292
293 /** Sets the commit PC of a specific thread. */
294 void setPC(Addr new_PC, unsigned tid);
295
296 /** Reads the next PC of a specific thread. */
297 uint64_t readNextPC(unsigned tid);
298
299 /** Sets the next PC of a specific thread. */
300 void setNextPC(uint64_t val, unsigned tid);
301
302 /** Function to add instruction onto the head of the list of the
303 * instructions. Used when new instructions are fetched.
304 */
305 ListIt addInst(DynInstPtr &inst);
306
307 /** Function to tell the CPU that an instruction has completed. */
308 void instDone(unsigned tid);
309
310 /** Add Instructions to the CPU Remove List*/
311 void addToRemoveList(DynInstPtr &inst);
312
313 /** Remove an instruction from the front end of the list. There's
314 * no restriction on location of the instruction.
315 */
316 void removeFrontInst(DynInstPtr &inst);
317
318 /** Remove all instructions that are not currently in the ROB. */
319 void removeInstsNotInROB(unsigned tid);
320
321 /** Remove all instructions younger than the given sequence number. */
322 void removeInstsUntil(const InstSeqNum &seq_num,unsigned tid);
323
324 /** Removes the instruction pointed to by the iterator. */
325 inline void squashInstIt(const ListIt &instIt, const unsigned &tid);
326
327 /** Cleans up all instructions on the remove list. */
328 void cleanUpRemovedInsts();
329
330 /** Debug function to print all instructions on the list. */
331 void dumpInsts();
332
333 public:
334 /** List of all the instructions in flight. */
335 std::list<DynInstPtr> instList;
336
337 /** List of all the instructions that will be removed at the end of this
338 * cycle.
339 */
340 std::queue<ListIt> removeList;
341
342#ifdef DEBUG
343 /** Debug structure to keep track of the sequence numbers still in
344 * flight.
345 */
346 std::set<InstSeqNum> snList;
347#endif
348
349 /** Records if instructions need to be removed this cycle due to
350 * being retired or squashed.
351 */
352 bool removeInstsThisCycle;
353
354 protected:
355 /** The fetch stage. */
356 typename CPUPolicy::Fetch fetch;
357
358 /** The decode stage. */
359 typename CPUPolicy::Decode decode;
360
361 /** The dispatch stage. */
362 typename CPUPolicy::Rename rename;
363
364 /** The issue/execute/writeback stages. */
365 typename CPUPolicy::IEW iew;
366
367 /** The commit stage. */
368 typename CPUPolicy::Commit commit;
369
370 /** The register file. */
371 typename CPUPolicy::RegFile regFile;
372
373 /** The free list. */
374 typename CPUPolicy::FreeList freeList;
375
376 /** The rename map. */
377 typename CPUPolicy::RenameMap renameMap[Impl::MaxThreads];
378
379 /** The commit rename map. */
380 typename CPUPolicy::RenameMap commitRenameMap[Impl::MaxThreads];
381
382 /** The re-order buffer. */
383 typename CPUPolicy::ROB rob;
384
385 /** Active Threads List */
386 std::list<unsigned> activeThreads;
387
388 /** Integer Register Scoreboard */
389 Scoreboard scoreboard;
390
391 public:
392 /** Enum to give each stage a specific index, so when calling
393 * activateStage() or deactivateStage(), they can specify which stage
394 * is being activated/deactivated.
395 */
396 enum StageIdx {
397 FetchIdx,
398 DecodeIdx,
399 RenameIdx,
400 IEWIdx,
401 CommitIdx,
402 NumStages };
403
404 /** Typedefs from the Impl to get the structs that each of the
405 * time buffers should use.
406 */
407 typedef typename CPUPolicy::TimeStruct TimeStruct;
408
409 typedef typename CPUPolicy::FetchStruct FetchStruct;
410
411 typedef typename CPUPolicy::DecodeStruct DecodeStruct;
412
413 typedef typename CPUPolicy::RenameStruct RenameStruct;
414
415 typedef typename CPUPolicy::IEWStruct IEWStruct;
416
417 /** The main time buffer to do backwards communication. */
418 TimeBuffer<TimeStruct> timeBuffer;
419
420 /** The fetch stage's instruction queue. */
421 TimeBuffer<FetchStruct> fetchQueue;
422
423 /** The decode stage's instruction queue. */
424 TimeBuffer<DecodeStruct> decodeQueue;
425
426 /** The rename stage's instruction queue. */
427 TimeBuffer<RenameStruct> renameQueue;
428
429 /** The IEW stage's instruction queue. */
430 TimeBuffer<IEWStruct> iewQueue;
431
432 private:
433 /** The activity recorder; used to tell if the CPU has any
434 * activity remaining or if it can go to idle and deschedule
435 * itself.
436 */
437 ActivityRecorder activityRec;
438
439 public:
440 /** Records that there was time buffer activity this cycle. */
441 void activityThisCycle() { activityRec.activity(); }
442
443 /** Changes a stage's status to active within the activity recorder. */
444 void activateStage(const StageIdx idx)
445 { activityRec.activateStage(idx); }
446
447 /** Changes a stage's status to inactive within the activity recorder. */
448 void deactivateStage(const StageIdx idx)
449 { activityRec.deactivateStage(idx); }
450
451 /** Wakes the CPU, rescheduling the CPU if it's not already active. */
452 void wakeCPU();
453
454 /** Gets a free thread id. Use if thread ids change across system. */
455 int getFreeTid();
456
457 public:
458 /** Returns a pointer to a thread context. */
459 ThreadContext *tcBase(unsigned tid)
460 {
461 return thread[tid]->getTC();
462 }
463
464 /** The global sequence number counter. */
465 InstSeqNum globalSeqNum;
466
467 /** Pointer to the checker, which can dynamically verify
468 * instruction results at run time. This can be set to NULL if it
469 * is not being used.
470 */
471 Checker<DynInstPtr> *checker;
472
473#if FULL_SYSTEM
474 /** Pointer to the system. */
475 System *system;
476
477 /** Pointer to physical memory. */
478 PhysicalMemory *physmem;
479#endif
480
481 /** Pointer to memory. */
482 MemObject *mem;
483
484 /** Pointer to the sampler */
485 Sampler *sampler;
486
487 /** Counter of how many stages have completed switching out. */
488 int switchCount;
489
490 /** Pointers to all of the threads in the CPU. */
491 std::vector<Thread *> thread;
492
493#if 0
494 /** Page table pointer. */
495 PageTable *pTable;
496#endif
497
498 /** Pointer to the icache interface. */
499 MemInterface *icacheInterface;
500 /** Pointer to the dcache interface. */
501 MemInterface *dcacheInterface;
502
503 /** Whether or not the CPU should defer its registration. */
504 bool deferRegistration;
505
506 /** Is there a context switch pending? */
507 bool contextSwitch;
508
509 /** Threads Scheduled to Enter CPU */
510 std::list<int> cpuWaitList;
511
512 /** The cycle that the CPU was last running, used for statistics. */
513 Tick lastRunningCycle;
514
515 /** Number of Threads CPU can process */
516 unsigned numThreads;
517
518 /** Mapping for system thread id to cpu id */
519 std::map<unsigned,unsigned> threadMap;
520
521 /** Available thread ids in the cpu*/
522 std::vector<unsigned> tids;
523
524 /** Stat for total number of times the CPU is descheduled. */
525 Stats::Scalar<> timesIdled;
526 /** Stat for total number of cycles the CPU spends descheduled. */
527 Stats::Scalar<> idleCycles;
528 /** Stat for the number of committed instructions per thread. */
529 Stats::Vector<> committedInsts;
530 /** Stat for the total number of committed instructions. */
531 Stats::Scalar<> totalCommittedInsts;
532 /** Stat for the CPI per thread. */
533 Stats::Formula cpi;
534 /** Stat for the total CPI. */
535 Stats::Formula totalCpi;
536 /** Stat for the IPC per thread. */
537 Stats::Formula ipc;
538 /** Stat for the total IPC. */
539 Stats::Formula totalIpc;
540};
541
542#endif // __CPU_O3_CPU_HH__
493 /** Pointer to the icache interface. */
494 MemInterface *icacheInterface;
495 /** Pointer to the dcache interface. */
496 MemInterface *dcacheInterface;
497
498 /** Whether or not the CPU should defer its registration. */
499 bool deferRegistration;
500
501 /** Is there a context switch pending? */
502 bool contextSwitch;
503
504 /** Threads Scheduled to Enter CPU */
505 std::list<int> cpuWaitList;
506
507 /** The cycle that the CPU was last running, used for statistics. */
508 Tick lastRunningCycle;
509
510 /** Number of Threads CPU can process */
511 unsigned numThreads;
512
513 /** Mapping for system thread id to cpu id */
514 std::map<unsigned,unsigned> threadMap;
515
516 /** Available thread ids in the cpu*/
517 std::vector<unsigned> tids;
518
519 /** Stat for total number of times the CPU is descheduled. */
520 Stats::Scalar<> timesIdled;
521 /** Stat for total number of cycles the CPU spends descheduled. */
522 Stats::Scalar<> idleCycles;
523 /** Stat for the number of committed instructions per thread. */
524 Stats::Vector<> committedInsts;
525 /** Stat for the total number of committed instructions. */
526 Stats::Scalar<> totalCommittedInsts;
527 /** Stat for the CPI per thread. */
528 Stats::Formula cpi;
529 /** Stat for the total CPI. */
530 Stats::Formula totalCpi;
531 /** Stat for the IPC per thread. */
532 Stats::Formula ipc;
533 /** Stat for the total IPC. */
534 Stats::Formula totalIpc;
535};
536
537#endif // __CPU_O3_CPU_HH__