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