📄 iew.hh
字号:
/* * Copyright (c) 2004, 2005, 2006 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. * * Authors: Kevin T. Lim */#ifndef __CPU_O3_IEW_HH__#define __CPU_O3_IEW_HH__#include "config/full_system.hh"#include <queue>#include "base/statistics.hh"#include "base/timebuf.hh"#include "cpu/o3/comm.hh"#include "cpu/o3/scoreboard.hh"#include "cpu/o3/lsq.hh"class FUPool;/** * DefaultIEW handles both single threaded and SMT IEW * (issue/execute/writeback). It handles the dispatching of * instructions to the LSQ/IQ as part of the issue stage, and has the * IQ try to issue instructions each cycle. The execute latency is * actually tied into the issue latency to allow the IQ to be able to * do back-to-back scheduling without having to speculatively schedule * instructions. This happens by having the IQ have access to the * functional units, and the IQ gets the execution latencies from the * FUs when it issues instructions. Instructions reach the execute * stage on the last cycle of their execution, which is when the IQ * knows to wake up any dependent instructions, allowing back to back * scheduling. The execute portion of IEW separates memory * instructions from non-memory instructions, either telling the LSQ * to execute the instruction, or executing the instruction directly. * The writeback portion of IEW completes the instructions by waking * up any dependents, and marking the register ready on the * scoreboard. */template<class Impl>class DefaultIEW{ private: //Typedefs from Impl typedef typename Impl::CPUPol CPUPol; typedef typename Impl::DynInstPtr DynInstPtr; typedef typename Impl::O3CPU O3CPU; typedef typename Impl::Params Params; typedef typename CPUPol::IQ IQ; typedef typename CPUPol::RenameMap RenameMap; typedef typename CPUPol::LSQ LSQ; typedef typename CPUPol::TimeStruct TimeStruct; typedef typename CPUPol::IEWStruct IEWStruct; typedef typename CPUPol::RenameStruct RenameStruct; typedef typename CPUPol::IssueStruct IssueStruct; friend class Impl::O3CPU; friend class CPUPol::IQ; public: /** Overall IEW stage status. Used to determine if the CPU can * deschedule itself due to a lack of activity. */ enum Status { Active, Inactive }; /** Status for Issue, Execute, and Writeback stages. */ enum StageStatus { Running, Blocked, Idle, StartSquash, Squashing, Unblocking }; private: /** Overall stage status. */ Status _status; /** Dispatch status. */ StageStatus dispatchStatus[Impl::MaxThreads]; /** Execute status. */ StageStatus exeStatus; /** Writeback status. */ StageStatus wbStatus; public: /** Constructs a DefaultIEW with the given parameters. */ DefaultIEW(O3CPU *_cpu, Params *params); /** Returns the name of the DefaultIEW stage. */ std::string name() const; /** Registers statistics. */ void regStats(); /** Initializes stage; sends back the number of free IQ and LSQ entries. */ void initStage(); /** Returns the dcache port. */ Port *getDcachePort() { return ldstQueue.getDcachePort(); } /** Sets main time buffer used for backwards communication. */ void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr); /** Sets time buffer for getting instructions coming from rename. */ void setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr); /** Sets time buffer to pass on instructions to commit. */ void setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr); /** Sets pointer to list of active threads. */ void setActiveThreads(std::list<unsigned> *at_ptr); /** Sets pointer to the scoreboard. */ void setScoreboard(Scoreboard *sb_ptr); /** Drains IEW stage. */ bool drain(); /** Resumes execution after a drain. */ void resume(); /** Completes switch out of IEW stage. */ void switchOut(); /** Takes over from another CPU's thread. */ void takeOverFrom(); /** Returns if IEW is switched out. */ bool isSwitchedOut() { return switchedOut; } /** Squashes instructions in IEW for a specific thread. */ void squash(unsigned tid); /** Wakes all dependents of a completed instruction. */ void wakeDependents(DynInstPtr &inst); /** Tells memory dependence unit that a memory instruction needs to be * rescheduled. It will re-execute once replayMemInst() is called. */ void rescheduleMemInst(DynInstPtr &inst); /** Re-executes all rescheduled memory instructions. */ void replayMemInst(DynInstPtr &inst); /** Sends an instruction to commit through the time buffer. */ void instToCommit(DynInstPtr &inst); /** Inserts unused instructions of a thread into the skid buffer. */ void skidInsert(unsigned tid); /** Returns the max of the number of entries in all of the skid buffers. */ int skidCount(); /** Returns if all of the skid buffers are empty. */ bool skidsEmpty(); /** Updates overall IEW status based on all of the stages' statuses. */ void updateStatus(); /** Resets entries of the IQ and the LSQ. */ void resetEntries(); /** Tells the CPU to wakeup if it has descheduled itself due to no * activity. Used mainly by the LdWritebackEvent. */ void wakeCPU(); /** Reports to the CPU that there is activity this cycle. */ void activityThisCycle(); /** Tells CPU that the IEW stage is active and running. */ inline void activateStage(); /** Tells CPU that the IEW stage is inactive and idle. */ inline void deactivateStage(); /** Returns if the LSQ has any stores to writeback. */ bool hasStoresToWB() { return ldstQueue.hasStoresToWB(); } void incrWb(InstSeqNum &sn) { if (++wbOutstanding == wbMax) ableToIssue = false; DPRINTF(IEW, "wbOutstanding: %i\n", wbOutstanding); assert(wbOutstanding <= wbMax);#ifdef DEBUG wbList.insert(sn);#endif } void decrWb(InstSeqNum &sn) { if (wbOutstanding-- == wbMax) ableToIssue = true; DPRINTF(IEW, "wbOutstanding: %i\n", wbOutstanding); assert(wbOutstanding >= 0);#ifdef DEBUG assert(wbList.find(sn) != wbList.end()); wbList.erase(sn);#endif }#ifdef DEBUG std::set<InstSeqNum> wbList; void dumpWb() { std::set<InstSeqNum>::iterator wb_it = wbList.begin(); while (wb_it != wbList.end()) { cprintf("[sn:%lli]\n", (*wb_it)); wb_it++; } }#endif bool canIssue() { return ableToIssue; } bool ableToIssue; private: /** Sends commit proper information for a squash due to a branch * mispredict. */ void squashDueToBranch(DynInstPtr &inst, unsigned thread_id); /** Sends commit proper information for a squash due to a memory order * violation. */ void squashDueToMemOrder(DynInstPtr &inst, unsigned thread_id); /** Sends commit proper information for a squash due to memory becoming * blocked (younger issued instructions must be retried). */ void squashDueToMemBlocked(DynInstPtr &inst, unsigned thread_id); /** Sets Dispatch to blocked, and signals back to other stages to block. */ void block(unsigned thread_id);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -