Merge zizzer:/bk/newmem
[gem5.git] / src / cpu / ozone / front_end.hh
1 /*
2 * Copyright (c) 2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Kevin Lim
29 */
30
31 #ifndef __CPU_OZONE_FRONT_END_HH__
32 #define __CPU_OZONE_FRONT_END_HH__
33
34 #include <deque>
35
36 #include "cpu/inst_seq.hh"
37 #include "cpu/o3/bpred_unit.hh"
38 #include "cpu/ozone/rename_table.hh"
39 #include "mem/request.hh"
40 #include "sim/eventq.hh"
41 #include "sim/stats.hh"
42
43 class ThreadContext;
44 class MemInterface;
45 template <class>
46 class OzoneThreadState;
47 class PageTable;
48 template <class>
49 class TimeBuffer;
50
51 template <class Impl>
52 class FrontEnd
53 {
54 public:
55 typedef typename Impl::Params Params;
56 typedef typename Impl::DynInst DynInst;
57 typedef typename Impl::DynInstPtr DynInstPtr;
58 typedef typename Impl::FullCPU FullCPU;
59 typedef typename Impl::BackEnd BackEnd;
60
61 typedef typename Impl::FullCPU::OzoneTC OzoneTC;
62 typedef typename Impl::FullCPU::CommStruct CommStruct;
63
64 FrontEnd(Params *params);
65
66 std::string name() const;
67
68 void setCPU(FullCPU *cpu_ptr)
69 { cpu = cpu_ptr; }
70
71 void setBackEnd(BackEnd *back_end_ptr)
72 { backEnd = back_end_ptr; }
73
74 void setCommBuffer(TimeBuffer<CommStruct> *_comm);
75
76 void setTC(ThreadContext *tc_ptr);
77
78 void setThreadState(OzoneThreadState<Impl> *thread_ptr)
79 { thread = thread_ptr; }
80
81 void regStats();
82
83 void tick();
84 Fault fetchCacheLine();
85 void processInst(DynInstPtr &inst);
86 void squash(const InstSeqNum &squash_num, const Addr &next_PC,
87 const bool is_branch = false, const bool branch_taken = false);
88 DynInstPtr getInst();
89
90 void processCacheCompletion(Packet *pkt);
91
92 void addFreeRegs(int num_freed);
93
94 bool isEmpty() { return instBuffer.empty(); }
95
96 void switchOut();
97
98 void doSwitchOut();
99
100 void takeOverFrom(ThreadContext *old_tc = NULL);
101
102 bool isSwitchedOut() { return switchedOut; }
103
104 bool switchedOut;
105
106 private:
107 bool updateStatus();
108
109 void checkBE();
110 DynInstPtr getInstFromCacheline();
111 void renameInst(DynInstPtr &inst);
112 // Returns true if we need to stop the front end this cycle
113 bool processBarriers(DynInstPtr &inst);
114
115 void handleFault(Fault &fault);
116 public:
117 Fault getFault() { return fetchFault; }
118 private:
119 Fault fetchFault;
120
121 // Align an address (typically a PC) to the start of an I-cache block.
122 // We fold in the PISA 64- to 32-bit conversion here as well.
123 Addr icacheBlockAlignPC(Addr addr)
124 {
125 addr = TheISA::realPCToFetchPC(addr);
126 return (addr & ~(cacheBlkMask));
127 }
128
129 InstSeqNum getAndIncrementInstSeq()
130 { return cpu->globalSeqNum++; }
131
132 public:
133 FullCPU *cpu;
134
135 BackEnd *backEnd;
136
137 ThreadContext *tc;
138
139 OzoneThreadState<Impl> *thread;
140
141 enum Status {
142 Running,
143 Idle,
144 IcacheMissStall,
145 IcacheMissComplete,
146 SerializeBlocked,
147 SerializeComplete,
148 RenameBlocked,
149 QuiescePending,
150 TrapPending,
151 BEBlocked
152 };
153
154 Status status;
155
156 private:
157 TimeBuffer<CommStruct> *comm;
158 typename TimeBuffer<CommStruct>::wire fromCommit;
159
160 typedef typename Impl::BranchPred BranchPred;
161
162 BranchPred branchPred;
163
164 class IcachePort : public Port
165 {
166 protected:
167 FrontEnd *fe;
168
169 public:
170 IcachePort(const std::string &_name, FrontEnd *_fe)
171 : Port(_name), fe(_fe)
172 { }
173
174 protected:
175 virtual Tick recvAtomic(PacketPtr pkt);
176
177 virtual void recvFunctional(PacketPtr pkt);
178
179 virtual void recvStatusChange(Status status);
180
181 virtual void getDeviceAddressRanges(AddrRangeList &resp,
182 AddrRangeList &snoop)
183 { resp.clear(); snoop.clear(); }
184
185 virtual bool recvTiming(PacketPtr pkt);
186
187 virtual void recvRetry();
188 };
189
190 IcachePort icachePort;
191
192 #if !FULL_SYSTEM
193 PageTable *pTable;
194 #endif
195
196 RequestPtr memReq;
197
198 /** Mask to get a cache block's address. */
199 Addr cacheBlkMask;
200
201 unsigned cacheBlkSize;
202
203 Addr cacheBlkPC;
204
205 /** The cache line being fetched. */
206 uint8_t *cacheData;
207
208 bool fetchCacheLineNextCycle;
209
210 bool cacheBlkValid;
211
212 public:
213 RenameTable<Impl> renameTable;
214
215 private:
216 Addr PC;
217 Addr nextPC;
218
219 public:
220 void setPC(Addr val) { PC = val; }
221 void setNextPC(Addr val) { nextPC = val; }
222
223 void wakeFromQuiesce();
224
225 void dumpInsts();
226
227 private:
228 typedef typename std::deque<DynInstPtr> InstBuff;
229 typedef typename InstBuff::iterator InstBuffIt;
230
231 InstBuff instBuffer;
232
233 int instBufferSize;
234
235 int maxInstBufferSize;
236
237 int width;
238
239 int freeRegs;
240
241 int numPhysRegs;
242
243 bool serializeNext;
244
245 DynInstPtr barrierInst;
246
247 public:
248 bool interruptPending;
249 private:
250 // number of idle cycles
251 /*
252 Stats::Average<> notIdleFraction;
253 Stats::Formula idleFraction;
254 */
255 // @todo: Consider making these vectors and tracking on a per thread basis.
256 /** Stat for total number of cycles stalled due to an icache miss. */
257 Stats::Scalar<> icacheStallCycles;
258 /** Stat for total number of fetched instructions. */
259 Stats::Scalar<> fetchedInsts;
260 Stats::Scalar<> fetchedBranches;
261 /** Stat for total number of predicted branches. */
262 Stats::Scalar<> predictedBranches;
263 /** Stat for total number of cycles spent fetching. */
264 Stats::Scalar<> fetchCycles;
265
266 Stats::Scalar<> fetchIdleCycles;
267 /** Stat for total number of cycles spent squashing. */
268 Stats::Scalar<> fetchSquashCycles;
269 /** Stat for total number of cycles spent blocked due to other stages in
270 * the pipeline.
271 */
272 Stats::Scalar<> fetchBlockedCycles;
273 /** Stat for total number of fetched cache lines. */
274 Stats::Scalar<> fetchedCacheLines;
275
276 Stats::Scalar<> fetchIcacheSquashes;
277 /** Distribution of number of instructions fetched each cycle. */
278 Stats::Distribution<> fetchNisnDist;
279 // Stats::Vector<> qfull_iq_occupancy;
280 // Stats::VectorDistribution<> qfull_iq_occ_dist_;
281 Stats::Formula idleRate;
282 Stats::Formula branchRate;
283 Stats::Formula fetchRate;
284 Stats::Scalar<> IFQCount; // cumulative IFQ occupancy
285 Stats::Formula IFQOccupancy;
286 Stats::Formula IFQLatency;
287 Stats::Scalar<> IFQFcount; // cumulative IFQ full count
288 Stats::Formula IFQFullRate;
289
290 Stats::Scalar<> dispatchCountStat;
291 Stats::Scalar<> dispatchedSerializing;
292 Stats::Scalar<> dispatchedTempSerializing;
293 Stats::Scalar<> dispatchSerializeStallCycles;
294 Stats::Formula dispatchRate;
295 Stats::Formula regIntFull;
296 Stats::Formula regFpFull;
297 };
298
299 #endif // __CPU_OZONE_FRONT_END_HH__