decode.hh revision 2307
112726Snikos.nikoleris@arm.com/* 29380SAndreas.Sandberg@ARM.com * Copyright (c) 2004-2005 The Regents of The University of Michigan 39380SAndreas.Sandberg@ARM.com * All rights reserved. 49380SAndreas.Sandberg@ARM.com * 59380SAndreas.Sandberg@ARM.com * Redistribution and use in source and binary forms, with or without 69380SAndreas.Sandberg@ARM.com * modification, are permitted provided that the following conditions are 79380SAndreas.Sandberg@ARM.com * met: redistributions of source code must retain the above copyright 89380SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer; 99380SAndreas.Sandberg@ARM.com * redistributions in binary form must reproduce the above copyright 109380SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer in the 119380SAndreas.Sandberg@ARM.com * documentation and/or other materials provided with the distribution; 129380SAndreas.Sandberg@ARM.com * neither the name of the copyright holders nor the names of its 139380SAndreas.Sandberg@ARM.com * contributors may be used to endorse or promote products derived from 149380SAndreas.Sandberg@ARM.com * this software without specific prior written permission. 159380SAndreas.Sandberg@ARM.com * 169380SAndreas.Sandberg@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179380SAndreas.Sandberg@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 189380SAndreas.Sandberg@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 199380SAndreas.Sandberg@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 209380SAndreas.Sandberg@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 219380SAndreas.Sandberg@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 229380SAndreas.Sandberg@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239380SAndreas.Sandberg@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249380SAndreas.Sandberg@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259380SAndreas.Sandberg@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 269380SAndreas.Sandberg@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279380SAndreas.Sandberg@ARM.com */ 289380SAndreas.Sandberg@ARM.com 299380SAndreas.Sandberg@ARM.com#ifndef __CPU_O3_DECODE_HH__ 309380SAndreas.Sandberg@ARM.com#define __CPU_O3_DECODE_HH__ 319380SAndreas.Sandberg@ARM.com 329380SAndreas.Sandberg@ARM.com#include <queue> 339380SAndreas.Sandberg@ARM.com 349380SAndreas.Sandberg@ARM.com#include "base/statistics.hh" 359380SAndreas.Sandberg@ARM.com#include "base/timebuf.hh" 369380SAndreas.Sandberg@ARM.com 379792Sandreas.hansson@arm.com/** 389380SAndreas.Sandberg@ARM.com * DefaultDecode class handles both single threaded and SMT decode. Its width is 399380SAndreas.Sandberg@ARM.com * specified by the parameters; each cycles it tries to decode that many 4012070Snikos.nikoleris@arm.com * instructions. Because instructions are actually decoded when the StaticInst 419380SAndreas.Sandberg@ARM.com * is created, this stage does not do much other than check any PC-relative 429380SAndreas.Sandberg@ARM.com * branches. 439380SAndreas.Sandberg@ARM.com */ 4411682Sandreas.hansson@arm.comtemplate<class Impl> 4511682Sandreas.hansson@arm.comclass DefaultDecode 4612070Snikos.nikoleris@arm.com{ 4711682Sandreas.hansson@arm.com private: 4812070Snikos.nikoleris@arm.com // Typedefs from the Impl. 499380SAndreas.Sandberg@ARM.com typedef typename Impl::FullCPU FullCPU; 509654SAndreas.Sandberg@ARM.com typedef typename Impl::DynInstPtr DynInstPtr; 519654SAndreas.Sandberg@ARM.com typedef typename Impl::Params Params; 529380SAndreas.Sandberg@ARM.com typedef typename Impl::CPUPol CPUPol; 539380SAndreas.Sandberg@ARM.com 549380SAndreas.Sandberg@ARM.com // Typedefs from the CPU policy. 559380SAndreas.Sandberg@ARM.com typedef typename CPUPol::FetchStruct FetchStruct; 569380SAndreas.Sandberg@ARM.com typedef typename CPUPol::DecodeStruct DecodeStruct; 579380SAndreas.Sandberg@ARM.com typedef typename CPUPol::TimeStruct TimeStruct; 589380SAndreas.Sandberg@ARM.com 599380SAndreas.Sandberg@ARM.com public: 609380SAndreas.Sandberg@ARM.com /** Overall decode stage status. Used to determine if the CPU can 619380SAndreas.Sandberg@ARM.com * deschedule itself due to a lack of activity. 629380SAndreas.Sandberg@ARM.com */ 639792Sandreas.hansson@arm.com enum DecodeStatus { 6411156Sandreas.sandberg@arm.com Active, 6512070Snikos.nikoleris@arm.com Inactive 669792Sandreas.hansson@arm.com }; 679380SAndreas.Sandberg@ARM.com 689380SAndreas.Sandberg@ARM.com /** Individual thread status. */ 699380SAndreas.Sandberg@ARM.com enum ThreadStatus { 709792Sandreas.hansson@arm.com Running, 719380SAndreas.Sandberg@ARM.com Idle, 729380SAndreas.Sandberg@ARM.com StartSquash, 739380SAndreas.Sandberg@ARM.com Squashing, 7410512SAli.Saidi@ARM.com Blocked, 7512070Snikos.nikoleris@arm.com Unblocking 769380SAndreas.Sandberg@ARM.com }; 779380SAndreas.Sandberg@ARM.com 789792Sandreas.hansson@arm.com private: 799380SAndreas.Sandberg@ARM.com /** Decode status. */ 809380SAndreas.Sandberg@ARM.com DecodeStatus _status; 8111156Sandreas.sandberg@arm.com 829380SAndreas.Sandberg@ARM.com /** Per-thread status. */ 8312070Snikos.nikoleris@arm.com ThreadStatus decodeStatus[Impl::MaxThreads]; 849380SAndreas.Sandberg@ARM.com 859793Sakash.bagdia@arm.com public: 869380SAndreas.Sandberg@ARM.com /** DefaultDecode constructor. */ 8711156Sandreas.sandberg@arm.com DefaultDecode(Params *params); 8811156Sandreas.sandberg@arm.com 899793Sakash.bagdia@arm.com /** Returns the name of decode. */ 909380SAndreas.Sandberg@ARM.com std::string name() const; 919380SAndreas.Sandberg@ARM.com 929380SAndreas.Sandberg@ARM.com /** Registers statistics. */ 939380SAndreas.Sandberg@ARM.com void regStats(); 949380SAndreas.Sandberg@ARM.com 959380SAndreas.Sandberg@ARM.com /** Sets CPU pointer. */ 969380SAndreas.Sandberg@ARM.com void setCPU(FullCPU *cpu_ptr); 979380SAndreas.Sandberg@ARM.com 989380SAndreas.Sandberg@ARM.com /** Sets the main backwards communication time buffer pointer. */ 999380SAndreas.Sandberg@ARM.com void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr); 1009380SAndreas.Sandberg@ARM.com 1019380SAndreas.Sandberg@ARM.com /** Sets pointer to time buffer used to communicate to the next stage. */ 10210884Sandreas.hansson@arm.com void setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr); 10310884Sandreas.hansson@arm.com 1049380SAndreas.Sandberg@ARM.com /** Sets pointer to time buffer coming from fetch. */ 1059380SAndreas.Sandberg@ARM.com void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr); 1069380SAndreas.Sandberg@ARM.com 1079380SAndreas.Sandberg@ARM.com /** Sets pointer to list of active threads. */ 1089380SAndreas.Sandberg@ARM.com void setActiveThreads(std::list<unsigned> *at_ptr); 1099380SAndreas.Sandberg@ARM.com 1109380SAndreas.Sandberg@ARM.com void switchOut(); 1119380SAndreas.Sandberg@ARM.com 1129380SAndreas.Sandberg@ARM.com void takeOverFrom(); 1139380SAndreas.Sandberg@ARM.com /** Ticks decode, processing all input signals and decoding as many 11410720Sandreas.hansson@arm.com * instructions as possible. 1159793Sakash.bagdia@arm.com */ 1169793Sakash.bagdia@arm.com void tick(); 1179380SAndreas.Sandberg@ARM.com 1189380SAndreas.Sandberg@ARM.com /** Determines what to do based on decode's current status. 1199380SAndreas.Sandberg@ARM.com * @param status_change decode() sets this variable if there was a status 1209380SAndreas.Sandberg@ARM.com * change (ie switching from from blocking to unblocking). 1219674Snilay@cs.wisc.edu * @param tid Thread id to decode instructions from. 1229380SAndreas.Sandberg@ARM.com */ 1239380SAndreas.Sandberg@ARM.com void decode(bool &status_change, unsigned tid); 1249380SAndreas.Sandberg@ARM.com 1259380SAndreas.Sandberg@ARM.com /** Processes instructions from fetch and passes them on to rename. 1269380SAndreas.Sandberg@ARM.com * Decoding of instructions actually happens when they are created in 1279380SAndreas.Sandberg@ARM.com * fetch, so this function mostly checks if PC-relative branches are 1289674Snilay@cs.wisc.edu * correct. 1299674Snilay@cs.wisc.edu */ 1309674Snilay@cs.wisc.edu void decodeInsts(unsigned tid); 1319674Snilay@cs.wisc.edu 1329674Snilay@cs.wisc.edu private: 1339380SAndreas.Sandberg@ARM.com /** Inserts a thread's instructions into the skid buffer, to be decoded 1349654SAndreas.Sandberg@ARM.com * once decode unblocks. 1359654SAndreas.Sandberg@ARM.com */ 1369654SAndreas.Sandberg@ARM.com void skidInsert(unsigned tid); 1379654SAndreas.Sandberg@ARM.com 1389654SAndreas.Sandberg@ARM.com /** Returns if all of the skid buffers are empty. */ 1399654SAndreas.Sandberg@ARM.com bool skidsEmpty(); 1409654SAndreas.Sandberg@ARM.com 1419654SAndreas.Sandberg@ARM.com /** Updates overall decode status based on all of the threads' statuses. */ 1429380SAndreas.Sandberg@ARM.com void updateStatus(); 1439380SAndreas.Sandberg@ARM.com 1449380SAndreas.Sandberg@ARM.com /** Separates instructions from fetch into individual lists of instructions 1459380SAndreas.Sandberg@ARM.com * sorted by thread. 1469380SAndreas.Sandberg@ARM.com */ 1479380SAndreas.Sandberg@ARM.com void sortInsts(); 1489793Sakash.bagdia@arm.com 1499793Sakash.bagdia@arm.com /** Reads all stall signals from the backwards communication timebuffer. */ 1509380SAndreas.Sandberg@ARM.com void readStallSignals(unsigned tid); 1519654SAndreas.Sandberg@ARM.com 1529654SAndreas.Sandberg@ARM.com /** Checks all input signals and updates decode's status appropriately. */ 1539654SAndreas.Sandberg@ARM.com bool checkSignalsAndUpdate(unsigned tid); 1549654SAndreas.Sandberg@ARM.com 15512070Snikos.nikoleris@arm.com /** Checks all stall signals, and returns if any are true. */ 15612070Snikos.nikoleris@arm.com bool checkStall(unsigned tid) const; 15712070Snikos.nikoleris@arm.com 15812070Snikos.nikoleris@arm.com /** Returns if there any instructions from fetch on this cycle. */ 15912070Snikos.nikoleris@arm.com inline bool fetchInstsValid(); 16012070Snikos.nikoleris@arm.com 16111604Sandreas.hansson@arm.com /** Switches decode to blocking, and signals back that decode has 16212070Snikos.nikoleris@arm.com * become blocked. 16312070Snikos.nikoleris@arm.com * @return Returns true if there is a status change. 16412070Snikos.nikoleris@arm.com */ 16512070Snikos.nikoleris@arm.com bool block(unsigned tid); 16612070Snikos.nikoleris@arm.com 16712070Snikos.nikoleris@arm.com /** Switches decode to unblocking if the skid buffer is empty, and 16812070Snikos.nikoleris@arm.com * signals back that decode has unblocked. 16912070Snikos.nikoleris@arm.com * @return Returns true if there is a status change. 17012070Snikos.nikoleris@arm.com */ 17112070Snikos.nikoleris@arm.com bool unblock(unsigned tid); 17212070Snikos.nikoleris@arm.com 17312598Snikos.nikoleris@arm.com /** Squashes if there is a PC-relative branch that was predicted 17412070Snikos.nikoleris@arm.com * incorrectly. Sends squash information back to fetch. 17512598Snikos.nikoleris@arm.com */ 17612070Snikos.nikoleris@arm.com void squash(DynInstPtr &inst, unsigned tid); 17712070Snikos.nikoleris@arm.com 17812070Snikos.nikoleris@arm.com public: 17912070Snikos.nikoleris@arm.com /** Squashes due to commit signalling a squash. Changes status to 18012070Snikos.nikoleris@arm.com * squashing and clears block/unblock signals as needed. 18112070Snikos.nikoleris@arm.com */ 18212070Snikos.nikoleris@arm.com unsigned squash(unsigned tid); 18312070Snikos.nikoleris@arm.com 18412070Snikos.nikoleris@arm.com private: 18512070Snikos.nikoleris@arm.com // Interfaces to objects outside of decode. 18612070Snikos.nikoleris@arm.com /** CPU interface. */ 18712070Snikos.nikoleris@arm.com FullCPU *cpu; 18812070Snikos.nikoleris@arm.com 18912070Snikos.nikoleris@arm.com /** Time buffer interface. */ 1909380SAndreas.Sandberg@ARM.com TimeBuffer<TimeStruct> *timeBuffer; 1919793Sakash.bagdia@arm.com 1929793Sakash.bagdia@arm.com /** Wire to get rename's output from backwards time buffer. */ 1939793Sakash.bagdia@arm.com typename TimeBuffer<TimeStruct>::wire fromRename; 1949793Sakash.bagdia@arm.com 1959827Sakash.bagdia@arm.com /** Wire to get iew's information from backwards time buffer. */ 1969827Sakash.bagdia@arm.com typename TimeBuffer<TimeStruct>::wire fromIEW; 1979827Sakash.bagdia@arm.com 1989827Sakash.bagdia@arm.com /** Wire to get commit's information from backwards time buffer. */ 1999793Sakash.bagdia@arm.com typename TimeBuffer<TimeStruct>::wire fromCommit; 2009793Sakash.bagdia@arm.com 2019793Sakash.bagdia@arm.com /** Wire to write information heading to previous stages. */ 2029827Sakash.bagdia@arm.com // Might not be the best name as not only fetch will read it. 2039827Sakash.bagdia@arm.com typename TimeBuffer<TimeStruct>::wire toFetch; 2049827Sakash.bagdia@arm.com 2059793Sakash.bagdia@arm.com /** Decode instruction queue. */ 2069380SAndreas.Sandberg@ARM.com TimeBuffer<DecodeStruct> *decodeQueue; 2079380SAndreas.Sandberg@ARM.com 2089380SAndreas.Sandberg@ARM.com /** Wire used to write any information heading to rename. */ 2099380SAndreas.Sandberg@ARM.com typename TimeBuffer<DecodeStruct>::wire toRename; 2109380SAndreas.Sandberg@ARM.com 2119380SAndreas.Sandberg@ARM.com /** Fetch instruction queue interface. */ 2129380SAndreas.Sandberg@ARM.com TimeBuffer<FetchStruct> *fetchQueue; 2139380SAndreas.Sandberg@ARM.com 2149380SAndreas.Sandberg@ARM.com /** Wire to get fetch's output from fetch queue. */ 2159380SAndreas.Sandberg@ARM.com typename TimeBuffer<FetchStruct>::wire fromFetch; 2169380SAndreas.Sandberg@ARM.com 2179792Sandreas.hansson@arm.com /** Queue of all instructions coming from fetch this cycle. */ 2189792Sandreas.hansson@arm.com std::queue<DynInstPtr> insts[Impl::MaxThreads]; 2199792Sandreas.hansson@arm.com 2209792Sandreas.hansson@arm.com /** Skid buffer between fetch and decode. */ 2219792Sandreas.hansson@arm.com std::queue<DynInstPtr> skidBuffer[Impl::MaxThreads]; 2229792Sandreas.hansson@arm.com 2239792Sandreas.hansson@arm.com /** Variable that tracks if decode has written to the time buffer this 2249792Sandreas.hansson@arm.com * cycle. Used to tell CPU if there is activity this cycle. 2259792Sandreas.hansson@arm.com */ 2269792Sandreas.hansson@arm.com bool wroteToTimeBuffer; 2279792Sandreas.hansson@arm.com 22810720Sandreas.hansson@arm.com /** Source of possible stalls. */ 22911156Sandreas.sandberg@arm.com struct Stalls { 23011156Sandreas.sandberg@arm.com bool rename; 23112070Snikos.nikoleris@arm.com bool iew; 23212070Snikos.nikoleris@arm.com bool commit; 2339792Sandreas.hansson@arm.com }; 2349792Sandreas.hansson@arm.com 2359792Sandreas.hansson@arm.com /** Tracks which stages are telling decode to stall. */ 2369792Sandreas.hansson@arm.com Stalls stalls[Impl::MaxThreads]; 2379792Sandreas.hansson@arm.com 2389792Sandreas.hansson@arm.com /** Rename to decode delay, in ticks. */ 2399792Sandreas.hansson@arm.com unsigned renameToDecodeDelay; 2409792Sandreas.hansson@arm.com 2419792Sandreas.hansson@arm.com /** IEW to decode delay, in ticks. */ 2429792Sandreas.hansson@arm.com unsigned iewToDecodeDelay; 2439792Sandreas.hansson@arm.com 2449792Sandreas.hansson@arm.com /** Commit to decode delay, in ticks. */ 2459792Sandreas.hansson@arm.com unsigned commitToDecodeDelay; 2469792Sandreas.hansson@arm.com 2479792Sandreas.hansson@arm.com /** Fetch to decode delay, in ticks. */ 2489792Sandreas.hansson@arm.com unsigned fetchToDecodeDelay; 2499792Sandreas.hansson@arm.com 2509792Sandreas.hansson@arm.com /** The width of decode, in instructions. */ 2519792Sandreas.hansson@arm.com unsigned decodeWidth; 2529792Sandreas.hansson@arm.com 2539792Sandreas.hansson@arm.com /** Index of instructions being sent to rename. */ 2549792Sandreas.hansson@arm.com unsigned toRenameIndex; 2559792Sandreas.hansson@arm.com 25610884Sandreas.hansson@arm.com /** number of Active Threads*/ 25710884Sandreas.hansson@arm.com unsigned numThreads; 2589792Sandreas.hansson@arm.com 2599792Sandreas.hansson@arm.com /** List of active thread ids */ 2609792Sandreas.hansson@arm.com std::list<unsigned> *activeThreads; 2619792Sandreas.hansson@arm.com 2629792Sandreas.hansson@arm.com /** Number of branches in flight. */ 2639380SAndreas.Sandberg@ARM.com unsigned branchCount[Impl::MaxThreads]; 2649380SAndreas.Sandberg@ARM.com 2659380SAndreas.Sandberg@ARM.com /** Maximum size of the skid buffer. */ 2669380SAndreas.Sandberg@ARM.com unsigned skidBufferMax; 2679380SAndreas.Sandberg@ARM.com 2689380SAndreas.Sandberg@ARM.com /** Stat for total number of idle cycles. */ 2699380SAndreas.Sandberg@ARM.com Stats::Scalar<> decodeIdleCycles; 2709380SAndreas.Sandberg@ARM.com /** Stat for total number of blocked cycles. */ 2719380SAndreas.Sandberg@ARM.com Stats::Scalar<> decodeBlockedCycles; 27212070Snikos.nikoleris@arm.com /** Stat for total number of normal running cycles. */ 27312070Snikos.nikoleris@arm.com Stats::Scalar<> decodeRunCycles; 27412070Snikos.nikoleris@arm.com /** Stat for total number of unblocking cycles. */ 27512070Snikos.nikoleris@arm.com Stats::Scalar<> decodeUnblockCycles; 27612070Snikos.nikoleris@arm.com /** Stat for total number of squashing cycles. */ 27712070Snikos.nikoleris@arm.com Stats::Scalar<> decodeSquashCycles; 27812070Snikos.nikoleris@arm.com /** Stat for number of times a branch is resolved at decode. */ 27912070Snikos.nikoleris@arm.com Stats::Scalar<> decodeBranchResolved; 28012070Snikos.nikoleris@arm.com /** Stat for number of times a branch mispredict is detected. */ 28112726Snikos.nikoleris@arm.com Stats::Scalar<> decodeBranchMispred; 28212726Snikos.nikoleris@arm.com /** Stat for number of times decode detected a non-control instruction 28312726Snikos.nikoleris@arm.com * incorrectly predicted as a branch. 28412726Snikos.nikoleris@arm.com */ 28512726Snikos.nikoleris@arm.com Stats::Scalar<> decodeControlMispred; 28612726Snikos.nikoleris@arm.com /** Stat for total number of decoded instructions. */ 28712726Snikos.nikoleris@arm.com Stats::Scalar<> decodeDecodedInsts; 28812726Snikos.nikoleris@arm.com /** Stat for total number of squashed instructions. */ 28912726Snikos.nikoleris@arm.com Stats::Scalar<> decodeSquashedInsts; 29012726Snikos.nikoleris@arm.com}; 29112070Snikos.nikoleris@arm.com 29212726Snikos.nikoleris@arm.com#endif // __CPU_O3_DECODE_HH__ 29312726Snikos.nikoleris@arm.com