decode.hh revision 1461
111507SCurtis.Dunham@arm.com// Todo: 211507SCurtis.Dunham@arm.com// Add a couple of the branch fields to DynInst. Figure out where DynInst 311960Sgabeblack@google.com// should try to compute the target of a PC-relative branch. Try to avoid 411960Sgabeblack@google.com// having so many returns within the code. 511960Sgabeblack@google.com// Fix up squashing too, as it's too 611960Sgabeblack@google.com// dependent upon the iew stage continually telling it to squash. 711960Sgabeblack@google.com 811960Sgabeblack@google.com#ifndef __CPU_BETA_CPU_SIMPLE_DECODE_HH__ 911960Sgabeblack@google.com#define __CPU_BETA_CPU_SIMPLE_DECODE_HH__ 1011960Sgabeblack@google.com 1111960Sgabeblack@google.com#include <queue> 1211960Sgabeblack@google.com 1311960Sgabeblack@google.com#include "base/statistics.hh" 1411960Sgabeblack@google.com#include "base/timebuf.hh" 1511960Sgabeblack@google.com 1611960Sgabeblack@google.comtemplate<class Impl> 1711960Sgabeblack@google.comclass SimpleDecode 1811960Sgabeblack@google.com{ 1911960Sgabeblack@google.com private: 2011960Sgabeblack@google.com // Typedefs from the Impl. 2111960Sgabeblack@google.com typedef typename Impl::ISA ISA; 2211960Sgabeblack@google.com typedef typename Impl::FullCPU FullCPU; 2311960Sgabeblack@google.com typedef typename Impl::DynInstPtr DynInstPtr; 2411960Sgabeblack@google.com typedef typename Impl::Params Params; 2511960Sgabeblack@google.com typedef typename Impl::CPUPol CPUPol; 2611960Sgabeblack@google.com 2711960Sgabeblack@google.com // Typedefs from the CPU policy. 2811960Sgabeblack@google.com typedef typename CPUPol::FetchStruct FetchStruct; 2911960Sgabeblack@google.com typedef typename CPUPol::DecodeStruct DecodeStruct; 3011960Sgabeblack@google.com typedef typename CPUPol::TimeStruct TimeStruct; 3111960Sgabeblack@google.com 3211960Sgabeblack@google.com // Typedefs from the ISA. 3311960Sgabeblack@google.com typedef typename ISA::Addr Addr; 3411960Sgabeblack@google.com 3511960Sgabeblack@google.com public: 3611960Sgabeblack@google.com // The only time decode will become blocked is if dispatch becomes 3711960Sgabeblack@google.com // blocked, which means IQ or ROB is probably full. 3811960Sgabeblack@google.com enum Status { 3911960Sgabeblack@google.com Running, 4011960Sgabeblack@google.com Idle, 4111960Sgabeblack@google.com Squashing, 4211960Sgabeblack@google.com Blocked, 4311960Sgabeblack@google.com Unblocking 4411960Sgabeblack@google.com }; 4511960Sgabeblack@google.com 4611960Sgabeblack@google.com private: 4711960Sgabeblack@google.com // May eventually need statuses on a per thread basis. 4811960Sgabeblack@google.com Status _status; 4911960Sgabeblack@google.com 5011960Sgabeblack@google.com public: 5111960Sgabeblack@google.com SimpleDecode(Params ¶ms); 5211960Sgabeblack@google.com 5311960Sgabeblack@google.com void regStats(); 5411960Sgabeblack@google.com 5511960Sgabeblack@google.com void setCPU(FullCPU *cpu_ptr); 5611960Sgabeblack@google.com 5711960Sgabeblack@google.com void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr); 5811960Sgabeblack@google.com 5911960Sgabeblack@google.com void setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr); 6011960Sgabeblack@google.com 6111960Sgabeblack@google.com void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr); 6211960Sgabeblack@google.com 6311960Sgabeblack@google.com void tick(); 6411960Sgabeblack@google.com 6511960Sgabeblack@google.com void decode(); 6611960Sgabeblack@google.com 6711960Sgabeblack@google.com // Might want to make squash a friend function. 6811960Sgabeblack@google.com void squash(); 6911960Sgabeblack@google.com 7011960Sgabeblack@google.com private: 7111960Sgabeblack@google.com void block(); 7211960Sgabeblack@google.com 7311960Sgabeblack@google.com inline void unblock(); 7411960Sgabeblack@google.com 7511960Sgabeblack@google.com void squash(DynInstPtr &inst); 7611960Sgabeblack@google.com 7711960Sgabeblack@google.com // Interfaces to objects outside of decode. 7811960Sgabeblack@google.com /** CPU interface. */ 7911960Sgabeblack@google.com FullCPU *cpu; 8011960Sgabeblack@google.com 8111960Sgabeblack@google.com /** Time buffer interface. */ 8211960Sgabeblack@google.com TimeBuffer<TimeStruct> *timeBuffer; 8311960Sgabeblack@google.com 8411960Sgabeblack@google.com /** Wire to get rename's output from backwards time buffer. */ 8511960Sgabeblack@google.com typename TimeBuffer<TimeStruct>::wire fromRename; 8611960Sgabeblack@google.com 8711960Sgabeblack@google.com /** Wire to get iew's information from backwards time buffer. */ 8811960Sgabeblack@google.com typename TimeBuffer<TimeStruct>::wire fromIEW; 8911960Sgabeblack@google.com 9011960Sgabeblack@google.com /** Wire to get commit's information from backwards time buffer. */ 9111960Sgabeblack@google.com typename TimeBuffer<TimeStruct>::wire fromCommit; 9211960Sgabeblack@google.com 9311960Sgabeblack@google.com /** Wire to write information heading to previous stages. */ 9411960Sgabeblack@google.com // Might not be the best name as not only fetch will read it. 9511960Sgabeblack@google.com typename TimeBuffer<TimeStruct>::wire toFetch; 9611960Sgabeblack@google.com 9711960Sgabeblack@google.com /** Decode instruction queue. */ 9811960Sgabeblack@google.com TimeBuffer<DecodeStruct> *decodeQueue; 9911960Sgabeblack@google.com 10011960Sgabeblack@google.com /** Wire used to write any information heading to rename. */ 10111960Sgabeblack@google.com typename TimeBuffer<DecodeStruct>::wire toRename; 10211960Sgabeblack@google.com 10311960Sgabeblack@google.com /** Fetch instruction queue interface. */ 10411960Sgabeblack@google.com TimeBuffer<FetchStruct> *fetchQueue; 10511960Sgabeblack@google.com 10611960Sgabeblack@google.com /** Wire to get fetch's output from fetch queue. */ 10711960Sgabeblack@google.com typename TimeBuffer<FetchStruct>::wire fromFetch; 10811960Sgabeblack@google.com 10911960Sgabeblack@google.com /** Skid buffer between fetch and decode. */ 11011960Sgabeblack@google.com std::queue<FetchStruct> skidBuffer; 11111960Sgabeblack@google.com 11211960Sgabeblack@google.com private: 11311960Sgabeblack@google.com //Consider making these unsigned to avoid any confusion. 11411960Sgabeblack@google.com /** Rename to decode delay, in ticks. */ 11511960Sgabeblack@google.com unsigned renameToDecodeDelay; 11611960Sgabeblack@google.com 11711960Sgabeblack@google.com /** IEW to decode delay, in ticks. */ 11811960Sgabeblack@google.com unsigned iewToDecodeDelay; 11911960Sgabeblack@google.com 12011960Sgabeblack@google.com /** Commit to decode delay, in ticks. */ 12111960Sgabeblack@google.com unsigned commitToDecodeDelay; 12211960Sgabeblack@google.com 12311960Sgabeblack@google.com /** Fetch to decode delay, in ticks. */ 12411960Sgabeblack@google.com unsigned fetchToDecodeDelay; 12511960Sgabeblack@google.com 12611960Sgabeblack@google.com /** The width of decode, in instructions. */ 12711960Sgabeblack@google.com unsigned decodeWidth; 12811960Sgabeblack@google.com 12911960Sgabeblack@google.com /** The instruction that decode is currently on. It needs to have 13011960Sgabeblack@google.com * persistent state so that when a stall occurs in the middle of a 13111960Sgabeblack@google.com * group of instructions, it can restart at the proper instruction. 13211960Sgabeblack@google.com */ 13311960Sgabeblack@google.com unsigned numInst; 13411960Sgabeblack@google.com 13511960Sgabeblack@google.com Stats::Scalar<> decodeIdleCycles; 13611960Sgabeblack@google.com Stats::Scalar<> decodeBlockedCycles; 13711960Sgabeblack@google.com Stats::Scalar<> decodeUnblockCycles; 13811960Sgabeblack@google.com Stats::Scalar<> decodeSquashCycles; 13911960Sgabeblack@google.com Stats::Scalar<> decodeBranchMispred; 14011960Sgabeblack@google.com Stats::Scalar<> decodeControlMispred; 14111960Sgabeblack@google.com Stats::Scalar<> decodeDecodedInsts; 14211960Sgabeblack@google.com Stats::Scalar<> decodeSquashedInsts; 14311960Sgabeblack@google.com}; 14411960Sgabeblack@google.com 14511960Sgabeblack@google.com#endif // __CPU_BETA_CPU_SIMPLE_DECODE_HH__ 14611960Sgabeblack@google.com