iew_impl.hh revision 2292
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29// @todo: Fix the instantaneous communication among all the stages within
30// iew.  There's a clear delay between issue and execute, yet backwards
31// communication happens simultaneously.
32
33#include <queue>
34
35#include "base/timebuf.hh"
36#include "cpu/o3/fu_pool.hh"
37#include "cpu/o3/iew.hh"
38
39using namespace std;
40
41template<class Impl>
42DefaultIEW<Impl>::LdWritebackEvent::LdWritebackEvent(DynInstPtr &_inst,
43                                                     DefaultIEW<Impl> *_iew)
44    : Event(&mainEventQueue), inst(_inst), iewStage(_iew)
45{
46    this->setFlags(Event::AutoDelete);
47}
48
49template<class Impl>
50void
51DefaultIEW<Impl>::LdWritebackEvent::process()
52{
53    DPRINTF(IEW, "Load writeback event [sn:%lli]\n", inst->seqNum);
54    DPRINTF(Activity, "Activity: Ld Writeback event [sn:%lli]\n", inst->seqNum);
55
56    //iewStage->ldstQueue.removeMSHR(inst->threadNumber,inst->seqNum);
57
58    iewStage->wakeCPU();
59
60    if (inst->isSquashed()) {
61        inst = NULL;
62        return;
63    }
64
65    if (!inst->isExecuted()) {
66        inst->setExecuted();
67
68        // Execute again to copy data to proper place.
69        if (inst->isStore()) {
70            inst->completeAcc();
71        }
72    }
73
74    // Need to insert instruction into queue to commit
75    iewStage->instToCommit(inst);
76
77    //wroteToTimeBuffer = true;
78    iewStage->activityThisCycle();
79
80    inst = NULL;
81}
82
83template<class Impl>
84const char *
85DefaultIEW<Impl>::LdWritebackEvent::description()
86{
87    return "Load writeback event";
88}
89
90template<class Impl>
91DefaultIEW<Impl>::DefaultIEW(Params *params)
92    : // Just make this time buffer really big for now
93    // @todo: Make this into a parameter.
94      issueToExecQueue(5, 5),
95      instQueue(params),
96      ldstQueue(params),
97      fuPool(params->fuPool),
98      commitToIEWDelay(params->commitToIEWDelay),
99      renameToIEWDelay(params->renameToIEWDelay),
100      issueToExecuteDelay(params->issueToExecuteDelay),
101      issueReadWidth(params->issueWidth),
102      issueWidth(params->issueWidth),
103      executeWidth(params->executeWidth),
104      numThreads(params->numberOfThreads)
105{
106    DPRINTF(IEW, "executeIntWidth: %i.\n", params->executeIntWidth);
107    _status = Active;
108    exeStatus = Running;
109    wbStatus = Idle;
110
111    // Setup wire to read instructions coming from issue.
112    fromIssue = issueToExecQueue.getWire(-issueToExecuteDelay);
113
114    // Instruction queue needs the queue between issue and execute.
115    instQueue.setIssueToExecuteQueue(&issueToExecQueue);
116
117    instQueue.setIEW(this);
118    ldstQueue.setIEW(this);
119
120    for (int i=0; i < numThreads; i++) {
121        dispatchStatus[i] = Running;
122        stalls[i].commit = false;
123        fetchRedirect[i] = false;
124    }
125
126    updateLSQNextCycle = false;
127
128    // @todo: Make into a parameter
129    skidBufferMax = (3 * (renameToIEWDelay * params->renameWidth)) + issueWidth;
130}
131
132template <class Impl>
133std::string
134DefaultIEW<Impl>::name() const
135{
136    return cpu->name() + ".iew";
137}
138
139template <class Impl>
140void
141DefaultIEW<Impl>::regStats()
142{
143    instQueue.regStats();
144
145    //ldstQueue.regStats();
146
147    iewIdleCycles
148        .name(name() + ".iewIdleCycles")
149        .desc("Number of cycles IEW is idle");
150
151    iewSquashCycles
152        .name(name() + ".iewSquashCycles")
153        .desc("Number of cycles IEW is squashing");
154
155    iewBlockCycles
156        .name(name() + ".iewBlockCycles")
157        .desc("Number of cycles IEW is blocking");
158
159    iewUnblockCycles
160        .name(name() + ".iewUnblockCycles")
161        .desc("Number of cycles IEW is unblocking");
162
163//    iewWBInsts;
164
165    iewDispatchedInsts
166        .name(name() + ".iewDispatchedInsts")
167        .desc("Number of instructions dispatched to IQ");
168
169    iewDispSquashedInsts
170        .name(name() + ".iewDispSquashedInsts")
171        .desc("Number of squashed instructions skipped by dispatch");
172
173    iewDispLoadInsts
174        .name(name() + ".iewDispLoadInsts")
175        .desc("Number of dispatched load instructions");
176
177    iewDispStoreInsts
178        .name(name() + ".iewDispStoreInsts")
179        .desc("Number of dispatched store instructions");
180
181    iewDispNonSpecInsts
182        .name(name() + ".iewDispNonSpecInsts")
183        .desc("Number of dispatched non-speculative instructions");
184
185    iewIQFullEvents
186        .name(name() + ".iewIQFullEvents")
187        .desc("Number of times the IQ has become full, causing a stall");
188
189    iewLSQFullEvents
190        .name(name() + ".iewLSQFullEvents")
191        .desc("Number of times the LSQ has become full, causing a stall");
192
193    iewExecutedInsts
194        .name(name() + ".iewExecutedInsts")
195        .desc("Number of executed instructions");
196
197    iewExecLoadInsts
198        .name(name() + ".iewExecLoadInsts")
199        .desc("Number of load instructions executed");
200
201    iewExecStoreInsts
202        .name(name() + ".iewExecStoreInsts")
203        .desc("Number of store instructions executed");
204
205    iewExecSquashedInsts
206        .name(name() + ".iewExecSquashedInsts")
207        .desc("Number of squashed instructions skipped in execute");
208
209    memOrderViolationEvents
210        .name(name() + ".memOrderViolationEvents")
211        .desc("Number of memory order violations");
212
213    predictedTakenIncorrect
214        .name(name() + ".predictedTakenIncorrect")
215        .desc("Number of branches that were predicted taken incorrectly");
216
217    predictedNotTakenIncorrect
218        .name(name() + ".predictedNotTakenIncorrect")
219        .desc("Number of branches that were predicted not taken incorrectly");
220
221    branchMispredicts
222        .name(name() + ".branchMispredicts")
223        .desc("Number of branch mispredicts detected at execute");
224
225    branchMispredicts = predictedTakenIncorrect + predictedNotTakenIncorrect;
226}
227
228template<class Impl>
229void
230DefaultIEW<Impl>::initStage()
231{
232    for (int tid=0; tid < numThreads; tid++) {
233        toRename->iewInfo[tid].usedIQ = true;
234        toRename->iewInfo[tid].freeIQEntries =
235            instQueue.numFreeEntries(tid);
236
237        toRename->iewInfo[tid].usedLSQ = true;
238        toRename->iewInfo[tid].freeLSQEntries =
239            ldstQueue.numFreeEntries(tid);
240    }
241}
242
243template<class Impl>
244void
245DefaultIEW<Impl>::setCPU(FullCPU *cpu_ptr)
246{
247    DPRINTF(IEW, "Setting CPU pointer.\n");
248    cpu = cpu_ptr;
249
250    instQueue.setCPU(cpu_ptr);
251    ldstQueue.setCPU(cpu_ptr);
252
253    cpu->activateStage(FullCPU::IEWIdx);
254}
255
256template<class Impl>
257void
258DefaultIEW<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
259{
260    DPRINTF(IEW, "Setting time buffer pointer.\n");
261    timeBuffer = tb_ptr;
262
263    // Setup wire to read information from time buffer, from commit.
264    fromCommit = timeBuffer->getWire(-commitToIEWDelay);
265
266    // Setup wire to write information back to previous stages.
267    toRename = timeBuffer->getWire(0);
268
269    toFetch = timeBuffer->getWire(0);
270
271    // Instruction queue also needs main time buffer.
272    instQueue.setTimeBuffer(tb_ptr);
273}
274
275template<class Impl>
276void
277DefaultIEW<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
278{
279    DPRINTF(IEW, "Setting rename queue pointer.\n");
280    renameQueue = rq_ptr;
281
282    // Setup wire to read information from rename queue.
283    fromRename = renameQueue->getWire(-renameToIEWDelay);
284}
285
286template<class Impl>
287void
288DefaultIEW<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr)
289{
290    DPRINTF(IEW, "Setting IEW queue pointer.\n");
291    iewQueue = iq_ptr;
292
293    // Setup wire to write instructions to commit.
294    toCommit = iewQueue->getWire(0);
295}
296
297template<class Impl>
298void
299DefaultIEW<Impl>::setActiveThreads(list<unsigned> *at_ptr)
300{
301    DPRINTF(IEW, "Setting active threads list pointer.\n");
302    activeThreads = at_ptr;
303
304    ldstQueue.setActiveThreads(at_ptr);
305    instQueue.setActiveThreads(at_ptr);
306}
307
308template<class Impl>
309void
310DefaultIEW<Impl>::setScoreboard(Scoreboard *sb_ptr)
311{
312    DPRINTF(IEW, "Setting scoreboard pointer.\n");
313    scoreboard = sb_ptr;
314}
315
316#if 0
317template<class Impl>
318void
319DefaultIEW<Impl>::setPageTable(PageTable *pt_ptr)
320{
321    ldstQueue.setPageTable(pt_ptr);
322}
323#endif
324
325template<class Impl>
326void
327DefaultIEW<Impl>::squash(unsigned tid)
328{
329    DPRINTF(IEW, "[tid:%i]: Squashing all instructions.\n",
330            tid);
331
332    // Tell the IQ to start squashing.
333    instQueue.squash(tid);
334
335    // Tell the LDSTQ to start squashing.
336    ldstQueue.squash(fromCommit->commitInfo[tid].doneSeqNum,tid);
337
338    updatedQueues = true;
339
340    // Clear the skid buffer in case it has any data in it.
341    while (!skidBuffer[tid].empty()) {
342
343        if (skidBuffer[tid].front()->isLoad() ||
344            skidBuffer[tid].front()->isStore() ) {
345            toRename->iewInfo[tid].dispatchedToLSQ++;
346        }
347
348        toRename->iewInfo[tid].dispatched++;
349
350        skidBuffer[tid].pop();
351    }
352
353    while (!insts[tid].empty()) {
354        if (insts[tid].front()->isLoad() ||
355            insts[tid].front()->isStore() ) {
356            toRename->iewInfo[tid].dispatchedToLSQ++;
357        }
358
359        toRename->iewInfo[tid].dispatched++;
360
361        insts[tid].pop();
362    }
363}
364
365template<class Impl>
366void
367DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, unsigned tid)
368{
369    DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, PC: %#x "
370            "[sn:%i].\n", tid, inst->readPC(), inst->seqNum);
371
372    // Tell rename to squash through the time buffer.
373    toCommit->squash[tid] = true;
374    toCommit->squashedSeqNum[tid] = inst->seqNum;
375    toCommit->mispredPC[tid] = inst->readPC();
376    toCommit->nextPC[tid] = inst->readNextPC();
377    toCommit->branchMispredict[tid] = true;
378    // Prediction was incorrect, so send back inverse.
379    toCommit->branchTaken[tid] = inst->readNextPC() !=
380        (inst->readPC() + sizeof(TheISA::MachInst));
381
382    toCommit->includeSquashInst[tid] = false;
383    //toCommit->iewSquashNum[tid] = inst->seqNum;
384
385    wroteToTimeBuffer = true;
386}
387
388template<class Impl>
389void
390DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, unsigned tid)
391{
392    DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, "
393            "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum);
394
395    // Tell rename to squash through the time buffer.
396    toCommit->squash[tid] = true;
397    toCommit->squashedSeqNum[tid] = inst->seqNum;
398    toCommit->nextPC[tid] = inst->readNextPC();
399
400    toCommit->includeSquashInst[tid] = false;
401    //toCommit->iewSquashNum[tid] = inst->seqNum;
402
403    wroteToTimeBuffer = true;
404}
405
406template<class Impl>
407void
408DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, unsigned tid)
409{
410    DPRINTF(IEW, "[tid:%i]: Memory blocked, squashing load and younger insts, "
411            "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum);
412
413    toCommit->squash[tid] = true;
414    toCommit->squashedSeqNum[tid] = inst->seqNum;
415    toCommit->nextPC[tid] = inst->readPC();
416
417    toCommit->includeSquashInst[tid] = true;
418
419    ldstQueue.setLoadBlockedHandled(tid);
420
421    wroteToTimeBuffer = true;
422}
423
424template<class Impl>
425void
426DefaultIEW<Impl>::block(unsigned tid)
427{
428    DPRINTF(IEW, "[tid:%u]: Blocking.\n", tid);
429
430    if (dispatchStatus[tid] != Blocked &&
431        dispatchStatus[tid] != Unblocking) {
432        toRename->iewBlock[tid] = true;
433        wroteToTimeBuffer = true;
434    }
435
436    // Add the current inputs to the skid buffer so they can be
437    // reprocessed when this stage unblocks.
438    skidInsert(tid);
439
440    // Set the status to Blocked.
441    dispatchStatus[tid] = Blocked;
442}
443
444template<class Impl>
445void
446DefaultIEW<Impl>::unblock(unsigned tid)
447{
448    DPRINTF(IEW, "[tid:%i]: Reading instructions out of the skid "
449            "buffer %u.\n",tid, tid);
450
451    // If the skid bufffer is empty, signal back to previous stages to unblock.
452    // Also switch status to running.
453    if (skidBuffer[tid].empty()) {
454        toRename->iewUnblock[tid] = true;
455        wroteToTimeBuffer = true;
456        DPRINTF(IEW, "[tid:%i]: Done unblocking.\n",tid);
457        dispatchStatus[tid] = Running;
458    }
459}
460
461template<class Impl>
462void
463DefaultIEW<Impl>::wakeDependents(DynInstPtr &inst)
464{
465    instQueue.wakeDependents(inst);
466}
467
468template<class Impl>
469void
470DefaultIEW<Impl>::rescheduleMemInst(DynInstPtr &inst)
471{
472    instQueue.rescheduleMemInst(inst);
473}
474
475template<class Impl>
476void
477DefaultIEW<Impl>::replayMemInst(DynInstPtr &inst)
478{
479    instQueue.replayMemInst(inst);
480}
481
482template<class Impl>
483void
484DefaultIEW<Impl>::instToCommit(DynInstPtr &inst)
485{
486    // First check the time slot that this instruction will write
487    // to.  If there are free write ports at the time, then go ahead
488    // and write the instruction to that time.  If there are not,
489    // keep looking back to see where's the first time there's a
490    // free slot.  What happens if you run out of free spaces?
491    // For now naively assume that all instructions take one cycle.
492    // Otherwise would have to look into the time buffer based on the
493    // latency of the instruction.
494    while ((*iewQueue)[wbCycle].insts[wbNumInst]) {
495        ++wbNumInst;
496        if (wbNumInst == issueWidth) {
497            ++wbCycle;
498            wbNumInst = 0;
499        }
500
501        assert(wbCycle < 5);
502    }
503
504    // Add finished instruction to queue to commit.
505    (*iewQueue)[wbCycle].insts[wbNumInst] = inst;
506    (*iewQueue)[wbCycle].size++;
507}
508
509template <class Impl>
510unsigned
511DefaultIEW<Impl>::validInstsFromRename()
512{
513    unsigned inst_count = 0;
514
515    for (int i=0; i<fromRename->size; i++) {
516        if (!fromRename->insts[i]->squashed)
517            inst_count++;
518    }
519
520    return inst_count;
521}
522
523template<class Impl>
524void
525DefaultIEW<Impl>::skidInsert(unsigned tid)
526{
527    DynInstPtr inst = NULL;
528
529    while (!insts[tid].empty()) {
530        inst = insts[tid].front();
531
532        insts[tid].pop();
533
534        DPRINTF(Decode,"[tid:%i]: Inserting [sn:%lli] PC:%#x into "
535                "dispatch skidBuffer %i\n",tid, inst->seqNum,
536                inst->readPC(),tid);
537
538        skidBuffer[tid].push(inst);
539    }
540
541    assert(skidBuffer[tid].size() <= skidBufferMax &&
542           "Skidbuffer Exceeded Max Size");
543}
544
545template<class Impl>
546int
547DefaultIEW<Impl>::skidCount()
548{
549    int max=0;
550
551    list<unsigned>::iterator threads = (*activeThreads).begin();
552
553    while (threads != (*activeThreads).end()) {
554        unsigned thread_count = skidBuffer[*threads++].size();
555        if (max < thread_count)
556            max = thread_count;
557    }
558
559    return max;
560}
561
562template<class Impl>
563bool
564DefaultIEW<Impl>::skidsEmpty()
565{
566    list<unsigned>::iterator threads = (*activeThreads).begin();
567
568    while (threads != (*activeThreads).end()) {
569        if (!skidBuffer[*threads++].empty())
570            return false;
571    }
572
573    return true;
574}
575
576template <class Impl>
577void
578DefaultIEW<Impl>::updateStatus()
579{
580    bool any_unblocking = false;
581
582    list<unsigned>::iterator threads = (*activeThreads).begin();
583
584    threads = (*activeThreads).begin();
585
586    while (threads != (*activeThreads).end()) {
587        unsigned tid = *threads++;
588
589        if (dispatchStatus[tid] == Unblocking) {
590            any_unblocking = true;
591            break;
592        }
593    }
594
595    // If there are no ready instructions waiting to be scheduled by the IQ,
596    // and there's no stores waiting to write back, and dispatch is not
597    // unblocking, then there is no internal activity for the IEW stage.
598    if (_status == Active && !instQueue.hasReadyInsts() &&
599        !ldstQueue.willWB() && !any_unblocking) {
600        DPRINTF(IEW, "IEW switching to idle\n");
601
602        deactivateStage();
603
604        _status = Inactive;
605    } else if (_status == Inactive && (instQueue.hasReadyInsts() ||
606                                       ldstQueue.willWB() ||
607                                       any_unblocking)) {
608        // Otherwise there is internal activity.  Set to active.
609        DPRINTF(IEW, "IEW switching to active\n");
610
611        activateStage();
612
613        _status = Active;
614    }
615}
616
617template <class Impl>
618void
619DefaultIEW<Impl>::resetEntries()
620{
621    instQueue.resetEntries();
622    ldstQueue.resetEntries();
623}
624
625template <class Impl>
626void
627DefaultIEW<Impl>::readStallSignals(unsigned tid)
628{
629    if (fromCommit->commitBlock[tid]) {
630        stalls[tid].commit = true;
631    }
632
633    if (fromCommit->commitUnblock[tid]) {
634        assert(stalls[tid].commit);
635        stalls[tid].commit = false;
636    }
637}
638
639template <class Impl>
640bool
641DefaultIEW<Impl>::checkStall(unsigned tid)
642{
643    bool ret_val(false);
644
645    if (stalls[tid].commit) {
646        DPRINTF(IEW,"[tid:%i]: Stall from Commit stage detected.\n",tid);
647        ret_val = true;
648    } else if (instQueue.isFull(tid)) {
649        DPRINTF(IEW,"[tid:%i]: Stall: IQ  is full.\n",tid);
650        ret_val = true;
651    } else if (ldstQueue.isFull(tid)) {
652        DPRINTF(IEW,"[tid:%i]: Stall: LSQ is full\n",tid);
653
654        if (ldstQueue.numLoads(tid) > 0 ) {
655
656            DPRINTF(IEW,"[tid:%i]: LSQ oldest load: [sn:%i] \n",
657                    tid,ldstQueue.getLoadHeadSeqNum(tid));
658        }
659
660        if (ldstQueue.numStores(tid) > 0) {
661
662            DPRINTF(IEW,"[tid:%i]: LSQ oldest store: [sn:%i] \n",
663                    tid,ldstQueue.getStoreHeadSeqNum(tid));
664        }
665
666        ret_val = true;
667    } else if (ldstQueue.isStalled(tid)) {
668        DPRINTF(IEW,"[tid:%i]: Stall: LSQ stall detected.\n",tid);
669        ret_val = true;
670    }
671
672    return ret_val;
673}
674
675template <class Impl>
676void
677DefaultIEW<Impl>::checkSignalsAndUpdate(unsigned tid)
678{
679    // Check if there's a squash signal, squash if there is
680    // Check stall signals, block if there is.
681    // If status was Blocked
682    //     if so then go to unblocking
683    // If status was Squashing
684    //     check if squashing is not high.  Switch to running this cycle.
685
686    readStallSignals(tid);
687
688    if (fromCommit->commitInfo[tid].squash) {
689        squash(tid);
690
691        if (dispatchStatus[tid] == Blocked ||
692            dispatchStatus[tid] == Unblocking) {
693            toRename->iewUnblock[tid] = true;
694            wroteToTimeBuffer = true;
695        }
696
697        dispatchStatus[tid] = Squashing;
698
699        fetchRedirect[tid] = false;
700        return;
701    }
702
703    if (fromCommit->commitInfo[tid].robSquashing) {
704        DPRINTF(IEW, "[tid:%i]: ROB is still squashing.\n");
705
706        dispatchStatus[tid] = Squashing;
707
708        return;
709    }
710
711    if (checkStall(tid)) {
712        block(tid);
713        dispatchStatus[tid] = Blocked;
714        return;
715    }
716
717    if (dispatchStatus[tid] == Blocked) {
718        // Status from previous cycle was blocked, but there are no more stall
719        // conditions.  Switch over to unblocking.
720        DPRINTF(IEW, "[tid:%i]: Done blocking, switching to unblocking.\n",
721                tid);
722
723        dispatchStatus[tid] = Unblocking;
724
725        unblock(tid);
726
727        return;
728    }
729
730    if (dispatchStatus[tid] == Squashing) {
731        // Switch status to running if rename isn't being told to block or
732        // squash this cycle.
733        DPRINTF(IEW, "[tid:%i]: Done squashing, switching to running.\n",
734                tid);
735
736        dispatchStatus[tid] = Running;
737
738        return;
739    }
740}
741
742template <class Impl>
743void
744DefaultIEW<Impl>::sortInsts()
745{
746    int insts_from_rename = fromRename->size;
747
748    for (int i = 0; i < numThreads; i++)
749        assert(insts[i].empty());
750
751    for (int i = 0; i < insts_from_rename; ++i) {
752        insts[fromRename->insts[i]->threadNumber].push(fromRename->insts[i]);
753    }
754}
755
756template <class Impl>
757void
758DefaultIEW<Impl>::wakeCPU()
759{
760    cpu->wakeCPU();
761}
762
763template <class Impl>
764void
765DefaultIEW<Impl>::activityThisCycle()
766{
767    DPRINTF(Activity, "Activity this cycle.\n");
768    cpu->activityThisCycle();
769}
770
771template <class Impl>
772inline void
773DefaultIEW<Impl>::activateStage()
774{
775    DPRINTF(Activity, "Activating stage.\n");
776    cpu->activateStage(FullCPU::IEWIdx);
777}
778
779template <class Impl>
780inline void
781DefaultIEW<Impl>::deactivateStage()
782{
783    DPRINTF(Activity, "Deactivating stage.\n");
784    cpu->deactivateStage(FullCPU::IEWIdx);
785}
786
787template<class Impl>
788void
789DefaultIEW<Impl>::dispatch(unsigned tid)
790{
791    // If status is Running or idle,
792    //     call dispatchInsts()
793    // If status is Unblocking,
794    //     buffer any instructions coming from rename
795    //     continue trying to empty skid buffer
796    //     check if stall conditions have passed
797
798    if (dispatchStatus[tid] == Blocked) {
799        ++iewBlockCycles;
800
801    } else if (dispatchStatus[tid] == Squashing) {
802        ++iewSquashCycles;
803    }
804
805    // Dispatch should try to dispatch as many instructions as its bandwidth
806    // will allow, as long as it is not currently blocked.
807    if (dispatchStatus[tid] == Running ||
808        dispatchStatus[tid] == Idle) {
809        DPRINTF(IEW, "[tid:%i] Not blocked, so attempting to run "
810                "dispatch.\n", tid);
811
812        dispatchInsts(tid);
813    } else if (dispatchStatus[tid] == Unblocking) {
814        // Make sure that the skid buffer has something in it if the
815        // status is unblocking.
816        assert(!skidsEmpty());
817
818        // If the status was unblocking, then instructions from the skid
819        // buffer were used.  Remove those instructions and handle
820        // the rest of unblocking.
821        dispatchInsts(tid);
822
823        ++iewUnblockCycles;
824
825        if (validInstsFromRename() && dispatchedAllInsts) {
826            // Add the current inputs to the skid buffer so they can be
827            // reprocessed when this stage unblocks.
828            skidInsert(tid);
829        }
830
831        unblock(tid);
832    }
833}
834
835template <class Impl>
836void
837DefaultIEW<Impl>::dispatchInsts(unsigned tid)
838{
839    dispatchedAllInsts = true;
840
841    // Obtain instructions from skid buffer if unblocking, or queue from rename
842    // otherwise.
843    std::queue<DynInstPtr> &insts_to_dispatch =
844        dispatchStatus[tid] == Unblocking ?
845        skidBuffer[tid] : insts[tid];
846
847    int insts_to_add = insts_to_dispatch.size();
848
849    DynInstPtr inst;
850    bool add_to_iq = false;
851    int dis_num_inst = 0;
852
853    // Loop through the instructions, putting them in the instruction
854    // queue.
855    for ( ; dis_num_inst < insts_to_add &&
856              dis_num_inst < issueReadWidth;
857          ++dis_num_inst)
858    {
859        inst = insts_to_dispatch.front();
860
861        if (dispatchStatus[tid] == Unblocking) {
862            DPRINTF(IEW, "[tid:%i]: Issue: Examining instruction from skid "
863                    "buffer\n", tid);
864        }
865
866        // Make sure there's a valid instruction there.
867        assert(inst);
868
869        DPRINTF(IEW, "[tid:%i]: Issue: Adding PC %#x [sn:%lli] [tid:%i] to "
870                "IQ.\n",
871                tid, inst->readPC(), inst->seqNum, inst->threadNumber);
872
873        // Be sure to mark these instructions as ready so that the
874        // commit stage can go ahead and execute them, and mark
875        // them as issued so the IQ doesn't reprocess them.
876        // -------------
877        // @TODO: What happens if the ldstqueue is full?
878        //        Do we process the other instructions?
879
880        // Check for squashed instructions.
881        if (inst->isSquashed()) {
882            DPRINTF(IEW, "[tid:%i]: Issue: Squashed instruction encountered, "
883                    "not adding to IQ.\n", tid);
884
885            ++iewDispSquashedInsts;
886
887            insts_to_dispatch.pop();
888
889            //Tell Rename That An Instruction has been processed
890            if (inst->isLoad() || inst->isStore()) {
891                toRename->iewInfo[tid].dispatchedToLSQ++;
892            }
893            toRename->iewInfo[tid].dispatched++;
894
895            continue;
896        }
897
898        // Check for full conditions.
899        if (instQueue.isFull(tid)) {
900            DPRINTF(IEW, "[tid:%i]: Issue: IQ has become full.\n", tid);
901
902            // Call function to start blocking.
903            block(tid);
904
905            // Set unblock to false. Special case where we are using
906            // skidbuffer (unblocking) instructions but then we still
907            // get full in the IQ.
908            toRename->iewUnblock[tid] = false;
909
910            dispatchedAllInsts = false;
911
912            ++iewIQFullEvents;
913            break;
914        } else if (ldstQueue.isFull(tid)) {
915            DPRINTF(IEW, "[tid:%i]: Issue: LSQ has become full.\n",tid);
916
917            // Call function to start blocking.
918            block(tid);
919
920            // Set unblock to false. Special case where we are using
921            // skidbuffer (unblocking) instructions but then we still
922            // get full in the IQ.
923            toRename->iewUnblock[tid] = false;
924
925            dispatchedAllInsts = false;
926
927            ++iewLSQFullEvents;
928            break;
929        }
930
931        // Otherwise issue the instruction just fine.
932        if (inst->isLoad()) {
933            DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction "
934                    "encountered, adding to LSQ.\n", tid);
935
936            // Reserve a spot in the load store queue for this
937            // memory access.
938            ldstQueue.insertLoad(inst);
939
940            ++iewDispLoadInsts;
941
942            add_to_iq = true;
943
944            toRename->iewInfo[tid].dispatchedToLSQ++;
945        } else if (inst->isStore()) {
946            DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction "
947                    "encountered, adding to LSQ.\n", tid);
948
949            ldstQueue.insertStore(inst);
950
951            ++iewDispStoreInsts;
952
953            if (inst->isNonSpeculative()) {
954                inst->setCanCommit();
955                instQueue.insertNonSpec(inst);
956                add_to_iq = false;
957
958                ++iewDispNonSpecInsts;
959            } else {
960                add_to_iq = true;
961            }
962
963            toRename->iewInfo[tid].dispatchedToLSQ++;
964#if FULL_SYSTEM
965        } else if (inst->isMemBarrier() || inst->isWriteBarrier()) {
966            inst->setCanCommit();
967            instQueue.insertBarrier(inst);
968            add_to_iq = false;
969#endif
970        } else if (inst->isNonSpeculative()) {
971            DPRINTF(IEW, "[tid:%i]: Issue: Nonspeculative instruction "
972                    "encountered, skipping.\n", tid);
973
974            // Same hack as with stores.
975            inst->setCanCommit();
976
977            // Specifically insert it as nonspeculative.
978            instQueue.insertNonSpec(inst);
979
980            ++iewDispNonSpecInsts;
981
982            add_to_iq = false;
983        } else if (inst->isNop()) {
984            DPRINTF(IEW, "[tid:%i]: Issue: Nop instruction encountered, "
985                    "skipping.\n", tid);
986
987            inst->setIssued();
988            inst->setExecuted();
989            inst->setCanCommit();
990
991            instQueue.advanceTail(inst);
992
993            add_to_iq = false;
994        } else if (inst->isExecuted()) {
995            assert(0 && "Instruction shouldn't be executed.\n");
996            DPRINTF(IEW, "Issue: Executed branch encountered, "
997                    "skipping.\n");
998
999            inst->setIssued();
1000            inst->setCanCommit();
1001
1002            instQueue.advanceTail(inst);
1003
1004            add_to_iq = false;
1005        } else {
1006            add_to_iq = true;
1007        }
1008
1009        // If the instruction queue is not full, then add the
1010        // instruction.
1011        if (add_to_iq) {
1012            instQueue.insert(inst);
1013        }
1014
1015        insts_to_dispatch.pop();
1016
1017        toRename->iewInfo[tid].dispatched++;
1018
1019        ++iewDispatchedInsts;
1020    }
1021
1022    if (!insts_to_dispatch.empty()) {
1023        DPRINTF(IEW,"[tid:%i]: Issue: Bandwidth Full. Blocking.\n");
1024        block(tid);
1025        toRename->iewUnblock[tid] = false;
1026    }
1027
1028    if (dispatchStatus[tid] == Idle && dis_num_inst) {
1029        dispatchStatus[tid] = Running;
1030
1031        updatedQueues = true;
1032    }
1033
1034    dis_num_inst = 0;
1035}
1036
1037template <class Impl>
1038void
1039DefaultIEW<Impl>::printAvailableInsts()
1040{
1041    int inst = 0;
1042
1043    cout << "Available Instructions: ";
1044
1045    while (fromIssue->insts[inst]) {
1046
1047        if (inst%3==0) cout << "\n\t";
1048
1049        cout << "PC: " << fromIssue->insts[inst]->readPC()
1050             << " TN: " << fromIssue->insts[inst]->threadNumber
1051             << " SN: " << fromIssue->insts[inst]->seqNum << " | ";
1052
1053        inst++;
1054
1055    }
1056
1057    cout << "\n";
1058}
1059
1060template <class Impl>
1061void
1062DefaultIEW<Impl>::executeInsts()
1063{
1064    //bool fetch_redirect[(*activeThreads).size()];
1065    wbNumInst = 0;
1066    wbCycle = 0;
1067
1068    list<unsigned>::iterator threads = (*activeThreads).begin();
1069
1070    while (threads != (*activeThreads).end()) {
1071        unsigned tid = *threads++;
1072        fetchRedirect[tid] = false;
1073    }
1074
1075#if 0
1076    printAvailableInsts();
1077#endif
1078
1079    // Execute/writeback any instructions that are available.
1080    int inst_num = 0;
1081    for ( ; inst_num < issueWidth &&  /* Haven't exceeded issue bandwidth */
1082              fromIssue->insts[inst_num];
1083         ++inst_num) {
1084
1085        DPRINTF(IEW, "Execute: Executing instructions from IQ.\n");
1086
1087        // Get instruction from issue's queue.
1088        DynInstPtr inst = fromIssue->insts[inst_num];
1089
1090        DPRINTF(IEW, "Execute: Processing PC %#x, [tid:%i] [sn:%i].\n",
1091                inst->readPC(), inst->threadNumber,inst->seqNum);
1092
1093        // Check if the instruction is squashed; if so then skip it
1094        // and don't count it towards the FU usage.
1095        if (inst->isSquashed()) {
1096            DPRINTF(IEW, "Execute: Instruction was squashed.\n");
1097
1098            // Consider this instruction executed so that commit can go
1099            // ahead and retire the instruction.
1100            inst->setExecuted();
1101
1102            // Not sure if I should set this here or just let commit try to
1103            // commit any squashed instructions.  I like the latter a bit more.
1104            inst->setCanCommit();
1105
1106            ++iewExecSquashedInsts;
1107
1108            continue;
1109        }
1110
1111        Fault fault = NoFault;
1112
1113        // Execute instruction.
1114        // Note that if the instruction faults, it will be handled
1115        // at the commit stage.
1116        if (inst->isMemRef() &&
1117            (!inst->isDataPrefetch() && !inst->isInstPrefetch())) {
1118            DPRINTF(IEW, "Execute: Calculating address for memory "
1119                    "reference.\n");
1120
1121            // Tell the LDSTQ to execute this instruction (if it is a load).
1122            if (inst->isLoad()) {
1123                // Loads will mark themselves as executed, and their writeback
1124                // event adds the instruction to the queue to commit
1125                fault = ldstQueue.executeLoad(inst);
1126
1127                ++iewExecLoadInsts;
1128            } else if (inst->isStore()) {
1129                ldstQueue.executeStore(inst);
1130
1131                ++iewExecStoreInsts;
1132
1133                // If the store had a fault then it may not have a mem req
1134                if (inst->req && !(inst->req->flags & LOCKED)) {
1135                    inst->setExecuted();
1136
1137                    instToCommit(inst);
1138                }
1139                // Store conditionals will mark themselves as executed, and
1140                // their writeback event will add the instruction to the queue
1141                // to commit.
1142            } else {
1143                panic("Unexpected memory type!\n");
1144            }
1145
1146        } else {
1147            inst->execute();
1148
1149            ++iewExecutedInsts;
1150
1151            inst->setExecuted();
1152
1153            instToCommit(inst);
1154        }
1155
1156        // Check if branch was correct.  This check happens after the
1157        // instruction is added to the queue because even if the branch
1158        // is mispredicted, the branch instruction itself is still valid.
1159        // Only handle this if there hasn't already been something that
1160        // redirects fetch in this group of instructions.
1161
1162        // This probably needs to prioritize the redirects if a different
1163        // scheduler is used.  Currently the scheduler schedules the oldest
1164        // instruction first, so the branch resolution order will be correct.
1165        unsigned tid = inst->threadNumber;
1166
1167        if (!fetchRedirect[tid]) {
1168
1169            if (inst->mispredicted()) {
1170                fetchRedirect[tid] = true;
1171
1172                DPRINTF(IEW, "Execute: Branch mispredict detected.\n");
1173                DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x.\n",
1174                        inst->nextPC);
1175
1176                // If incorrect, then signal the ROB that it must be squashed.
1177                squashDueToBranch(inst, tid);
1178
1179                if (inst->predTaken()) {
1180                    predictedTakenIncorrect++;
1181                } else {
1182                    predictedNotTakenIncorrect++;
1183                }
1184            } else if (ldstQueue.violation(tid)) {
1185                fetchRedirect[tid] = true;
1186
1187                // Get the DynInst that caused the violation.  Note that this
1188                // clears the violation signal.
1189                DynInstPtr violator;
1190                violator = ldstQueue.getMemDepViolator(tid);
1191
1192                DPRINTF(IEW, "LDSTQ detected a violation.  Violator PC: "
1193                        "%#x, inst PC: %#x.  Addr is: %#x.\n",
1194                        violator->readPC(), inst->readPC(), inst->physEffAddr);
1195
1196                // Tell the instruction queue that a violation has occured.
1197                instQueue.violation(inst, violator);
1198
1199                // Squash.
1200                squashDueToMemOrder(inst,tid);
1201
1202                ++memOrderViolationEvents;
1203            } else if (ldstQueue.loadBlocked(tid) &&
1204                       !ldstQueue.isLoadBlockedHandled(tid)) {
1205                fetchRedirect[tid] = true;
1206
1207                DPRINTF(IEW, "Load operation couldn't execute because the "
1208                        "memory system is blocked.  PC: %#x [sn:%lli]\n",
1209                        inst->readPC(), inst->seqNum);
1210
1211                squashDueToMemBlocked(inst, tid);
1212            }
1213        }
1214    }
1215
1216    if (inst_num) {
1217        if (exeStatus == Idle) {
1218            exeStatus = Running;
1219        }
1220
1221        updatedQueues = true;
1222
1223        cpu->activityThisCycle();
1224    }
1225
1226    // Need to reset this in case a writeback event needs to write into the
1227    // iew queue.  That way the writeback event will write into the correct
1228    // spot in the queue.
1229    wbNumInst = 0;
1230}
1231
1232template <class Impl>
1233void
1234DefaultIEW<Impl>::writebackInsts()
1235{
1236    // Loop through the head of the time buffer and wake any dependents.
1237    // These instructions are about to write back.  In the simple model
1238    // this loop can really happen within the previous loop, but when
1239    // instructions have actual latencies, this loop must be separate.
1240    // Also mark scoreboard that this instruction is finally complete.
1241    // Either have IEW have direct access to rename map, or have this as
1242    // part of backwards communication.
1243    for (int inst_num = 0; inst_num < issueWidth &&
1244             toCommit->insts[inst_num]; inst_num++) {
1245        DynInstPtr inst = toCommit->insts[inst_num];
1246
1247        DPRINTF(IEW, "Sending instructions to commit, PC %#x.\n",
1248                inst->readPC());
1249
1250        // Some instructions will be sent to commit without having
1251        // executed because they need commit to handle them.
1252        // E.g. Uncached loads have not actually executed when they
1253        // are first sent to commit.  Instead commit must tell the LSQ
1254        // when it's ready to execute the uncached load.
1255        if (!inst->isSquashed() && inst->isExecuted()) {
1256            instQueue.wakeDependents(inst);
1257
1258            for (int i = 0; i < inst->numDestRegs(); i++) {
1259                //mark as Ready
1260                DPRINTF(IEW,"Setting Destination Register %i\n",
1261                        inst->renamedDestRegIdx(i));
1262                scoreboard->setReg(inst->renamedDestRegIdx(i));
1263            }
1264        }
1265    }
1266}
1267
1268template<class Impl>
1269void
1270DefaultIEW<Impl>::tick()
1271{
1272    // Try to fill up issue queue with as many instructions as bandwidth
1273    // allows.
1274    wbNumInst = 0;
1275    wbCycle = 0;
1276
1277    wroteToTimeBuffer = false;
1278    updatedQueues = false;
1279
1280    sortInsts();
1281
1282    list<unsigned>::iterator threads = (*activeThreads).begin();
1283
1284    // Check stall and squash signals.
1285    while (threads != (*activeThreads).end()) {
1286           unsigned tid = *threads++;
1287
1288        DPRINTF(IEW,"Issue: Processing [tid:%i]\n",tid);
1289
1290        checkSignalsAndUpdate(tid);
1291        dispatch(tid);
1292
1293    }
1294
1295    if (exeStatus != Squashing) {
1296        executeInsts();
1297
1298        writebackInsts();
1299
1300        // Have the instruction queue try to schedule any ready instructions.
1301        // (In actuality, this scheduling is for instructions that will
1302        // be executed next cycle.)
1303        instQueue.scheduleReadyInsts();
1304
1305        // Also should advance its own time buffers if the stage ran.
1306        // Not the best place for it, but this works (hopefully).
1307        issueToExecQueue.advance();
1308    }
1309
1310    bool broadcast_free_entries = false;
1311
1312    if (updatedQueues || exeStatus == Running || updateLSQNextCycle) {
1313        exeStatus = Idle;
1314        updateLSQNextCycle = false;
1315
1316        broadcast_free_entries = true;
1317    }
1318
1319    // Writeback any stores using any leftover bandwidth.
1320    ldstQueue.writebackStores();
1321
1322    // Free function units marked as being freed this cycle.
1323    fuPool->processFreeUnits();
1324
1325    // Check the committed load/store signals to see if there's a load
1326    // or store to commit.  Also check if it's being told to execute a
1327    // nonspeculative instruction.
1328    // This is pretty inefficient...
1329
1330    threads = (*activeThreads).begin();
1331    while (threads != (*activeThreads).end()) {
1332        unsigned tid = (*threads++);
1333
1334        DPRINTF(IEW,"Processing [tid:%i]\n",tid);
1335
1336        if (fromCommit->commitInfo[tid].doneSeqNum != 0 &&
1337            !fromCommit->commitInfo[tid].squash &&
1338            !fromCommit->commitInfo[tid].robSquashing) {
1339
1340            ldstQueue.commitStores(fromCommit->commitInfo[tid].doneSeqNum,tid);
1341
1342            ldstQueue.commitLoads(fromCommit->commitInfo[tid].doneSeqNum,tid);
1343
1344            updateLSQNextCycle = true;
1345            instQueue.commit(fromCommit->commitInfo[tid].doneSeqNum,tid);
1346        }
1347
1348        if (fromCommit->commitInfo[tid].nonSpecSeqNum != 0) {
1349
1350            //DPRINTF(IEW,"NonspecInst from thread %i",tid);
1351            if (fromCommit->commitInfo[tid].uncached) {
1352                instQueue.replayMemInst(fromCommit->commitInfo[tid].uncachedLoad);
1353            } else {
1354                instQueue.scheduleNonSpec(
1355                    fromCommit->commitInfo[tid].nonSpecSeqNum);
1356            }
1357        }
1358
1359        if (broadcast_free_entries) {
1360            toFetch->iewInfo[tid].iqCount =
1361                instQueue.getCount(tid);
1362            toFetch->iewInfo[tid].ldstqCount =
1363                ldstQueue.getCount(tid);
1364
1365            toRename->iewInfo[tid].usedIQ = true;
1366            toRename->iewInfo[tid].freeIQEntries =
1367                instQueue.numFreeEntries();
1368            toRename->iewInfo[tid].usedLSQ = true;
1369            toRename->iewInfo[tid].freeLSQEntries =
1370                ldstQueue.numFreeEntries(tid);
1371
1372            wroteToTimeBuffer = true;
1373        }
1374
1375        DPRINTF(IEW, "[tid:%i], Dispatch dispatched %i instructions.\n",
1376                tid, toRename->iewInfo[tid].dispatched);
1377
1378        //thread_queue.pop();
1379    }
1380
1381    DPRINTF(IEW, "IQ has %i free entries (Can schedule: %i).  "
1382            "LSQ has %i free entries.\n",
1383            instQueue.numFreeEntries(), instQueue.hasReadyInsts(),
1384            ldstQueue.numFreeEntries());
1385
1386    updateStatus();
1387
1388    if (wroteToTimeBuffer) {
1389        DPRINTF(Activity, "Activity this cycle.\n");
1390        cpu->activityThisCycle();
1391    }
1392}
1393