| /* | |
| * Copyright (c) 2013-2014 ARM Limited | |
| * All rights reserved | |
| * | |
| * The license below extends only to copyright in the software and shall | |
| * not be construed as granting a license to any other intellectual | |
| * property including but not limited to intellectual property relating | |
| * to a hardware implementation of the functionality of the software | |
| * licensed hereunder. You may use the software subject to the license | |
| * terms below provided that you ensure that this notice is replicated | |
| * unmodified and in its entirety in all distributions of the software, | |
| * modified or unmodified, in source code or in binary form. | |
| * | |
| * Redistribution and use in source and binary forms, with or without | |
| * modification, are permitted provided that the following conditions are | |
| * met: redistributions of source code must retain the above copyright | |
| * notice, this list of conditions and the following disclaimer; | |
| * redistributions in binary form must reproduce the above copyright | |
| * notice, this list of conditions and the following disclaimer in the | |
| * documentation and/or other materials provided with the distribution; | |
| * neither the name of the copyright holders nor the names of its | |
| * contributors may be used to endorse or promote products derived from | |
| * this software without specific prior written permission. | |
| * | |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| * | |
| * Authors: Andrew Bardsley | |
| */ | |
| /** | |
| * @file | |
| * | |
| * Contains class definitions for data flowing between pipeline stages in | |
| * the top-level structure portion of this model. Latch types are also | |
| * defined which pair forward/backward flowing data specific to each stage | |
| * pair. | |
| * | |
| * No post-configuration inter-stage communication should *ever* take place | |
| * outside these classes (except for reservation!) | |
| */ | |
| #ifndef __CPU_MINOR_PIPE_DATA_HH__ | |
| #define __CPU_MINOR_PIPE_DATA_HH__ | |
| #include "cpu/minor/buffers.hh" | |
| #include "cpu/minor/dyn_inst.hh" | |
| #include "cpu/base.hh" | |
| namespace Minor | |
| { | |
| /** Forward data betwen Execute and Fetch1 carrying change-of-address/stream | |
| * information. */ | |
| class BranchData /* : public ReportIF, public BubbleIF */ | |
| { | |
| public: | |
| enum Reason | |
| { | |
| /* *** No change of stream (information to branch prediction) */ | |
| /* Don't branch at all (bubble) */ | |
| NoBranch, | |
| /* Don't branch, but here's the details of a correct prediction | |
| * that was executed */ | |
| CorrectlyPredictedBranch, | |
| /* *** Change of stream */ | |
| /* Take an unpredicted branch */ | |
| UnpredictedBranch, | |
| /* Take a branch on branch prediction data (from Fetch2) */ | |
| BranchPrediction, | |
| /* Prediction of wrong target PC */ | |
| BadlyPredictedBranchTarget, | |
| /* Bad branch prediction (didn't actually branch). Need to branch | |
| * back to correct stream. If the target is wrong, use | |
| * BadlyPredictedBranchTarget */ | |
| BadlyPredictedBranch, | |
| /* Suspend fetching for this thread (inst->id.threadId). | |
| * This will be woken up by another stream changing branch so | |
| * count it as stream changing itself and expect pc to be the PC | |
| * of the next instruction */ | |
| SuspendThread, | |
| /* Wakeup fetching from Halted */ | |
| WakeupFetch, | |
| /* Branch from an interrupt (no instruction) */ | |
| Interrupt, | |
| /* Stop fetching in anticipation of of draining */ | |
| HaltFetch | |
| }; | |
| /** Is a request with this reason actually a request to change the | |
| * PC rather than a bubble or branch prediction information */ | |
| static bool isStreamChange(const BranchData::Reason reason); | |
| /** Is a request with this reason actually a 'real' branch, that is, | |
| * a stream change that's not just an instruction to Fetch1 to halt | |
| * or wake up */ | |
| static bool isBranch(const BranchData::Reason reason); | |
| public: | |
| /** Explanation for this branch */ | |
| Reason reason; | |
| /** Sequence number of new stream/prediction to be adopted */ | |
| InstSeqNum newStreamSeqNum; | |
| InstSeqNum newPredictionSeqNum; | |
| /** Starting PC of that stream */ | |
| TheISA::PCState target; | |
| /** Instruction which caused this branch */ | |
| MinorDynInstPtr inst; | |
| public: | |
| BranchData() : | |
| reason(NoBranch), newStreamSeqNum(0), | |
| newPredictionSeqNum(0), target(TheISA::PCState(0)), | |
| inst(MinorDynInst::bubble()) | |
| { } | |
| BranchData( | |
| Reason reason_, | |
| InstSeqNum new_stream_seq_num, | |
| InstSeqNum new_prediction_seq_num, | |
| TheISA::PCState target, | |
| MinorDynInstPtr inst_) : | |
| reason(reason_), | |
| newStreamSeqNum(new_stream_seq_num), | |
| newPredictionSeqNum(new_prediction_seq_num), | |
| target(target), | |
| inst(inst_) | |
| { } | |
| /** BubbleIF interface */ | |
| static BranchData bubble() { return BranchData(); } | |
| bool isBubble() const { return reason == NoBranch; } | |
| /** As static isStreamChange but on this branch data */ | |
| bool isStreamChange() const { return isStreamChange(reason); } | |
| /** As static isBranch but on this branch data */ | |
| bool isBranch() const { return isBranch(reason); } | |
| /** ReportIF interface */ | |
| void reportData(std::ostream &os) const; | |
| }; | |
| /** Print a branch reason enum */ | |
| std::ostream &operator <<(std::ostream &os, BranchData::Reason reason); | |
| /** Print BranchData contents in a format suitable for DPRINTF comments, not | |
| * for MinorTrace */ | |
| std::ostream &operator <<(std::ostream &os, const BranchData &branch); | |
| /** Line fetch data in the forward direction. Contains a single cache line | |
| * (or fragment of a line), its address, a sequence number assigned when | |
| * that line was fetched and a bubbleFlag that can allow ForwardLineData to | |
| * be used to represent the absence of line data in a pipeline. */ | |
| class ForwardLineData /* : public ReportIF, public BubbleIF */ | |
| { | |
| private: | |
| /** This line is a bubble. No other data member is required to be valid | |
| * if this is true */ | |
| bool bubbleFlag; | |
| public: | |
| /** First byte address in the line. This is allowed to be | |
| * <= pc.instAddr() */ | |
| Addr lineBaseAddr; | |
| /** PC of the first requested inst within this line */ | |
| TheISA::PCState pc; | |
| /** Explicit line width, don't rely on data.size */ | |
| unsigned int lineWidth; | |
| public: | |
| /** This line has a fault. The bubble flag will be false and seqNums | |
| * will be valid but no data will */ | |
| Fault fault; | |
| /** Thread, stream, prediction ... id of this line */ | |
| InstId id; | |
| /** Line data. line[0] is the byte at address pc.instAddr(). Data is | |
| * only valid upto lineWidth - 1. */ | |
| uint8_t *line; | |
| /** Packet from which the line is taken */ | |
| Packet *packet; | |
| public: | |
| ForwardLineData() : | |
| bubbleFlag(true), | |
| lineBaseAddr(0), | |
| lineWidth(0), | |
| fault(NoFault), | |
| line(NULL), | |
| packet(NULL) | |
| { | |
| /* Make lines bubbles by default */ | |
| } | |
| ~ForwardLineData() { line = NULL; } | |
| public: | |
| /** This is a fault, not a line */ | |
| bool isFault() const { return fault != NoFault; } | |
| /** Set fault and possible clear the bubble flag */ | |
| void setFault(Fault fault_); | |
| /** In-place initialise a ForwardLineData, freeing and overridding the | |
| * line */ | |
| void allocateLine(unsigned int width_); | |
| /** Use the data from a packet as line instead of allocating new | |
| * space. On destruction of this object, the packet will be destroyed */ | |
| void adoptPacketData(Packet *packet); | |
| /** Free this ForwardLineData line. Note that these are shared between | |
| * line objects and so you must be careful when deallocating them. | |
| * Copying of ForwardLineData can, therefore, be done by default copy | |
| * constructors/assignment */ | |
| void freeLine(); | |
| /** BubbleIF interface */ | |
| static ForwardLineData bubble() { return ForwardLineData(); } | |
| bool isBubble() const { return bubbleFlag; } | |
| /** ReportIF interface */ | |
| void reportData(std::ostream &os) const; | |
| }; | |
| /** Maximum number of instructions that can be carried by the pipeline. */ | |
| const unsigned int MAX_FORWARD_INSTS = 16; | |
| /** Forward flowing data between Fetch2,Decode,Execute carrying a packet of | |
| * instructions of a width appropriate to the configured stage widths. | |
| * Also carries exception information where instructions are not valid */ | |
| class ForwardInstData /* : public ReportIF, public BubbleIF */ | |
| { | |
| public: | |
| /** Array of carried insts, ref counted */ | |
| MinorDynInstPtr insts[MAX_FORWARD_INSTS]; | |
| /** The number of insts slots that can be expected to be valid insts */ | |
| unsigned int numInsts; | |
| public: | |
| explicit ForwardInstData(unsigned int width = 0); | |
| ForwardInstData(const ForwardInstData &src); | |
| public: | |
| /** Number of instructions carried by this object */ | |
| unsigned int width() const { return numInsts; } | |
| /** Copy the inst array only as far as numInsts */ | |
| ForwardInstData &operator =(const ForwardInstData &src); | |
| /** Resize a bubble/empty ForwardInstData and fill with bubbles */ | |
| void resize(unsigned int width); | |
| /** Fill with bubbles from 0 to width() - 1 */ | |
| void bubbleFill(); | |
| /** BubbleIF interface */ | |
| bool isBubble() const; | |
| /** ReportIF interface */ | |
| void reportData(std::ostream &os) const; | |
| }; | |
| } | |
| #endif /* __CPU_MINOR_PIPE_DATA_HH__ */ |