| /* |
| * 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, |
| /* 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; |
| |
| /** ThreadID associated with branch */ |
| ThreadID threadId; |
| |
| /** 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), threadId(InvalidThreadID), newStreamSeqNum(0), |
| newPredictionSeqNum(0), target(TheISA::PCState(0)), |
| inst(MinorDynInst::bubble()) |
| { } |
| |
| BranchData( |
| Reason reason_, |
| ThreadID thread_id, |
| InstSeqNum new_stream_seq_num, |
| InstSeqNum new_prediction_seq_num, |
| TheISA::PCState target, |
| MinorDynInstPtr inst_) : |
| reason(reason_), |
| threadId(thread_id), |
| 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; |
| |
| /** Thread associated with these instructions */ |
| ThreadID threadId; |
| |
| public: |
| explicit ForwardInstData(unsigned int width = 0, |
| ThreadID tid = InvalidThreadID); |
| |
| 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__ */ |