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 ¶ms) 49 : BaseCPU(¶ms), 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 ¶ms) 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 |
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 |
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>; |