cpu.cc (2654:9559cfa91b9d) cpu.cc (2665:a124942bacb8)
1/*
1/*
2 * Copyright (c) 2004-2006 The Regents of The University of Michigan
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

--- 8 unchanged lines hidden (view full) ---

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.
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

--- 8 unchanged lines hidden (view full) ---

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
27 */
28
29#include "config/full_system.hh"
30
31#if FULL_SYSTEM
32#include "sim/system.hh"
33#else
34#include "sim/process.hh"
35#endif
29 */
30
31#include "config/full_system.hh"
32
33#if FULL_SYSTEM
34#include "sim/system.hh"
35#else
36#include "sim/process.hh"
37#endif
38#include "sim/root.hh"
36
39
37#include "cpu/activity.hh"
38#include "cpu/checker/cpu.hh"
39#include "cpu/cpu_exec_context.hh"
40#include "cpu/exec_context.hh"
41#include "cpu/o3/alpha_dyn_inst.hh"
42#include "cpu/o3/alpha_impl.hh"
43#include "cpu/o3/cpu.hh"
44
40#include "cpu/cpu_exec_context.hh"
41#include "cpu/exec_context.hh"
42#include "cpu/o3/alpha_dyn_inst.hh"
43#include "cpu/o3/alpha_impl.hh"
44#include "cpu/o3/cpu.hh"
45
45#include "sim/root.hh"
46#include "sim/stat_control.hh"
47
48using namespace std;
49
46using namespace std;
47
50BaseFullCPU::BaseFullCPU(Params *params)
51 : BaseCPU(params), cpu_id(0)
48BaseFullCPU::BaseFullCPU(Params &params)
49 : BaseCPU(&params), cpu_id(0)
52{
53}
54
50{
51}
52
55void
56BaseFullCPU::regStats()
57{
58 BaseCPU::regStats();
59}
60
61template <class Impl>
62FullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c)
63 : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c)
64{
65}
66
67template <class Impl>
68void

--- 4 unchanged lines hidden (view full) ---

73
74template <class Impl>
75const char *
76FullO3CPU<Impl>::TickEvent::description()
77{
78 return "FullO3CPU tick event";
79}
80
53template <class Impl>
54FullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c)
55 : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c)
56{
57}
58
59template <class Impl>
60void

--- 4 unchanged lines hidden (view full) ---

65
66template <class Impl>
67const char *
68FullO3CPU<Impl>::TickEvent::description()
69{
70 return "FullO3CPU tick event";
71}
72
73//Call constructor to all the pipeline stages here
81template <class Impl>
74template <class Impl>
82FullO3CPU<Impl>::FullO3CPU(Params *params)
75FullO3CPU<Impl>::FullO3CPU(Params &params)
76#if FULL_SYSTEM
83 : BaseFullCPU(params),
77 : BaseFullCPU(params),
78#else
79 : BaseFullCPU(params),
80#endif // FULL_SYSTEM
84 tickEvent(this),
81 tickEvent(this),
85 removeInstsThisCycle(false),
86 fetch(params),
87 decode(params),
88 rename(params),
89 iew(params),
90 commit(params),
91
82 fetch(params),
83 decode(params),
84 rename(params),
85 iew(params),
86 commit(params),
87
92 regFile(params->numPhysIntRegs, params->numPhysFloatRegs),
88 regFile(params.numPhysIntRegs, params.numPhysFloatRegs),
93
89
94 freeList(params->numberOfThreads,//number of activeThreads
95 TheISA::NumIntRegs, params->numPhysIntRegs,
96 TheISA::NumFloatRegs, params->numPhysFloatRegs),
90 freeList(TheISA::NumIntRegs, params.numPhysIntRegs,
91 TheISA::NumFloatRegs, params.numPhysFloatRegs),
97
92
98 rob(params->numROBEntries, params->squashWidth,
99 params->smtROBPolicy, params->smtROBThreshold,
100 params->numberOfThreads),
93 renameMap(TheISA::NumIntRegs, params.numPhysIntRegs,
94 TheISA::NumFloatRegs, params.numPhysFloatRegs,
95 TheISA::NumMiscRegs,
96 TheISA::ZeroReg,
97 TheISA::ZeroReg + TheISA::NumIntRegs),
101
98
102 scoreboard(params->numberOfThreads,//number of activeThreads
103 TheISA::NumIntRegs, params->numPhysIntRegs,
104 TheISA::NumFloatRegs, params->numPhysFloatRegs,
105 TheISA::NumMiscRegs * number_of_threads,
106 TheISA::ZeroReg),
99 rob(params.numROBEntries, params.squashWidth),
107
100
101 // What to pass to these time buffers?
108 // For now just have these time buffers be pretty big.
102 // For now just have these time buffers be pretty big.
109 // @todo: Make these time buffer sizes parameters or derived
110 // from latencies
111 timeBuffer(5, 5),
112 fetchQueue(5, 5),
113 decodeQueue(5, 5),
114 renameQueue(5, 5),
115 iewQueue(5, 5),
103 timeBuffer(5, 5),
104 fetchQueue(5, 5),
105 decodeQueue(5, 5),
106 renameQueue(5, 5),
107 iewQueue(5, 5),
116 activityRec(NumStages, 10, params->activity),
117
108
109 cpuXC(NULL),
110
118 globalSeqNum(1),
119
120#if FULL_SYSTEM
111 globalSeqNum(1),
112
113#if FULL_SYSTEM
121 system(params->system),
114 system(params.system),
122 memCtrl(system->memctrl),
123 physmem(system->physmem),
115 memCtrl(system->memctrl),
116 physmem(system->physmem),
124 mem(params->mem),
117 itb(params.itb),
118 dtb(params.dtb),
119 mem(params.mem),
125#else
120#else
126// pTable(params->pTable),
127 mem(params->workload[0]->getMemory()),
121 // Hardcoded for a single thread!!
122 mem(params.workload[0]->getMemory()),
128#endif // FULL_SYSTEM
123#endif // FULL_SYSTEM
129 switchCount(0),
130 icacheInterface(params->icacheInterface),
131 dcacheInterface(params->dcacheInterface),
132 deferRegistration(params->deferRegistration),
133 numThreads(number_of_threads)
124
125 icacheInterface(params.icacheInterface),
126 dcacheInterface(params.dcacheInterface),
127 deferRegistration(params.defReg),
128 numInsts(0),
129 funcExeInst(0)
134{
135 _status = Idle;
136
130{
131 _status = Idle;
132
137 if (params->checker) {
138 BaseCPU *temp_checker = params->checker;
139 checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
140 checker->setMemory(mem);
141#if FULL_SYSTEM
142 checker->setSystem(params->system);
143#endif
144 } else {
145 checker = NULL;
146 }
147
148#if !FULL_SYSTEM
133#if !FULL_SYSTEM
149 thread.resize(number_of_threads);
150 tids.resize(number_of_threads);
134 thread.resize(this->number_of_threads);
151#endif
152
135#endif
136
153 // The stages also need their CPU pointer setup. However this
154 // must be done at the upper level CPU because they have pointers
155 // to the upper level CPU, and not this FullO3CPU.
137 for (int i = 0; i < this->number_of_threads; ++i) {
138#if FULL_SYSTEM
139 assert(i == 0);
140 thread[i] = new CPUExecContext(this, 0, system, itb, dtb, mem);
141 system->execContexts[i] = thread[i]->getProxy();
156
142
157 // Set up Pointers to the activeThreads list for each stage
158 fetch.setActiveThreads(&activeThreads);
159 decode.setActiveThreads(&activeThreads);
160 rename.setActiveThreads(&activeThreads);
161 iew.setActiveThreads(&activeThreads);
162 commit.setActiveThreads(&activeThreads);
143 execContexts.push_back(system->execContexts[i]);
144#else
145 if (i < params.workload.size()) {
146 DPRINTF(FullCPU, "FullCPU: Workload[%i]'s starting PC is %#x, "
147 "process is %#x",
148 i, params.workload[i]->prog_entry, thread[i]);
149 thread[i] = new CPUExecContext(this, i, params.workload[i], i);
150 }
151 assert(params.workload[i]->getMemory() != NULL);
152 assert(mem != NULL);
153 execContexts.push_back(thread[i]->getProxy());
154#endif // !FULL_SYSTEM
155 }
163
156
157 // Note that this is a hack so that my code which still uses xc-> will
158 // still work. I should remove this eventually
159 cpuXC = thread[0];
160
161 // The stages also need their CPU pointer setup. However this must be
162 // done at the upper level CPU because they have pointers to the upper
163 // level CPU, and not this FullO3CPU.
164
164 // Give each of the stages the time buffer they will use.
165 fetch.setTimeBuffer(&timeBuffer);
166 decode.setTimeBuffer(&timeBuffer);
167 rename.setTimeBuffer(&timeBuffer);
168 iew.setTimeBuffer(&timeBuffer);
169 commit.setTimeBuffer(&timeBuffer);
170
171 // Also setup each of the stages' queues.
172 fetch.setFetchQueue(&fetchQueue);
173 decode.setFetchQueue(&fetchQueue);
165 // Give each of the stages the time buffer they will use.
166 fetch.setTimeBuffer(&timeBuffer);
167 decode.setTimeBuffer(&timeBuffer);
168 rename.setTimeBuffer(&timeBuffer);
169 iew.setTimeBuffer(&timeBuffer);
170 commit.setTimeBuffer(&timeBuffer);
171
172 // Also setup each of the stages' queues.
173 fetch.setFetchQueue(&fetchQueue);
174 decode.setFetchQueue(&fetchQueue);
174 commit.setFetchQueue(&fetchQueue);
175 decode.setDecodeQueue(&decodeQueue);
176 rename.setDecodeQueue(&decodeQueue);
177 rename.setRenameQueue(&renameQueue);
178 iew.setRenameQueue(&renameQueue);
179 iew.setIEWQueue(&iewQueue);
180 commit.setIEWQueue(&iewQueue);
181 commit.setRenameQueue(&renameQueue);
182
175 decode.setDecodeQueue(&decodeQueue);
176 rename.setDecodeQueue(&decodeQueue);
177 rename.setRenameQueue(&renameQueue);
178 iew.setRenameQueue(&renameQueue);
179 iew.setIEWQueue(&iewQueue);
180 commit.setIEWQueue(&iewQueue);
181 commit.setRenameQueue(&renameQueue);
182
183 commit.setFetchStage(&fetch);
184 commit.setIEWStage(&iew);
185 rename.setIEWStage(&iew);
186 rename.setCommitStage(&commit);
187
188#if !FULL_SYSTEM
189 int active_threads = params->workload.size();
190#else
191 int active_threads = 1;
192#endif
193
194 //Make Sure That this a Valid Architeture
195 assert(params->numPhysIntRegs >= numThreads * TheISA::NumIntRegs);
196 assert(params->numPhysFloatRegs >= numThreads * TheISA::NumFloatRegs);
197
198 rename.setScoreboard(&scoreboard);
199 iew.setScoreboard(&scoreboard);
200
201 // Setup the rename map for whichever stages need it.
183 // Setup the rename map for whichever stages need it.
202 PhysRegIndex lreg_idx = 0;
203 PhysRegIndex freg_idx = params->numPhysIntRegs; //Index to 1 after int regs
184 rename.setRenameMap(&renameMap);
185 iew.setRenameMap(&renameMap);
204
186
205 for (int tid=0; tid < numThreads; tid++) {
206 bool bindRegs = (tid <= active_threads - 1);
207
208 commitRenameMap[tid].init(TheISA::NumIntRegs,
209 params->numPhysIntRegs,
210 lreg_idx, //Index for Logical. Regs
211
212 TheISA::NumFloatRegs,
213 params->numPhysFloatRegs,
214 freg_idx, //Index for Float Regs
215
216 TheISA::NumMiscRegs,
217
218 TheISA::ZeroReg,
219 TheISA::ZeroReg,
220
221 tid,
222 false);
223
224 renameMap[tid].init(TheISA::NumIntRegs,
225 params->numPhysIntRegs,
226 lreg_idx, //Index for Logical. Regs
227
228 TheISA::NumFloatRegs,
229 params->numPhysFloatRegs,
230 freg_idx, //Index for Float Regs
231
232 TheISA::NumMiscRegs,
233
234 TheISA::ZeroReg,
235 TheISA::ZeroReg,
236
237 tid,
238 bindRegs);
239 }
240
241 rename.setRenameMap(renameMap);
242 commit.setRenameMap(commitRenameMap);
243
244 // Give renameMap & rename stage access to the freeList;
245 for (int i=0; i < numThreads; i++) {
246 renameMap[i].setFreeList(&freeList);
247 }
187 // Setup the free list for whichever stages need it.
248 rename.setFreeList(&freeList);
188 rename.setFreeList(&freeList);
189 renameMap.setFreeList(&freeList);
249
190
250 // Setup the page table for whichever stages need it.
251#if !FULL_SYSTEM
252// fetch.setPageTable(pTable);
253// iew.setPageTable(pTable);
254#endif
255
256 // Setup the ROB for whichever stages need it.
257 commit.setROB(&rob);
191 // Setup the ROB for whichever stages need it.
192 commit.setROB(&rob);
258
259 lastRunningCycle = curTick;
260
261 contextSwitch = false;
262}
263
264template <class Impl>
265FullO3CPU<Impl>::~FullO3CPU()
266{
267}
268
269template <class Impl>
270void
271FullO3CPU<Impl>::fullCPURegStats()
272{
193}
194
195template <class Impl>
196FullO3CPU<Impl>::~FullO3CPU()
197{
198}
199
200template <class Impl>
201void
202FullO3CPU<Impl>::fullCPURegStats()
203{
273 BaseFullCPU::regStats();
274
275 // Register any of the FullCPU's stats here.
204 // Register any of the FullCPU's stats here.
276 timesIdled
277 .name(name() + ".timesIdled")
278 .desc("Number of times that the entire CPU went into an idle state and"
279 " unscheduled itself")
280 .prereq(timesIdled);
281
282 idleCycles
283 .name(name() + ".idleCycles")
284 .desc("Total number of cycles that the CPU has spent unscheduled due "
285 "to idling")
286 .prereq(idleCycles);
287
288 // Number of Instructions simulated
289 // --------------------------------
290 // Should probably be in Base CPU but need templated
291 // MaxThreads so put in here instead
292 committedInsts
293 .init(numThreads)
294 .name(name() + ".committedInsts")
295 .desc("Number of Instructions Simulated");
296
297 totalCommittedInsts
298 .name(name() + ".committedInsts_total")
299 .desc("Number of Instructions Simulated");
300
301 cpi
302 .name(name() + ".cpi")
303 .desc("CPI: Cycles Per Instruction")
304 .precision(6);
305 cpi = simTicks / committedInsts;
306
307 totalCpi
308 .name(name() + ".cpi_total")
309 .desc("CPI: Total CPI of All Threads")
310 .precision(6);
311 totalCpi = simTicks / totalCommittedInsts;
312
313 ipc
314 .name(name() + ".ipc")
315 .desc("IPC: Instructions Per Cycle")
316 .precision(6);
317 ipc = committedInsts / simTicks;
318
319 totalIpc
320 .name(name() + ".ipc_total")
321 .desc("IPC: Total IPC of All Threads")
322 .precision(6);
323 totalIpc = totalCommittedInsts / simTicks;
324
325}
326
327template <class Impl>
328void
329FullO3CPU<Impl>::tick()
330{
331 DPRINTF(FullCPU, "\n\nFullCPU: Ticking main, FullO3CPU.\n");
332
205}
206
207template <class Impl>
208void
209FullO3CPU<Impl>::tick()
210{
211 DPRINTF(FullCPU, "\n\nFullCPU: Ticking main, FullO3CPU.\n");
212
333 ++numCycles;
334
335// activity = false;
336
337 //Tick each of the stages
213 //Tick each of the stages if they're actually running.
214 //Will want to figure out a way to unschedule itself if they're all
215 //going to be idle for a long time.
338 fetch.tick();
339
340 decode.tick();
341
342 rename.tick();
343
344 iew.tick();
345
346 commit.tick();
347
216 fetch.tick();
217
218 decode.tick();
219
220 rename.tick();
221
222 iew.tick();
223
224 commit.tick();
225
348#if !FULL_SYSTEM
349 doContextSwitch();
350#endif
351
352 // Now advance the time buffers
226 // Now advance the time buffers, unless the stage is stalled.
353 timeBuffer.advance();
354
355 fetchQueue.advance();
356 decodeQueue.advance();
357 renameQueue.advance();
358 iewQueue.advance();
359
227 timeBuffer.advance();
228
229 fetchQueue.advance();
230 decodeQueue.advance();
231 renameQueue.advance();
232 iewQueue.advance();
233
360 activityRec.advance();
361
362 if (removeInstsThisCycle) {
363 cleanUpRemovedInsts();
364 }
365
366 if (!tickEvent.scheduled()) {
367 if (_status == SwitchedOut) {
368 // increment stat
369 lastRunningCycle = curTick;
370 } else if (!activityRec.active()) {
371 lastRunningCycle = curTick;
372 timesIdled++;
373 } else {
374 tickEvent.schedule(curTick + cycles(1));
375 }
376 }
377
378#if !FULL_SYSTEM
379 updateThreadPriority();
380#endif
381
234 if (_status == Running && !tickEvent.scheduled())
235 tickEvent.schedule(curTick + 1);
382}
383
384template <class Impl>
385void
386FullO3CPU<Impl>::init()
387{
236}
237
238template <class Impl>
239void
240FullO3CPU<Impl>::init()
241{
388 if (!deferRegistration) {
389 registerExecContexts();
390 }
242 if(!deferRegistration)
243 {
244 this->registerExecContexts();
391
245
392 // Set inSyscall so that the CPU doesn't squash when initially
393 // setting up registers.
394 for (int i = 0; i < number_of_threads; ++i)
395 thread[i]->inSyscall = true;
396
397 for (int tid=0; tid < number_of_threads; tid++) {
246 // Need to do a copy of the xc->regs into the CPU's regfile so
247 // that it can start properly.
398#if FULL_SYSTEM
248#if FULL_SYSTEM
399 ExecContext *src_xc = execContexts[tid];
249 ExecContext *src_xc = system->execContexts[0];
250 TheISA::initCPU(src_xc, src_xc->readCpuId());
400#else
251#else
401 ExecContext *src_xc = thread[tid]->getXCProxy();
252 ExecContext *src_xc = thread[0]->getProxy();
402#endif
253#endif
403 // Threads start in the Suspended State
404 if (src_xc->status() != ExecContext::Suspended) {
405 continue;
254 // First loop through the integer registers.
255 for (int i = 0; i < TheISA::NumIntRegs; ++i)
256 {
257 regFile.intRegFile[i] = src_xc->readIntReg(i);
406 }
407
258 }
259
408#if FULL_SYSTEM
409 TheISA::initCPU(src_xc, src_xc->readCpuId());
410#endif
260 // Then loop through the floating point registers.
261 for (int i = 0; i < TheISA::NumFloatRegs; ++i)
262 {
263 regFile.floatRegFile.setRegBits(i, src_xc->readRegBits(i))
264 }
265/*
266 // Then loop through the misc registers.
267 regFile.miscRegs.fpcr = src_xc->regs.miscRegs.fpcr;
268 regFile.miscRegs.uniq = src_xc->regs.miscRegs.uniq;
269 regFile.miscRegs.lock_flag = src_xc->regs.miscRegs.lock_flag;
270 regFile.miscRegs.lock_addr = src_xc->regs.miscRegs.lock_addr;
271*/
272 // Then finally set the PC and the next PC.
273 regFile.pc = src_xc->readPC();
274 regFile.npc = src_xc->readNextPC();
411 }
275 }
412
413 // Clear inSyscall.
414 for (int i = 0; i < number_of_threads; ++i)
415 thread[i]->inSyscall = false;
416
417 // Initialize stages.
418 fetch.initStage();
419 iew.initStage();
420 rename.initStage();
421 commit.initStage();
422
423 commit.setThreads(thread);
424}
425
426template <class Impl>
427void
276}
277
278template <class Impl>
279void
428FullO3CPU<Impl>::insertThread(unsigned tid)
280FullO3CPU<Impl>::activateContext(int thread_num, int delay)
429{
281{
430 DPRINTF(FullCPU,"[tid:%i] Initializing thread data");
431 // Will change now that the PC and thread state is internal to the CPU
432 // and not in the CPUExecContext.
433#if 0
434#if FULL_SYSTEM
435 ExecContext *src_xc = system->execContexts[tid];
436#else
437 CPUExecContext *src_xc = thread[tid];
438#endif
439
440 //Bind Int Regs to Rename Map
441 for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) {
442 PhysRegIndex phys_reg = freeList.getIntReg();
443
444 renameMap[tid].setEntry(ireg,phys_reg);
445 scoreboard.setReg(phys_reg);
446 }
447
448 //Bind Float Regs to Rename Map
449 for (int freg = 0; freg < TheISA::NumFloatRegs; freg++) {
450 PhysRegIndex phys_reg = freeList.getFloatReg();
451
452 renameMap[tid].setEntry(freg,phys_reg);
453 scoreboard.setReg(phys_reg);
454 }
455
456 //Copy Thread Data Into RegFile
457 this->copyFromXC(tid);
458
459 //Set PC/NPC
460 regFile.pc[tid] = src_xc->readPC();
461 regFile.npc[tid] = src_xc->readNextPC();
462
463 src_xc->setStatus(ExecContext::Active);
464
465 activateContext(tid,1);
466
467 //Reset ROB/IQ/LSQ Entries
468 commit.rob->resetEntries();
469 iew.resetEntries();
470#endif
471}
472
473template <class Impl>
474void
475FullO3CPU<Impl>::removeThread(unsigned tid)
476{
477 DPRINTF(FullCPU,"[tid:%i] Removing thread data");
478#if 0
479 //Unbind Int Regs from Rename Map
480 for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) {
481 PhysRegIndex phys_reg = renameMap[tid].lookup(ireg);
482
483 scoreboard.unsetReg(phys_reg);
484 freeList.addReg(phys_reg);
485 }
486
487 //Unbind Float Regs from Rename Map
488 for (int freg = 0; freg < TheISA::NumFloatRegs; freg++) {
489 PhysRegIndex phys_reg = renameMap[tid].lookup(freg);
490
491 scoreboard.unsetReg(phys_reg);
492 freeList.addReg(phys_reg);
493 }
494
495 //Copy Thread Data From RegFile
496 /* Fix Me:
497 * Do we really need to do this if we are removing a thread
498 * in the sense that it's finished (exiting)? If the thread is just
499 * being suspended we might...
500 */
501// this->copyToXC(tid);
502
503 //Squash Throughout Pipeline
504 fetch.squash(0,tid);
505 decode.squash(tid);
506 rename.squash(tid);
507
508 assert(iew.ldstQueue.getCount(tid) == 0);
509
510 //Reset ROB/IQ/LSQ Entries
511 if (activeThreads.size() >= 1) {
512 commit.rob->resetEntries();
513 iew.resetEntries();
514 }
515#endif
516}
517
518
519template <class Impl>
520void
521FullO3CPU<Impl>::activateWhenReady(int tid)
522{
523 DPRINTF(FullCPU,"[tid:%i]: Checking if resources are available for incoming"
524 "(e.g. PhysRegs/ROB/IQ/LSQ) \n",
525 tid);
526
527 bool ready = true;
528
529 if (freeList.numFreeIntRegs() >= TheISA::NumIntRegs) {
530 DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough "
531 "Phys. Int. Regs.\n",
532 tid);
533 ready = false;
534 } else if (freeList.numFreeFloatRegs() >= TheISA::NumFloatRegs) {
535 DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough "
536 "Phys. Float. Regs.\n",
537 tid);
538 ready = false;
539 } else if (commit.rob->numFreeEntries() >=
540 commit.rob->entryAmount(activeThreads.size() + 1)) {
541 DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough "
542 "ROB entries.\n",
543 tid);
544 ready = false;
545 } else if (iew.instQueue.numFreeEntries() >=
546 iew.instQueue.entryAmount(activeThreads.size() + 1)) {
547 DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough "
548 "IQ entries.\n",
549 tid);
550 ready = false;
551 } else if (iew.ldstQueue.numFreeEntries() >=
552 iew.ldstQueue.entryAmount(activeThreads.size() + 1)) {
553 DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough "
554 "LSQ entries.\n",
555 tid);
556 ready = false;
557 }
558
559 if (ready) {
560 insertThread(tid);
561
562 contextSwitch = false;
563
564 cpuWaitList.remove(tid);
565 } else {
566 suspendContext(tid);
567
568 //blocks fetch
569 contextSwitch = true;
570
571 //do waitlist
572 cpuWaitList.push_back(tid);
573 }
574}
575
576template <class Impl>
577void
578FullO3CPU<Impl>::activateContext(int tid, int delay)
579{
580 // Needs to set each stage to running as well.
282 // Needs to set each stage to running as well.
581 list<unsigned>::iterator isActive = find(
582 activeThreads.begin(), activeThreads.end(), tid);
583
283
584 if (isActive == activeThreads.end()) {
585 //May Need to Re-code this if the delay variable is the
586 //delay needed for thread to activate
587 DPRINTF(FullCPU, "Adding Thread %i to active threads list\n",
588 tid);
589
590 activeThreads.push_back(tid);
591 }
592
593 assert(_status == Idle || _status == SwitchedOut);
594
595 scheduleTickEvent(delay);
596
284 scheduleTickEvent(delay);
285
597 // Be sure to signal that there's some activity so the CPU doesn't
598 // deschedule itself.
599 activityRec.activity();
600 fetch.wakeFromQuiesce();
601
602 _status = Running;
603}
604
605template <class Impl>
606void
286 _status = Running;
287}
288
289template <class Impl>
290void
607FullO3CPU<Impl>::suspendContext(int tid)
291FullO3CPU<Impl>::suspendContext(int thread_num)
608{
292{
609 DPRINTF(FullCPU,"[tid: %i]: Suspended ...\n", tid);
610 unscheduleTickEvent();
611 _status = Idle;
612/*
613 //Remove From Active List, if Active
614 list<unsigned>::iterator isActive = find(
615 activeThreads.begin(), activeThreads.end(), tid);
616
617 if (isActive != activeThreads.end()) {
618 DPRINTF(FullCPU,"[tid:%i]: Removing from active threads list\n",
619 tid);
620 activeThreads.erase(isActive);
621 }
622*/
293 panic("suspendContext unimplemented!");
623}
624
625template <class Impl>
626void
294}
295
296template <class Impl>
297void
627FullO3CPU<Impl>::deallocateContext(int tid)
298FullO3CPU<Impl>::deallocateContext(int thread_num)
628{
299{
629 DPRINTF(FullCPU,"[tid:%i]: Deallocating ...", tid);
630/*
631 //Remove From Active List, if Active
632 list<unsigned>::iterator isActive = find(
633 activeThreads.begin(), activeThreads.end(), tid);
634
635 if (isActive != activeThreads.end()) {
636 DPRINTF(FullCPU,"[tid:%i]: Removing from active threads list\n",
637 tid);
638 activeThreads.erase(isActive);
639
640 removeThread(tid);
641 }
642*/
300 panic("deallocateContext unimplemented!");
643}
644
645template <class Impl>
646void
301}
302
303template <class Impl>
304void
647FullO3CPU<Impl>::haltContext(int tid)
305FullO3CPU<Impl>::haltContext(int thread_num)
648{
306{
649 DPRINTF(FullCPU,"[tid:%i]: Halted ...", tid);
650/*
651 //Remove From Active List, if Active
652 list<unsigned>::iterator isActive = find(
653 activeThreads.begin(), activeThreads.end(), tid);
654
655 if (isActive != activeThreads.end()) {
656 DPRINTF(FullCPU,"[tid:%i]: Removing from active threads list\n",
657 tid);
658 activeThreads.erase(isActive);
659
660 removeThread(tid);
661 }
662*/
307 panic("haltContext unimplemented!");
663}
664
665template <class Impl>
666void
308}
309
310template <class Impl>
311void
667FullO3CPU<Impl>::switchOut(Sampler *_sampler)
312FullO3CPU::switchOut()
668{
313{
669 sampler = _sampler;
670 switchCount = 0;
671 fetch.switchOut();
672 decode.switchOut();
673 rename.switchOut();
674 iew.switchOut();
675 commit.switchOut();
676
677 // Wake the CPU and record activity so everything can drain out if
678 // the CPU is currently idle.
679 wakeCPU();
680 activityRec.activity();
314 panic("FullO3CPU does not have a switch out function.\n");
681}
682
683template <class Impl>
684void
315}
316
317template <class Impl>
318void
685FullO3CPU<Impl>::signalSwitched()
686{
687 if (++switchCount == NumStages) {
688 fetch.doSwitchOut();
689 rename.doSwitchOut();
690 commit.doSwitchOut();
691 instList.clear();
692 while (!removeList.empty()) {
693 removeList.pop();
694 }
695
696 if (checker)
697 checker->switchOut(sampler);
698
699 if (tickEvent.scheduled())
700 tickEvent.squash();
701 sampler->signalSwitched();
702 _status = SwitchedOut;
703 }
704 assert(switchCount <= 5);
705}
706
707template <class Impl>
708void
709FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
710{
319FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
320{
711 // Flush out any old data from the time buffers.
712 for (int i = 0; i < 10; ++i) {
713 timeBuffer.advance();
714 fetchQueue.advance();
715 decodeQueue.advance();
716 renameQueue.advance();
717 iewQueue.advance();
718 }
719
720 activityRec.reset();
721
722 BaseCPU::takeOverFrom(oldCPU);
723
321 BaseCPU::takeOverFrom(oldCPU);
322
724 fetch.takeOverFrom();
725 decode.takeOverFrom();
726 rename.takeOverFrom();
727 iew.takeOverFrom();
728 commit.takeOverFrom();
729
730 assert(!tickEvent.scheduled());
731
323 assert(!tickEvent.scheduled());
324
732 // @todo: Figure out how to properly select the tid to put onto
733 // the active threads list.
734 int tid = 0;
735
736 list<unsigned>::iterator isActive = find(
737 activeThreads.begin(), activeThreads.end(), tid);
738
739 if (isActive == activeThreads.end()) {
740 //May Need to Re-code this if the delay variable is the delay
741 //needed for thread to activate
742 DPRINTF(FullCPU, "Adding Thread %i to active threads list\n",
743 tid);
744
745 activeThreads.push_back(tid);
746 }
747
748 // Set all statuses to active, schedule the CPU's tick event.
749 // @todo: Fix up statuses so this is handled properly
325 // Set all status's to active, schedule the
326 // CPU's tick event.
750 for (int i = 0; i < execContexts.size(); ++i) {
751 ExecContext *xc = execContexts[i];
752 if (xc->status() == ExecContext::Active && _status != Running) {
753 _status = Running;
754 tickEvent.schedule(curTick);
755 }
756 }
327 for (int i = 0; i < execContexts.size(); ++i) {
328 ExecContext *xc = execContexts[i];
329 if (xc->status() == ExecContext::Active && _status != Running) {
330 _status = Running;
331 tickEvent.schedule(curTick);
332 }
333 }
757 if (!tickEvent.scheduled())
758 tickEvent.schedule(curTick);
759}
760
761template <class Impl>
334}
335
336template <class Impl>
337InstSeqNum
338FullO3CPU<Impl>::getAndIncrementInstSeq()
339{
340 // Hopefully this works right.
341 return globalSeqNum++;
342}
343
344template <class Impl>
762uint64_t
763FullO3CPU<Impl>::readIntReg(int reg_idx)
764{
765 return regFile.readIntReg(reg_idx);
766}
767
768template <class Impl>
769FloatReg

--- 7 unchanged lines hidden (view full) ---

777FullO3CPU<Impl>::readFloatReg(int reg_idx)
778{
779 return regFile.readFloatReg(reg_idx);
780}
781
782template <class Impl>
783FloatRegBits
784FullO3CPU<Impl>::readFloatRegBits(int reg_idx, int width)
345uint64_t
346FullO3CPU<Impl>::readIntReg(int reg_idx)
347{
348 return regFile.readIntReg(reg_idx);
349}
350
351template <class Impl>
352FloatReg

--- 7 unchanged lines hidden (view full) ---

360FullO3CPU<Impl>::readFloatReg(int reg_idx)
361{
362 return regFile.readFloatReg(reg_idx);
363}
364
365template <class Impl>
366FloatRegBits
367FullO3CPU<Impl>::readFloatRegBits(int reg_idx, int width)
368{
785 return regFile.readFloatRegBits(reg_idx, width);
786}
787
788template <class Impl>
789FloatRegBits
790FullO3CPU<Impl>::readFloatRegBits(int reg_idx)
791{
792 return regFile.readFloatRegBits(reg_idx);

--- 31 unchanged lines hidden (view full) ---

824void
825FullO3CPU<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val)
826{
827 regFile.setFloatRegBits(reg_idx, val);
828}
829
830template <class Impl>
831uint64_t
369 return regFile.readFloatRegBits(reg_idx, width);
370}
371
372template <class Impl>
373FloatRegBits
374FullO3CPU<Impl>::readFloatRegBits(int reg_idx)
375{
376 return regFile.readFloatRegBits(reg_idx);

--- 31 unchanged lines hidden (view full) ---

408void
409FullO3CPU<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val)
410{
411 regFile.setFloatRegBits(reg_idx, val);
412}
413
414template <class Impl>
415uint64_t
832FullO3CPU<Impl>::readArchIntReg(int reg_idx, unsigned tid)
416FullO3CPU<Impl>::readPC()
833{
417{
834 PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx);
835
836 return regFile.readIntReg(phys_reg);
418 return regFile.readPC();
837}
838
839template <class Impl>
419}
420
421template <class Impl>
840float
841FullO3CPU<Impl>::readArchFloatRegSingle(int reg_idx, unsigned tid)
842{
843 int idx = reg_idx + TheISA::FP_Base_DepTag;
844 PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx);
845
846 return regFile.readFloatRegSingle(phys_reg);
847}
848
849template <class Impl>
850double
851FullO3CPU<Impl>::readArchFloatRegDouble(int reg_idx, unsigned tid)
852{
853 int idx = reg_idx + TheISA::FP_Base_DepTag;
854 PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx);
855
856 return regFile.readFloatRegDouble(phys_reg);
857}
858
859template <class Impl>
860uint64_t
861FullO3CPU<Impl>::readArchFloatRegInt(int reg_idx, unsigned tid)
862{
863 int idx = reg_idx + TheISA::FP_Base_DepTag;
864 PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx);
865
866 return regFile.readFloatRegInt(phys_reg);
867}
868
869template <class Impl>
870void
422void
871FullO3CPU<Impl>::setArchIntReg(int reg_idx, uint64_t val, unsigned tid)
423FullO3CPU<Impl>::setNextPC(uint64_t val)
872{
424{
873 PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx);
874
875 regFile.setIntReg(phys_reg, val);
425 regFile.setNextPC(val);
876}
877
878template <class Impl>
879void
426}
427
428template <class Impl>
429void
880FullO3CPU<Impl>::setArchFloatRegSingle(int reg_idx, float val, unsigned tid)
430FullO3CPU<Impl>::setPC(Addr new_PC)
881{
431{
882 PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx);
883
884 regFile.setFloatRegSingle(phys_reg, val);
432 regFile.setPC(new_PC);
885}
886
887template <class Impl>
888void
433}
434
435template <class Impl>
436void
889FullO3CPU<Impl>::setArchFloatRegDouble(int reg_idx, double val, unsigned tid)
437FullO3CPU<Impl>::addInst(DynInstPtr &inst)
890{
438{
891 PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx);
892
893 regFile.setFloatRegDouble(phys_reg, val);
439 instList.push_back(inst);
894}
895
896template <class Impl>
897void
440}
441
442template <class Impl>
443void
898FullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, unsigned tid)
444FullO3CPU<Impl>::instDone()
899{
445{
900 PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx);
446 // Keep an instruction count.
447 numInsts++;
901
448
902 regFile.setFloatRegInt(phys_reg, val);
449 // Check for instruction-count-based events.
450 comInstEventQueue[0]->serviceEvents(numInsts);
903}
904
905template <class Impl>
451}
452
453template <class Impl>
906uint64_t
907FullO3CPU<Impl>::readPC(unsigned tid)
908{
909 return commit.readPC(tid);
910}
911
912template <class Impl>
913void
454void
914FullO3CPU<Impl>::setPC(Addr new_PC,unsigned tid)
455FullO3CPU<Impl>::removeBackInst(DynInstPtr &inst)
915{
456{
916 commit.setPC(new_PC, tid);
917}
457 DynInstPtr inst_to_delete;
918
458
919template <class Impl>
920uint64_t
921FullO3CPU<Impl>::readNextPC(unsigned tid)
922{
923 return commit.readNextPC(tid);
924}
459 // Walk through the instruction list, removing any instructions
460 // that were inserted after the given instruction, inst.
461 while (instList.back() != inst)
462 {
463 assert(!instList.empty());
925
464
926template <class Impl>
927void
928FullO3CPU<Impl>::setNextPC(uint64_t val,unsigned tid)
929{
930 commit.setNextPC(val, tid);
931}
465 // Obtain the pointer to the instruction.
466 inst_to_delete = instList.back();
932
467
933template <class Impl>
934typename FullO3CPU<Impl>::ListIt
935FullO3CPU<Impl>::addInst(DynInstPtr &inst)
936{
937 instList.push_back(inst);
468 DPRINTF(FullCPU, "FullCPU: Removing instruction %i, PC %#x\n",
469 inst_to_delete->seqNum, inst_to_delete->readPC());
938
470
939 return --(instList.end());
940}
471 // Remove the instruction from the list.
472 instList.pop_back();
941
473
942template <class Impl>
943void
944FullO3CPU<Impl>::instDone(unsigned tid)
945{
946 // Keep an instruction count.
947 thread[tid]->numInst++;
948 thread[tid]->numInsts++;
949 committedInsts[tid]++;
950 totalCommittedInsts++;
951
952 // Check for instruction-count-based events.
953 comInstEventQueue[tid]->serviceEvents(thread[tid]->numInst);
474 // Mark it as squashed.
475 inst_to_delete->setSquashed();
476 }
954}
955
956template <class Impl>
957void
477}
478
479template <class Impl>
480void
958FullO3CPU<Impl>::addToRemoveList(DynInstPtr &inst)
959{
960 removeInstsThisCycle = true;
961
962 removeList.push(inst->getInstListIt());
963}
964
965template <class Impl>
966void
967FullO3CPU<Impl>::removeFrontInst(DynInstPtr &inst)
968{
481FullO3CPU<Impl>::removeFrontInst(DynInstPtr &inst)
482{
969 DPRINTF(FullCPU, "FullCPU: Removing committed instruction [tid:%i] PC %#x "
970 "[sn:%lli]\n",
971 inst->threadNumber, inst->readPC(), inst->seqNum);
483 DynInstPtr inst_to_remove;
972
484
973 removeInstsThisCycle = true;
485 // The front instruction should be the same one being asked to be removed.
486 assert(instList.front() == inst);
974
975 // Remove the front instruction.
487
488 // Remove the front instruction.
976 removeList.push(inst->getInstListIt());
489 inst_to_remove = inst;
490 instList.pop_front();
491
492 DPRINTF(FullCPU, "FullCPU: Removing committed instruction %#x, PC %#x\n",
493 inst_to_remove, inst_to_remove->readPC());
977}
978
979template <class Impl>
980void
494}
495
496template <class Impl>
497void
981FullO3CPU<Impl>::removeInstsNotInROB(unsigned tid)
498FullO3CPU::removeInstsNotInROB()
982{
499{
983 DPRINTF(FullCPU, "FullCPU: Thread %i: Deleting instructions from instruction"
984 " list.\n", tid);
500 DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction "
501 "list.\n");
985
502
986 ListIt end_it;
503 DynInstPtr rob_tail = rob.readTailInst();
987
504
988 bool rob_empty = false;
989
990 if (instList.empty()) {
991 return;
992 } else if (rob.isEmpty(/*tid*/)) {
993 DPRINTF(FullCPU, "FullCPU: ROB is empty, squashing all insts.\n");
994 end_it = instList.begin();
995 rob_empty = true;
996 } else {
997 end_it = (rob.readTailInst(tid))->getInstListIt();
998 DPRINTF(FullCPU, "FullCPU: ROB is not empty, squashing insts not in ROB.\n");
999 }
1000
1001 removeInstsThisCycle = true;
1002
1003 ListIt inst_it = instList.end();
1004
1005 inst_it--;
1006
1007 // Walk through the instruction list, removing any instructions
1008 // that were inserted after the given instruction iterator, end_it.
1009 while (inst_it != end_it) {
1010 assert(!instList.empty());
1011
1012 squashInstIt(inst_it, tid);
1013
1014 inst_it--;
1015 }
1016
1017 // If the ROB was empty, then we actually need to remove the first
1018 // instruction as well.
1019 if (rob_empty) {
1020 squashInstIt(inst_it, tid);
1021 }
505 removeBackInst(rob_tail);
1022}
1023
1024template <class Impl>
1025void
506}
507
508template <class Impl>
509void
1026FullO3CPU<Impl>::removeInstsUntil(const InstSeqNum &seq_num,
1027 unsigned tid)
510FullO3CPU<Impl>::removeInstsUntil(const InstSeqNum &seq_num)
1028{
511{
1029 assert(!instList.empty());
1030
1031 removeInstsThisCycle = true;
1032
1033 ListIt inst_iter = instList.end();
1034
1035 inst_iter--;
1036
1037 DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction "
512 DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction "
1038 "list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n",
1039 tid, seq_num, (*inst_iter)->seqNum);
513 "list.\n");
1040
514
1041 while ((*inst_iter)->seqNum > seq_num) {
515 DynInstPtr inst_to_delete;
1042
516
1043 bool break_loop = (inst_iter == instList.begin());
517 while (instList.back()->seqNum > seq_num) {
518 assert(!instList.empty());
1044
519
1045 squashInstIt(inst_iter, tid);
520 // Obtain the pointer to the instruction.
521 inst_to_delete = instList.back();
1046
522
1047 inst_iter--;
523 DPRINTF(FullCPU, "FullCPU: Removing instruction %i, PC %#x\n",
524 inst_to_delete->seqNum, inst_to_delete->readPC());
1048
525
1049 if (break_loop)
1050 break;
1051 }
1052}
526 // Remove the instruction from the list.
527 instList.back() = NULL;
528 instList.pop_back();
1053
529
1054template <class Impl>
1055inline void
1056FullO3CPU<Impl>::squashInstIt(const ListIt &instIt, const unsigned &tid)
1057{
1058 if ((*instIt)->threadNumber == tid) {
1059 DPRINTF(FullCPU, "FullCPU: Squashing instruction, "
1060 "[tid:%i] [sn:%lli] PC %#x\n",
1061 (*instIt)->threadNumber,
1062 (*instIt)->seqNum,
1063 (*instIt)->readPC());
1064
1065 // Mark it as squashed.
530 // Mark it as squashed.
1066 (*instIt)->setSquashed();
1067
1068 // @todo: Formulate a consistent method for deleting
1069 // instructions from the instruction list
1070 // Remove the instruction from the list.
1071 removeList.push(instIt);
531 inst_to_delete->setSquashed();
1072 }
532 }
533
1073}
1074
1075template <class Impl>
1076void
534}
535
536template <class Impl>
537void
1077FullO3CPU<Impl>::cleanUpRemovedInsts()
1078{
1079 while (!removeList.empty()) {
1080 DPRINTF(FullCPU, "FullCPU: Removing instruction, "
1081 "[tid:%i] [sn:%lli] PC %#x\n",
1082 (*removeList.front())->threadNumber,
1083 (*removeList.front())->seqNum,
1084 (*removeList.front())->readPC());
1085
1086 instList.erase(removeList.front());
1087
1088 removeList.pop();
1089 }
1090
1091 removeInstsThisCycle = false;
1092}
1093/*
1094template <class Impl>
1095void
1096FullO3CPU<Impl>::removeAllInsts()
1097{
1098 instList.clear();
1099}
538FullO3CPU<Impl>::removeAllInsts()
539{
540 instList.clear();
541}
1100*/
542
1101template <class Impl>
1102void
1103FullO3CPU<Impl>::dumpInsts()
1104{
1105 int num = 0;
543template <class Impl>
544void
545FullO3CPU<Impl>::dumpInsts()
546{
547 int num = 0;
548 typename list<DynInstPtr>::iterator inst_list_it = instList.begin();
1106
549
1107 ListIt inst_list_it = instList.begin();
1108
1109 cprintf("Dumping Instruction List\n");
1110
1111 while (inst_list_it != instList.end()) {
1112 cprintf("Instruction:%i\nPC:%#x\n[tid:%i]\n[sn:%lli]\nIssued:%i\n"
1113 "Squashed:%i\n\n",
1114 num, (*inst_list_it)->readPC(), (*inst_list_it)->threadNumber,
1115 (*inst_list_it)->seqNum, (*inst_list_it)->isIssued(),
1116 (*inst_list_it)->isSquashed());
550 while (inst_list_it != instList.end())
551 {
552 cprintf("Instruction:%i\nPC:%#x\nSN:%lli\nIssued:%i\nSquashed:%i\n\n",
553 num, (*inst_list_it)->readPC(), (*inst_list_it)->seqNum,
554 (*inst_list_it)->isIssued(), (*inst_list_it)->isSquashed());
1117 inst_list_it++;
1118 ++num;
1119 }
1120}
555 inst_list_it++;
556 ++num;
557 }
558}
1121/*
559
1122template <class Impl>
1123void
1124FullO3CPU<Impl>::wakeDependents(DynInstPtr &inst)
1125{
1126 iew.wakeDependents(inst);
1127}
560template <class Impl>
561void
562FullO3CPU<Impl>::wakeDependents(DynInstPtr &inst)
563{
564 iew.wakeDependents(inst);
565}
1128*/
1129template <class Impl>
1130void
1131FullO3CPU<Impl>::wakeCPU()
1132{
1133 if (activityRec.active() || tickEvent.scheduled()) {
1134 DPRINTF(Activity, "CPU already running.\n");
1135 return;
1136 }
1137
566
1138 DPRINTF(Activity, "Waking up CPU\n");
1139
1140 idleCycles += (curTick - 1) - lastRunningCycle;
1141
1142 tickEvent.schedule(curTick);
1143}
1144
1145template <class Impl>
1146int
1147FullO3CPU<Impl>::getFreeTid()
1148{
1149 for (int i=0; i < numThreads; i++) {
1150 if (!tids[i]) {
1151 tids[i] = true;
1152 return i;
1153 }
1154 }
1155
1156 return -1;
1157}
1158
1159template <class Impl>
1160void
1161FullO3CPU<Impl>::doContextSwitch()
1162{
1163 if (contextSwitch) {
1164
1165 //ADD CODE TO DEACTIVE THREAD HERE (???)
1166
1167 for (int tid=0; tid < cpuWaitList.size(); tid++) {
1168 activateWhenReady(tid);
1169 }
1170
1171 if (cpuWaitList.size() == 0)
1172 contextSwitch = true;
1173 }
1174}
1175
1176template <class Impl>
1177void
1178FullO3CPU<Impl>::updateThreadPriority()
1179{
1180 if (activeThreads.size() > 1)
1181 {
1182 //DEFAULT TO ROUND ROBIN SCHEME
1183 //e.g. Move highest priority to end of thread list
1184 list<unsigned>::iterator list_begin = activeThreads.begin();
1185 list<unsigned>::iterator list_end = activeThreads.end();
1186
1187 unsigned high_thread = *list_begin;
1188
1189 activeThreads.erase(list_begin);
1190
1191 activeThreads.push_back(high_thread);
1192 }
1193}
1194
1195// Forward declaration of FullO3CPU.
1196template class FullO3CPU<AlphaSimpleImpl>;
567// Forward declaration of FullO3CPU.
568template class FullO3CPU<AlphaSimpleImpl>;