110259SAndrew.Bardsley@arm.com/* 210259SAndrew.Bardsley@arm.com * Copyright (c) 2013-2014 ARM Limited 310259SAndrew.Bardsley@arm.com * All rights reserved 410259SAndrew.Bardsley@arm.com * 510259SAndrew.Bardsley@arm.com * The license below extends only to copyright in the software and shall 610259SAndrew.Bardsley@arm.com * not be construed as granting a license to any other intellectual 710259SAndrew.Bardsley@arm.com * property including but not limited to intellectual property relating 810259SAndrew.Bardsley@arm.com * to a hardware implementation of the functionality of the software 910259SAndrew.Bardsley@arm.com * licensed hereunder. You may use the software subject to the license 1010259SAndrew.Bardsley@arm.com * terms below provided that you ensure that this notice is replicated 1110259SAndrew.Bardsley@arm.com * unmodified and in its entirety in all distributions of the software, 1210259SAndrew.Bardsley@arm.com * modified or unmodified, in source code or in binary form. 1310259SAndrew.Bardsley@arm.com * 1410259SAndrew.Bardsley@arm.com * Redistribution and use in source and binary forms, with or without 1510259SAndrew.Bardsley@arm.com * modification, are permitted provided that the following conditions are 1610259SAndrew.Bardsley@arm.com * met: redistributions of source code must retain the above copyright 1710259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer; 1810259SAndrew.Bardsley@arm.com * redistributions in binary form must reproduce the above copyright 1910259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer in the 2010259SAndrew.Bardsley@arm.com * documentation and/or other materials provided with the distribution; 2110259SAndrew.Bardsley@arm.com * neither the name of the copyright holders nor the names of its 2210259SAndrew.Bardsley@arm.com * contributors may be used to endorse or promote products derived from 2310259SAndrew.Bardsley@arm.com * this software without specific prior written permission. 2410259SAndrew.Bardsley@arm.com * 2510259SAndrew.Bardsley@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610259SAndrew.Bardsley@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710259SAndrew.Bardsley@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810259SAndrew.Bardsley@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910259SAndrew.Bardsley@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010259SAndrew.Bardsley@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110259SAndrew.Bardsley@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210259SAndrew.Bardsley@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310259SAndrew.Bardsley@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410259SAndrew.Bardsley@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510259SAndrew.Bardsley@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610259SAndrew.Bardsley@arm.com * 3710259SAndrew.Bardsley@arm.com * Authors: Andrew Bardsley 3810259SAndrew.Bardsley@arm.com */ 3910259SAndrew.Bardsley@arm.com 4010259SAndrew.Bardsley@arm.com/** 4110259SAndrew.Bardsley@arm.com * @file 4210259SAndrew.Bardsley@arm.com * 4310259SAndrew.Bardsley@arm.com * Contains class definitions for data flowing between pipeline stages in 4410259SAndrew.Bardsley@arm.com * the top-level structure portion of this model. Latch types are also 4510259SAndrew.Bardsley@arm.com * defined which pair forward/backward flowing data specific to each stage 4610259SAndrew.Bardsley@arm.com * pair. 4710259SAndrew.Bardsley@arm.com * 4810259SAndrew.Bardsley@arm.com * No post-configuration inter-stage communication should *ever* take place 4910259SAndrew.Bardsley@arm.com * outside these classes (except for reservation!) 5010259SAndrew.Bardsley@arm.com */ 5110259SAndrew.Bardsley@arm.com 5210259SAndrew.Bardsley@arm.com#ifndef __CPU_MINOR_PIPE_DATA_HH__ 5310259SAndrew.Bardsley@arm.com#define __CPU_MINOR_PIPE_DATA_HH__ 5410259SAndrew.Bardsley@arm.com 5510259SAndrew.Bardsley@arm.com#include "cpu/minor/buffers.hh" 5610259SAndrew.Bardsley@arm.com#include "cpu/minor/dyn_inst.hh" 5710259SAndrew.Bardsley@arm.com#include "cpu/base.hh" 5810259SAndrew.Bardsley@arm.com 5910259SAndrew.Bardsley@arm.comnamespace Minor 6010259SAndrew.Bardsley@arm.com{ 6110259SAndrew.Bardsley@arm.com 6210259SAndrew.Bardsley@arm.com/** Forward data betwen Execute and Fetch1 carrying change-of-address/stream 6310259SAndrew.Bardsley@arm.com * information. */ 6410259SAndrew.Bardsley@arm.comclass BranchData /* : public ReportIF, public BubbleIF */ 6510259SAndrew.Bardsley@arm.com{ 6610259SAndrew.Bardsley@arm.com public: 6710259SAndrew.Bardsley@arm.com enum Reason 6810259SAndrew.Bardsley@arm.com { 6910259SAndrew.Bardsley@arm.com /* *** No change of stream (information to branch prediction) */ 7010259SAndrew.Bardsley@arm.com 7110259SAndrew.Bardsley@arm.com /* Don't branch at all (bubble) */ 7210259SAndrew.Bardsley@arm.com NoBranch, 7310259SAndrew.Bardsley@arm.com /* Don't branch, but here's the details of a correct prediction 7410259SAndrew.Bardsley@arm.com * that was executed */ 7510259SAndrew.Bardsley@arm.com CorrectlyPredictedBranch, 7610259SAndrew.Bardsley@arm.com 7710259SAndrew.Bardsley@arm.com /* *** Change of stream */ 7810259SAndrew.Bardsley@arm.com 7910259SAndrew.Bardsley@arm.com /* Take an unpredicted branch */ 8010259SAndrew.Bardsley@arm.com UnpredictedBranch, 8110259SAndrew.Bardsley@arm.com /* Take a branch on branch prediction data (from Fetch2) */ 8210259SAndrew.Bardsley@arm.com BranchPrediction, 8310259SAndrew.Bardsley@arm.com /* Prediction of wrong target PC */ 8410259SAndrew.Bardsley@arm.com BadlyPredictedBranchTarget, 8510259SAndrew.Bardsley@arm.com /* Bad branch prediction (didn't actually branch). Need to branch 8610259SAndrew.Bardsley@arm.com * back to correct stream. If the target is wrong, use 8710259SAndrew.Bardsley@arm.com * BadlyPredictedBranchTarget */ 8810259SAndrew.Bardsley@arm.com BadlyPredictedBranch, 8910259SAndrew.Bardsley@arm.com /* Suspend fetching for this thread (inst->id.threadId). 9010259SAndrew.Bardsley@arm.com * This will be woken up by another stream changing branch so 9110259SAndrew.Bardsley@arm.com * count it as stream changing itself and expect pc to be the PC 9210259SAndrew.Bardsley@arm.com * of the next instruction */ 9310259SAndrew.Bardsley@arm.com SuspendThread, 9410259SAndrew.Bardsley@arm.com /* Branch from an interrupt (no instruction) */ 9510259SAndrew.Bardsley@arm.com Interrupt, 9610259SAndrew.Bardsley@arm.com /* Stop fetching in anticipation of of draining */ 9710259SAndrew.Bardsley@arm.com HaltFetch 9810259SAndrew.Bardsley@arm.com }; 9910259SAndrew.Bardsley@arm.com 10010259SAndrew.Bardsley@arm.com /** Is a request with this reason actually a request to change the 10110259SAndrew.Bardsley@arm.com * PC rather than a bubble or branch prediction information */ 10210259SAndrew.Bardsley@arm.com static bool isStreamChange(const BranchData::Reason reason); 10310259SAndrew.Bardsley@arm.com 10410259SAndrew.Bardsley@arm.com /** Is a request with this reason actually a 'real' branch, that is, 10510259SAndrew.Bardsley@arm.com * a stream change that's not just an instruction to Fetch1 to halt 10610259SAndrew.Bardsley@arm.com * or wake up */ 10710259SAndrew.Bardsley@arm.com static bool isBranch(const BranchData::Reason reason); 10810259SAndrew.Bardsley@arm.com 10910259SAndrew.Bardsley@arm.com public: 11010259SAndrew.Bardsley@arm.com /** Explanation for this branch */ 11110259SAndrew.Bardsley@arm.com Reason reason; 11210259SAndrew.Bardsley@arm.com 11311567Smitch.hayenga@arm.com /** ThreadID associated with branch */ 11411567Smitch.hayenga@arm.com ThreadID threadId; 11511567Smitch.hayenga@arm.com 11610259SAndrew.Bardsley@arm.com /** Sequence number of new stream/prediction to be adopted */ 11710259SAndrew.Bardsley@arm.com InstSeqNum newStreamSeqNum; 11810259SAndrew.Bardsley@arm.com InstSeqNum newPredictionSeqNum; 11910259SAndrew.Bardsley@arm.com 12010259SAndrew.Bardsley@arm.com /** Starting PC of that stream */ 12110259SAndrew.Bardsley@arm.com TheISA::PCState target; 12210259SAndrew.Bardsley@arm.com 12310259SAndrew.Bardsley@arm.com /** Instruction which caused this branch */ 12410259SAndrew.Bardsley@arm.com MinorDynInstPtr inst; 12510259SAndrew.Bardsley@arm.com 12610259SAndrew.Bardsley@arm.com public: 12710259SAndrew.Bardsley@arm.com BranchData() : 12811567Smitch.hayenga@arm.com reason(NoBranch), threadId(InvalidThreadID), newStreamSeqNum(0), 12910259SAndrew.Bardsley@arm.com newPredictionSeqNum(0), target(TheISA::PCState(0)), 13010259SAndrew.Bardsley@arm.com inst(MinorDynInst::bubble()) 13110259SAndrew.Bardsley@arm.com { } 13210259SAndrew.Bardsley@arm.com 13310259SAndrew.Bardsley@arm.com BranchData( 13410259SAndrew.Bardsley@arm.com Reason reason_, 13511567Smitch.hayenga@arm.com ThreadID thread_id, 13610259SAndrew.Bardsley@arm.com InstSeqNum new_stream_seq_num, 13710259SAndrew.Bardsley@arm.com InstSeqNum new_prediction_seq_num, 13810259SAndrew.Bardsley@arm.com TheISA::PCState target, 13910259SAndrew.Bardsley@arm.com MinorDynInstPtr inst_) : 14010259SAndrew.Bardsley@arm.com reason(reason_), 14111567Smitch.hayenga@arm.com threadId(thread_id), 14210259SAndrew.Bardsley@arm.com newStreamSeqNum(new_stream_seq_num), 14310259SAndrew.Bardsley@arm.com newPredictionSeqNum(new_prediction_seq_num), 14410259SAndrew.Bardsley@arm.com target(target), 14510259SAndrew.Bardsley@arm.com inst(inst_) 14610259SAndrew.Bardsley@arm.com { } 14710259SAndrew.Bardsley@arm.com 14810259SAndrew.Bardsley@arm.com /** BubbleIF interface */ 14910259SAndrew.Bardsley@arm.com static BranchData bubble() { return BranchData(); } 15010259SAndrew.Bardsley@arm.com bool isBubble() const { return reason == NoBranch; } 15110259SAndrew.Bardsley@arm.com 15210259SAndrew.Bardsley@arm.com /** As static isStreamChange but on this branch data */ 15310259SAndrew.Bardsley@arm.com bool isStreamChange() const { return isStreamChange(reason); } 15410259SAndrew.Bardsley@arm.com 15510259SAndrew.Bardsley@arm.com /** As static isBranch but on this branch data */ 15610259SAndrew.Bardsley@arm.com bool isBranch() const { return isBranch(reason); } 15710259SAndrew.Bardsley@arm.com 15810259SAndrew.Bardsley@arm.com /** ReportIF interface */ 15910259SAndrew.Bardsley@arm.com void reportData(std::ostream &os) const; 16010259SAndrew.Bardsley@arm.com}; 16110259SAndrew.Bardsley@arm.com 16210259SAndrew.Bardsley@arm.com/** Print a branch reason enum */ 16310259SAndrew.Bardsley@arm.comstd::ostream &operator <<(std::ostream &os, BranchData::Reason reason); 16410259SAndrew.Bardsley@arm.com 16510259SAndrew.Bardsley@arm.com/** Print BranchData contents in a format suitable for DPRINTF comments, not 16610259SAndrew.Bardsley@arm.com * for MinorTrace */ 16710259SAndrew.Bardsley@arm.comstd::ostream &operator <<(std::ostream &os, const BranchData &branch); 16810259SAndrew.Bardsley@arm.com 16910259SAndrew.Bardsley@arm.com/** Line fetch data in the forward direction. Contains a single cache line 17010259SAndrew.Bardsley@arm.com * (or fragment of a line), its address, a sequence number assigned when 17110259SAndrew.Bardsley@arm.com * that line was fetched and a bubbleFlag that can allow ForwardLineData to 17210259SAndrew.Bardsley@arm.com * be used to represent the absence of line data in a pipeline. */ 17310259SAndrew.Bardsley@arm.comclass ForwardLineData /* : public ReportIF, public BubbleIF */ 17410259SAndrew.Bardsley@arm.com{ 17510259SAndrew.Bardsley@arm.com private: 17610259SAndrew.Bardsley@arm.com /** This line is a bubble. No other data member is required to be valid 17710259SAndrew.Bardsley@arm.com * if this is true */ 17810259SAndrew.Bardsley@arm.com bool bubbleFlag; 17910259SAndrew.Bardsley@arm.com 18010259SAndrew.Bardsley@arm.com public: 18110259SAndrew.Bardsley@arm.com /** First byte address in the line. This is allowed to be 18210259SAndrew.Bardsley@arm.com * <= pc.instAddr() */ 18310259SAndrew.Bardsley@arm.com Addr lineBaseAddr; 18410259SAndrew.Bardsley@arm.com 18510259SAndrew.Bardsley@arm.com /** PC of the first requested inst within this line */ 18610259SAndrew.Bardsley@arm.com TheISA::PCState pc; 18710259SAndrew.Bardsley@arm.com 18810259SAndrew.Bardsley@arm.com /** Explicit line width, don't rely on data.size */ 18910259SAndrew.Bardsley@arm.com unsigned int lineWidth; 19010259SAndrew.Bardsley@arm.com 19110259SAndrew.Bardsley@arm.com public: 19210259SAndrew.Bardsley@arm.com /** This line has a fault. The bubble flag will be false and seqNums 19310259SAndrew.Bardsley@arm.com * will be valid but no data will */ 19410259SAndrew.Bardsley@arm.com Fault fault; 19510259SAndrew.Bardsley@arm.com 19610259SAndrew.Bardsley@arm.com /** Thread, stream, prediction ... id of this line */ 19710259SAndrew.Bardsley@arm.com InstId id; 19810259SAndrew.Bardsley@arm.com 19910259SAndrew.Bardsley@arm.com /** Line data. line[0] is the byte at address pc.instAddr(). Data is 20010259SAndrew.Bardsley@arm.com * only valid upto lineWidth - 1. */ 20110259SAndrew.Bardsley@arm.com uint8_t *line; 20210259SAndrew.Bardsley@arm.com 20310259SAndrew.Bardsley@arm.com /** Packet from which the line is taken */ 20410259SAndrew.Bardsley@arm.com Packet *packet; 20510259SAndrew.Bardsley@arm.com 20610259SAndrew.Bardsley@arm.com public: 20710259SAndrew.Bardsley@arm.com ForwardLineData() : 20810259SAndrew.Bardsley@arm.com bubbleFlag(true), 20910259SAndrew.Bardsley@arm.com lineBaseAddr(0), 21010259SAndrew.Bardsley@arm.com lineWidth(0), 21110259SAndrew.Bardsley@arm.com fault(NoFault), 21210259SAndrew.Bardsley@arm.com line(NULL), 21310259SAndrew.Bardsley@arm.com packet(NULL) 21410259SAndrew.Bardsley@arm.com { 21510259SAndrew.Bardsley@arm.com /* Make lines bubbles by default */ 21610259SAndrew.Bardsley@arm.com } 21710259SAndrew.Bardsley@arm.com 21810259SAndrew.Bardsley@arm.com ~ForwardLineData() { line = NULL; } 21910259SAndrew.Bardsley@arm.com 22010259SAndrew.Bardsley@arm.com public: 22110259SAndrew.Bardsley@arm.com /** This is a fault, not a line */ 22210259SAndrew.Bardsley@arm.com bool isFault() const { return fault != NoFault; } 22310259SAndrew.Bardsley@arm.com 22410259SAndrew.Bardsley@arm.com /** Set fault and possible clear the bubble flag */ 22510259SAndrew.Bardsley@arm.com void setFault(Fault fault_); 22610259SAndrew.Bardsley@arm.com 22710259SAndrew.Bardsley@arm.com /** In-place initialise a ForwardLineData, freeing and overridding the 22810259SAndrew.Bardsley@arm.com * line */ 22910259SAndrew.Bardsley@arm.com void allocateLine(unsigned int width_); 23010259SAndrew.Bardsley@arm.com 23110259SAndrew.Bardsley@arm.com /** Use the data from a packet as line instead of allocating new 23210259SAndrew.Bardsley@arm.com * space. On destruction of this object, the packet will be destroyed */ 23310259SAndrew.Bardsley@arm.com void adoptPacketData(Packet *packet); 23410259SAndrew.Bardsley@arm.com 23510259SAndrew.Bardsley@arm.com /** Free this ForwardLineData line. Note that these are shared between 23610259SAndrew.Bardsley@arm.com * line objects and so you must be careful when deallocating them. 23710259SAndrew.Bardsley@arm.com * Copying of ForwardLineData can, therefore, be done by default copy 23810259SAndrew.Bardsley@arm.com * constructors/assignment */ 23910259SAndrew.Bardsley@arm.com void freeLine(); 24010259SAndrew.Bardsley@arm.com 24110259SAndrew.Bardsley@arm.com /** BubbleIF interface */ 24210259SAndrew.Bardsley@arm.com static ForwardLineData bubble() { return ForwardLineData(); } 24310259SAndrew.Bardsley@arm.com bool isBubble() const { return bubbleFlag; } 24410259SAndrew.Bardsley@arm.com 24510259SAndrew.Bardsley@arm.com /** ReportIF interface */ 24610259SAndrew.Bardsley@arm.com void reportData(std::ostream &os) const; 24710259SAndrew.Bardsley@arm.com}; 24810259SAndrew.Bardsley@arm.com 24910259SAndrew.Bardsley@arm.com/** Maximum number of instructions that can be carried by the pipeline. */ 25010259SAndrew.Bardsley@arm.comconst unsigned int MAX_FORWARD_INSTS = 16; 25110259SAndrew.Bardsley@arm.com 25210259SAndrew.Bardsley@arm.com/** Forward flowing data between Fetch2,Decode,Execute carrying a packet of 25310259SAndrew.Bardsley@arm.com * instructions of a width appropriate to the configured stage widths. 25410259SAndrew.Bardsley@arm.com * Also carries exception information where instructions are not valid */ 25510259SAndrew.Bardsley@arm.comclass ForwardInstData /* : public ReportIF, public BubbleIF */ 25610259SAndrew.Bardsley@arm.com{ 25710259SAndrew.Bardsley@arm.com public: 25810259SAndrew.Bardsley@arm.com /** Array of carried insts, ref counted */ 25910259SAndrew.Bardsley@arm.com MinorDynInstPtr insts[MAX_FORWARD_INSTS]; 26010259SAndrew.Bardsley@arm.com 26110259SAndrew.Bardsley@arm.com /** The number of insts slots that can be expected to be valid insts */ 26210259SAndrew.Bardsley@arm.com unsigned int numInsts; 26310259SAndrew.Bardsley@arm.com 26411567Smitch.hayenga@arm.com /** Thread associated with these instructions */ 26511567Smitch.hayenga@arm.com ThreadID threadId; 26611567Smitch.hayenga@arm.com 26710259SAndrew.Bardsley@arm.com public: 26811567Smitch.hayenga@arm.com explicit ForwardInstData(unsigned int width = 0, 26911567Smitch.hayenga@arm.com ThreadID tid = InvalidThreadID); 27010259SAndrew.Bardsley@arm.com 27110259SAndrew.Bardsley@arm.com ForwardInstData(const ForwardInstData &src); 27210259SAndrew.Bardsley@arm.com 27310259SAndrew.Bardsley@arm.com public: 27410259SAndrew.Bardsley@arm.com /** Number of instructions carried by this object */ 27510259SAndrew.Bardsley@arm.com unsigned int width() const { return numInsts; } 27610259SAndrew.Bardsley@arm.com 27710259SAndrew.Bardsley@arm.com /** Copy the inst array only as far as numInsts */ 27810259SAndrew.Bardsley@arm.com ForwardInstData &operator =(const ForwardInstData &src); 27910259SAndrew.Bardsley@arm.com 28010259SAndrew.Bardsley@arm.com /** Resize a bubble/empty ForwardInstData and fill with bubbles */ 28110259SAndrew.Bardsley@arm.com void resize(unsigned int width); 28210259SAndrew.Bardsley@arm.com 28310259SAndrew.Bardsley@arm.com /** Fill with bubbles from 0 to width() - 1 */ 28410259SAndrew.Bardsley@arm.com void bubbleFill(); 28510259SAndrew.Bardsley@arm.com 28610259SAndrew.Bardsley@arm.com /** BubbleIF interface */ 28710259SAndrew.Bardsley@arm.com bool isBubble() const; 28810259SAndrew.Bardsley@arm.com 28910259SAndrew.Bardsley@arm.com /** ReportIF interface */ 29010259SAndrew.Bardsley@arm.com void reportData(std::ostream &os) const; 29110259SAndrew.Bardsley@arm.com}; 29210259SAndrew.Bardsley@arm.com 29310259SAndrew.Bardsley@arm.com} 29410259SAndrew.Bardsley@arm.com 29510259SAndrew.Bardsley@arm.com#endif /* __CPU_MINOR_PIPE_DATA_HH__ */ 296