fetch_impl.hh (8460:3893d9d2c6c2) | fetch_impl.hh (8462:80492ae5148e) |
---|---|
1/* 2 * Copyright (c) 2010 ARM Limited 3 * All rights reserved. 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 35 unchanged lines hidden (view full) --- 44#include <algorithm> 45#include <cstring> 46 47#include "arch/isa_traits.hh" 48#include "arch/utility.hh" 49#include "base/types.hh" 50#include "config/the_isa.hh" 51#include "config/use_checker.hh" | 1/* 2 * Copyright (c) 2010 ARM Limited 3 * All rights reserved. 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 35 unchanged lines hidden (view full) --- 44#include <algorithm> 45#include <cstring> 46 47#include "arch/isa_traits.hh" 48#include "arch/utility.hh" 49#include "base/types.hh" 50#include "config/the_isa.hh" 51#include "config/use_checker.hh" |
52#include "cpu/base.hh" |
|
52#include "cpu/checker/cpu.hh" 53#include "cpu/o3/fetch.hh" 54#include "cpu/exetrace.hh" 55#include "debug/Activity.hh" 56#include "debug/Fetch.hh" 57#include "mem/packet.hh" 58#include "mem/request.hh" 59#include "params/DerivO3CPU.hh" 60#include "sim/byteswap.hh" 61#include "sim/core.hh" | 53#include "cpu/checker/cpu.hh" 54#include "cpu/o3/fetch.hh" 55#include "cpu/exetrace.hh" 56#include "debug/Activity.hh" 57#include "debug/Fetch.hh" 58#include "mem/packet.hh" 59#include "mem/request.hh" 60#include "params/DerivO3CPU.hh" 61#include "sim/byteswap.hh" 62#include "sim/core.hh" |
63#include "sim/eventq.hh" |
|
62 63#if FULL_SYSTEM 64#include "arch/tlb.hh" 65#include "arch/vtophys.hh" 66#include "sim/system.hh" 67#endif // FULL_SYSTEM 68 69using namespace std; --- 60 unchanged lines hidden (view full) --- 130 fetch->recvRetry(); 131} 132 133template<class Impl> 134DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params) 135 : cpu(_cpu), 136 branchPred(params), 137 predecoder(NULL), | 64 65#if FULL_SYSTEM 66#include "arch/tlb.hh" 67#include "arch/vtophys.hh" 68#include "sim/system.hh" 69#endif // FULL_SYSTEM 70 71using namespace std; --- 60 unchanged lines hidden (view full) --- 132 fetch->recvRetry(); 133} 134 135template<class Impl> 136DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params) 137 : cpu(_cpu), 138 branchPred(params), 139 predecoder(NULL), |
140 numInst(0), |
|
138 decodeToFetchDelay(params->decodeToFetchDelay), 139 renameToFetchDelay(params->renameToFetchDelay), 140 iewToFetchDelay(params->iewToFetchDelay), 141 commitToFetchDelay(params->commitToFetchDelay), 142 fetchWidth(params->fetchWidth), 143 cacheBlocked(false), 144 retryPkt(NULL), 145 retryTid(InvalidThreadID), 146 numThreads(params->numThreads), 147 numFetchingThreads(params->smtNumFetchingThreads), 148 interruptPending(false), 149 drainPending(false), | 141 decodeToFetchDelay(params->decodeToFetchDelay), 142 renameToFetchDelay(params->renameToFetchDelay), 143 iewToFetchDelay(params->iewToFetchDelay), 144 commitToFetchDelay(params->commitToFetchDelay), 145 fetchWidth(params->fetchWidth), 146 cacheBlocked(false), 147 retryPkt(NULL), 148 retryTid(InvalidThreadID), 149 numThreads(params->numThreads), 150 numFetchingThreads(params->smtNumFetchingThreads), 151 interruptPending(false), 152 drainPending(false), |
150 switchedOut(false) | 153 switchedOut(false), 154 finishTranslationEvent(this) |
151{ 152 if (numThreads > Impl::MaxThreads) 153 fatal("numThreads (%d) is larger than compiled limit (%d),\n" 154 "\tincrease MaxThreads in src/cpu/o3/impl.hh\n", 155 numThreads, static_cast<int>(Impl::MaxThreads)); 156 157 // Set fetch stage's status to inactive. 158 _status = Inactive; --- 104 unchanged lines hidden (view full) --- 263 .prereq(fetchedCacheLines); 264 265 fetchMiscStallCycles 266 .name(name() + ".MiscStallCycles") 267 .desc("Number of cycles fetch has spent waiting on interrupts, or " 268 "bad addresses, or out of MSHRs") 269 .prereq(fetchMiscStallCycles); 270 | 155{ 156 if (numThreads > Impl::MaxThreads) 157 fatal("numThreads (%d) is larger than compiled limit (%d),\n" 158 "\tincrease MaxThreads in src/cpu/o3/impl.hh\n", 159 numThreads, static_cast<int>(Impl::MaxThreads)); 160 161 // Set fetch stage's status to inactive. 162 _status = Inactive; --- 104 unchanged lines hidden (view full) --- 267 .prereq(fetchedCacheLines); 268 269 fetchMiscStallCycles 270 .name(name() + ".MiscStallCycles") 271 .desc("Number of cycles fetch has spent waiting on interrupts, or " 272 "bad addresses, or out of MSHRs") 273 .prereq(fetchMiscStallCycles); 274 |
275 fetchPendingDrainCycles 276 .name(name() + ".PendingDrainCycles") 277 .desc("Number of cycles fetch has spent waiting on pipes to drain") 278 .prereq(fetchPendingDrainCycles); 279 280 fetchNoActiveThreadStallCycles 281 .name(name() + ".NoActiveThreadStallCycles") 282 .desc("Number of stall cycles due to no active thread to fetch from") 283 .prereq(fetchNoActiveThreadStallCycles); 284 285 fetchPendingTrapStallCycles 286 .name(name() + ".PendingTrapStallCycles") 287 .desc("Number of stall cycles due to pending traps") 288 .prereq(fetchPendingTrapStallCycles); 289 290 fetchPendingQuiesceStallCycles 291 .name(name() + ".PendingQuiesceStallCycles") 292 .desc("Number of stall cycles due to pending quiesce instructions") 293 .prereq(fetchPendingQuiesceStallCycles); 294 295 fetchIcacheWaitRetryStallCycles 296 .name(name() + ".IcacheWaitRetryStallCycles") 297 .desc("Number of stall cycles due to full MSHR") 298 .prereq(fetchIcacheWaitRetryStallCycles); 299 |
|
271 fetchIcacheSquashes 272 .name(name() + ".IcacheSquashes") 273 .desc("Number of outstanding Icache misses that were squashed") 274 .prereq(fetchIcacheSquashes); 275 276 fetchTlbSquashes 277 .name(name() + ".ItlbSquashes") 278 .desc("Number of outstanding ITLB misses that were squashed") --- 391 unchanged lines hidden (view full) --- 670 DPRINTF(Fetch, "[tid:%i]: Doing Icache access.\n", tid); 671 DPRINTF(Activity, "[tid:%i]: Activity: Waiting on I-cache " 672 "response.\n", tid); 673 674 lastIcacheStall[tid] = curTick(); 675 fetchStatus[tid] = IcacheWaitResponse; 676 } 677 } else { | 300 fetchIcacheSquashes 301 .name(name() + ".IcacheSquashes") 302 .desc("Number of outstanding Icache misses that were squashed") 303 .prereq(fetchIcacheSquashes); 304 305 fetchTlbSquashes 306 .name(name() + ".ItlbSquashes") 307 .desc("Number of outstanding ITLB misses that were squashed") --- 391 unchanged lines hidden (view full) --- 699 DPRINTF(Fetch, "[tid:%i]: Doing Icache access.\n", tid); 700 DPRINTF(Activity, "[tid:%i]: Activity: Waiting on I-cache " 701 "response.\n", tid); 702 703 lastIcacheStall[tid] = curTick(); 704 fetchStatus[tid] = IcacheWaitResponse; 705 } 706 } else { |
707 if (!(numInst < fetchWidth)) { 708 assert(!finishTranslationEvent.scheduled()); 709 finishTranslationEvent.setFault(fault); 710 finishTranslationEvent.setReq(mem_req); 711 cpu->schedule(finishTranslationEvent, cpu->nextCycle(curTick() + cpu->ticks(1))); 712 return; 713 } |
|
678 DPRINTF(Fetch, "[tid:%i] Got back req with addr %#x but expected %#x\n", | 714 DPRINTF(Fetch, "[tid:%i] Got back req with addr %#x but expected %#x\n", |
679 mem_req->getVaddr(), memReq[tid]->getVaddr()); | 715 tid, mem_req->getVaddr(), memReq[tid]->getVaddr()); |
680 // Translation faulted, icache request won't be sent. 681 delete mem_req; 682 memReq[tid] = NULL; 683 684 // Send the fault to commit. This thread will not do anything 685 // until commit handles the fault. The only other way it can 686 // wake up is if a squash comes along and changes the PC. 687 TheISA::PCState fetchPC = pc[tid]; --- 158 unchanged lines hidden (view full) --- 846DefaultFetch<Impl>::tick() 847{ 848 list<ThreadID>::iterator threads = activeThreads->begin(); 849 list<ThreadID>::iterator end = activeThreads->end(); 850 bool status_change = false; 851 852 wroteToTimeBuffer = false; 853 | 716 // Translation faulted, icache request won't be sent. 717 delete mem_req; 718 memReq[tid] = NULL; 719 720 // Send the fault to commit. This thread will not do anything 721 // until commit handles the fault. The only other way it can 722 // wake up is if a squash comes along and changes the PC. 723 TheISA::PCState fetchPC = pc[tid]; --- 158 unchanged lines hidden (view full) --- 882DefaultFetch<Impl>::tick() 883{ 884 list<ThreadID>::iterator threads = activeThreads->begin(); 885 list<ThreadID>::iterator end = activeThreads->end(); 886 bool status_change = false; 887 888 wroteToTimeBuffer = false; 889 |
890 for (ThreadID i = 0; i < Impl::MaxThreads; ++i) { 891 issuePipelinedIfetch[i] = false; 892 } 893 |
|
854 while (threads != end) { 855 ThreadID tid = *threads++; 856 857 // Check the signals for each thread to determine the proper status 858 // for each thread. 859 bool updated_status = checkSignalsAndUpdate(tid); 860 status_change = status_change || updated_status; 861 } 862 863 DPRINTF(Fetch, "Running stage.\n"); 864 | 894 while (threads != end) { 895 ThreadID tid = *threads++; 896 897 // Check the signals for each thread to determine the proper status 898 // for each thread. 899 bool updated_status = checkSignalsAndUpdate(tid); 900 status_change = status_change || updated_status; 901 } 902 903 DPRINTF(Fetch, "Running stage.\n"); 904 |
865 // Reset the number of the instruction we're fetching. 866 numInst = 0; 867 868#if FULL_SYSTEM | 905 #if FULL_SYSTEM |
869 if (fromCommit->commitInfo[0].interruptPending) { 870 interruptPending = true; 871 } 872 873 if (fromCommit->commitInfo[0].clearInterrupt) { 874 interruptPending = false; 875 } 876#endif --- 13 unchanged lines hidden (view full) --- 890 } 891 892 // If there was activity this cycle, inform the CPU of it. 893 if (wroteToTimeBuffer || cpu->contextSwitch) { 894 DPRINTF(Activity, "Activity this cycle.\n"); 895 896 cpu->activityThisCycle(); 897 } | 906 if (fromCommit->commitInfo[0].interruptPending) { 907 interruptPending = true; 908 } 909 910 if (fromCommit->commitInfo[0].clearInterrupt) { 911 interruptPending = false; 912 } 913#endif --- 13 unchanged lines hidden (view full) --- 927 } 928 929 // If there was activity this cycle, inform the CPU of it. 930 if (wroteToTimeBuffer || cpu->contextSwitch) { 931 DPRINTF(Activity, "Activity this cycle.\n"); 932 933 cpu->activityThisCycle(); 934 } |
935 936 // Issue the next I-cache request if possible. 937 for (ThreadID i = 0; i < Impl::MaxThreads; ++i) { 938 if (issuePipelinedIfetch[i]) { 939 pipelineIcacheAccesses(i); 940 } 941 } 942 943 // Reset the number of the instruction we've fetched. 944 numInst = 0; |
|
898} 899 900template <class Impl> 901bool 902DefaultFetch<Impl>::checkSignalsAndUpdate(ThreadID tid) 903{ 904 // Update the per thread stall statuses. 905 if (fromDecode->decodeBlock[tid]) { --- 188 unchanged lines hidden (view full) --- 1094DefaultFetch<Impl>::fetch(bool &status_change) 1095{ 1096 ////////////////////////////////////////// 1097 // Start actual fetch 1098 ////////////////////////////////////////// 1099 ThreadID tid = getFetchingThread(fetchPolicy); 1100 1101 if (tid == InvalidThreadID || drainPending) { | 945} 946 947template <class Impl> 948bool 949DefaultFetch<Impl>::checkSignalsAndUpdate(ThreadID tid) 950{ 951 // Update the per thread stall statuses. 952 if (fromDecode->decodeBlock[tid]) { --- 188 unchanged lines hidden (view full) --- 1141DefaultFetch<Impl>::fetch(bool &status_change) 1142{ 1143 ////////////////////////////////////////// 1144 // Start actual fetch 1145 ////////////////////////////////////////// 1146 ThreadID tid = getFetchingThread(fetchPolicy); 1147 1148 if (tid == InvalidThreadID || drainPending) { |
1102 DPRINTF(Fetch,"There are no more threads available to fetch from.\n"); 1103 | |
1104 // Breaks looping condition in tick() 1105 threadFetched = numFetchingThreads; | 1149 // Breaks looping condition in tick() 1150 threadFetched = numFetchingThreads; |
1151 1152 if (numThreads == 1) { // @todo Per-thread stats 1153 profileStall(0); 1154 } 1155 |
|
1106 return; 1107 } 1108 1109 DPRINTF(Fetch, "Attempting to fetch from [tid:%i]\n", tid); 1110 1111 // The current PC. 1112 TheISA::PCState thisPC = pc[tid]; 1113 --- 38 unchanged lines hidden (view full) --- 1152 // are not interruptable by interrupts, only faults) 1153 ++fetchMiscStallCycles; 1154 return; 1155 } 1156 } else { 1157 if (fetchStatus[tid] == Idle) { 1158 ++fetchIdleCycles; 1159 DPRINTF(Fetch, "[tid:%i]: Fetch is idle!\n", tid); | 1156 return; 1157 } 1158 1159 DPRINTF(Fetch, "Attempting to fetch from [tid:%i]\n", tid); 1160 1161 // The current PC. 1162 TheISA::PCState thisPC = pc[tid]; 1163 --- 38 unchanged lines hidden (view full) --- 1202 // are not interruptable by interrupts, only faults) 1203 ++fetchMiscStallCycles; 1204 return; 1205 } 1206 } else { 1207 if (fetchStatus[tid] == Idle) { 1208 ++fetchIdleCycles; 1209 DPRINTF(Fetch, "[tid:%i]: Fetch is idle!\n", tid); |
1160 } else if (fetchStatus[tid] == Blocked) { 1161 ++fetchBlockedCycles; 1162 DPRINTF(Fetch, "[tid:%i]: Fetch is blocked!\n", tid); 1163 } else if (fetchStatus[tid] == Squashing) { 1164 ++fetchSquashCycles; 1165 DPRINTF(Fetch, "[tid:%i]: Fetch is squashing!\n", tid); 1166 } else if (fetchStatus[tid] == IcacheWaitResponse) { 1167 ++icacheStallCycles; 1168 DPRINTF(Fetch, "[tid:%i]: Fetch is waiting cache response!\n", 1169 tid); 1170 } else if (fetchStatus[tid] == ItlbWait) { 1171 DPRINTF(Fetch, "[tid:%i]: Fetch is waiting ITLB walk to " 1172 "finish! \n", tid); 1173 ++fetchTlbCycles; 1174 } else if (fetchStatus[tid] == TrapPending) { 1175 DPRINTF(Fetch, "[tid:%i]: Fetch is waiting for a pending trap\n", 1176 tid); 1177 } else if (fetchStatus[tid] == NoGoodAddr) { 1178 DPRINTF(Fetch, "[tid:%i]: Fetch predicted non-executable address\n", 1179 tid); | |
1180 } 1181 | 1210 } 1211 |
1182 1183 1184 // Status is Idle, Squashing, Blocked, ItlbWait or IcacheWaitResponse 1185 // so fetch should do nothing. | 1212 // Status is Idle, so fetch should do nothing. |
1186 return; 1187 } 1188 1189 ++fetchCycles; 1190 1191 TheISA::PCState nextPC = thisPC; 1192 1193 StaticInstPtr staticInst = NULL; --- 130 unchanged lines hidden (view full) --- 1324 macroop[tid] = curMacroop; 1325 fetchOffset[tid] = pcOffset; 1326 1327 if (numInst > 0) { 1328 wroteToTimeBuffer = true; 1329 } 1330 1331 pc[tid] = thisPC; | 1213 return; 1214 } 1215 1216 ++fetchCycles; 1217 1218 TheISA::PCState nextPC = thisPC; 1219 1220 StaticInstPtr staticInst = NULL; --- 130 unchanged lines hidden (view full) --- 1351 macroop[tid] = curMacroop; 1352 fetchOffset[tid] = pcOffset; 1353 1354 if (numInst > 0) { 1355 wroteToTimeBuffer = true; 1356 } 1357 1358 pc[tid] = thisPC; |
1359 1360 // pipeline a fetch if we're crossing a cache boundary and not in 1361 // a state that would preclude fetching 1362 fetchAddr = (thisPC.instAddr() + pcOffset) & BaseCPU::PCMask; 1363 Addr block_PC = icacheBlockAlignPC(fetchAddr); 1364 issuePipelinedIfetch[tid] = block_PC != cacheDataPC[tid] && 1365 fetchStatus[tid] != IcacheWaitResponse && 1366 fetchStatus[tid] != ItlbWait && 1367 fetchStatus[tid] != IcacheWaitRetry && 1368 fetchStatus[tid] != QuiescePending && 1369 !curMacroop; |
|
1332} 1333 1334template<class Impl> 1335void 1336DefaultFetch<Impl>::recvRetry() 1337{ 1338 if (retryPkt != NULL) { 1339 assert(cacheBlocked); --- 166 unchanged lines hidden (view full) --- 1506 list<ThreadID>::iterator thread = activeThreads->begin(); 1507 assert(thread != activeThreads->end()); 1508 ThreadID tid = *thread; 1509#endif 1510 1511 panic("Branch Count Fetch policy unimplemented\n"); 1512 return InvalidThreadID; 1513} | 1370} 1371 1372template<class Impl> 1373void 1374DefaultFetch<Impl>::recvRetry() 1375{ 1376 if (retryPkt != NULL) { 1377 assert(cacheBlocked); --- 166 unchanged lines hidden (view full) --- 1544 list<ThreadID>::iterator thread = activeThreads->begin(); 1545 assert(thread != activeThreads->end()); 1546 ThreadID tid = *thread; 1547#endif 1548 1549 panic("Branch Count Fetch policy unimplemented\n"); 1550 return InvalidThreadID; 1551} |
1552 1553template<class Impl> 1554void 1555DefaultFetch<Impl>::pipelineIcacheAccesses(ThreadID tid) 1556{ 1557 if (!issuePipelinedIfetch[tid]) { 1558 return; 1559 } 1560 1561 // The next PC to access. 1562 TheISA::PCState thisPC = pc[tid]; 1563 1564 if (isRomMicroPC(thisPC.microPC())) { 1565 return; 1566 } 1567 1568 Addr pcOffset = fetchOffset[tid]; 1569 Addr fetchAddr = (thisPC.instAddr() + pcOffset) & BaseCPU::PCMask; 1570 1571 // Align the fetch PC so its at the start of a cache block. 1572 Addr block_PC = icacheBlockAlignPC(fetchAddr); 1573 1574 // Unless buffer already got the block, fetch it from icache. 1575 if (!(cacheDataValid[tid] && block_PC == cacheDataPC[tid])) { 1576 DPRINTF(Fetch, "[tid:%i]: Issuing a pipelined I-cache access, " 1577 "starting at PC %s.\n", tid, thisPC); 1578 1579 fetchCacheLine(fetchAddr, tid, thisPC.instAddr()); 1580 } 1581} 1582 1583template<class Impl> 1584void 1585DefaultFetch<Impl>::profileStall(ThreadID tid) { 1586 DPRINTF(Fetch,"There are no more threads available to fetch from.\n"); 1587 1588 // @todo Per-thread stats 1589 1590 if (drainPending) { 1591 ++fetchPendingDrainCycles; 1592 DPRINTF(Fetch, "Fetch is waiting for a drain!\n"); 1593 } else if (activeThreads->empty()) { 1594 ++fetchNoActiveThreadStallCycles; 1595 DPRINTF(Fetch, "Fetch has no active thread!\n"); 1596 } else if (fetchStatus[tid] == Blocked) { 1597 ++fetchBlockedCycles; 1598 DPRINTF(Fetch, "[tid:%i]: Fetch is blocked!\n", tid); 1599 } else if (fetchStatus[tid] == Squashing) { 1600 ++fetchSquashCycles; 1601 DPRINTF(Fetch, "[tid:%i]: Fetch is squashing!\n", tid); 1602 } else if (fetchStatus[tid] == IcacheWaitResponse) { 1603 ++icacheStallCycles; 1604 DPRINTF(Fetch, "[tid:%i]: Fetch is waiting cache response!\n", 1605 tid); 1606 } else if (fetchStatus[tid] == ItlbWait) { 1607 ++fetchTlbCycles; 1608 DPRINTF(Fetch, "[tid:%i]: Fetch is waiting ITLB walk to " 1609 "finish!\n", tid); 1610 } else if (fetchStatus[tid] == TrapPending) { 1611 ++fetchPendingTrapStallCycles; 1612 DPRINTF(Fetch, "[tid:%i]: Fetch is waiting for a pending trap!\n", 1613 tid); 1614 } else if (fetchStatus[tid] == QuiescePending) { 1615 ++fetchPendingQuiesceStallCycles; 1616 DPRINTF(Fetch, "[tid:%i]: Fetch is waiting for a pending quiesce " 1617 "instruction!\n", tid); 1618 } else if (fetchStatus[tid] == IcacheWaitRetry) { 1619 ++fetchIcacheWaitRetryStallCycles; 1620 DPRINTF(Fetch, "[tid:%i]: Fetch is waiting for an I-cache retry!\n", 1621 tid); 1622 } else if (fetchStatus[tid] == NoGoodAddr) { 1623 DPRINTF(Fetch, "[tid:%i]: Fetch predicted non-executable address\n", 1624 tid); 1625 } else { 1626 DPRINTF(Fetch, "[tid:%i]: Unexpected fetch stall reason (Status: %i).\n", 1627 tid, fetchStatus[tid]); 1628 } 1629} |
|