cpu.cc (2665:a124942bacb8) | cpu.cc (2669:f2b336e89d2a) |
---|---|
1/* | 1/* |
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan | 2 * Copyright (c) 2004-2006 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 | |
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 | 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 |
38#include "sim/root.hh" | |
39 | 36 |
37#include "cpu/activity.hh" 38#include "cpu/checker/cpu.hh" |
|
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 | 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 |
45#include "sim/root.hh" 46#include "sim/stat_control.hh" 47 |
|
46using namespace std; | 48using namespace std; |
49using namespace TheISA; |
|
47 | 50 |
48BaseFullCPU::BaseFullCPU(Params ¶ms) 49 : BaseCPU(¶ms), cpu_id(0) | 51BaseFullCPU::BaseFullCPU(Params *params) 52 : BaseCPU(params), cpu_id(0) |
50{ 51} 52 | 53{ 54} 55 |
56void 57BaseFullCPU::regStats() 58{ 59 BaseCPU::regStats(); 60} 61 |
|
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 | 62template <class Impl> 63FullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c) 64 : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c) 65{ 66} 67 68template <class Impl> 69void --- 4 unchanged lines hidden (view full) --- 74 75template <class Impl> 76const char * 77FullO3CPU<Impl>::TickEvent::description() 78{ 79 return "FullO3CPU tick event"; 80} 81 |
73//Call constructor to all the pipeline stages here | |
74template <class Impl> | 82template <class Impl> |
75FullO3CPU<Impl>::FullO3CPU(Params ¶ms) 76#if FULL_SYSTEM | 83FullO3CPU<Impl>::FullO3CPU(Params *params) |
77 : BaseFullCPU(params), | 84 : BaseFullCPU(params), |
78#else 79 : BaseFullCPU(params), 80#endif // FULL_SYSTEM | |
81 tickEvent(this), | 85 tickEvent(this), |
86 removeInstsThisCycle(false), |
|
82 fetch(params), 83 decode(params), 84 rename(params), 85 iew(params), 86 commit(params), 87 | 87 fetch(params), 88 decode(params), 89 rename(params), 90 iew(params), 91 commit(params), 92 |
88 regFile(params.numPhysIntRegs, params.numPhysFloatRegs), | 93 regFile(params->numPhysIntRegs, params->numPhysFloatRegs), |
89 | 94 |
90 freeList(TheISA::NumIntRegs, params.numPhysIntRegs, 91 TheISA::NumFloatRegs, params.numPhysFloatRegs), | 95 freeList(params->numberOfThreads,//number of activeThreads 96 TheISA::NumIntRegs, params->numPhysIntRegs, 97 TheISA::NumFloatRegs, params->numPhysFloatRegs), |
92 | 98 |
93 renameMap(TheISA::NumIntRegs, params.numPhysIntRegs, 94 TheISA::NumFloatRegs, params.numPhysFloatRegs, 95 TheISA::NumMiscRegs, 96 TheISA::ZeroReg, 97 TheISA::ZeroReg + TheISA::NumIntRegs), | 99 rob(params->numROBEntries, params->squashWidth, 100 params->smtROBPolicy, params->smtROBThreshold, 101 params->numberOfThreads), |
98 | 102 |
99 rob(params.numROBEntries, params.squashWidth), | 103 scoreboard(params->numberOfThreads,//number of activeThreads 104 TheISA::NumIntRegs, params->numPhysIntRegs, 105 TheISA::NumFloatRegs, params->numPhysFloatRegs, 106 TheISA::NumMiscRegs * number_of_threads, 107 TheISA::ZeroReg), |
100 | 108 |
101 // What to pass to these time buffers? | |
102 // For now just have these time buffers be pretty big. | 109 // For now just have these time buffers be pretty big. |
110 // @todo: Make these time buffer sizes parameters or derived 111 // from latencies |
|
103 timeBuffer(5, 5), 104 fetchQueue(5, 5), 105 decodeQueue(5, 5), 106 renameQueue(5, 5), 107 iewQueue(5, 5), | 112 timeBuffer(5, 5), 113 fetchQueue(5, 5), 114 decodeQueue(5, 5), 115 renameQueue(5, 5), 116 iewQueue(5, 5), |
117 activityRec(NumStages, 10, params->activity), |
|
108 | 118 |
109 cpuXC(NULL), 110 | |
111 globalSeqNum(1), 112 113#if FULL_SYSTEM | 119 globalSeqNum(1), 120 121#if FULL_SYSTEM |
114 system(params.system), | 122 system(params->system), |
115 memCtrl(system->memctrl), 116 physmem(system->physmem), | 123 memCtrl(system->memctrl), 124 physmem(system->physmem), |
117 itb(params.itb), 118 dtb(params.dtb), 119 mem(params.mem), 120#else 121 // Hardcoded for a single thread!! 122 mem(params.workload[0]->getMemory()), | |
123#endif // FULL_SYSTEM | 125#endif // FULL_SYSTEM |
124 125 icacheInterface(params.icacheInterface), 126 dcacheInterface(params.dcacheInterface), 127 deferRegistration(params.defReg), 128 numInsts(0), 129 funcExeInst(0) | 126 mem(params->mem), 127 switchCount(0), 128 deferRegistration(params->deferRegistration), 129 numThreads(number_of_threads) |
130{ 131 _status = Idle; 132 | 130{ 131 _status = Idle; 132 |
133#if !FULL_SYSTEM 134 thread.resize(this->number_of_threads); 135#endif 136 137 for (int i = 0; i < this->number_of_threads; ++i) { | 133 if (params->checker) { 134 BaseCPU *temp_checker = params->checker; 135 checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker); 136 checker->setMemory(mem); |
138#if FULL_SYSTEM | 137#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(); 142 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 | 138 checker->setSystem(params->system); 139#endif 140 } else { 141 checker = NULL; |
155 } 156 | 142 } 143 |
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]; | 144#if !FULL_SYSTEM 145 thread.resize(number_of_threads); 146 tids.resize(number_of_threads); 147#endif |
160 | 148 |
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. | 149 // The stages also need their CPU pointer setup. However this 150 // must be done at the upper level CPU because they have pointers 151 // to the upper level CPU, and not this FullO3CPU. |
164 | 152 |
153 // Set up Pointers to the activeThreads list for each stage 154 fetch.setActiveThreads(&activeThreads); 155 decode.setActiveThreads(&activeThreads); 156 rename.setActiveThreads(&activeThreads); 157 iew.setActiveThreads(&activeThreads); 158 commit.setActiveThreads(&activeThreads); 159 |
|
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); | 160 // Give each of the stages the time buffer they will use. 161 fetch.setTimeBuffer(&timeBuffer); 162 decode.setTimeBuffer(&timeBuffer); 163 rename.setTimeBuffer(&timeBuffer); 164 iew.setTimeBuffer(&timeBuffer); 165 commit.setTimeBuffer(&timeBuffer); 166 167 // Also setup each of the stages' queues. 168 fetch.setFetchQueue(&fetchQueue); 169 decode.setFetchQueue(&fetchQueue); |
170 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 | 171 decode.setDecodeQueue(&decodeQueue); 172 rename.setDecodeQueue(&decodeQueue); 173 rename.setRenameQueue(&renameQueue); 174 iew.setRenameQueue(&renameQueue); 175 iew.setIEWQueue(&iewQueue); 176 commit.setIEWQueue(&iewQueue); 177 commit.setRenameQueue(&renameQueue); 178 |
179 commit.setFetchStage(&fetch); 180 commit.setIEWStage(&iew); 181 rename.setIEWStage(&iew); 182 rename.setCommitStage(&commit); 183 184#if !FULL_SYSTEM 185 int active_threads = params->workload.size(); 186#else 187 int active_threads = 1; 188#endif 189 190 //Make Sure That this a Valid Architeture 191 assert(params->numPhysIntRegs >= numThreads * TheISA::NumIntRegs); 192 assert(params->numPhysFloatRegs >= numThreads * TheISA::NumFloatRegs); 193 194 rename.setScoreboard(&scoreboard); 195 iew.setScoreboard(&scoreboard); 196 |
|
183 // Setup the rename map for whichever stages need it. | 197 // Setup the rename map for whichever stages need it. |
184 rename.setRenameMap(&renameMap); 185 iew.setRenameMap(&renameMap); | 198 PhysRegIndex lreg_idx = 0; 199 PhysRegIndex freg_idx = params->numPhysIntRegs; //Index to 1 after int regs |
186 | 200 |
187 // Setup the free list for whichever stages need it. | 201 for (int tid=0; tid < numThreads; tid++) { 202 bool bindRegs = (tid <= active_threads - 1); 203 204 commitRenameMap[tid].init(TheISA::NumIntRegs, 205 params->numPhysIntRegs, 206 lreg_idx, //Index for Logical. Regs 207 208 TheISA::NumFloatRegs, 209 params->numPhysFloatRegs, 210 freg_idx, //Index for Float Regs 211 212 TheISA::NumMiscRegs, 213 214 TheISA::ZeroReg, 215 TheISA::ZeroReg, 216 217 tid, 218 false); 219 220 renameMap[tid].init(TheISA::NumIntRegs, 221 params->numPhysIntRegs, 222 lreg_idx, //Index for Logical. Regs 223 224 TheISA::NumFloatRegs, 225 params->numPhysFloatRegs, 226 freg_idx, //Index for Float Regs 227 228 TheISA::NumMiscRegs, 229 230 TheISA::ZeroReg, 231 TheISA::ZeroReg, 232 233 tid, 234 bindRegs); 235 } 236 237 rename.setRenameMap(renameMap); 238 commit.setRenameMap(commitRenameMap); 239 240 // Give renameMap & rename stage access to the freeList; 241 for (int i=0; i < numThreads; i++) { 242 renameMap[i].setFreeList(&freeList); 243 } |
188 rename.setFreeList(&freeList); | 244 rename.setFreeList(&freeList); |
189 renameMap.setFreeList(&freeList); | |
190 | 245 |
246 // Setup the page table for whichever stages need it. 247#if !FULL_SYSTEM 248// fetch.setPageTable(pTable); 249// iew.setPageTable(pTable); 250#endif 251 |
|
191 // Setup the ROB for whichever stages need it. 192 commit.setROB(&rob); | 252 // Setup the ROB for whichever stages need it. 253 commit.setROB(&rob); |
254 255 lastRunningCycle = curTick; 256 257 contextSwitch = false; |
|
193} 194 195template <class Impl> 196FullO3CPU<Impl>::~FullO3CPU() 197{ 198} 199 200template <class Impl> 201void 202FullO3CPU<Impl>::fullCPURegStats() 203{ | 258} 259 260template <class Impl> 261FullO3CPU<Impl>::~FullO3CPU() 262{ 263} 264 265template <class Impl> 266void 267FullO3CPU<Impl>::fullCPURegStats() 268{ |
269 BaseFullCPU::regStats(); 270 |
|
204 // Register any of the FullCPU's stats here. | 271 // Register any of the FullCPU's stats here. |
272 timesIdled 273 .name(name() + ".timesIdled") 274 .desc("Number of times that the entire CPU went into an idle state and" 275 " unscheduled itself") 276 .prereq(timesIdled); 277 278 idleCycles 279 .name(name() + ".idleCycles") 280 .desc("Total number of cycles that the CPU has spent unscheduled due " 281 "to idling") 282 .prereq(idleCycles); 283 284 // Number of Instructions simulated 285 // -------------------------------- 286 // Should probably be in Base CPU but need templated 287 // MaxThreads so put in here instead 288 committedInsts 289 .init(numThreads) 290 .name(name() + ".committedInsts") 291 .desc("Number of Instructions Simulated"); 292 293 totalCommittedInsts 294 .name(name() + ".committedInsts_total") 295 .desc("Number of Instructions Simulated"); 296 297 cpi 298 .name(name() + ".cpi") 299 .desc("CPI: Cycles Per Instruction") 300 .precision(6); 301 cpi = simTicks / committedInsts; 302 303 totalCpi 304 .name(name() + ".cpi_total") 305 .desc("CPI: Total CPI of All Threads") 306 .precision(6); 307 totalCpi = simTicks / totalCommittedInsts; 308 309 ipc 310 .name(name() + ".ipc") 311 .desc("IPC: Instructions Per Cycle") 312 .precision(6); 313 ipc = committedInsts / simTicks; 314 315 totalIpc 316 .name(name() + ".ipc_total") 317 .desc("IPC: Total IPC of All Threads") 318 .precision(6); 319 totalIpc = totalCommittedInsts / simTicks; 320 |
|
205} 206 207template <class Impl> 208void 209FullO3CPU<Impl>::tick() 210{ 211 DPRINTF(FullCPU, "\n\nFullCPU: Ticking main, FullO3CPU.\n"); 212 | 321} 322 323template <class Impl> 324void 325FullO3CPU<Impl>::tick() 326{ 327 DPRINTF(FullCPU, "\n\nFullCPU: Ticking main, FullO3CPU.\n"); 328 |
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. | 329 ++numCycles; 330 331// activity = false; 332 333 //Tick each of the stages |
216 fetch.tick(); 217 218 decode.tick(); 219 220 rename.tick(); 221 222 iew.tick(); 223 224 commit.tick(); 225 | 334 fetch.tick(); 335 336 decode.tick(); 337 338 rename.tick(); 339 340 iew.tick(); 341 342 commit.tick(); 343 |
226 // Now advance the time buffers, unless the stage is stalled. | 344#if !FULL_SYSTEM 345 doContextSwitch(); 346#endif 347 348 // Now advance the time buffers |
227 timeBuffer.advance(); 228 229 fetchQueue.advance(); 230 decodeQueue.advance(); 231 renameQueue.advance(); 232 iewQueue.advance(); 233 | 349 timeBuffer.advance(); 350 351 fetchQueue.advance(); 352 decodeQueue.advance(); 353 renameQueue.advance(); 354 iewQueue.advance(); 355 |
234 if (_status == Running && !tickEvent.scheduled()) 235 tickEvent.schedule(curTick + 1); | 356 activityRec.advance(); 357 358 if (removeInstsThisCycle) { 359 cleanUpRemovedInsts(); 360 } 361 362 if (!tickEvent.scheduled()) { 363 if (_status == SwitchedOut) { 364 // increment stat 365 lastRunningCycle = curTick; 366 } else if (!activityRec.active()) { 367 lastRunningCycle = curTick; 368 timesIdled++; 369 } else { 370 tickEvent.schedule(curTick + cycles(1)); 371 } 372 } 373 374#if !FULL_SYSTEM 375 updateThreadPriority(); 376#endif 377 |
236} 237 238template <class Impl> 239void 240FullO3CPU<Impl>::init() 241{ | 378} 379 380template <class Impl> 381void 382FullO3CPU<Impl>::init() 383{ |
242 if(!deferRegistration) 243 { 244 this->registerExecContexts(); | 384 if (!deferRegistration) { 385 registerExecContexts(); 386 } |
245 | 387 |
246 // Need to do a copy of the xc->regs into the CPU's regfile so 247 // that it can start properly. | 388 // Set inSyscall so that the CPU doesn't squash when initially 389 // setting up registers. 390 for (int i = 0; i < number_of_threads; ++i) 391 thread[i]->inSyscall = true; 392 393 for (int tid=0; tid < number_of_threads; tid++) { |
248#if FULL_SYSTEM | 394#if FULL_SYSTEM |
249 ExecContext *src_xc = system->execContexts[0]; 250 TheISA::initCPU(src_xc, src_xc->readCpuId()); | 395 ExecContext *src_xc = execContexts[tid]; |
251#else | 396#else |
252 ExecContext *src_xc = thread[0]->getProxy(); | 397 ExecContext *src_xc = thread[tid]->getXCProxy(); |
253#endif | 398#endif |
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); | 399 // Threads start in the Suspended State 400 if (src_xc->status() != ExecContext::Suspended) { 401 continue; |
258 } 259 | 402 } 403 |
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(); | 404#if FULL_SYSTEM 405 TheISA::initCPU(src_xc, src_xc->readCpuId()); 406#endif |
275 } | 407 } |
408 409 // Clear inSyscall. 410 for (int i = 0; i < number_of_threads; ++i) 411 thread[i]->inSyscall = false; 412 413 // Initialize stages. 414 fetch.initStage(); 415 iew.initStage(); 416 rename.initStage(); 417 commit.initStage(); 418 419 commit.setThreads(thread); |
|
276} 277 278template <class Impl> 279void | 420} 421 422template <class Impl> 423void |
280FullO3CPU<Impl>::activateContext(int thread_num, int delay) | 424FullO3CPU<Impl>::insertThread(unsigned tid) |
281{ | 425{ |
426 DPRINTF(FullCPU,"[tid:%i] Initializing thread data"); 427 // Will change now that the PC and thread state is internal to the CPU 428 // and not in the CPUExecContext. 429#if 0 430#if FULL_SYSTEM 431 ExecContext *src_xc = system->execContexts[tid]; 432#else 433 CPUExecContext *src_xc = thread[tid]; 434#endif 435 436 //Bind Int Regs to Rename Map 437 for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) { 438 PhysRegIndex phys_reg = freeList.getIntReg(); 439 440 renameMap[tid].setEntry(ireg,phys_reg); 441 scoreboard.setReg(phys_reg); 442 } 443 444 //Bind Float Regs to Rename Map 445 for (int freg = 0; freg < TheISA::NumFloatRegs; freg++) { 446 PhysRegIndex phys_reg = freeList.getFloatReg(); 447 448 renameMap[tid].setEntry(freg,phys_reg); 449 scoreboard.setReg(phys_reg); 450 } 451 452 //Copy Thread Data Into RegFile 453 this->copyFromXC(tid); 454 455 //Set PC/NPC 456 regFile.pc[tid] = src_xc->readPC(); 457 regFile.npc[tid] = src_xc->readNextPC(); 458 459 src_xc->setStatus(ExecContext::Active); 460 461 activateContext(tid,1); 462 463 //Reset ROB/IQ/LSQ Entries 464 commit.rob->resetEntries(); 465 iew.resetEntries(); 466#endif 467} 468 469template <class Impl> 470void 471FullO3CPU<Impl>::removeThread(unsigned tid) 472{ 473 DPRINTF(FullCPU,"[tid:%i] Removing thread data"); 474#if 0 475 //Unbind Int Regs from Rename Map 476 for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) { 477 PhysRegIndex phys_reg = renameMap[tid].lookup(ireg); 478 479 scoreboard.unsetReg(phys_reg); 480 freeList.addReg(phys_reg); 481 } 482 483 //Unbind Float Regs from Rename Map 484 for (int freg = 0; freg < TheISA::NumFloatRegs; freg++) { 485 PhysRegIndex phys_reg = renameMap[tid].lookup(freg); 486 487 scoreboard.unsetReg(phys_reg); 488 freeList.addReg(phys_reg); 489 } 490 491 //Copy Thread Data From RegFile 492 /* Fix Me: 493 * Do we really need to do this if we are removing a thread 494 * in the sense that it's finished (exiting)? If the thread is just 495 * being suspended we might... 496 */ 497// this->copyToXC(tid); 498 499 //Squash Throughout Pipeline 500 fetch.squash(0,tid); 501 decode.squash(tid); 502 rename.squash(tid); 503 504 assert(iew.ldstQueue.getCount(tid) == 0); 505 506 //Reset ROB/IQ/LSQ Entries 507 if (activeThreads.size() >= 1) { 508 commit.rob->resetEntries(); 509 iew.resetEntries(); 510 } 511#endif 512} 513 514 515template <class Impl> 516void 517FullO3CPU<Impl>::activateWhenReady(int tid) 518{ 519 DPRINTF(FullCPU,"[tid:%i]: Checking if resources are available for incoming" 520 "(e.g. PhysRegs/ROB/IQ/LSQ) \n", 521 tid); 522 523 bool ready = true; 524 525 if (freeList.numFreeIntRegs() >= TheISA::NumIntRegs) { 526 DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough " 527 "Phys. Int. Regs.\n", 528 tid); 529 ready = false; 530 } else if (freeList.numFreeFloatRegs() >= TheISA::NumFloatRegs) { 531 DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough " 532 "Phys. Float. Regs.\n", 533 tid); 534 ready = false; 535 } else if (commit.rob->numFreeEntries() >= 536 commit.rob->entryAmount(activeThreads.size() + 1)) { 537 DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough " 538 "ROB entries.\n", 539 tid); 540 ready = false; 541 } else if (iew.instQueue.numFreeEntries() >= 542 iew.instQueue.entryAmount(activeThreads.size() + 1)) { 543 DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough " 544 "IQ entries.\n", 545 tid); 546 ready = false; 547 } else if (iew.ldstQueue.numFreeEntries() >= 548 iew.ldstQueue.entryAmount(activeThreads.size() + 1)) { 549 DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough " 550 "LSQ entries.\n", 551 tid); 552 ready = false; 553 } 554 555 if (ready) { 556 insertThread(tid); 557 558 contextSwitch = false; 559 560 cpuWaitList.remove(tid); 561 } else { 562 suspendContext(tid); 563 564 //blocks fetch 565 contextSwitch = true; 566 567 //do waitlist 568 cpuWaitList.push_back(tid); 569 } 570} 571 572template <class Impl> 573void 574FullO3CPU<Impl>::activateContext(int tid, int delay) 575{ |
|
282 // Needs to set each stage to running as well. | 576 // Needs to set each stage to running as well. |
577 list<unsigned>::iterator isActive = find( 578 activeThreads.begin(), activeThreads.end(), tid); |
|
283 | 579 |
580 if (isActive == activeThreads.end()) { 581 //May Need to Re-code this if the delay variable is the 582 //delay needed for thread to activate 583 DPRINTF(FullCPU, "Adding Thread %i to active threads list\n", 584 tid); 585 586 activeThreads.push_back(tid); 587 } 588 589 assert(_status == Idle || _status == SwitchedOut); 590 |
|
284 scheduleTickEvent(delay); 285 | 591 scheduleTickEvent(delay); 592 |
593 // Be sure to signal that there's some activity so the CPU doesn't 594 // deschedule itself. 595 activityRec.activity(); 596 fetch.wakeFromQuiesce(); 597 |
|
286 _status = Running; 287} 288 289template <class Impl> 290void | 598 _status = Running; 599} 600 601template <class Impl> 602void |
291FullO3CPU<Impl>::suspendContext(int thread_num) | 603FullO3CPU<Impl>::suspendContext(int tid) |
292{ | 604{ |
293 panic("suspendContext unimplemented!"); | 605 DPRINTF(FullCPU,"[tid: %i]: Suspended ...\n", tid); 606 unscheduleTickEvent(); 607 _status = Idle; 608/* 609 //Remove From Active List, if Active 610 list<unsigned>::iterator isActive = find( 611 activeThreads.begin(), activeThreads.end(), tid); 612 613 if (isActive != activeThreads.end()) { 614 DPRINTF(FullCPU,"[tid:%i]: Removing from active threads list\n", 615 tid); 616 activeThreads.erase(isActive); 617 } 618*/ |
294} 295 296template <class Impl> 297void | 619} 620 621template <class Impl> 622void |
298FullO3CPU<Impl>::deallocateContext(int thread_num) | 623FullO3CPU<Impl>::deallocateContext(int tid) |
299{ | 624{ |
300 panic("deallocateContext unimplemented!"); | 625 DPRINTF(FullCPU,"[tid:%i]: Deallocating ...", tid); 626/* 627 //Remove From Active List, if Active 628 list<unsigned>::iterator isActive = find( 629 activeThreads.begin(), activeThreads.end(), tid); 630 631 if (isActive != activeThreads.end()) { 632 DPRINTF(FullCPU,"[tid:%i]: Removing from active threads list\n", 633 tid); 634 activeThreads.erase(isActive); 635 636 removeThread(tid); 637 } 638*/ |
301} 302 303template <class Impl> 304void | 639} 640 641template <class Impl> 642void |
305FullO3CPU<Impl>::haltContext(int thread_num) | 643FullO3CPU<Impl>::haltContext(int tid) |
306{ | 644{ |
307 panic("haltContext unimplemented!"); | 645 DPRINTF(FullCPU,"[tid:%i]: Halted ...", tid); 646/* 647 //Remove From Active List, if Active 648 list<unsigned>::iterator isActive = find( 649 activeThreads.begin(), activeThreads.end(), tid); 650 651 if (isActive != activeThreads.end()) { 652 DPRINTF(FullCPU,"[tid:%i]: Removing from active threads list\n", 653 tid); 654 activeThreads.erase(isActive); 655 656 removeThread(tid); 657 } 658*/ |
308} 309 310template <class Impl> 311void | 659} 660 661template <class Impl> 662void |
312FullO3CPU | 663FullO3CPU<Impl>::switchOut(Sampler *_sampler) |
313{ | 664{ |
314 panic("FullO3CPU does not have a switch out function.\n"); | 665 sampler = _sampler; 666 switchCount = 0; 667 fetch.switchOut(); 668 decode.switchOut(); 669 rename.switchOut(); 670 iew.switchOut(); 671 commit.switchOut(); 672 673 // Wake the CPU and record activity so everything can drain out if 674 // the CPU is currently idle. 675 wakeCPU(); 676 activityRec.activity(); |
315} 316 317template <class Impl> 318void | 677} 678 679template <class Impl> 680void |
681FullO3CPU<Impl>::signalSwitched() 682{ 683 if (++switchCount == NumStages) { 684 fetch.doSwitchOut(); 685 rename.doSwitchOut(); 686 commit.doSwitchOut(); 687 instList.clear(); 688 while (!removeList.empty()) { 689 removeList.pop(); 690 } 691 692 if (checker) 693 checker->switchOut(sampler); 694 695 if (tickEvent.scheduled()) 696 tickEvent.squash(); 697 sampler->signalSwitched(); 698 _status = SwitchedOut; 699 } 700 assert(switchCount <= 5); 701} 702 703template <class Impl> 704void |
|
319FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU) 320{ | 705FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU) 706{ |
707 // Flush out any old data from the time buffers. 708 for (int i = 0; i < 10; ++i) { 709 timeBuffer.advance(); 710 fetchQueue.advance(); 711 decodeQueue.advance(); 712 renameQueue.advance(); 713 iewQueue.advance(); 714 } 715 716 activityRec.reset(); 717 |
|
321 BaseCPU::takeOverFrom(oldCPU); 322 | 718 BaseCPU::takeOverFrom(oldCPU); 719 |
720 fetch.takeOverFrom(); 721 decode.takeOverFrom(); 722 rename.takeOverFrom(); 723 iew.takeOverFrom(); 724 commit.takeOverFrom(); 725 |
|
323 assert(!tickEvent.scheduled()); 324 | 726 assert(!tickEvent.scheduled()); 727 |
325 // Set all status's to active, schedule the 326 // CPU's tick event. | 728 // @todo: Figure out how to properly select the tid to put onto 729 // the active threads list. 730 int tid = 0; 731 732 list<unsigned>::iterator isActive = find( 733 activeThreads.begin(), activeThreads.end(), tid); 734 735 if (isActive == activeThreads.end()) { 736 //May Need to Re-code this if the delay variable is the delay 737 //needed for thread to activate 738 DPRINTF(FullCPU, "Adding Thread %i to active threads list\n", 739 tid); 740 741 activeThreads.push_back(tid); 742 } 743 744 // Set all statuses to active, schedule the CPU's tick event. 745 // @todo: Fix up statuses so this is handled properly |
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 } | 746 for (int i = 0; i < execContexts.size(); ++i) { 747 ExecContext *xc = execContexts[i]; 748 if (xc->status() == ExecContext::Active && _status != Running) { 749 _status = Running; 750 tickEvent.schedule(curTick); 751 } 752 } |
753 if (!tickEvent.scheduled()) 754 tickEvent.schedule(curTick); |
|
334} 335 336template <class Impl> | 755} 756 757template <class Impl> |
337InstSeqNum 338FullO3CPU<Impl>::getAndIncrementInstSeq() 339{ 340 // Hopefully this works right. 341 return globalSeqNum++; 342} 343 344template <class Impl> | |
345uint64_t 346FullO3CPU<Impl>::readIntReg(int reg_idx) 347{ 348 return regFile.readIntReg(reg_idx); 349} 350 351template <class Impl> 352FloatReg --- 55 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 | 758uint64_t 759FullO3CPU<Impl>::readIntReg(int reg_idx) 760{ 761 return regFile.readIntReg(reg_idx); 762} 763 764template <class Impl> 765FloatReg --- 55 unchanged lines hidden (view full) --- 821void 822FullO3CPU<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val) 823{ 824 regFile.setFloatRegBits(reg_idx, val); 825} 826 827template <class Impl> 828uint64_t |
416FullO3CPU<Impl>::readPC() | 829FullO3CPU<Impl>::readArchIntReg(int reg_idx, unsigned tid) |
417{ | 830{ |
418 return regFile.readPC(); | 831 PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx); 832 833 return regFile.readIntReg(phys_reg); |
419} 420 421template <class Impl> | 834} 835 836template <class Impl> |
837float 838FullO3CPU<Impl>::readArchFloatRegSingle(int reg_idx, unsigned tid) 839{ 840 int idx = reg_idx + TheISA::FP_Base_DepTag; 841 PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); 842 843 return regFile.readFloatReg(phys_reg); 844} 845 846template <class Impl> 847double 848FullO3CPU<Impl>::readArchFloatRegDouble(int reg_idx, unsigned tid) 849{ 850 int idx = reg_idx + TheISA::FP_Base_DepTag; 851 PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); 852 853 return regFile.readFloatReg(phys_reg, 64); 854} 855 856template <class Impl> 857uint64_t 858FullO3CPU<Impl>::readArchFloatRegInt(int reg_idx, unsigned tid) 859{ 860 int idx = reg_idx + TheISA::FP_Base_DepTag; 861 PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); 862 863 return regFile.readFloatRegBits(phys_reg); 864} 865 866template <class Impl> |
|
422void | 867void |
423FullO3CPU<Impl>::setNextPC(uint64_t val) | 868FullO3CPU<Impl>::setArchIntReg(int reg_idx, uint64_t val, unsigned tid) |
424{ | 869{ |
425 regFile.setNextPC(val); | 870 PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx); 871 872 regFile.setIntReg(phys_reg, val); |
426} 427 428template <class Impl> 429void | 873} 874 875template <class Impl> 876void |
430FullO3CPU<Impl>::setPC(Addr new_PC) | 877FullO3CPU<Impl>::setArchFloatRegSingle(int reg_idx, float val, unsigned tid) |
431{ | 878{ |
432 regFile.setPC(new_PC); | 879 PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx); 880 881 regFile.setFloatReg(phys_reg, val); |
433} 434 435template <class Impl> 436void | 882} 883 884template <class Impl> 885void |
437FullO3CPU<Impl>::addInst(DynInstPtr &inst) | 886FullO3CPU<Impl>::setArchFloatRegDouble(int reg_idx, double val, unsigned tid) |
438{ | 887{ |
439 instList.push_back(inst); | 888 PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx); 889 890 regFile.setFloatReg(phys_reg, val, 64); |
440} 441 442template <class Impl> 443void | 891} 892 893template <class Impl> 894void |
444FullO3CPU<Impl>::instDone() | 895FullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, unsigned tid) |
445{ | 896{ |
446 // Keep an instruction count. 447 numInsts++; | 897 PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx); |
448 | 898 |
449 // Check for instruction-count-based events. 450 comInstEventQueue[0]->serviceEvents(numInsts); | 899 regFile.setFloatRegBits(phys_reg, val); |
451} 452 453template <class Impl> | 900} 901 902template <class Impl> |
903uint64_t 904FullO3CPU<Impl>::readPC(unsigned tid) 905{ 906 return commit.readPC(tid); 907} 908 909template <class Impl> |
|
454void | 910void |
455FullO3CPU<Impl>::removeBackInst(DynInstPtr &inst) | 911FullO3CPU<Impl>::setPC(Addr new_PC,unsigned tid) |
456{ | 912{ |
457 DynInstPtr inst_to_delete; | 913 commit.setPC(new_PC, tid); 914} |
458 | 915 |
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()); | 916template <class Impl> 917uint64_t 918FullO3CPU<Impl>::readNextPC(unsigned tid) 919{ 920 return commit.readNextPC(tid); 921} |
464 | 922 |
465 // Obtain the pointer to the instruction. 466 inst_to_delete = instList.back(); | 923template <class Impl> 924void 925FullO3CPU<Impl>::setNextPC(uint64_t val,unsigned tid) 926{ 927 commit.setNextPC(val, tid); 928} |
467 | 929 |
468 DPRINTF(FullCPU, "FullCPU: Removing instruction %i, PC %#x\n", 469 inst_to_delete->seqNum, inst_to_delete->readPC()); | 930template <class Impl> 931typename FullO3CPU<Impl>::ListIt 932FullO3CPU<Impl>::addInst(DynInstPtr &inst) 933{ 934 instList.push_back(inst); |
470 | 935 |
471 // Remove the instruction from the list. 472 instList.pop_back(); | 936 return --(instList.end()); 937} |
473 | 938 |
474 // Mark it as squashed. 475 inst_to_delete->setSquashed(); 476 } | 939template <class Impl> 940void 941FullO3CPU<Impl>::instDone(unsigned tid) 942{ 943 // Keep an instruction count. 944 thread[tid]->numInst++; 945 thread[tid]->numInsts++; 946 committedInsts[tid]++; 947 totalCommittedInsts++; 948 949 // Check for instruction-count-based events. 950 comInstEventQueue[tid]->serviceEvents(thread[tid]->numInst); |
477} 478 479template <class Impl> 480void | 951} 952 953template <class Impl> 954void |
955FullO3CPU<Impl>::addToRemoveList(DynInstPtr &inst) 956{ 957 removeInstsThisCycle = true; 958 959 removeList.push(inst->getInstListIt()); 960} 961 962template <class Impl> 963void |
|
481FullO3CPU<Impl>::removeFrontInst(DynInstPtr &inst) 482{ | 964FullO3CPU<Impl>::removeFrontInst(DynInstPtr &inst) 965{ |
483 DynInstPtr inst_to_remove; | 966 DPRINTF(FullCPU, "FullCPU: Removing committed instruction [tid:%i] PC %#x " 967 "[sn:%lli]\n", 968 inst->threadNumber, inst->readPC(), inst->seqNum); |
484 | 969 |
485 // The front instruction should be the same one being asked to be removed. 486 assert(instList.front() == inst); | 970 removeInstsThisCycle = true; |
487 488 // Remove the front instruction. | 971 972 // Remove the front instruction. |
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()); | 973 removeList.push(inst->getInstListIt()); |
494} 495 496template <class Impl> 497void | 974} 975 976template <class Impl> 977void |
498FullO3CPU | 978FullO3CPU<Impl>::removeInstsNotInROB(unsigned tid) |
499{ | 979{ |
500 DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction " 501 "list.\n"); | 980 DPRINTF(FullCPU, "FullCPU: Thread %i: Deleting instructions from instruction" 981 " list.\n", tid); |
502 | 982 |
503 DynInstPtr rob_tail = rob.readTailInst(); | 983 ListIt end_it; |
504 | 984 |
505 removeBackInst(rob_tail); | 985 bool rob_empty = false; 986 987 if (instList.empty()) { 988 return; 989 } else if (rob.isEmpty(/*tid*/)) { 990 DPRINTF(FullCPU, "FullCPU: ROB is empty, squashing all insts.\n"); 991 end_it = instList.begin(); 992 rob_empty = true; 993 } else { 994 end_it = (rob.readTailInst(tid))->getInstListIt(); 995 DPRINTF(FullCPU, "FullCPU: ROB is not empty, squashing insts not in ROB.\n"); 996 } 997 998 removeInstsThisCycle = true; 999 1000 ListIt inst_it = instList.end(); 1001 1002 inst_it--; 1003 1004 // Walk through the instruction list, removing any instructions 1005 // that were inserted after the given instruction iterator, end_it. 1006 while (inst_it != end_it) { 1007 assert(!instList.empty()); 1008 1009 squashInstIt(inst_it, tid); 1010 1011 inst_it--; 1012 } 1013 1014 // If the ROB was empty, then we actually need to remove the first 1015 // instruction as well. 1016 if (rob_empty) { 1017 squashInstIt(inst_it, tid); 1018 } |
506} 507 508template <class Impl> 509void | 1019} 1020 1021template <class Impl> 1022void |
510FullO3CPU<Impl>::removeInstsUntil(const InstSeqNum &seq_num) | 1023FullO3CPU<Impl>::removeInstsUntil(const InstSeqNum &seq_num, 1024 unsigned tid) |
511{ | 1025{ |
1026 assert(!instList.empty()); 1027 1028 removeInstsThisCycle = true; 1029 1030 ListIt inst_iter = instList.end(); 1031 1032 inst_iter--; 1033 |
|
512 DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction " | 1034 DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction " |
513 "list.\n"); | 1035 "list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n", 1036 tid, seq_num, (*inst_iter)->seqNum); |
514 | 1037 |
515 DynInstPtr inst_to_delete; | 1038 while ((*inst_iter)->seqNum > seq_num) { |
516 | 1039 |
517 while (instList.back()->seqNum > seq_num) { 518 assert(!instList.empty()); | 1040 bool break_loop = (inst_iter == instList.begin()); |
519 | 1041 |
520 // Obtain the pointer to the instruction. 521 inst_to_delete = instList.back(); | 1042 squashInstIt(inst_iter, tid); |
522 | 1043 |
523 DPRINTF(FullCPU, "FullCPU: Removing instruction %i, PC %#x\n", 524 inst_to_delete->seqNum, inst_to_delete->readPC()); | 1044 inst_iter--; |
525 | 1045 |
526 // Remove the instruction from the list. 527 instList.back() = NULL; 528 instList.pop_back(); | 1046 if (break_loop) 1047 break; 1048 } 1049} |
529 | 1050 |
1051template <class Impl> 1052inline void 1053FullO3CPU<Impl>::squashInstIt(const ListIt &instIt, const unsigned &tid) 1054{ 1055 if ((*instIt)->threadNumber == tid) { 1056 DPRINTF(FullCPU, "FullCPU: Squashing instruction, " 1057 "[tid:%i] [sn:%lli] PC %#x\n", 1058 (*instIt)->threadNumber, 1059 (*instIt)->seqNum, 1060 (*instIt)->readPC()); 1061 |
|
530 // Mark it as squashed. | 1062 // Mark it as squashed. |
531 inst_to_delete->setSquashed(); 532 } | 1063 (*instIt)->setSquashed(); |
533 | 1064 |
1065 // @todo: Formulate a consistent method for deleting 1066 // instructions from the instruction list 1067 // Remove the instruction from the list. 1068 removeList.push(instIt); 1069 } |
|
534} 535 536template <class Impl> 537void | 1070} 1071 1072template <class Impl> 1073void |
1074FullO3CPU<Impl>::cleanUpRemovedInsts() 1075{ 1076 while (!removeList.empty()) { 1077 DPRINTF(FullCPU, "FullCPU: Removing instruction, " 1078 "[tid:%i] [sn:%lli] PC %#x\n", 1079 (*removeList.front())->threadNumber, 1080 (*removeList.front())->seqNum, 1081 (*removeList.front())->readPC()); 1082 1083 instList.erase(removeList.front()); 1084 1085 removeList.pop(); 1086 } 1087 1088 removeInstsThisCycle = false; 1089} 1090/* 1091template <class Impl> 1092void |
|
538FullO3CPU<Impl>::removeAllInsts() 539{ 540 instList.clear(); 541} | 1093FullO3CPU<Impl>::removeAllInsts() 1094{ 1095 instList.clear(); 1096} |
542 | 1097*/ |
543template <class Impl> 544void 545FullO3CPU<Impl>::dumpInsts() 546{ 547 int num = 0; | 1098template <class Impl> 1099void 1100FullO3CPU<Impl>::dumpInsts() 1101{ 1102 int num = 0; |
548 typename list<DynInstPtr>::iterator inst_list_it = instList.begin(); | |
549 | 1103 |
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()); | 1104 ListIt inst_list_it = instList.begin(); 1105 1106 cprintf("Dumping Instruction List\n"); 1107 1108 while (inst_list_it != instList.end()) { 1109 cprintf("Instruction:%i\nPC:%#x\n[tid:%i]\n[sn:%lli]\nIssued:%i\n" 1110 "Squashed:%i\n\n", 1111 num, (*inst_list_it)->readPC(), (*inst_list_it)->threadNumber, 1112 (*inst_list_it)->seqNum, (*inst_list_it)->isIssued(), 1113 (*inst_list_it)->isSquashed()); |
555 inst_list_it++; 556 ++num; 557 } 558} | 1114 inst_list_it++; 1115 ++num; 1116 } 1117} |
559 | 1118/* |
560template <class Impl> 561void 562FullO3CPU<Impl>::wakeDependents(DynInstPtr &inst) 563{ 564 iew.wakeDependents(inst); 565} | 1119template <class Impl> 1120void 1121FullO3CPU<Impl>::wakeDependents(DynInstPtr &inst) 1122{ 1123 iew.wakeDependents(inst); 1124} |
1125*/ 1126template <class Impl> 1127void 1128FullO3CPU<Impl>::wakeCPU() 1129{ 1130 if (activityRec.active() || tickEvent.scheduled()) { 1131 DPRINTF(Activity, "CPU already running.\n"); 1132 return; 1133 } |
|
566 | 1134 |
1135 DPRINTF(Activity, "Waking up CPU\n"); 1136 1137 idleCycles += (curTick - 1) - lastRunningCycle; 1138 1139 tickEvent.schedule(curTick); 1140} 1141 1142template <class Impl> 1143int 1144FullO3CPU<Impl>::getFreeTid() 1145{ 1146 for (int i=0; i < numThreads; i++) { 1147 if (!tids[i]) { 1148 tids[i] = true; 1149 return i; 1150 } 1151 } 1152 1153 return -1; 1154} 1155 1156template <class Impl> 1157void 1158FullO3CPU<Impl>::doContextSwitch() 1159{ 1160 if (contextSwitch) { 1161 1162 //ADD CODE TO DEACTIVE THREAD HERE (???) 1163 1164 for (int tid=0; tid < cpuWaitList.size(); tid++) { 1165 activateWhenReady(tid); 1166 } 1167 1168 if (cpuWaitList.size() == 0) 1169 contextSwitch = true; 1170 } 1171} 1172 1173template <class Impl> 1174void 1175FullO3CPU<Impl>::updateThreadPriority() 1176{ 1177 if (activeThreads.size() > 1) 1178 { 1179 //DEFAULT TO ROUND ROBIN SCHEME 1180 //e.g. Move highest priority to end of thread list 1181 list<unsigned>::iterator list_begin = activeThreads.begin(); 1182 list<unsigned>::iterator list_end = activeThreads.end(); 1183 1184 unsigned high_thread = *list_begin; 1185 1186 activeThreads.erase(list_begin); 1187 1188 activeThreads.push_back(high_thread); 1189 } 1190} 1191 |
|
567// Forward declaration of FullO3CPU. 568template class FullO3CPU<AlphaSimpleImpl>; | 1192// Forward declaration of FullO3CPU. 1193template class FullO3CPU<AlphaSimpleImpl>; |