decode.hh revision 1061
1// Todo:
2// Add a couple of the branch fields to DynInst.  Figure out where DynInst
3// should try to compute the target of a PC-relative branch.  Try to avoid
4// having so many returns within the code.
5// Fix up squashing too, as it's too
6// dependent upon the iew stage continually telling it to squash.
7
8#ifndef __SIMPLE_DECODE_HH__
9#define __SIMPLE_DECODE_HH__
10
11#include <queue>
12
13#include "base/timebuf.hh"
14
15template<class Impl>
16class SimpleDecode
17{
18  private:
19    // Typedefs from the Impl.
20    typedef typename Impl::ISA ISA;
21    typedef typename Impl::FullCPU FullCPU;
22    typedef typename Impl::DynInstPtr DynInstPtr;
23    typedef typename Impl::Params Params;
24    typedef typename Impl::CPUPol CPUPol;
25
26    // Typedefs from the CPU policy.
27    typedef typename CPUPol::FetchStruct FetchStruct;
28    typedef typename CPUPol::DecodeStruct DecodeStruct;
29    typedef typename CPUPol::TimeStruct TimeStruct;
30
31    // Typedefs from the ISA.
32    typedef typename ISA::Addr Addr;
33
34  public:
35    // The only time decode will become blocked is if dispatch becomes
36    // blocked, which means IQ or ROB is probably full.
37    enum Status {
38        Running,
39        Idle,
40        Squashing,
41        Blocked,
42        Unblocking
43    };
44
45  private:
46    // May eventually need statuses on a per thread basis.
47    Status _status;
48
49  public:
50    SimpleDecode(Params &params);
51
52    void setCPU(FullCPU *cpu_ptr);
53
54    void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
55
56    void setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr);
57
58    void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr);
59
60    void tick();
61
62    void decode();
63
64    // Might want to make squash a friend function.
65    void squash();
66
67  private:
68    void block();
69
70    inline void unblock();
71
72    void squash(DynInstPtr &inst);
73
74    // Interfaces to objects outside of decode.
75    /** CPU interface. */
76    FullCPU *cpu;
77
78    /** Time buffer interface. */
79    TimeBuffer<TimeStruct> *timeBuffer;
80
81    /** Wire to get rename's output from backwards time buffer. */
82    typename TimeBuffer<TimeStruct>::wire fromRename;
83
84    /** Wire to get iew's information from backwards time buffer. */
85    typename TimeBuffer<TimeStruct>::wire fromIEW;
86
87    /** Wire to get commit's information from backwards time buffer. */
88    typename TimeBuffer<TimeStruct>::wire fromCommit;
89
90    /** Wire to write information heading to previous stages. */
91    // Might not be the best name as not only fetch will read it.
92    typename TimeBuffer<TimeStruct>::wire toFetch;
93
94    /** Decode instruction queue. */
95    TimeBuffer<DecodeStruct> *decodeQueue;
96
97    /** Wire used to write any information heading to rename. */
98    typename TimeBuffer<DecodeStruct>::wire toRename;
99
100    /** Fetch instruction queue interface. */
101    TimeBuffer<FetchStruct> *fetchQueue;
102
103    /** Wire to get fetch's output from fetch queue. */
104    typename TimeBuffer<FetchStruct>::wire fromFetch;
105
106    /** Skid buffer between fetch and decode. */
107    std::queue<FetchStruct> skidBuffer;
108
109  private:
110    //Consider making these unsigned to avoid any confusion.
111    /** Rename to decode delay, in ticks. */
112    unsigned renameToDecodeDelay;
113
114    /** IEW to decode delay, in ticks. */
115    unsigned iewToDecodeDelay;
116
117    /** Commit to decode delay, in ticks. */
118    unsigned commitToDecodeDelay;
119
120    /** Fetch to decode delay, in ticks. */
121    unsigned fetchToDecodeDelay;
122
123    /** The width of decode, in instructions. */
124    unsigned decodeWidth;
125
126    /** The instruction that decode is currently on.  It needs to have
127     *  persistent state so that when a stall occurs in the middle of a
128     *  group of instructions, it can restart at the proper instruction.
129     */
130    unsigned numInst;
131};
132
133#endif // __SIMPLE_DECODE_HH__
134