decode.hh revision 1461
16899SN/A// Todo:
26899SN/A// Add a couple of the branch fields to DynInst.  Figure out where DynInst
37553SN/A// should try to compute the target of a PC-relative branch.  Try to avoid
46899SN/A// having so many returns within the code.
56899SN/A// Fix up squashing too, as it's too
66899SN/A// dependent upon the iew stage continually telling it to squash.
76899SN/A
86899SN/A#ifndef __CPU_BETA_CPU_SIMPLE_DECODE_HH__
96899SN/A#define __CPU_BETA_CPU_SIMPLE_DECODE_HH__
106899SN/A
116899SN/A#include <queue>
126899SN/A
136899SN/A#include "base/statistics.hh"
146899SN/A#include "base/timebuf.hh"
156899SN/A
166899SN/Atemplate<class Impl>
176899SN/Aclass SimpleDecode
186899SN/A{
196899SN/A  private:
206899SN/A    // Typedefs from the Impl.
216899SN/A    typedef typename Impl::ISA ISA;
226899SN/A    typedef typename Impl::FullCPU FullCPU;
236899SN/A    typedef typename Impl::DynInstPtr DynInstPtr;
246899SN/A    typedef typename Impl::Params Params;
256899SN/A    typedef typename Impl::CPUPol CPUPol;
266899SN/A
276899SN/A    // Typedefs from the CPU policy.
286899SN/A    typedef typename CPUPol::FetchStruct FetchStruct;
296899SN/A    typedef typename CPUPol::DecodeStruct DecodeStruct;
307553SN/A    typedef typename CPUPol::TimeStruct TimeStruct;
317553SN/A
326899SN/A    // Typedefs from the ISA.
337055SN/A    typedef typename ISA::Addr Addr;
348229Snate@binkert.org
357454SN/A  public:
367055SN/A    // The only time decode will become blocked is if dispatch becomes
377053SN/A    // blocked, which means IQ or ROB is probably full.
386899SN/A    enum Status {
397053SN/A        Running,
406899SN/A        Idle,
418229Snate@binkert.org        Squashing,
428229Snate@binkert.org        Blocked,
437553SN/A        Unblocking
446899SN/A    };
457553SN/A
467553SN/A  private:
477553SN/A    // May eventually need statuses on a per thread basis.
486899SN/A    Status _status;
497053SN/A
508922Swilliam.wang@arm.com  public:
517053SN/A    SimpleDecode(Params &params);
527053SN/A
537553SN/A    void regStats();
546899SN/A
557053SN/A    void setCPU(FullCPU *cpu_ptr);
568854Sandreas.hansson@arm.com
579031Sandreas.hansson@arm.com    void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
588965Sandreas.hansson@arm.com
597053SN/A    void setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr);
606899SN/A
617053SN/A    void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr);
628975Sandreas.hansson@arm.com
638922Swilliam.wang@arm.com    void tick();
648922Swilliam.wang@arm.com
657053SN/A    void decode();
666899SN/A
677553SN/A    // Might want to make squash a friend function.
687553SN/A    void squash();
697553SN/A
706899SN/A  private:
718922Swilliam.wang@arm.com    void block();
728922Swilliam.wang@arm.com
736899SN/A    inline void unblock();
748922Swilliam.wang@arm.com
756899SN/A    void squash(DynInstPtr &inst);
767053SN/A
776899SN/A    // Interfaces to objects outside of decode.
787053SN/A    /** CPU interface. */
796899SN/A    FullCPU *cpu;
807553SN/A
816899SN/A    /** Time buffer interface. */
827055SN/A    TimeBuffer<TimeStruct> *timeBuffer;
837053SN/A
847055SN/A    /** Wire to get rename's output from backwards time buffer. */
856899SN/A    typename TimeBuffer<TimeStruct>::wire fromRename;
867055SN/A
876899SN/A    /** Wire to get iew's information from backwards time buffer. */
887053SN/A    typename TimeBuffer<TimeStruct>::wire fromIEW;
897553SN/A
907053SN/A    /** Wire to get commit's information from backwards time buffer. */
917053SN/A    typename TimeBuffer<TimeStruct>::wire fromCommit;
927553SN/A
936899SN/A    /** Wire to write information heading to previous stages. */
947053SN/A    // Might not be the best name as not only fetch will read it.
957553SN/A    typename TimeBuffer<TimeStruct>::wire toFetch;
967053SN/A
977053SN/A    /** Decode instruction queue. */
987053SN/A    TimeBuffer<DecodeStruct> *decodeQueue;
997553SN/A
1007053SN/A    /** Wire used to write any information heading to rename. */
1017053SN/A    typename TimeBuffer<DecodeStruct>::wire toRename;
1027553SN/A
1037053SN/A    /** Fetch instruction queue interface. */
1046899SN/A    TimeBuffer<FetchStruct> *fetchQueue;
1057553SN/A
1066899SN/A    /** Wire to get fetch's output from fetch queue. */
1077053SN/A    typename TimeBuffer<FetchStruct>::wire fromFetch;
1086899SN/A
1097053SN/A    /** Skid buffer between fetch and decode. */
1107553SN/A    std::queue<FetchStruct> skidBuffer;
1117553SN/A
1126899SN/A  private:
1137553SN/A    //Consider making these unsigned to avoid any confusion.
1148950Sandreas.hansson@arm.com    /** Rename to decode delay, in ticks. */
1157553SN/A    unsigned renameToDecodeDelay;
1167553SN/A
1176899SN/A    /** IEW to decode delay, in ticks. */
1186899SN/A    unsigned iewToDecodeDelay;
1197553SN/A
120    /** Commit to decode delay, in ticks. */
121    unsigned commitToDecodeDelay;
122
123    /** Fetch to decode delay, in ticks. */
124    unsigned fetchToDecodeDelay;
125
126    /** The width of decode, in instructions. */
127    unsigned decodeWidth;
128
129    /** The instruction that decode is currently on.  It needs to have
130     *  persistent state so that when a stall occurs in the middle of a
131     *  group of instructions, it can restart at the proper instruction.
132     */
133    unsigned numInst;
134
135    Stats::Scalar<> decodeIdleCycles;
136    Stats::Scalar<> decodeBlockedCycles;
137    Stats::Scalar<> decodeUnblockCycles;
138    Stats::Scalar<> decodeSquashCycles;
139    Stats::Scalar<> decodeBranchMispred;
140    Stats::Scalar<> decodeControlMispred;
141    Stats::Scalar<> decodeDecodedInsts;
142    Stats::Scalar<> decodeSquashedInsts;
143};
144
145#endif // __CPU_BETA_CPU_SIMPLE_DECODE_HH__
146