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 ¶ms); 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