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}