fetch_impl.hh revision 11429:cf5af0cc3be4
1/*
2 * Copyright (c) 2010-2014 ARM Limited
3 * Copyright (c) 2012-2013 AMD
4 * All rights reserved.
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder.  You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Copyright (c) 2004-2006 The Regents of The University of Michigan
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Authors: Kevin Lim
42 *          Korey Sewell
43 */
44
45#ifndef __CPU_O3_FETCH_IMPL_HH__
46#define __CPU_O3_FETCH_IMPL_HH__
47
48#include <algorithm>
49#include <cstring>
50#include <list>
51#include <map>
52#include <queue>
53
54#include "arch/isa_traits.hh"
55#include "arch/tlb.hh"
56#include "arch/utility.hh"
57#include "arch/vtophys.hh"
58#include "base/random.hh"
59#include "base/types.hh"
60#include "config/the_isa.hh"
61#include "cpu/base.hh"
62//#include "cpu/checker/cpu.hh"
63#include "cpu/o3/fetch.hh"
64#include "cpu/exetrace.hh"
65#include "debug/Activity.hh"
66#include "debug/Drain.hh"
67#include "debug/Fetch.hh"
68#include "debug/O3PipeView.hh"
69#include "mem/packet.hh"
70#include "params/DerivO3CPU.hh"
71#include "sim/byteswap.hh"
72#include "sim/core.hh"
73#include "sim/eventq.hh"
74#include "sim/full_system.hh"
75#include "sim/system.hh"
76#include "cpu/o3/isa_specific.hh"
77
78using namespace std;
79
80template<class Impl>
81DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params)
82    : cpu(_cpu),
83      decodeToFetchDelay(params->decodeToFetchDelay),
84      renameToFetchDelay(params->renameToFetchDelay),
85      iewToFetchDelay(params->iewToFetchDelay),
86      commitToFetchDelay(params->commitToFetchDelay),
87      fetchWidth(params->fetchWidth),
88      decodeWidth(params->decodeWidth),
89      retryPkt(NULL),
90      retryTid(InvalidThreadID),
91      cacheBlkSize(cpu->cacheLineSize()),
92      fetchBufferSize(params->fetchBufferSize),
93      fetchBufferMask(fetchBufferSize - 1),
94      fetchQueueSize(params->fetchQueueSize),
95      numThreads(params->numThreads),
96      numFetchingThreads(params->smtNumFetchingThreads),
97      finishTranslationEvent(this)
98{
99    if (numThreads > Impl::MaxThreads)
100        fatal("numThreads (%d) is larger than compiled limit (%d),\n"
101              "\tincrease MaxThreads in src/cpu/o3/impl.hh\n",
102              numThreads, static_cast<int>(Impl::MaxThreads));
103    if (fetchWidth > Impl::MaxWidth)
104        fatal("fetchWidth (%d) is larger than compiled limit (%d),\n"
105             "\tincrease MaxWidth in src/cpu/o3/impl.hh\n",
106             fetchWidth, static_cast<int>(Impl::MaxWidth));
107    if (fetchBufferSize > cacheBlkSize)
108        fatal("fetch buffer size (%u bytes) is greater than the cache "
109              "block size (%u bytes)\n", fetchBufferSize, cacheBlkSize);
110    if (cacheBlkSize % fetchBufferSize)
111        fatal("cache block (%u bytes) is not a multiple of the "
112              "fetch buffer (%u bytes)\n", cacheBlkSize, fetchBufferSize);
113
114    std::string policy = params->smtFetchPolicy;
115
116    // Convert string to lowercase
117    std::transform(policy.begin(), policy.end(), policy.begin(),
118                   (int(*)(int)) tolower);
119
120    // Figure out fetch policy
121    if (policy == "singlethread") {
122        fetchPolicy = SingleThread;
123        if (numThreads > 1)
124            panic("Invalid Fetch Policy for a SMT workload.");
125    } else if (policy == "roundrobin") {
126        fetchPolicy = RoundRobin;
127        DPRINTF(Fetch, "Fetch policy set to Round Robin\n");
128    } else if (policy == "branch") {
129        fetchPolicy = Branch;
130        DPRINTF(Fetch, "Fetch policy set to Branch Count\n");
131    } else if (policy == "iqcount") {
132        fetchPolicy = IQ;
133        DPRINTF(Fetch, "Fetch policy set to IQ count\n");
134    } else if (policy == "lsqcount") {
135        fetchPolicy = LSQ;
136        DPRINTF(Fetch, "Fetch policy set to LSQ count\n");
137    } else {
138        fatal("Invalid Fetch Policy. Options Are: {SingleThread,"
139              " RoundRobin,LSQcount,IQcount}\n");
140    }
141
142    // Get the size of an instruction.
143    instSize = sizeof(TheISA::MachInst);
144
145    for (int i = 0; i < Impl::MaxThreads; i++) {
146        decoder[i] = NULL;
147        fetchBuffer[i] = NULL;
148        fetchBufferPC[i] = 0;
149        fetchBufferValid[i] = false;
150    }
151
152    branchPred = params->branchPred;
153
154    for (ThreadID tid = 0; tid < numThreads; tid++) {
155        decoder[tid] = new TheISA::Decoder(params->isa[tid]);
156        // Create space to buffer the cache line data,
157        // which may not hold the entire cache line.
158        fetchBuffer[tid] = new uint8_t[fetchBufferSize];
159    }
160}
161
162template <class Impl>
163std::string
164DefaultFetch<Impl>::name() const
165{
166    return cpu->name() + ".fetch";
167}
168
169template <class Impl>
170void
171DefaultFetch<Impl>::regProbePoints()
172{
173    ppFetch = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Fetch");
174    ppFetchRequestSent = new ProbePointArg<RequestPtr>(cpu->getProbeManager(),
175                                                       "FetchRequest");
176
177}
178
179template <class Impl>
180void
181DefaultFetch<Impl>::regStats()
182{
183    icacheStallCycles
184        .name(name() + ".icacheStallCycles")
185        .desc("Number of cycles fetch is stalled on an Icache miss")
186        .prereq(icacheStallCycles);
187
188    fetchedInsts
189        .name(name() + ".Insts")
190        .desc("Number of instructions fetch has processed")
191        .prereq(fetchedInsts);
192
193    fetchedBranches
194        .name(name() + ".Branches")
195        .desc("Number of branches that fetch encountered")
196        .prereq(fetchedBranches);
197
198    predictedBranches
199        .name(name() + ".predictedBranches")
200        .desc("Number of branches that fetch has predicted taken")
201        .prereq(predictedBranches);
202
203    fetchCycles
204        .name(name() + ".Cycles")
205        .desc("Number of cycles fetch has run and was not squashing or"
206              " blocked")
207        .prereq(fetchCycles);
208
209    fetchSquashCycles
210        .name(name() + ".SquashCycles")
211        .desc("Number of cycles fetch has spent squashing")
212        .prereq(fetchSquashCycles);
213
214    fetchTlbCycles
215        .name(name() + ".TlbCycles")
216        .desc("Number of cycles fetch has spent waiting for tlb")
217        .prereq(fetchTlbCycles);
218
219    fetchIdleCycles
220        .name(name() + ".IdleCycles")
221        .desc("Number of cycles fetch was idle")
222        .prereq(fetchIdleCycles);
223
224    fetchBlockedCycles
225        .name(name() + ".BlockedCycles")
226        .desc("Number of cycles fetch has spent blocked")
227        .prereq(fetchBlockedCycles);
228
229    fetchedCacheLines
230        .name(name() + ".CacheLines")
231        .desc("Number of cache lines fetched")
232        .prereq(fetchedCacheLines);
233
234    fetchMiscStallCycles
235        .name(name() + ".MiscStallCycles")
236        .desc("Number of cycles fetch has spent waiting on interrupts, or "
237              "bad addresses, or out of MSHRs")
238        .prereq(fetchMiscStallCycles);
239
240    fetchPendingDrainCycles
241        .name(name() + ".PendingDrainCycles")
242        .desc("Number of cycles fetch has spent waiting on pipes to drain")
243        .prereq(fetchPendingDrainCycles);
244
245    fetchNoActiveThreadStallCycles
246        .name(name() + ".NoActiveThreadStallCycles")
247        .desc("Number of stall cycles due to no active thread to fetch from")
248        .prereq(fetchNoActiveThreadStallCycles);
249
250    fetchPendingTrapStallCycles
251        .name(name() + ".PendingTrapStallCycles")
252        .desc("Number of stall cycles due to pending traps")
253        .prereq(fetchPendingTrapStallCycles);
254
255    fetchPendingQuiesceStallCycles
256        .name(name() + ".PendingQuiesceStallCycles")
257        .desc("Number of stall cycles due to pending quiesce instructions")
258        .prereq(fetchPendingQuiesceStallCycles);
259
260    fetchIcacheWaitRetryStallCycles
261        .name(name() + ".IcacheWaitRetryStallCycles")
262        .desc("Number of stall cycles due to full MSHR")
263        .prereq(fetchIcacheWaitRetryStallCycles);
264
265    fetchIcacheSquashes
266        .name(name() + ".IcacheSquashes")
267        .desc("Number of outstanding Icache misses that were squashed")
268        .prereq(fetchIcacheSquashes);
269
270    fetchTlbSquashes
271        .name(name() + ".ItlbSquashes")
272        .desc("Number of outstanding ITLB misses that were squashed")
273        .prereq(fetchTlbSquashes);
274
275    fetchNisnDist
276        .init(/* base value */ 0,
277              /* last value */ fetchWidth,
278              /* bucket size */ 1)
279        .name(name() + ".rateDist")
280        .desc("Number of instructions fetched each cycle (Total)")
281        .flags(Stats::pdf);
282
283    idleRate
284        .name(name() + ".idleRate")
285        .desc("Percent of cycles fetch was idle")
286        .prereq(idleRate);
287    idleRate = fetchIdleCycles * 100 / cpu->numCycles;
288
289    branchRate
290        .name(name() + ".branchRate")
291        .desc("Number of branch fetches per cycle")
292        .flags(Stats::total);
293    branchRate = fetchedBranches / cpu->numCycles;
294
295    fetchRate
296        .name(name() + ".rate")
297        .desc("Number of inst fetches per cycle")
298        .flags(Stats::total);
299    fetchRate = fetchedInsts / cpu->numCycles;
300}
301
302template<class Impl>
303void
304DefaultFetch<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer)
305{
306    timeBuffer = time_buffer;
307
308    // Create wires to get information from proper places in time buffer.
309    fromDecode = timeBuffer->getWire(-decodeToFetchDelay);
310    fromRename = timeBuffer->getWire(-renameToFetchDelay);
311    fromIEW = timeBuffer->getWire(-iewToFetchDelay);
312    fromCommit = timeBuffer->getWire(-commitToFetchDelay);
313}
314
315template<class Impl>
316void
317DefaultFetch<Impl>::setActiveThreads(std::list<ThreadID> *at_ptr)
318{
319    activeThreads = at_ptr;
320}
321
322template<class Impl>
323void
324DefaultFetch<Impl>::setFetchQueue(TimeBuffer<FetchStruct> *ftb_ptr)
325{
326    // Create wire to write information to proper place in fetch time buf.
327    toDecode = ftb_ptr->getWire(0);
328}
329
330template<class Impl>
331void
332DefaultFetch<Impl>::startupStage()
333{
334    assert(priorityList.empty());
335    resetStage();
336
337    // Fetch needs to start fetching instructions at the very beginning,
338    // so it must start up in active state.
339    switchToActive();
340}
341
342template<class Impl>
343void
344DefaultFetch<Impl>::resetStage()
345{
346    numInst = 0;
347    interruptPending = false;
348    cacheBlocked = false;
349
350    priorityList.clear();
351
352    // Setup PC and nextPC with initial state.
353    for (ThreadID tid = 0; tid < numThreads; ++tid) {
354        fetchStatus[tid] = Running;
355        pc[tid] = cpu->pcState(tid);
356        fetchOffset[tid] = 0;
357        macroop[tid] = NULL;
358
359        delayedCommit[tid] = false;
360        memReq[tid] = NULL;
361
362        stalls[tid].decode = false;
363        stalls[tid].drain = false;
364
365        fetchBufferPC[tid] = 0;
366        fetchBufferValid[tid] = false;
367
368        fetchQueue[tid].clear();
369
370        priorityList.push_back(tid);
371    }
372
373    wroteToTimeBuffer = false;
374    _status = Inactive;
375}
376
377template<class Impl>
378void
379DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
380{
381    ThreadID tid = pkt->req->threadId();
382
383    DPRINTF(Fetch, "[tid:%u] Waking up from cache miss.\n", tid);
384    assert(!cpu->switchedOut());
385
386    // Only change the status if it's still waiting on the icache access
387    // to return.
388    if (fetchStatus[tid] != IcacheWaitResponse ||
389        pkt->req != memReq[tid]) {
390        ++fetchIcacheSquashes;
391        delete pkt->req;
392        delete pkt;
393        return;
394    }
395
396    memcpy(fetchBuffer[tid], pkt->getConstPtr<uint8_t>(), fetchBufferSize);
397    fetchBufferValid[tid] = true;
398
399    // Wake up the CPU (if it went to sleep and was waiting on
400    // this completion event).
401    cpu->wakeCPU();
402
403    DPRINTF(Activity, "[tid:%u] Activating fetch due to cache completion\n",
404            tid);
405
406    switchToActive();
407
408    // Only switch to IcacheAccessComplete if we're not stalled as well.
409    if (checkStall(tid)) {
410        fetchStatus[tid] = Blocked;
411    } else {
412        fetchStatus[tid] = IcacheAccessComplete;
413    }
414
415    pkt->req->setAccessLatency();
416    cpu->ppInstAccessComplete->notify(pkt);
417    // Reset the mem req to NULL.
418    delete pkt->req;
419    delete pkt;
420    memReq[tid] = NULL;
421}
422
423template <class Impl>
424void
425DefaultFetch<Impl>::drainResume()
426{
427    for (ThreadID i = 0; i < numThreads; ++i)
428        stalls[i].drain = false;
429}
430
431template <class Impl>
432void
433DefaultFetch<Impl>::drainSanityCheck() const
434{
435    assert(isDrained());
436    assert(retryPkt == NULL);
437    assert(retryTid == InvalidThreadID);
438    assert(!cacheBlocked);
439    assert(!interruptPending);
440
441    for (ThreadID i = 0; i < numThreads; ++i) {
442        assert(!memReq[i]);
443        assert(fetchStatus[i] == Idle || stalls[i].drain);
444    }
445
446    branchPred->drainSanityCheck();
447}
448
449template <class Impl>
450bool
451DefaultFetch<Impl>::isDrained() const
452{
453    /* Make sure that threads are either idle of that the commit stage
454     * has signaled that draining has completed by setting the drain
455     * stall flag. This effectively forces the pipeline to be disabled
456     * until the whole system is drained (simulation may continue to
457     * drain other components).
458     */
459    for (ThreadID i = 0; i < numThreads; ++i) {
460        // Verify fetch queues are drained
461        if (!fetchQueue[i].empty())
462            return false;
463
464        // Return false if not idle or drain stalled
465        if (fetchStatus[i] != Idle) {
466            if (fetchStatus[i] == Blocked && stalls[i].drain)
467                continue;
468            else
469                return false;
470        }
471    }
472
473    /* The pipeline might start up again in the middle of the drain
474     * cycle if the finish translation event is scheduled, so make
475     * sure that's not the case.
476     */
477    return !finishTranslationEvent.scheduled();
478}
479
480template <class Impl>
481void
482DefaultFetch<Impl>::takeOverFrom()
483{
484    assert(cpu->getInstPort().isConnected());
485    resetStage();
486
487}
488
489template <class Impl>
490void
491DefaultFetch<Impl>::drainStall(ThreadID tid)
492{
493    assert(cpu->isDraining());
494    assert(!stalls[tid].drain);
495    DPRINTF(Drain, "%i: Thread drained.\n", tid);
496    stalls[tid].drain = true;
497}
498
499template <class Impl>
500void
501DefaultFetch<Impl>::wakeFromQuiesce()
502{
503    DPRINTF(Fetch, "Waking up from quiesce\n");
504    // Hopefully this is safe
505    // @todo: Allow other threads to wake from quiesce.
506    fetchStatus[0] = Running;
507}
508
509template <class Impl>
510inline void
511DefaultFetch<Impl>::switchToActive()
512{
513    if (_status == Inactive) {
514        DPRINTF(Activity, "Activating stage.\n");
515
516        cpu->activateStage(O3CPU::FetchIdx);
517
518        _status = Active;
519    }
520}
521
522template <class Impl>
523inline void
524DefaultFetch<Impl>::switchToInactive()
525{
526    if (_status == Active) {
527        DPRINTF(Activity, "Deactivating stage.\n");
528
529        cpu->deactivateStage(O3CPU::FetchIdx);
530
531        _status = Inactive;
532    }
533}
534
535template <class Impl>
536void
537DefaultFetch<Impl>::deactivateThread(ThreadID tid)
538{
539    // Update priority list
540    auto thread_it = std::find(priorityList.begin(), priorityList.end(), tid);
541    if (thread_it != priorityList.end()) {
542        priorityList.erase(thread_it);
543    }
544}
545
546template <class Impl>
547bool
548DefaultFetch<Impl>::lookupAndUpdateNextPC(
549        DynInstPtr &inst, TheISA::PCState &nextPC)
550{
551    // Do branch prediction check here.
552    // A bit of a misnomer...next_PC is actually the current PC until
553    // this function updates it.
554    bool predict_taken;
555
556    if (!inst->isControl()) {
557        TheISA::advancePC(nextPC, inst->staticInst);
558        inst->setPredTarg(nextPC);
559        inst->setPredTaken(false);
560        return false;
561    }
562
563    ThreadID tid = inst->threadNumber;
564    predict_taken = branchPred->predict(inst->staticInst, inst->seqNum,
565                                        nextPC, tid);
566
567    if (predict_taken) {
568        DPRINTF(Fetch, "[tid:%i]: [sn:%i]:  Branch predicted to be taken to %s.\n",
569                tid, inst->seqNum, nextPC);
570    } else {
571        DPRINTF(Fetch, "[tid:%i]: [sn:%i]:Branch predicted to be not taken.\n",
572                tid, inst->seqNum);
573    }
574
575    DPRINTF(Fetch, "[tid:%i]: [sn:%i] Branch predicted to go to %s.\n",
576            tid, inst->seqNum, nextPC);
577    inst->setPredTarg(nextPC);
578    inst->setPredTaken(predict_taken);
579
580    ++fetchedBranches;
581
582    if (predict_taken) {
583        ++predictedBranches;
584    }
585
586    return predict_taken;
587}
588
589template <class Impl>
590bool
591DefaultFetch<Impl>::fetchCacheLine(Addr vaddr, ThreadID tid, Addr pc)
592{
593    Fault fault = NoFault;
594
595    assert(!cpu->switchedOut());
596
597    // @todo: not sure if these should block translation.
598    //AlphaDep
599    if (cacheBlocked) {
600        DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, cache blocked\n",
601                tid);
602        return false;
603    } else if (checkInterrupt(pc) && !delayedCommit[tid]) {
604        // Hold off fetch from getting new instructions when:
605        // Cache is blocked, or
606        // while an interrupt is pending and we're not in PAL mode, or
607        // fetch is switched out.
608        DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, interrupt pending\n",
609                tid);
610        return false;
611    }
612
613    // Align the fetch address to the start of a fetch buffer segment.
614    Addr fetchBufferBlockPC = fetchBufferAlignPC(vaddr);
615
616    DPRINTF(Fetch, "[tid:%i] Fetching cache line %#x for addr %#x\n",
617            tid, fetchBufferBlockPC, vaddr);
618
619    // Setup the memReq to do a read of the first instruction's address.
620    // Set the appropriate read size and flags as well.
621    // Build request here.
622    RequestPtr mem_req =
623        new Request(tid, fetchBufferBlockPC, fetchBufferSize,
624                    Request::INST_FETCH, cpu->instMasterId(), pc,
625                    cpu->thread[tid]->contextId(), tid);
626
627    mem_req->taskId(cpu->taskId());
628
629    memReq[tid] = mem_req;
630
631    // Initiate translation of the icache block
632    fetchStatus[tid] = ItlbWait;
633    FetchTranslation *trans = new FetchTranslation(this);
634    cpu->itb->translateTiming(mem_req, cpu->thread[tid]->getTC(),
635                              trans, BaseTLB::Execute);
636    return true;
637}
638
639template <class Impl>
640void
641DefaultFetch<Impl>::finishTranslation(const Fault &fault, RequestPtr mem_req)
642{
643    ThreadID tid = mem_req->threadId();
644    Addr fetchBufferBlockPC = mem_req->getVaddr();
645
646    assert(!cpu->switchedOut());
647
648    // Wake up CPU if it was idle
649    cpu->wakeCPU();
650
651    if (fetchStatus[tid] != ItlbWait || mem_req != memReq[tid] ||
652        mem_req->getVaddr() != memReq[tid]->getVaddr()) {
653        DPRINTF(Fetch, "[tid:%i] Ignoring itlb completed after squash\n",
654                tid);
655        ++fetchTlbSquashes;
656        delete mem_req;
657        return;
658    }
659
660
661    // If translation was successful, attempt to read the icache block.
662    if (fault == NoFault) {
663        // Check that we're not going off into random memory
664        // If we have, just wait around for commit to squash something and put
665        // us on the right track
666        if (!cpu->system->isMemAddr(mem_req->getPaddr())) {
667            warn("Address %#x is outside of physical memory, stopping fetch\n",
668                    mem_req->getPaddr());
669            fetchStatus[tid] = NoGoodAddr;
670            delete mem_req;
671            memReq[tid] = NULL;
672            return;
673        }
674
675        // Build packet here.
676        PacketPtr data_pkt = new Packet(mem_req, MemCmd::ReadReq);
677        data_pkt->dataDynamic(new uint8_t[fetchBufferSize]);
678
679        fetchBufferPC[tid] = fetchBufferBlockPC;
680        fetchBufferValid[tid] = false;
681        DPRINTF(Fetch, "Fetch: Doing instruction read.\n");
682
683        fetchedCacheLines++;
684
685        // Access the cache.
686        if (!cpu->getInstPort().sendTimingReq(data_pkt)) {
687            assert(retryPkt == NULL);
688            assert(retryTid == InvalidThreadID);
689            DPRINTF(Fetch, "[tid:%i] Out of MSHRs!\n", tid);
690
691            fetchStatus[tid] = IcacheWaitRetry;
692            retryPkt = data_pkt;
693            retryTid = tid;
694            cacheBlocked = true;
695        } else {
696            DPRINTF(Fetch, "[tid:%i]: Doing Icache access.\n", tid);
697            DPRINTF(Activity, "[tid:%i]: Activity: Waiting on I-cache "
698                    "response.\n", tid);
699            lastIcacheStall[tid] = curTick();
700            fetchStatus[tid] = IcacheWaitResponse;
701            // Notify Fetch Request probe when a packet containing a fetch
702            // request is successfully sent
703            ppFetchRequestSent->notify(mem_req);
704        }
705    } else {
706        // Don't send an instruction to decode if we can't handle it.
707        if (!(numInst < fetchWidth) || !(fetchQueue[tid].size() < fetchQueueSize)) {
708            assert(!finishTranslationEvent.scheduled());
709            finishTranslationEvent.setFault(fault);
710            finishTranslationEvent.setReq(mem_req);
711            cpu->schedule(finishTranslationEvent,
712                          cpu->clockEdge(Cycles(1)));
713            return;
714        }
715        DPRINTF(Fetch, "[tid:%i] Got back req with addr %#x but expected %#x\n",
716                tid, mem_req->getVaddr(), memReq[tid]->getVaddr());
717        // Translation faulted, icache request won't be sent.
718        delete mem_req;
719        memReq[tid] = NULL;
720
721        // Send the fault to commit.  This thread will not do anything
722        // until commit handles the fault.  The only other way it can
723        // wake up is if a squash comes along and changes the PC.
724        TheISA::PCState fetchPC = pc[tid];
725
726        DPRINTF(Fetch, "[tid:%i]: Translation faulted, building noop.\n", tid);
727        // We will use a nop in ordier to carry the fault.
728        DynInstPtr instruction = buildInst(tid,
729                decoder[tid]->decode(TheISA::NoopMachInst, fetchPC.instAddr()),
730                NULL, fetchPC, fetchPC, false);
731
732        instruction->setPredTarg(fetchPC);
733        instruction->fault = fault;
734        wroteToTimeBuffer = true;
735
736        DPRINTF(Activity, "Activity this cycle.\n");
737        cpu->activityThisCycle();
738
739        fetchStatus[tid] = TrapPending;
740
741        DPRINTF(Fetch, "[tid:%i]: Blocked, need to handle the trap.\n", tid);
742        DPRINTF(Fetch, "[tid:%i]: fault (%s) detected @ PC %s.\n",
743                tid, fault->name(), pc[tid]);
744    }
745    _status = updateFetchStatus();
746}
747
748template <class Impl>
749inline void
750DefaultFetch<Impl>::doSquash(const TheISA::PCState &newPC,
751                             const DynInstPtr squashInst, ThreadID tid)
752{
753    DPRINTF(Fetch, "[tid:%i]: Squashing, setting PC to: %s.\n",
754            tid, newPC);
755
756    pc[tid] = newPC;
757    fetchOffset[tid] = 0;
758    if (squashInst && squashInst->pcState().instAddr() == newPC.instAddr())
759        macroop[tid] = squashInst->macroop;
760    else
761        macroop[tid] = NULL;
762    decoder[tid]->reset();
763
764    // Clear the icache miss if it's outstanding.
765    if (fetchStatus[tid] == IcacheWaitResponse) {
766        DPRINTF(Fetch, "[tid:%i]: Squashing outstanding Icache miss.\n",
767                tid);
768        memReq[tid] = NULL;
769    } else if (fetchStatus[tid] == ItlbWait) {
770        DPRINTF(Fetch, "[tid:%i]: Squashing outstanding ITLB miss.\n",
771                tid);
772        memReq[tid] = NULL;
773    }
774
775    // Get rid of the retrying packet if it was from this thread.
776    if (retryTid == tid) {
777        assert(cacheBlocked);
778        if (retryPkt) {
779            delete retryPkt->req;
780            delete retryPkt;
781        }
782        retryPkt = NULL;
783        retryTid = InvalidThreadID;
784    }
785
786    fetchStatus[tid] = Squashing;
787
788    // Empty fetch queue
789    fetchQueue[tid].clear();
790
791    // microops are being squashed, it is not known wheather the
792    // youngest non-squashed microop was  marked delayed commit
793    // or not. Setting the flag to true ensures that the
794    // interrupts are not handled when they cannot be, though
795    // some opportunities to handle interrupts may be missed.
796    delayedCommit[tid] = true;
797
798    ++fetchSquashCycles;
799}
800
801template<class Impl>
802void
803DefaultFetch<Impl>::squashFromDecode(const TheISA::PCState &newPC,
804                                     const DynInstPtr squashInst,
805                                     const InstSeqNum seq_num, ThreadID tid)
806{
807    DPRINTF(Fetch, "[tid:%i]: Squashing from decode.\n", tid);
808
809    doSquash(newPC, squashInst, tid);
810
811    // Tell the CPU to remove any instructions that are in flight between
812    // fetch and decode.
813    cpu->removeInstsUntil(seq_num, tid);
814}
815
816template<class Impl>
817bool
818DefaultFetch<Impl>::checkStall(ThreadID tid) const
819{
820    bool ret_val = false;
821
822    if (stalls[tid].drain) {
823        assert(cpu->isDraining());
824        DPRINTF(Fetch,"[tid:%i]: Drain stall detected.\n",tid);
825        ret_val = true;
826    }
827
828    return ret_val;
829}
830
831template<class Impl>
832typename DefaultFetch<Impl>::FetchStatus
833DefaultFetch<Impl>::updateFetchStatus()
834{
835    //Check Running
836    list<ThreadID>::iterator threads = activeThreads->begin();
837    list<ThreadID>::iterator end = activeThreads->end();
838
839    while (threads != end) {
840        ThreadID tid = *threads++;
841
842        if (fetchStatus[tid] == Running ||
843            fetchStatus[tid] == Squashing ||
844            fetchStatus[tid] == IcacheAccessComplete) {
845
846            if (_status == Inactive) {
847                DPRINTF(Activity, "[tid:%i]: Activating stage.\n",tid);
848
849                if (fetchStatus[tid] == IcacheAccessComplete) {
850                    DPRINTF(Activity, "[tid:%i]: Activating fetch due to cache"
851                            "completion\n",tid);
852                }
853
854                cpu->activateStage(O3CPU::FetchIdx);
855            }
856
857            return Active;
858        }
859    }
860
861    // Stage is switching from active to inactive, notify CPU of it.
862    if (_status == Active) {
863        DPRINTF(Activity, "Deactivating stage.\n");
864
865        cpu->deactivateStage(O3CPU::FetchIdx);
866    }
867
868    return Inactive;
869}
870
871template <class Impl>
872void
873DefaultFetch<Impl>::squash(const TheISA::PCState &newPC,
874                           const InstSeqNum seq_num, DynInstPtr squashInst,
875                           ThreadID tid)
876{
877    DPRINTF(Fetch, "[tid:%u]: Squash from commit.\n", tid);
878
879    doSquash(newPC, squashInst, tid);
880
881    // Tell the CPU to remove any instructions that are not in the ROB.
882    cpu->removeInstsNotInROB(tid);
883}
884
885template <class Impl>
886void
887DefaultFetch<Impl>::tick()
888{
889    list<ThreadID>::iterator threads = activeThreads->begin();
890    list<ThreadID>::iterator end = activeThreads->end();
891    bool status_change = false;
892
893    wroteToTimeBuffer = false;
894
895    for (ThreadID i = 0; i < numThreads; ++i) {
896        issuePipelinedIfetch[i] = false;
897    }
898
899    while (threads != end) {
900        ThreadID tid = *threads++;
901
902        // Check the signals for each thread to determine the proper status
903        // for each thread.
904        bool updated_status = checkSignalsAndUpdate(tid);
905        status_change =  status_change || updated_status;
906    }
907
908    DPRINTF(Fetch, "Running stage.\n");
909
910    if (FullSystem) {
911        if (fromCommit->commitInfo[0].interruptPending) {
912            interruptPending = true;
913        }
914
915        if (fromCommit->commitInfo[0].clearInterrupt) {
916            interruptPending = false;
917        }
918    }
919
920    for (threadFetched = 0; threadFetched < numFetchingThreads;
921         threadFetched++) {
922        // Fetch each of the actively fetching threads.
923        fetch(status_change);
924    }
925
926    // Record number of instructions fetched this cycle for distribution.
927    fetchNisnDist.sample(numInst);
928
929    if (status_change) {
930        // Change the fetch stage status if there was a status change.
931        _status = updateFetchStatus();
932    }
933
934    // Issue the next I-cache request if possible.
935    for (ThreadID i = 0; i < numThreads; ++i) {
936        if (issuePipelinedIfetch[i]) {
937            pipelineIcacheAccesses(i);
938        }
939    }
940
941    // Send instructions enqueued into the fetch queue to decode.
942    // Limit rate by fetchWidth.  Stall if decode is stalled.
943    unsigned insts_to_decode = 0;
944    unsigned available_insts = 0;
945
946    for (auto tid : *activeThreads) {
947        if (!stalls[tid].decode) {
948            available_insts += fetchQueue[tid].size();
949        }
950    }
951
952    // Pick a random thread to start trying to grab instructions from
953    auto tid_itr = activeThreads->begin();
954    std::advance(tid_itr, random_mt.random<uint8_t>(0, activeThreads->size() - 1));
955
956    while (available_insts != 0 && insts_to_decode < decodeWidth) {
957        ThreadID tid = *tid_itr;
958        if (!stalls[tid].decode && !fetchQueue[tid].empty()) {
959            auto inst = fetchQueue[tid].front();
960            toDecode->insts[toDecode->size++] = inst;
961            DPRINTF(Fetch, "[tid:%i][sn:%i]: Sending instruction to decode from "
962                    "fetch queue. Fetch queue size: %i.\n",
963                    tid, inst->seqNum, fetchQueue[tid].size());
964
965            wroteToTimeBuffer = true;
966            fetchQueue[tid].pop_front();
967            insts_to_decode++;
968            available_insts--;
969        }
970
971        tid_itr++;
972        // Wrap around if at end of active threads list
973        if (tid_itr == activeThreads->end())
974            tid_itr = activeThreads->begin();
975    }
976
977    // If there was activity this cycle, inform the CPU of it.
978    if (wroteToTimeBuffer) {
979        DPRINTF(Activity, "Activity this cycle.\n");
980        cpu->activityThisCycle();
981    }
982
983    // Reset the number of the instruction we've fetched.
984    numInst = 0;
985}
986
987template <class Impl>
988bool
989DefaultFetch<Impl>::checkSignalsAndUpdate(ThreadID tid)
990{
991    // Update the per thread stall statuses.
992    if (fromDecode->decodeBlock[tid]) {
993        stalls[tid].decode = true;
994    }
995
996    if (fromDecode->decodeUnblock[tid]) {
997        assert(stalls[tid].decode);
998        assert(!fromDecode->decodeBlock[tid]);
999        stalls[tid].decode = false;
1000    }
1001
1002    // Check squash signals from commit.
1003    if (fromCommit->commitInfo[tid].squash) {
1004
1005        DPRINTF(Fetch, "[tid:%u]: Squashing instructions due to squash "
1006                "from commit.\n",tid);
1007        // In any case, squash.
1008        squash(fromCommit->commitInfo[tid].pc,
1009               fromCommit->commitInfo[tid].doneSeqNum,
1010               fromCommit->commitInfo[tid].squashInst, tid);
1011
1012        // If it was a branch mispredict on a control instruction, update the
1013        // branch predictor with that instruction, otherwise just kill the
1014        // invalid state we generated in after sequence number
1015        if (fromCommit->commitInfo[tid].mispredictInst &&
1016            fromCommit->commitInfo[tid].mispredictInst->isControl()) {
1017            branchPred->squash(fromCommit->commitInfo[tid].doneSeqNum,
1018                              fromCommit->commitInfo[tid].pc,
1019                              fromCommit->commitInfo[tid].branchTaken,
1020                              tid);
1021        } else {
1022            branchPred->squash(fromCommit->commitInfo[tid].doneSeqNum,
1023                              tid);
1024        }
1025
1026        return true;
1027    } else if (fromCommit->commitInfo[tid].doneSeqNum) {
1028        // Update the branch predictor if it wasn't a squashed instruction
1029        // that was broadcasted.
1030        branchPred->update(fromCommit->commitInfo[tid].doneSeqNum, tid);
1031    }
1032
1033    // Check squash signals from decode.
1034    if (fromDecode->decodeInfo[tid].squash) {
1035        DPRINTF(Fetch, "[tid:%u]: Squashing instructions due to squash "
1036                "from decode.\n",tid);
1037
1038        // Update the branch predictor.
1039        if (fromDecode->decodeInfo[tid].branchMispredict) {
1040            branchPred->squash(fromDecode->decodeInfo[tid].doneSeqNum,
1041                              fromDecode->decodeInfo[tid].nextPC,
1042                              fromDecode->decodeInfo[tid].branchTaken,
1043                              tid);
1044        } else {
1045            branchPred->squash(fromDecode->decodeInfo[tid].doneSeqNum,
1046                              tid);
1047        }
1048
1049        if (fetchStatus[tid] != Squashing) {
1050
1051            DPRINTF(Fetch, "Squashing from decode with PC = %s\n",
1052                fromDecode->decodeInfo[tid].nextPC);
1053            // Squash unless we're already squashing
1054            squashFromDecode(fromDecode->decodeInfo[tid].nextPC,
1055                             fromDecode->decodeInfo[tid].squashInst,
1056                             fromDecode->decodeInfo[tid].doneSeqNum,
1057                             tid);
1058
1059            return true;
1060        }
1061    }
1062
1063    if (checkStall(tid) &&
1064        fetchStatus[tid] != IcacheWaitResponse &&
1065        fetchStatus[tid] != IcacheWaitRetry &&
1066        fetchStatus[tid] != ItlbWait &&
1067        fetchStatus[tid] != QuiescePending) {
1068        DPRINTF(Fetch, "[tid:%i]: Setting to blocked\n",tid);
1069
1070        fetchStatus[tid] = Blocked;
1071
1072        return true;
1073    }
1074
1075    if (fetchStatus[tid] == Blocked ||
1076        fetchStatus[tid] == Squashing) {
1077        // Switch status to running if fetch isn't being told to block or
1078        // squash this cycle.
1079        DPRINTF(Fetch, "[tid:%i]: Done squashing, switching to running.\n",
1080                tid);
1081
1082        fetchStatus[tid] = Running;
1083
1084        return true;
1085    }
1086
1087    // If we've reached this point, we have not gotten any signals that
1088    // cause fetch to change its status.  Fetch remains the same as before.
1089    return false;
1090}
1091
1092template<class Impl>
1093typename Impl::DynInstPtr
1094DefaultFetch<Impl>::buildInst(ThreadID tid, StaticInstPtr staticInst,
1095                              StaticInstPtr curMacroop, TheISA::PCState thisPC,
1096                              TheISA::PCState nextPC, bool trace)
1097{
1098    // Get a sequence number.
1099    InstSeqNum seq = cpu->getAndIncrementInstSeq();
1100
1101    // Create a new DynInst from the instruction fetched.
1102    DynInstPtr instruction =
1103        new DynInst(staticInst, curMacroop, thisPC, nextPC, seq, cpu);
1104    instruction->setTid(tid);
1105
1106    instruction->setASID(tid);
1107
1108    instruction->setThreadState(cpu->thread[tid]);
1109
1110    DPRINTF(Fetch, "[tid:%i]: Instruction PC %#x (%d) created "
1111            "[sn:%lli].\n", tid, thisPC.instAddr(),
1112            thisPC.microPC(), seq);
1113
1114    DPRINTF(Fetch, "[tid:%i]: Instruction is: %s\n", tid,
1115            instruction->staticInst->
1116            disassemble(thisPC.instAddr()));
1117
1118#if TRACING_ON
1119    if (trace) {
1120        instruction->traceData =
1121            cpu->getTracer()->getInstRecord(curTick(), cpu->tcBase(tid),
1122                    instruction->staticInst, thisPC, curMacroop);
1123    }
1124#else
1125    instruction->traceData = NULL;
1126#endif
1127
1128    // Add instruction to the CPU's list of instructions.
1129    instruction->setInstListIt(cpu->addInst(instruction));
1130
1131    // Write the instruction to the first slot in the queue
1132    // that heads to decode.
1133    assert(numInst < fetchWidth);
1134    fetchQueue[tid].push_back(instruction);
1135    assert(fetchQueue[tid].size() <= fetchQueueSize);
1136    DPRINTF(Fetch, "[tid:%i]: Fetch queue entry created (%i/%i).\n",
1137            tid, fetchQueue[tid].size(), fetchQueueSize);
1138    //toDecode->insts[toDecode->size++] = instruction;
1139
1140    // Keep track of if we can take an interrupt at this boundary
1141    delayedCommit[tid] = instruction->isDelayedCommit();
1142
1143    return instruction;
1144}
1145
1146template<class Impl>
1147void
1148DefaultFetch<Impl>::fetch(bool &status_change)
1149{
1150    //////////////////////////////////////////
1151    // Start actual fetch
1152    //////////////////////////////////////////
1153    ThreadID tid = getFetchingThread(fetchPolicy);
1154
1155    assert(!cpu->switchedOut());
1156
1157    if (tid == InvalidThreadID) {
1158        // Breaks looping condition in tick()
1159        threadFetched = numFetchingThreads;
1160
1161        if (numThreads == 1) {  // @todo Per-thread stats
1162            profileStall(0);
1163        }
1164
1165        return;
1166    }
1167
1168    DPRINTF(Fetch, "Attempting to fetch from [tid:%i]\n", tid);
1169
1170    // The current PC.
1171    TheISA::PCState thisPC = pc[tid];
1172
1173    Addr pcOffset = fetchOffset[tid];
1174    Addr fetchAddr = (thisPC.instAddr() + pcOffset) & BaseCPU::PCMask;
1175
1176    bool inRom = isRomMicroPC(thisPC.microPC());
1177
1178    // If returning from the delay of a cache miss, then update the status
1179    // to running, otherwise do the cache access.  Possibly move this up
1180    // to tick() function.
1181    if (fetchStatus[tid] == IcacheAccessComplete) {
1182        DPRINTF(Fetch, "[tid:%i]: Icache miss is complete.\n", tid);
1183
1184        fetchStatus[tid] = Running;
1185        status_change = true;
1186    } else if (fetchStatus[tid] == Running) {
1187        // Align the fetch PC so its at the start of a fetch buffer segment.
1188        Addr fetchBufferBlockPC = fetchBufferAlignPC(fetchAddr);
1189
1190        // If buffer is no longer valid or fetchAddr has moved to point
1191        // to the next cache block, AND we have no remaining ucode
1192        // from a macro-op, then start fetch from icache.
1193        if (!(fetchBufferValid[tid] && fetchBufferBlockPC == fetchBufferPC[tid])
1194            && !inRom && !macroop[tid]) {
1195            DPRINTF(Fetch, "[tid:%i]: Attempting to translate and read "
1196                    "instruction, starting at PC %s.\n", tid, thisPC);
1197
1198            fetchCacheLine(fetchAddr, tid, thisPC.instAddr());
1199
1200            if (fetchStatus[tid] == IcacheWaitResponse)
1201                ++icacheStallCycles;
1202            else if (fetchStatus[tid] == ItlbWait)
1203                ++fetchTlbCycles;
1204            else
1205                ++fetchMiscStallCycles;
1206            return;
1207        } else if ((checkInterrupt(thisPC.instAddr()) && !delayedCommit[tid])) {
1208            // Stall CPU if an interrupt is posted and we're not issuing
1209            // an delayed commit micro-op currently (delayed commit instructions
1210            // are not interruptable by interrupts, only faults)
1211            ++fetchMiscStallCycles;
1212            DPRINTF(Fetch, "[tid:%i]: Fetch is stalled!\n", tid);
1213            return;
1214        }
1215    } else {
1216        if (fetchStatus[tid] == Idle) {
1217            ++fetchIdleCycles;
1218            DPRINTF(Fetch, "[tid:%i]: Fetch is idle!\n", tid);
1219        }
1220
1221        // Status is Idle, so fetch should do nothing.
1222        return;
1223    }
1224
1225    ++fetchCycles;
1226
1227    TheISA::PCState nextPC = thisPC;
1228
1229    StaticInstPtr staticInst = NULL;
1230    StaticInstPtr curMacroop = macroop[tid];
1231
1232    // If the read of the first instruction was successful, then grab the
1233    // instructions from the rest of the cache line and put them into the
1234    // queue heading to decode.
1235
1236    DPRINTF(Fetch, "[tid:%i]: Adding instructions to queue to "
1237            "decode.\n", tid);
1238
1239    // Need to keep track of whether or not a predicted branch
1240    // ended this fetch block.
1241    bool predictedBranch = false;
1242
1243    // Need to halt fetch if quiesce instruction detected
1244    bool quiesce = false;
1245
1246    TheISA::MachInst *cacheInsts =
1247        reinterpret_cast<TheISA::MachInst *>(fetchBuffer[tid]);
1248
1249    const unsigned numInsts = fetchBufferSize / instSize;
1250    unsigned blkOffset = (fetchAddr - fetchBufferPC[tid]) / instSize;
1251
1252    // Loop through instruction memory from the cache.
1253    // Keep issuing while fetchWidth is available and branch is not
1254    // predicted taken
1255    while (numInst < fetchWidth && fetchQueue[tid].size() < fetchQueueSize
1256           && !predictedBranch && !quiesce) {
1257        // We need to process more memory if we aren't going to get a
1258        // StaticInst from the rom, the current macroop, or what's already
1259        // in the decoder.
1260        bool needMem = !inRom && !curMacroop &&
1261            !decoder[tid]->instReady();
1262        fetchAddr = (thisPC.instAddr() + pcOffset) & BaseCPU::PCMask;
1263        Addr fetchBufferBlockPC = fetchBufferAlignPC(fetchAddr);
1264
1265        if (needMem) {
1266            // If buffer is no longer valid or fetchAddr has moved to point
1267            // to the next cache block then start fetch from icache.
1268            if (!fetchBufferValid[tid] ||
1269                fetchBufferBlockPC != fetchBufferPC[tid])
1270                break;
1271
1272            if (blkOffset >= numInsts) {
1273                // We need to process more memory, but we've run out of the
1274                // current block.
1275                break;
1276            }
1277
1278            if (ISA_HAS_DELAY_SLOT && pcOffset == 0) {
1279                // Walk past any annulled delay slot instructions.
1280                Addr pcAddr = thisPC.instAddr() & BaseCPU::PCMask;
1281                while (fetchAddr != pcAddr && blkOffset < numInsts) {
1282                    blkOffset++;
1283                    fetchAddr += instSize;
1284                }
1285                if (blkOffset >= numInsts)
1286                    break;
1287            }
1288
1289            MachInst inst = TheISA::gtoh(cacheInsts[blkOffset]);
1290            decoder[tid]->moreBytes(thisPC, fetchAddr, inst);
1291
1292            if (decoder[tid]->needMoreBytes()) {
1293                blkOffset++;
1294                fetchAddr += instSize;
1295                pcOffset += instSize;
1296            }
1297        }
1298
1299        // Extract as many instructions and/or microops as we can from
1300        // the memory we've processed so far.
1301        do {
1302            if (!(curMacroop || inRom)) {
1303                if (decoder[tid]->instReady()) {
1304                    staticInst = decoder[tid]->decode(thisPC);
1305
1306                    // Increment stat of fetched instructions.
1307                    ++fetchedInsts;
1308
1309                    if (staticInst->isMacroop()) {
1310                        curMacroop = staticInst;
1311                    } else {
1312                        pcOffset = 0;
1313                    }
1314                } else {
1315                    // We need more bytes for this instruction so blkOffset and
1316                    // pcOffset will be updated
1317                    break;
1318                }
1319            }
1320            // Whether we're moving to a new macroop because we're at the
1321            // end of the current one, or the branch predictor incorrectly
1322            // thinks we are...
1323            bool newMacro = false;
1324            if (curMacroop || inRom) {
1325                if (inRom) {
1326                    staticInst = cpu->microcodeRom.fetchMicroop(
1327                            thisPC.microPC(), curMacroop);
1328                } else {
1329                    staticInst = curMacroop->fetchMicroop(thisPC.microPC());
1330                }
1331                newMacro |= staticInst->isLastMicroop();
1332            }
1333
1334            DynInstPtr instruction =
1335                buildInst(tid, staticInst, curMacroop,
1336                          thisPC, nextPC, true);
1337
1338            ppFetch->notify(instruction);
1339            numInst++;
1340
1341#if TRACING_ON
1342            if (DTRACE(O3PipeView)) {
1343                instruction->fetchTick = curTick();
1344            }
1345#endif
1346
1347            nextPC = thisPC;
1348
1349            // If we're branching after this instruction, quit fetching
1350            // from the same block.
1351            predictedBranch |= thisPC.branching();
1352            predictedBranch |=
1353                lookupAndUpdateNextPC(instruction, nextPC);
1354            if (predictedBranch) {
1355                DPRINTF(Fetch, "Branch detected with PC = %s\n", thisPC);
1356            }
1357
1358            newMacro |= thisPC.instAddr() != nextPC.instAddr();
1359
1360            // Move to the next instruction, unless we have a branch.
1361            thisPC = nextPC;
1362            inRom = isRomMicroPC(thisPC.microPC());
1363
1364            if (newMacro) {
1365                fetchAddr = thisPC.instAddr() & BaseCPU::PCMask;
1366                blkOffset = (fetchAddr - fetchBufferPC[tid]) / instSize;
1367                pcOffset = 0;
1368                curMacroop = NULL;
1369            }
1370
1371            if (instruction->isQuiesce()) {
1372                DPRINTF(Fetch,
1373                        "Quiesce instruction encountered, halting fetch!\n");
1374                fetchStatus[tid] = QuiescePending;
1375                status_change = true;
1376                quiesce = true;
1377                break;
1378            }
1379        } while ((curMacroop || decoder[tid]->instReady()) &&
1380                 numInst < fetchWidth &&
1381                 fetchQueue[tid].size() < fetchQueueSize);
1382
1383        // Re-evaluate whether the next instruction to fetch is in micro-op ROM
1384        // or not.
1385        inRom = isRomMicroPC(thisPC.microPC());
1386    }
1387
1388    if (predictedBranch) {
1389        DPRINTF(Fetch, "[tid:%i]: Done fetching, predicted branch "
1390                "instruction encountered.\n", tid);
1391    } else if (numInst >= fetchWidth) {
1392        DPRINTF(Fetch, "[tid:%i]: Done fetching, reached fetch bandwidth "
1393                "for this cycle.\n", tid);
1394    } else if (blkOffset >= fetchBufferSize) {
1395        DPRINTF(Fetch, "[tid:%i]: Done fetching, reached the end of the"
1396                "fetch buffer.\n", tid);
1397    }
1398
1399    macroop[tid] = curMacroop;
1400    fetchOffset[tid] = pcOffset;
1401
1402    if (numInst > 0) {
1403        wroteToTimeBuffer = true;
1404    }
1405
1406    pc[tid] = thisPC;
1407
1408    // pipeline a fetch if we're crossing a fetch buffer boundary and not in
1409    // a state that would preclude fetching
1410    fetchAddr = (thisPC.instAddr() + pcOffset) & BaseCPU::PCMask;
1411    Addr fetchBufferBlockPC = fetchBufferAlignPC(fetchAddr);
1412    issuePipelinedIfetch[tid] = fetchBufferBlockPC != fetchBufferPC[tid] &&
1413        fetchStatus[tid] != IcacheWaitResponse &&
1414        fetchStatus[tid] != ItlbWait &&
1415        fetchStatus[tid] != IcacheWaitRetry &&
1416        fetchStatus[tid] != QuiescePending &&
1417        !curMacroop;
1418}
1419
1420template<class Impl>
1421void
1422DefaultFetch<Impl>::recvReqRetry()
1423{
1424    if (retryPkt != NULL) {
1425        assert(cacheBlocked);
1426        assert(retryTid != InvalidThreadID);
1427        assert(fetchStatus[retryTid] == IcacheWaitRetry);
1428
1429        if (cpu->getInstPort().sendTimingReq(retryPkt)) {
1430            fetchStatus[retryTid] = IcacheWaitResponse;
1431            // Notify Fetch Request probe when a retryPkt is successfully sent.
1432            // Note that notify must be called before retryPkt is set to NULL.
1433            ppFetchRequestSent->notify(retryPkt->req);
1434            retryPkt = NULL;
1435            retryTid = InvalidThreadID;
1436            cacheBlocked = false;
1437        }
1438    } else {
1439        assert(retryTid == InvalidThreadID);
1440        // Access has been squashed since it was sent out.  Just clear
1441        // the cache being blocked.
1442        cacheBlocked = false;
1443    }
1444}
1445
1446///////////////////////////////////////
1447//                                   //
1448//  SMT FETCH POLICY MAINTAINED HERE //
1449//                                   //
1450///////////////////////////////////////
1451template<class Impl>
1452ThreadID
1453DefaultFetch<Impl>::getFetchingThread(FetchPriority &fetch_priority)
1454{
1455    if (numThreads > 1) {
1456        switch (fetch_priority) {
1457
1458          case SingleThread:
1459            return 0;
1460
1461          case RoundRobin:
1462            return roundRobin();
1463
1464          case IQ:
1465            return iqCount();
1466
1467          case LSQ:
1468            return lsqCount();
1469
1470          case Branch:
1471            return branchCount();
1472
1473          default:
1474            return InvalidThreadID;
1475        }
1476    } else {
1477        list<ThreadID>::iterator thread = activeThreads->begin();
1478        if (thread == activeThreads->end()) {
1479            return InvalidThreadID;
1480        }
1481
1482        ThreadID tid = *thread;
1483
1484        if (fetchStatus[tid] == Running ||
1485            fetchStatus[tid] == IcacheAccessComplete ||
1486            fetchStatus[tid] == Idle) {
1487            return tid;
1488        } else {
1489            return InvalidThreadID;
1490        }
1491    }
1492}
1493
1494
1495template<class Impl>
1496ThreadID
1497DefaultFetch<Impl>::roundRobin()
1498{
1499    list<ThreadID>::iterator pri_iter = priorityList.begin();
1500    list<ThreadID>::iterator end      = priorityList.end();
1501
1502    ThreadID high_pri;
1503
1504    while (pri_iter != end) {
1505        high_pri = *pri_iter;
1506
1507        assert(high_pri <= numThreads);
1508
1509        if (fetchStatus[high_pri] == Running ||
1510            fetchStatus[high_pri] == IcacheAccessComplete ||
1511            fetchStatus[high_pri] == Idle) {
1512
1513            priorityList.erase(pri_iter);
1514            priorityList.push_back(high_pri);
1515
1516            return high_pri;
1517        }
1518
1519        pri_iter++;
1520    }
1521
1522    return InvalidThreadID;
1523}
1524
1525template<class Impl>
1526ThreadID
1527DefaultFetch<Impl>::iqCount()
1528{
1529    //sorted from lowest->highest
1530    std::priority_queue<unsigned,vector<unsigned>,
1531                        std::greater<unsigned> > PQ;
1532    std::map<unsigned, ThreadID> threadMap;
1533
1534    list<ThreadID>::iterator threads = activeThreads->begin();
1535    list<ThreadID>::iterator end = activeThreads->end();
1536
1537    while (threads != end) {
1538        ThreadID tid = *threads++;
1539        unsigned iqCount = fromIEW->iewInfo[tid].iqCount;
1540
1541        //we can potentially get tid collisions if two threads
1542        //have the same iqCount, but this should be rare.
1543        PQ.push(iqCount);
1544        threadMap[iqCount] = tid;
1545    }
1546
1547    while (!PQ.empty()) {
1548        ThreadID high_pri = threadMap[PQ.top()];
1549
1550        if (fetchStatus[high_pri] == Running ||
1551            fetchStatus[high_pri] == IcacheAccessComplete ||
1552            fetchStatus[high_pri] == Idle)
1553            return high_pri;
1554        else
1555            PQ.pop();
1556
1557    }
1558
1559    return InvalidThreadID;
1560}
1561
1562template<class Impl>
1563ThreadID
1564DefaultFetch<Impl>::lsqCount()
1565{
1566    //sorted from lowest->highest
1567    std::priority_queue<unsigned,vector<unsigned>,
1568                        std::greater<unsigned> > PQ;
1569    std::map<unsigned, ThreadID> threadMap;
1570
1571    list<ThreadID>::iterator threads = activeThreads->begin();
1572    list<ThreadID>::iterator end = activeThreads->end();
1573
1574    while (threads != end) {
1575        ThreadID tid = *threads++;
1576        unsigned ldstqCount = fromIEW->iewInfo[tid].ldstqCount;
1577
1578        //we can potentially get tid collisions if two threads
1579        //have the same iqCount, but this should be rare.
1580        PQ.push(ldstqCount);
1581        threadMap[ldstqCount] = tid;
1582    }
1583
1584    while (!PQ.empty()) {
1585        ThreadID high_pri = threadMap[PQ.top()];
1586
1587        if (fetchStatus[high_pri] == Running ||
1588            fetchStatus[high_pri] == IcacheAccessComplete ||
1589            fetchStatus[high_pri] == Idle)
1590            return high_pri;
1591        else
1592            PQ.pop();
1593    }
1594
1595    return InvalidThreadID;
1596}
1597
1598template<class Impl>
1599ThreadID
1600DefaultFetch<Impl>::branchCount()
1601{
1602#if 0
1603    list<ThreadID>::iterator thread = activeThreads->begin();
1604    assert(thread != activeThreads->end());
1605    ThreadID tid = *thread;
1606#endif
1607
1608    panic("Branch Count Fetch policy unimplemented\n");
1609    return InvalidThreadID;
1610}
1611
1612template<class Impl>
1613void
1614DefaultFetch<Impl>::pipelineIcacheAccesses(ThreadID tid)
1615{
1616    if (!issuePipelinedIfetch[tid]) {
1617        return;
1618    }
1619
1620    // The next PC to access.
1621    TheISA::PCState thisPC = pc[tid];
1622
1623    if (isRomMicroPC(thisPC.microPC())) {
1624        return;
1625    }
1626
1627    Addr pcOffset = fetchOffset[tid];
1628    Addr fetchAddr = (thisPC.instAddr() + pcOffset) & BaseCPU::PCMask;
1629
1630    // Align the fetch PC so its at the start of a fetch buffer segment.
1631    Addr fetchBufferBlockPC = fetchBufferAlignPC(fetchAddr);
1632
1633    // Unless buffer already got the block, fetch it from icache.
1634    if (!(fetchBufferValid[tid] && fetchBufferBlockPC == fetchBufferPC[tid])) {
1635        DPRINTF(Fetch, "[tid:%i]: Issuing a pipelined I-cache access, "
1636                "starting at PC %s.\n", tid, thisPC);
1637
1638        fetchCacheLine(fetchAddr, tid, thisPC.instAddr());
1639    }
1640}
1641
1642template<class Impl>
1643void
1644DefaultFetch<Impl>::profileStall(ThreadID tid) {
1645    DPRINTF(Fetch,"There are no more threads available to fetch from.\n");
1646
1647    // @todo Per-thread stats
1648
1649    if (stalls[tid].drain) {
1650        ++fetchPendingDrainCycles;
1651        DPRINTF(Fetch, "Fetch is waiting for a drain!\n");
1652    } else if (activeThreads->empty()) {
1653        ++fetchNoActiveThreadStallCycles;
1654        DPRINTF(Fetch, "Fetch has no active thread!\n");
1655    } else if (fetchStatus[tid] == Blocked) {
1656        ++fetchBlockedCycles;
1657        DPRINTF(Fetch, "[tid:%i]: Fetch is blocked!\n", tid);
1658    } else if (fetchStatus[tid] == Squashing) {
1659        ++fetchSquashCycles;
1660        DPRINTF(Fetch, "[tid:%i]: Fetch is squashing!\n", tid);
1661    } else if (fetchStatus[tid] == IcacheWaitResponse) {
1662        ++icacheStallCycles;
1663        DPRINTF(Fetch, "[tid:%i]: Fetch is waiting cache response!\n",
1664                tid);
1665    } else if (fetchStatus[tid] == ItlbWait) {
1666        ++fetchTlbCycles;
1667        DPRINTF(Fetch, "[tid:%i]: Fetch is waiting ITLB walk to "
1668                "finish!\n", tid);
1669    } else if (fetchStatus[tid] == TrapPending) {
1670        ++fetchPendingTrapStallCycles;
1671        DPRINTF(Fetch, "[tid:%i]: Fetch is waiting for a pending trap!\n",
1672                tid);
1673    } else if (fetchStatus[tid] == QuiescePending) {
1674        ++fetchPendingQuiesceStallCycles;
1675        DPRINTF(Fetch, "[tid:%i]: Fetch is waiting for a pending quiesce "
1676                "instruction!\n", tid);
1677    } else if (fetchStatus[tid] == IcacheWaitRetry) {
1678        ++fetchIcacheWaitRetryStallCycles;
1679        DPRINTF(Fetch, "[tid:%i]: Fetch is waiting for an I-cache retry!\n",
1680                tid);
1681    } else if (fetchStatus[tid] == NoGoodAddr) {
1682            DPRINTF(Fetch, "[tid:%i]: Fetch predicted non-executable address\n",
1683                    tid);
1684    } else {
1685        DPRINTF(Fetch, "[tid:%i]: Unexpected fetch stall reason (Status: %i).\n",
1686             tid, fetchStatus[tid]);
1687    }
1688}
1689
1690#endif//__CPU_O3_FETCH_IMPL_HH__
1691