summaryrefslogtreecommitdiff
path: root/cpu/ozone/back_end.hh
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/ozone/back_end.hh')
-rw-r--r--cpu/ozone/back_end.hh516
1 files changed, 0 insertions, 516 deletions
diff --git a/cpu/ozone/back_end.hh b/cpu/ozone/back_end.hh
deleted file mode 100644
index 14b011ab8..000000000
--- a/cpu/ozone/back_end.hh
+++ /dev/null
@@ -1,516 +0,0 @@
-
-#ifndef __CPU_OZONE_BACK_END_HH__
-#define __CPU_OZONE_BACK_END_HH__
-
-#include <list>
-#include <queue>
-#include <string>
-
-#include "arch/faults.hh"
-#include "base/timebuf.hh"
-#include "cpu/inst_seq.hh"
-#include "cpu/ozone/rename_table.hh"
-#include "cpu/ozone/thread_state.hh"
-#include "mem/functional/functional.hh"
-#include "mem/mem_interface.hh"
-#include "mem/mem_req.hh"
-#include "sim/eventq.hh"
-
-class ExecContext;
-
-template <class Impl>
-class OzoneThreadState;
-
-template <class Impl>
-class BackEnd
-{
- public:
- typedef OzoneThreadState<Impl> Thread;
-
- typedef typename Impl::Params Params;
- typedef typename Impl::DynInst DynInst;
- typedef typename Impl::DynInstPtr DynInstPtr;
- typedef typename Impl::FullCPU FullCPU;
- typedef typename Impl::FrontEnd FrontEnd;
- typedef typename Impl::FullCPU::CommStruct CommStruct;
-
- struct SizeStruct {
- int size;
- };
-
- typedef SizeStruct DispatchToIssue;
- typedef SizeStruct IssueToExec;
- typedef SizeStruct ExecToCommit;
- typedef SizeStruct Writeback;
-
- TimeBuffer<DispatchToIssue> d2i;
- typename TimeBuffer<DispatchToIssue>::wire instsToDispatch;
- TimeBuffer<IssueToExec> i2e;
- typename TimeBuffer<IssueToExec>::wire instsToExecute;
- TimeBuffer<ExecToCommit> e2c;
- TimeBuffer<Writeback> numInstsToWB;
-
- TimeBuffer<CommStruct> *comm;
- typename TimeBuffer<CommStruct>::wire toIEW;
- typename TimeBuffer<CommStruct>::wire fromCommit;
-
- class InstQueue {
- enum queue {
- NonSpec,
- IQ,
- ToBeScheduled,
- ReadyList,
- ReplayList
- };
- struct pqCompare {
- bool operator() (const DynInstPtr &lhs, const DynInstPtr &rhs) const
- {
- return lhs->seqNum > rhs->seqNum;
- }
- };
- public:
- InstQueue(Params *params);
-
- std::string name() const;
-
- void regStats();
-
- void setIssueExecQueue(TimeBuffer<IssueToExec> *i2e_queue);
-
- void setBE(BackEnd *_be) { be = _be; }
-
- void insert(DynInstPtr &inst);
-
- void scheduleReadyInsts();
-
- void scheduleNonSpec(const InstSeqNum &sn);
-
- DynInstPtr getReadyInst();
-
- void commit(const InstSeqNum &sn) {}
-
- void squash(const InstSeqNum &sn);
-
- int 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);
-
- /** Completes memory instruction. */
- void completeMemInst(DynInstPtr &inst);
-
- void violation(DynInstPtr &inst, DynInstPtr &violation) { }
-
- bool isFull() { return numInsts >= size; }
-
- void dumpInsts();
-
- private:
- bool find(queue q, typename std::list<DynInstPtr>::iterator it);
- BackEnd *be;
- TimeBuffer<IssueToExec> *i2e;
- typename TimeBuffer<IssueToExec>::wire numIssued;
- typedef typename std::list<DynInstPtr> InstList;
- typedef typename std::list<DynInstPtr>::iterator InstListIt;
- typedef typename std::priority_queue<DynInstPtr, std::vector<DynInstPtr>, pqCompare> ReadyInstQueue;
- // Not sure I need the IQ list; it just needs to be a count.
- InstList iq;
- InstList toBeScheduled;
- InstList readyList;
- InstList nonSpec;
- InstList replayList;
- ReadyInstQueue readyQueue;
- public:
- int size;
- int numInsts;
- int width;
-
- Stats::VectorDistribution<> occ_dist;
-
- Stats::Vector<> inst_count;
- Stats::Vector<> peak_inst_count;
- Stats::Scalar<> empty_count;
- Stats::Scalar<> current_count;
- Stats::Scalar<> fullCount;
-
- Stats::Formula occ_rate;
- Stats::Formula avg_residency;
- Stats::Formula empty_rate;
- Stats::Formula full_rate;
- };
-
- /** LdWriteback event for a load completion. */
- class LdWritebackEvent : public Event {
- private:
- /** Instruction that is writing back data to the register file. */
- DynInstPtr inst;
- /** Pointer to IEW stage. */
- BackEnd *be;
-
- public:
- /** Constructs a load writeback event. */
- LdWritebackEvent(DynInstPtr &_inst, BackEnd *be);
-
- /** Processes writeback event. */
- virtual void process();
- /** Returns the description of the writeback event. */
- virtual const char *description();
- };
-
- BackEnd(Params *params);
-
- std::string name() const;
-
- void regStats();
-
- void setCPU(FullCPU *cpu_ptr)
- { cpu = cpu_ptr; }
-
- void setFrontEnd(FrontEnd *front_end_ptr)
- { frontEnd = front_end_ptr; }
-
- void setXC(ExecContext *xc_ptr)
- { xc = xc_ptr; }
-
- void setThreadState(Thread *thread_ptr)
- { thread = thread_ptr; }
-
- void setCommBuffer(TimeBuffer<CommStruct> *_comm);
-
- void tick();
- void squash();
- void squashFromXC();
- bool xcSquash;
-
- template <class T>
- Fault read(MemReqPtr &req, T &data, int load_idx);
-
- template <class T>
- Fault write(MemReqPtr &req, T &data, int store_idx);
-
- Addr readCommitPC() { return commitPC; }
-
- Addr commitPC;
-
- bool robEmpty() { return instList.empty(); }
-
- bool isFull() { return numInsts >= numROBEntries; }
- bool isBlocked() { return status == Blocked || dispatchStatus == Blocked; }
-
- /** Tells memory dependence unit that a memory instruction needs to be
- * rescheduled. It will re-execute once replayMemInst() is called.
- */
- void rescheduleMemInst(DynInstPtr &inst)
- { IQ.rescheduleMemInst(inst); }
-
- /** Re-executes all rescheduled memory instructions. */
- void replayMemInst(DynInstPtr &inst)
- { IQ.replayMemInst(inst); }
-
- /** Completes memory instruction. */
- void completeMemInst(DynInstPtr &inst)
- { IQ.completeMemInst(inst); }
-
- void fetchFault(Fault &fault);
-
- private:
- void updateStructures();
- void dispatchInsts();
- void dispatchStall();
- void checkDispatchStatus();
- void scheduleReadyInsts();
- void executeInsts();
- void commitInsts();
- void addToIQ(DynInstPtr &inst);
- void addToLSQ(DynInstPtr &inst);
- void instToCommit(DynInstPtr &inst);
- void writebackInsts();
- bool commitInst(int inst_num);
- void squash(const InstSeqNum &sn);
- void squashDueToBranch(DynInstPtr &inst);
- void squashDueToMemBlocked(DynInstPtr &inst);
- void updateExeInstStats(DynInstPtr &inst);
- void updateComInstStats(DynInstPtr &inst);
-
- public:
- FullCPU *cpu;
-
- FrontEnd *frontEnd;
-
- ExecContext *xc;
-
- Thread *thread;
-
- enum Status {
- Running,
- Idle,
- DcacheMissStall,
- DcacheMissComplete,
- Blocked
- };
-
- Status status;
-
- Status dispatchStatus;
-
- Counter funcExeInst;
-
- private:
-// typedef typename Impl::InstQueue InstQueue;
-
- InstQueue IQ;
-
- typedef typename Impl::LdstQueue LdstQueue;
-
- LdstQueue LSQ;
- public:
- RenameTable<Impl> commitRenameTable;
-
- RenameTable<Impl> renameTable;
- private:
- class DCacheCompletionEvent : public Event
- {
- private:
- BackEnd *be;
-
- public:
- DCacheCompletionEvent(BackEnd *_be);
-
- virtual void process();
- virtual const char *description();
- };
-
- friend class DCacheCompletionEvent;
-
- DCacheCompletionEvent cacheCompletionEvent;
-
- MemInterface *dcacheInterface;
-
- MemReqPtr memReq;
-
- // General back end width. Used if the more specific isn't given.
- int width;
-
- // Dispatch width.
- int dispatchWidth;
- int numDispatchEntries;
- int dispatchSize;
-
- int issueWidth;
-
- // Writeback width
- int wbWidth;
-
- // Commit width
- int commitWidth;
-
- /** Index into queue of instructions being written back. */
- unsigned wbNumInst;
-
- /** Cycle number within the queue of instructions being written
- * back. Used in case there are too many instructions writing
- * back at the current cycle and writesbacks need to be scheduled
- * for the future. See comments in instToCommit().
- */
- unsigned wbCycle;
-
- int numROBEntries;
- int numInsts;
-
- bool squashPending;
- InstSeqNum squashSeqNum;
- Addr squashNextPC;
-
- Fault faultFromFetch;
-
- private:
- typedef typename std::list<DynInstPtr>::iterator InstListIt;
-
- std::list<DynInstPtr> instList;
- std::list<DynInstPtr> dispatch;
- std::list<DynInstPtr> writeback;
-
- int latency;
-
- int squashLatency;
-
- bool exactFullStall;
-
- bool fetchRedirect[Impl::MaxThreads];
-
- // number of cycles stalled for D-cache misses
-/* Stats::Scalar<> dcacheStallCycles;
- Counter lastDcacheStall;
-*/
- Stats::Vector<> rob_cap_events;
- Stats::Vector<> rob_cap_inst_count;
- Stats::Vector<> iq_cap_events;
- Stats::Vector<> iq_cap_inst_count;
- // total number of instructions executed
- Stats::Vector<> exe_inst;
- Stats::Vector<> exe_swp;
- Stats::Vector<> exe_nop;
- Stats::Vector<> exe_refs;
- Stats::Vector<> exe_loads;
- Stats::Vector<> exe_branches;
-
- Stats::Vector<> issued_ops;
-
- // total number of loads forwaded from LSQ stores
- Stats::Vector<> lsq_forw_loads;
-
- // total number of loads ignored due to invalid addresses
- Stats::Vector<> inv_addr_loads;
-
- // total number of software prefetches ignored due to invalid addresses
- Stats::Vector<> inv_addr_swpfs;
- // ready loads blocked due to memory disambiguation
- Stats::Vector<> lsq_blocked_loads;
-
- Stats::Scalar<> lsqInversion;
-
- Stats::Vector<> n_issued_dist;
- Stats::VectorDistribution<> issue_delay_dist;
-
- Stats::VectorDistribution<> queue_res_dist;
-/*
- Stats::Vector<> stat_fu_busy;
- Stats::Vector2d<> stat_fuBusy;
- Stats::Vector<> dist_unissued;
- Stats::Vector2d<> stat_issued_inst_type;
-
- Stats::Formula misspec_cnt;
- Stats::Formula misspec_ipc;
- Stats::Formula issue_rate;
- Stats::Formula issue_stores;
- Stats::Formula issue_op_rate;
- Stats::Formula fu_busy_rate;
- Stats::Formula commit_stores;
- Stats::Formula commit_ipc;
- Stats::Formula commit_ipb;
- Stats::Formula lsq_inv_rate;
-*/
- Stats::Vector<> writeback_count;
- Stats::Vector<> producer_inst;
- Stats::Vector<> consumer_inst;
- Stats::Vector<> wb_penalized;
-
- Stats::Formula wb_rate;
- Stats::Formula wb_fanout;
- Stats::Formula wb_penalized_rate;
-
- // total number of instructions committed
- Stats::Vector<> stat_com_inst;
- Stats::Vector<> stat_com_swp;
- Stats::Vector<> stat_com_refs;
- Stats::Vector<> stat_com_loads;
- Stats::Vector<> stat_com_membars;
- Stats::Vector<> stat_com_branches;
-
- Stats::Distribution<> n_committed_dist;
-
- Stats::Scalar<> commit_eligible_samples;
- Stats::Vector<> commit_eligible;
-
- Stats::Scalar<> ROB_fcount;
- Stats::Formula ROB_full_rate;
-
- Stats::Vector<> ROB_count; // cumulative ROB occupancy
- Stats::Formula ROB_occ_rate;
- Stats::VectorDistribution<> ROB_occ_dist;
- public:
- void dumpInsts();
-};
-
-template <class Impl>
-template <class T>
-Fault
-BackEnd<Impl>::read(MemReqPtr &req, T &data, int load_idx)
-{
-/* memReq->reset(addr, sizeof(T), flags);
-
- // translate to physical address
- Fault fault = cpu->translateDataReadReq(memReq);
-
- // if we have a cache, do cache access too
- if (fault == NoFault && dcacheInterface) {
- memReq->cmd = Read;
- memReq->completionEvent = NULL;
- memReq->time = curTick;
- memReq->flags &= ~INST_READ;
- MemAccessResult result = dcacheInterface->access(memReq);
-
- // Ugly hack to get an event scheduled *only* if the access is
- // a miss. We really should add first-class support for this
- // at some point.
- if (result != MA_HIT && dcacheInterface->doEvents()) {
- // Fix this hack for keeping funcExeInst correct with loads that
- // are executed twice.
- --funcExeInst;
-
- memReq->completionEvent = &cacheCompletionEvent;
- lastDcacheStall = curTick;
-// unscheduleTickEvent();
-// status = DcacheMissStall;
- DPRINTF(OzoneCPU, "Dcache miss stall!\n");
- } else {
- // do functional access
- fault = thread->mem->read(memReq, data);
-
- }
- }
-*/
-/*
- if (!dcacheInterface && (memReq->flags & UNCACHEABLE))
- recordEvent("Uncached Read");
-*/
- return LSQ.read(req, data, load_idx);
-}
-
-template <class Impl>
-template <class T>
-Fault
-BackEnd<Impl>::write(MemReqPtr &req, T &data, int store_idx)
-{
-/*
- memReq->reset(addr, sizeof(T), flags);
-
- // translate to physical address
- Fault fault = cpu->translateDataWriteReq(memReq);
-
- if (fault == NoFault && dcacheInterface) {
- memReq->cmd = Write;
- memcpy(memReq->data,(uint8_t *)&data,memReq->size);
- memReq->completionEvent = NULL;
- memReq->time = curTick;
- memReq->flags &= ~INST_READ;
- MemAccessResult result = dcacheInterface->access(memReq);
-
- // Ugly hack to get an event scheduled *only* if the access is
- // a miss. We really should add first-class support for this
- // at some point.
- if (result != MA_HIT && dcacheInterface->doEvents()) {
- memReq->completionEvent = &cacheCompletionEvent;
- lastDcacheStall = curTick;
-// unscheduleTickEvent();
-// status = DcacheMissStall;
- DPRINTF(OzoneCPU, "Dcache miss stall!\n");
- }
- }
-
- if (res && (fault == NoFault))
- *res = memReq->result;
- */
-/*
- if (!dcacheInterface && (memReq->flags & UNCACHEABLE))
- recordEvent("Uncached Write");
-*/
- return LSQ.write(req, data, store_idx);
-}
-
-#endif // __CPU_OZONE_BACK_END_HH__