decode.hh revision 5529:9ae69b9cd7fd
16657Snate@binkert.org/* 26657Snate@binkert.org * Copyright (c) 2004-2006 The Regents of The University of Michigan 310972Sdavid.hashe@amd.com * All rights reserved. 46657Snate@binkert.org * 56657Snate@binkert.org * Redistribution and use in source and binary forms, with or without 66657Snate@binkert.org * modification, are permitted provided that the following conditions are 76657Snate@binkert.org * met: redistributions of source code must retain the above copyright 86657Snate@binkert.org * notice, this list of conditions and the following disclaimer; 96657Snate@binkert.org * redistributions in binary form must reproduce the above copyright 106657Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 116657Snate@binkert.org * documentation and/or other materials provided with the distribution; 126657Snate@binkert.org * neither the name of the copyright holders nor the names of its 136657Snate@binkert.org * contributors may be used to endorse or promote products derived from 146657Snate@binkert.org * this software without specific prior written permission. 156657Snate@binkert.org * 166657Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176657Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186657Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196657Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206657Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216657Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226657Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236657Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246657Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256657Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266657Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276657Snate@binkert.org * 286657Snate@binkert.org * Authors: Kevin Lim 296657Snate@binkert.org */ 306657Snate@binkert.org 316657Snate@binkert.org#ifndef __CPU_O3_DECODE_HH__ 326657Snate@binkert.org#define __CPU_O3_DECODE_HH__ 336657Snate@binkert.org 346657Snate@binkert.org#include <queue> 356657Snate@binkert.org 366657Snate@binkert.org#include "base/statistics.hh" 376657Snate@binkert.org#include "base/timebuf.hh" 386657Snate@binkert.org 396657Snate@binkert.orgclass DerivO3CPUParams; 406657Snate@binkert.org 416657Snate@binkert.org/** 426657Snate@binkert.org * DefaultDecode class handles both single threaded and SMT 436657Snate@binkert.org * decode. Its width is specified by the parameters; each cycles it 447780Snilay@cs.wisc.edu * tries to decode that many instructions. Because instructions are 457780Snilay@cs.wisc.edu * actually decoded when the StaticInst is created, this stage does 467780Snilay@cs.wisc.edu * not do much other than check any PC-relative branches. 477780Snilay@cs.wisc.edu */ 487780Snilay@cs.wisc.edutemplate<class Impl> 497780Snilay@cs.wisc.educlass DefaultDecode 507780Snilay@cs.wisc.edu{ 517780Snilay@cs.wisc.edu private: 527780Snilay@cs.wisc.edu // Typedefs from the Impl. 537780Snilay@cs.wisc.edu typedef typename Impl::O3CPU O3CPU; 547780Snilay@cs.wisc.edu typedef typename Impl::DynInstPtr DynInstPtr; 557780Snilay@cs.wisc.edu typedef typename Impl::CPUPol CPUPol; 567780Snilay@cs.wisc.edu 5710972Sdavid.hashe@amd.com // Typedefs from the CPU policy. 5810972Sdavid.hashe@amd.com typedef typename CPUPol::FetchStruct FetchStruct; 597780Snilay@cs.wisc.edu typedef typename CPUPol::DecodeStruct DecodeStruct; 607780Snilay@cs.wisc.edu typedef typename CPUPol::TimeStruct TimeStruct; 617780Snilay@cs.wisc.edu 627780Snilay@cs.wisc.edu public: 637780Snilay@cs.wisc.edu /** Overall decode stage status. Used to determine if the CPU can 647780Snilay@cs.wisc.edu * deschedule itself due to a lack of activity. 657780Snilay@cs.wisc.edu */ 667780Snilay@cs.wisc.edu enum DecodeStatus { 6710972Sdavid.hashe@amd.com Active, 6810972Sdavid.hashe@amd.com Inactive 697780Snilay@cs.wisc.edu }; 7010972Sdavid.hashe@amd.com 7110972Sdavid.hashe@amd.com /** Individual thread status. */ 727780Snilay@cs.wisc.edu enum ThreadStatus { 737780Snilay@cs.wisc.edu Running, 746657Snate@binkert.org Idle, 756657Snate@binkert.org StartSquash, 766657Snate@binkert.org Squashing, 776657Snate@binkert.org Blocked, 786657Snate@binkert.org Unblocking 796657Snate@binkert.org }; 806657Snate@binkert.org 816657Snate@binkert.org private: 826657Snate@binkert.org /** Decode status. */ 836657Snate@binkert.org DecodeStatus _status; 846657Snate@binkert.org 856657Snate@binkert.org /** Per-thread status. */ 866657Snate@binkert.org ThreadStatus decodeStatus[Impl::MaxThreads]; 876657Snate@binkert.org 886657Snate@binkert.org public: 896657Snate@binkert.org /** DefaultDecode constructor. */ 906657Snate@binkert.org DefaultDecode(O3CPU *_cpu, DerivO3CPUParams *params); 916657Snate@binkert.org 926657Snate@binkert.org /** Returns the name of decode. */ 936657Snate@binkert.org std::string name() const; 946657Snate@binkert.org 956657Snate@binkert.org /** Registers statistics. */ 967839Snilay@cs.wisc.edu void regStats(); 976657Snate@binkert.org 986657Snate@binkert.org /** Sets the main backwards communication time buffer pointer. */ 996657Snate@binkert.org void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr); 10010009Snilay@cs.wisc.edu 10110009Snilay@cs.wisc.edu /** Sets pointer to time buffer used to communicate to the next stage. */ 1026657Snate@binkert.org void setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr); 1036657Snate@binkert.org 1046657Snate@binkert.org /** Sets pointer to time buffer coming from fetch. */ 1057839Snilay@cs.wisc.edu void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr); 1066657Snate@binkert.org 1076657Snate@binkert.org /** Sets pointer to list of active threads. */ 1086657Snate@binkert.org void setActiveThreads(std::list<unsigned> *at_ptr); 1096657Snate@binkert.org 1106657Snate@binkert.org /** Drains the decode stage. */ 1116657Snate@binkert.org bool drain(); 1126657Snate@binkert.org 1136657Snate@binkert.org /** Resumes execution after a drain. */ 1146657Snate@binkert.org void resume() { } 1156657Snate@binkert.org 1166657Snate@binkert.org /** Switches out the decode stage. */ 1176657Snate@binkert.org void switchOut() { } 1186657Snate@binkert.org 1196657Snate@binkert.org /** Takes over from another CPU's thread. */ 1206657Snate@binkert.org void takeOverFrom(); 1216657Snate@binkert.org 1226657Snate@binkert.org /** Ticks decode, processing all input signals and decoding as many 1236657Snate@binkert.org * instructions as possible. 1247839Snilay@cs.wisc.edu */ 1257839Snilay@cs.wisc.edu void tick(); 1267839Snilay@cs.wisc.edu 12710009Snilay@cs.wisc.edu /** Determines what to do based on decode's current status. 1287839Snilay@cs.wisc.edu * @param status_change decode() sets this variable if there was a status 1297839Snilay@cs.wisc.edu * change (ie switching from from blocking to unblocking). 1307839Snilay@cs.wisc.edu * @param tid Thread id to decode instructions from. 13110009Snilay@cs.wisc.edu */ 1327839Snilay@cs.wisc.edu void decode(bool &status_change, unsigned tid); 1337839Snilay@cs.wisc.edu 1347839Snilay@cs.wisc.edu /** Processes instructions from fetch and passes them on to rename. 13510009Snilay@cs.wisc.edu * Decoding of instructions actually happens when they are created in 1367839Snilay@cs.wisc.edu * fetch, so this function mostly checks if PC-relative branches are 1377839Snilay@cs.wisc.edu * correct. 1387839Snilay@cs.wisc.edu */ 13910009Snilay@cs.wisc.edu void decodeInsts(unsigned tid); 1407839Snilay@cs.wisc.edu 1416657Snate@binkert.org private: 1427839Snilay@cs.wisc.edu /** Inserts a thread's instructions into the skid buffer, to be decoded 1436657Snate@binkert.org * once decode unblocks. 1446657Snate@binkert.org */ 1456657Snate@binkert.org void skidInsert(unsigned tid); 1466657Snate@binkert.org 1476657Snate@binkert.org /** Returns if all of the skid buffers are empty. */ 14810981SBrad.Beckmann@amd.com bool skidsEmpty(); 14910981SBrad.Beckmann@amd.com 1509499Snilay@cs.wisc.edu /** Updates overall decode status based on all of the threads' statuses. */ 1516657Snate@binkert.org void updateStatus(); 1526657Snate@binkert.org 1536657Snate@binkert.org /** Separates instructions from fetch into individual lists of instructions 1546657Snate@binkert.org * sorted by thread. 1556657Snate@binkert.org */ 1566657Snate@binkert.org void sortInsts(); 1576657Snate@binkert.org 1586657Snate@binkert.org /** Reads all stall signals from the backwards communication timebuffer. */ 1596657Snate@binkert.org void readStallSignals(unsigned tid); 1606657Snate@binkert.org 1617793SBrad.Beckmann@amd.com /** Checks all input signals and updates decode's status appropriately. */ 1627793SBrad.Beckmann@amd.com bool checkSignalsAndUpdate(unsigned tid); 1636657Snate@binkert.org 1646657Snate@binkert.org /** Checks all stall signals, and returns if any are true. */ 1657793SBrad.Beckmann@amd.com bool checkStall(unsigned tid) const; 1666657Snate@binkert.org 1676657Snate@binkert.org /** Returns if there any instructions from fetch on this cycle. */ 1687839Snilay@cs.wisc.edu inline bool fetchInstsValid(); 1697839Snilay@cs.wisc.edu 1707839Snilay@cs.wisc.edu /** Switches decode to blocking, and signals back that decode has 1717839Snilay@cs.wisc.edu * become blocked. 1727839Snilay@cs.wisc.edu * @return Returns true if there is a status change. 1737839Snilay@cs.wisc.edu */ 1747839Snilay@cs.wisc.edu bool block(unsigned tid); 1757839Snilay@cs.wisc.edu 17610981SBrad.Beckmann@amd.com /** Switches decode to unblocking if the skid buffer is empty, and 17710981SBrad.Beckmann@amd.com * signals back that decode has unblocked. 1787839Snilay@cs.wisc.edu * @return Returns true if there is a status change. 1796657Snate@binkert.org */ 1806657Snate@binkert.org bool unblock(unsigned tid); 1816657Snate@binkert.org 1829271Snilay@cs.wisc.edu /** Squashes if there is a PC-relative branch that was predicted 1836657Snate@binkert.org * incorrectly. Sends squash information back to fetch. 1847839Snilay@cs.wisc.edu */ 1857839Snilay@cs.wisc.edu void squash(DynInstPtr &inst, unsigned tid); 1867839Snilay@cs.wisc.edu 1877839Snilay@cs.wisc.edu public: 1888192SLisa.Hsu@amd.com /** Squashes due to commit signalling a squash. Changes status to 1898192SLisa.Hsu@amd.com * squashing and clears block/unblock signals as needed. 1908192SLisa.Hsu@amd.com */ 1918192SLisa.Hsu@amd.com unsigned squash(unsigned tid); 1928192SLisa.Hsu@amd.com 1938192SLisa.Hsu@amd.com private: 1947839Snilay@cs.wisc.edu // Interfaces to objects outside of decode. 1956657Snate@binkert.org /** CPU interface. */ 1969271Snilay@cs.wisc.edu O3CPU *cpu; 1976657Snate@binkert.org 1986657Snate@binkert.org /** Time buffer interface. */ 1996657Snate@binkert.org TimeBuffer<TimeStruct> *timeBuffer; 200 201 /** Wire to get rename's output from backwards time buffer. */ 202 typename TimeBuffer<TimeStruct>::wire fromRename; 203 204 /** Wire to get iew's information from backwards time buffer. */ 205 typename TimeBuffer<TimeStruct>::wire fromIEW; 206 207 /** Wire to get commit's information from backwards time buffer. */ 208 typename TimeBuffer<TimeStruct>::wire fromCommit; 209 210 /** Wire to write information heading to previous stages. */ 211 // Might not be the best name as not only fetch will read it. 212 typename TimeBuffer<TimeStruct>::wire toFetch; 213 214 /** Decode instruction queue. */ 215 TimeBuffer<DecodeStruct> *decodeQueue; 216 217 /** Wire used to write any information heading to rename. */ 218 typename TimeBuffer<DecodeStruct>::wire toRename; 219 220 /** Fetch instruction queue interface. */ 221 TimeBuffer<FetchStruct> *fetchQueue; 222 223 /** Wire to get fetch's output from fetch queue. */ 224 typename TimeBuffer<FetchStruct>::wire fromFetch; 225 226 /** Queue of all instructions coming from fetch this cycle. */ 227 std::queue<DynInstPtr> insts[Impl::MaxThreads]; 228 229 /** Skid buffer between fetch and decode. */ 230 std::queue<DynInstPtr> skidBuffer[Impl::MaxThreads]; 231 232 /** Variable that tracks if decode has written to the time buffer this 233 * cycle. Used to tell CPU if there is activity this cycle. 234 */ 235 bool wroteToTimeBuffer; 236 237 /** Source of possible stalls. */ 238 struct Stalls { 239 bool rename; 240 bool iew; 241 bool commit; 242 }; 243 244 /** Tracks which stages are telling decode to stall. */ 245 Stalls stalls[Impl::MaxThreads]; 246 247 /** Rename to decode delay, in ticks. */ 248 unsigned renameToDecodeDelay; 249 250 /** IEW to decode delay, in ticks. */ 251 unsigned iewToDecodeDelay; 252 253 /** Commit to decode delay, in ticks. */ 254 unsigned commitToDecodeDelay; 255 256 /** Fetch to decode delay, in ticks. */ 257 unsigned fetchToDecodeDelay; 258 259 /** The width of decode, in instructions. */ 260 unsigned decodeWidth; 261 262 /** Index of instructions being sent to rename. */ 263 unsigned toRenameIndex; 264 265 /** number of Active Threads*/ 266 unsigned numThreads; 267 268 /** List of active thread ids */ 269 std::list<unsigned> *activeThreads; 270 271 /** Number of branches in flight. */ 272 unsigned branchCount[Impl::MaxThreads]; 273 274 /** Maximum size of the skid buffer. */ 275 unsigned skidBufferMax; 276 277 /** SeqNum of Squashing Branch Delay Instruction (used for MIPS)*/ 278 Addr bdelayDoneSeqNum[Impl::MaxThreads]; 279 280 /** Instruction used for squashing branch (used for MIPS)*/ 281 DynInstPtr squashInst[Impl::MaxThreads]; 282 283 /** Tells when their is a pending delay slot inst. to send 284 * to rename. If there is, then wait squash after the next 285 * instruction (used for MIPS). 286 */ 287 bool squashAfterDelaySlot[Impl::MaxThreads]; 288 289 290 /** Stat for total number of idle cycles. */ 291 Stats::Scalar<> decodeIdleCycles; 292 /** Stat for total number of blocked cycles. */ 293 Stats::Scalar<> decodeBlockedCycles; 294 /** Stat for total number of normal running cycles. */ 295 Stats::Scalar<> decodeRunCycles; 296 /** Stat for total number of unblocking cycles. */ 297 Stats::Scalar<> decodeUnblockCycles; 298 /** Stat for total number of squashing cycles. */ 299 Stats::Scalar<> decodeSquashCycles; 300 /** Stat for number of times a branch is resolved at decode. */ 301 Stats::Scalar<> decodeBranchResolved; 302 /** Stat for number of times a branch mispredict is detected. */ 303 Stats::Scalar<> decodeBranchMispred; 304 /** Stat for number of times decode detected a non-control instruction 305 * incorrectly predicted as a branch. 306 */ 307 Stats::Scalar<> decodeControlMispred; 308 /** Stat for total number of decoded instructions. */ 309 Stats::Scalar<> decodeDecodedInsts; 310 /** Stat for total number of squashed instructions. */ 311 Stats::Scalar<> decodeSquashedInsts; 312}; 313 314#endif // __CPU_O3_DECODE_HH__ 315