xbar.hh revision 10888
12023SN/A/*
25222Sksewell@umich.edu * Copyright (c) 2011-2015 ARM Limited
32023SN/A * All rights reserved
45222Sksewell@umich.edu *
52023SN/A * The license below extends only to copyright in the software and shall
65222Sksewell@umich.edu * not be construed as granting a license to any other intellectual
75222Sksewell@umich.edu * property including but not limited to intellectual property relating
85222Sksewell@umich.edu * to a hardware implementation of the functionality of the software
92665Ssaidi@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
105222Sksewell@umich.edu * terms below provided that you ensure that this notice is replicated
115222Sksewell@umich.edu * unmodified and in its entirety in all distributions of the software,
125222Sksewell@umich.edu * modified or unmodified, in source code or in binary form.
135222Sksewell@umich.edu *
145222Sksewell@umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan
155222Sksewell@umich.edu * All rights reserved.
165222Sksewell@umich.edu *
175222Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without
185222Sksewell@umich.edu * modification, are permitted provided that the following conditions are
195222Sksewell@umich.edu * met: redistributions of source code must retain the above copyright
205222Sksewell@umich.edu * notice, this list of conditions and the following disclaimer;
215222Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright
225222Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the
235222Sksewell@umich.edu * documentation and/or other materials provided with the distribution;
245222Sksewell@umich.edu * neither the name of the copyright holders nor the names of its
255222Sksewell@umich.edu * contributors may be used to endorse or promote products derived from
265222Sksewell@umich.edu * this software without specific prior written permission.
275222Sksewell@umich.edu *
285222Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
295222Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
305222Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
315222Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
325222Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
335222Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
345222Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
355222Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
365222Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372023SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382023SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392028SN/A *
402028SN/A * Authors: Ron Dreslinski
412023SN/A *          Ali Saidi
422597SN/A *          Andreas Hansson
435222Sksewell@umich.edu *          William Wang
442023SN/A */
452023SN/A
462239SN/A/**
472239SN/A * @file
482028SN/A * Declaration of an abstract crossbar base class.
492023SN/A */
502131SN/A
512023SN/A#ifndef __MEM_XBAR_HH__
522131SN/A#define __MEM_XBAR_HH__
532023SN/A
542525SN/A#include <deque>
552525SN/A
562447SN/A#include "base/addr_range_map.hh"
572023SN/A#include "base/hashmap.hh"
585222Sksewell@umich.edu#include "base/types.hh"
593093Sksewell@umich.edu#include "mem/mem_object.hh"
603093Sksewell@umich.edu#include "mem/qport.hh"
612972Sgblack@eecs.umich.edu#include "params/BaseXBar.hh"
622972Sgblack@eecs.umich.edu#include "sim/stats.hh"
635222Sksewell@umich.edu
642972Sgblack@eecs.umich.edu/**
652239SN/A * The base crossbar contains the common elements of the non-coherent
665222Sksewell@umich.edu * and coherent crossbar. It is an abstract class that does not have
675222Sksewell@umich.edu * any of the functionality relating to the actual reception and
685222Sksewell@umich.edu * transmission of packets, as this is left for the subclasses.
695222Sksewell@umich.edu *
705222Sksewell@umich.edu * The BaseXBar is responsible for the basic flow control (busy or
715222Sksewell@umich.edu * not), the administration of retries, and the address decoding.
725222Sksewell@umich.edu */
735222Sksewell@umich.educlass BaseXBar : public MemObject
745222Sksewell@umich.edu{
755222Sksewell@umich.edu
765222Sksewell@umich.edu  protected:
775222Sksewell@umich.edu
785222Sksewell@umich.edu    /**
795222Sksewell@umich.edu     * A layer is an internal crossbar arbitration point with its own
805222Sksewell@umich.edu     * flow control. Each layer is a converging multiplexer tree. By
815222Sksewell@umich.edu     * instantiating one layer per destination port (and per packet
825222Sksewell@umich.edu     * type, i.e. request, response, snoop request and snoop
835222Sksewell@umich.edu     * response), we model full crossbar structures like AXI, ACE,
845222Sksewell@umich.edu     * PCIe, etc.
855222Sksewell@umich.edu     *
865222Sksewell@umich.edu     * The template parameter, PortClass, indicates the destination
875222Sksewell@umich.edu     * port type for the layer. The retry list holds either master
885222Sksewell@umich.edu     * ports or slave ports, depending on the direction of the
895222Sksewell@umich.edu     * layer. Thus, a request layer has a retry list containing slave
905222Sksewell@umich.edu     * ports, whereas a response layer holds master ports.
915222Sksewell@umich.edu     */
925222Sksewell@umich.edu    template <typename SrcType, typename DstType>
935222Sksewell@umich.edu    class Layer : public Drainable
945222Sksewell@umich.edu    {
955222Sksewell@umich.edu
965222Sksewell@umich.edu      public:
975222Sksewell@umich.edu
985222Sksewell@umich.edu        /**
995222Sksewell@umich.edu         * Create a layer and give it a name. The layer uses
1005222Sksewell@umich.edu         * the crossbar an event manager.
1015222Sksewell@umich.edu         *
1025222Sksewell@umich.edu         * @param _port destination port the layer converges at
1035222Sksewell@umich.edu         * @param _xbar the crossbar this layer belongs to
1045222Sksewell@umich.edu         * @param _name the layer's name
1055222Sksewell@umich.edu         */
1065222Sksewell@umich.edu        Layer(DstType& _port, BaseXBar& _xbar, const std::string& _name);
1075222Sksewell@umich.edu
1085222Sksewell@umich.edu        /**
1095222Sksewell@umich.edu         * Drain according to the normal semantics, so that the crossbar
1105222Sksewell@umich.edu         * can tell the layer to drain, and pass an event to signal
1115222Sksewell@umich.edu         * back when drained.
1125222Sksewell@umich.edu         *
1135222Sksewell@umich.edu         * @param de drain event to call once drained
1145222Sksewell@umich.edu         *
1155222Sksewell@umich.edu         * @return 1 if busy or waiting to retry, or 0 if idle
1165222Sksewell@umich.edu         */
1175222Sksewell@umich.edu        unsigned int drain(DrainManager *dm);
1185222Sksewell@umich.edu
1195222Sksewell@umich.edu        /**
1205222Sksewell@umich.edu         * Get the crossbar layer's name
1215222Sksewell@umich.edu         */
1225222Sksewell@umich.edu        const std::string name() const { return xbar.name() + _name; }
1235222Sksewell@umich.edu
1245222Sksewell@umich.edu
1255222Sksewell@umich.edu        /**
1265222Sksewell@umich.edu         * Determine if the layer accepts a packet from a specific
1275222Sksewell@umich.edu         * port. If not, the port in question is also added to the
1285222Sksewell@umich.edu         * retry list. In either case the state of the layer is
1295222Sksewell@umich.edu         * updated accordingly.
1305222Sksewell@umich.edu         *
1315222Sksewell@umich.edu         * @param port Source port presenting the packet
1325222Sksewell@umich.edu         *
1335222Sksewell@umich.edu         * @return True if the layer accepts the packet
1345222Sksewell@umich.edu         */
1355222Sksewell@umich.edu        bool tryTiming(SrcType* src_port);
1365222Sksewell@umich.edu
1375222Sksewell@umich.edu        /**
1385222Sksewell@umich.edu         * Deal with a destination port accepting a packet by potentially
1395222Sksewell@umich.edu         * removing the source port from the retry list (if retrying) and
1405222Sksewell@umich.edu         * occupying the layer accordingly.
1415222Sksewell@umich.edu         *
1425222Sksewell@umich.edu         * @param busy_time Time to spend as a result of a successful send
1435222Sksewell@umich.edu         */
1445222Sksewell@umich.edu        void succeededTiming(Tick busy_time);
1455222Sksewell@umich.edu
1465222Sksewell@umich.edu        /**
1475222Sksewell@umich.edu         * Deal with a destination port not accepting a packet by
1485222Sksewell@umich.edu         * potentially adding the source port to the retry list (if
1495222Sksewell@umich.edu         * not already at the front) and occupying the layer
1505222Sksewell@umich.edu         * accordingly.
1515222Sksewell@umich.edu         *
1525222Sksewell@umich.edu         * @param src_port Source port
1535222Sksewell@umich.edu         * @param busy_time Time to spend as a result of a failed send
1545222Sksewell@umich.edu         */
1555222Sksewell@umich.edu        void failedTiming(SrcType* src_port, Tick busy_time);
1565222Sksewell@umich.edu
1575222Sksewell@umich.edu        /** Occupy the layer until until */
1585222Sksewell@umich.edu        void occupyLayer(Tick until);
1595222Sksewell@umich.edu
1605222Sksewell@umich.edu        /**
1615222Sksewell@umich.edu         * Send a retry to the port at the head of waitingForLayer. The
1625222Sksewell@umich.edu         * caller must ensure that the list is not empty.
1635222Sksewell@umich.edu         */
1642972Sgblack@eecs.umich.edu        void retryWaiting();
1652972Sgblack@eecs.umich.edu
1662131SN/A        /**
1672972Sgblack@eecs.umich.edu         * Handle a retry from a neighbouring module. This wraps
1682972Sgblack@eecs.umich.edu         * retryWaiting by verifying that there are ports waiting
1694661Sksewell@umich.edu         * before calling retryWaiting.
1702972Sgblack@eecs.umich.edu         */
1712972Sgblack@eecs.umich.edu        void recvRetry();
1722597SN/A
1735222Sksewell@umich.edu        /**
1745222Sksewell@umich.edu         * Register stats for the layer
1755222Sksewell@umich.edu         */
1765222Sksewell@umich.edu        void regStats();
1772972Sgblack@eecs.umich.edu
1785222Sksewell@umich.edu      protected:
1795222Sksewell@umich.edu
1802597SN/A        /**
1812972Sgblack@eecs.umich.edu         * Sending the actual retry, in a manner specific to the
1822972Sgblack@eecs.umich.edu         * individual layers. Note that for a MasterPort, there is
1832972Sgblack@eecs.umich.edu         * both a RequestLayer and a SnoopResponseLayer using the same
1842972Sgblack@eecs.umich.edu         * port, but using different functions for the flow control.
1852972Sgblack@eecs.umich.edu         */
1862972Sgblack@eecs.umich.edu        virtual void sendRetry(SrcType* retry_port) = 0;
1875222Sksewell@umich.edu
1885222Sksewell@umich.edu      private:
1895222Sksewell@umich.edu
1905222Sksewell@umich.edu        /** The destination port this layer converges at. */
1912972Sgblack@eecs.umich.edu        DstType& port;
1922972Sgblack@eecs.umich.edu
1932972Sgblack@eecs.umich.edu        /** The crossbar this layer is a part of. */
1942972Sgblack@eecs.umich.edu        BaseXBar& xbar;
1952972Sgblack@eecs.umich.edu
1962972Sgblack@eecs.umich.edu        /** A name for this layer. */
1972597SN/A        std::string _name;
1985222Sksewell@umich.edu
1995222Sksewell@umich.edu        /**
2005222Sksewell@umich.edu         * We declare an enum to track the state of the layer. The
2012972Sgblack@eecs.umich.edu         * starting point is an idle state where the layer is waiting
2024661Sksewell@umich.edu         * for a packet to arrive. Upon arrival, the layer
2035222Sksewell@umich.edu         * transitions to the busy state, where it remains either
2042131SN/A         * until the packet transfer is done, or the header time is
2052972Sgblack@eecs.umich.edu         * spent. Once the layer leaves the busy state, it can
2062972Sgblack@eecs.umich.edu         * either go back to idle, if no packets have arrived while it
2072131SN/A         * was busy, or the layer goes on to retry the first port
2082972Sgblack@eecs.umich.edu         * in waitingForLayer. A similar transition takes place from
2092131SN/A         * idle to retry if the layer receives a retry from one of
2102972Sgblack@eecs.umich.edu         * its connected ports. The retry state lasts until the port
2112972Sgblack@eecs.umich.edu         * in questions calls sendTiming and returns control to the
2122972Sgblack@eecs.umich.edu         * layer, or goes to a busy state if the port does not
2132972Sgblack@eecs.umich.edu         * immediately react to the retry by calling sendTiming.
2142131SN/A         */
2152972Sgblack@eecs.umich.edu        enum State { IDLE, BUSY, RETRY };
2162972Sgblack@eecs.umich.edu
2172131SN/A        /** track the state of the layer */
2185222Sksewell@umich.edu        State state;
2195222Sksewell@umich.edu
2205222Sksewell@umich.edu        /** manager to signal when drained */
2215222Sksewell@umich.edu        DrainManager *drainManager;
2224661Sksewell@umich.edu
2234661Sksewell@umich.edu        /**
2244661Sksewell@umich.edu         * A deque of ports that retry should be called on because
2254661Sksewell@umich.edu         * the original send was delayed due to a busy layer.
2264661Sksewell@umich.edu         */
2274661Sksewell@umich.edu        std::deque<SrcType*> waitingForLayer;
2284661Sksewell@umich.edu
2294661Sksewell@umich.edu        /**
2305222Sksewell@umich.edu         * Track who is waiting for the retry when receiving it from a
2314661Sksewell@umich.edu         * peer. If no port is waiting NULL is stored.
2324661Sksewell@umich.edu         */
2334661Sksewell@umich.edu        SrcType* waitingForPeer;
2344661Sksewell@umich.edu
2355222Sksewell@umich.edu        /**
2364661Sksewell@umich.edu         * Release the layer after being occupied and return to an
2374661Sksewell@umich.edu         * idle state where we proceed to send a retry to any
2384661Sksewell@umich.edu         * potential waiting port, or drain if asked to do so.
2394661Sksewell@umich.edu         */
2404661Sksewell@umich.edu        void releaseLayer();
2414661Sksewell@umich.edu
2424661Sksewell@umich.edu        /** event used to schedule a release of the layer */
2434661Sksewell@umich.edu        EventWrapper<Layer, &Layer::releaseLayer> releaseEvent;
2445222Sksewell@umich.edu
2454661Sksewell@umich.edu        /**
2464661Sksewell@umich.edu         * Stats for occupancy and utilization. These stats capture
2474661Sksewell@umich.edu         * the time the layer spends in the busy state and are thus only
2484661Sksewell@umich.edu         * relevant when the memory system is in timing mode.
2494661Sksewell@umich.edu         */
2504661Sksewell@umich.edu        Stats::Scalar occupancy;
2514661Sksewell@umich.edu        Stats::Formula utilization;
2524661Sksewell@umich.edu
2535222Sksewell@umich.edu    };
2544661Sksewell@umich.edu
2555222Sksewell@umich.edu    class ReqLayer : public Layer<SlavePort,MasterPort>
2564661Sksewell@umich.edu    {
2574661Sksewell@umich.edu      public:
2585222Sksewell@umich.edu        /**
2595222Sksewell@umich.edu         * Create a request layer and give it a name.
2604661Sksewell@umich.edu         *
2615222Sksewell@umich.edu         * @param _port destination port the layer converges at
2624661Sksewell@umich.edu         * @param _xbar the crossbar this layer belongs to
2634661Sksewell@umich.edu         * @param _name the layer's name
2644661Sksewell@umich.edu         */
2654661Sksewell@umich.edu        ReqLayer(MasterPort& _port, BaseXBar& _xbar, const std::string& _name) :
2664661Sksewell@umich.edu            Layer(_port, _xbar, _name) {}
2674661Sksewell@umich.edu
2685222Sksewell@umich.edu      protected:
2694661Sksewell@umich.edu
2705222Sksewell@umich.edu        void sendRetry(SlavePort* retry_port)
2714661Sksewell@umich.edu        { retry_port->sendRetryReq(); }
2725222Sksewell@umich.edu    };
2734661Sksewell@umich.edu
2745222Sksewell@umich.edu    class RespLayer : public Layer<MasterPort,SlavePort>
2754661Sksewell@umich.edu    {
2765222Sksewell@umich.edu      public:
2774661Sksewell@umich.edu        /**
2785222Sksewell@umich.edu         * Create a response layer and give it a name.
2794661Sksewell@umich.edu         *
2804661Sksewell@umich.edu         * @param _port destination port the layer converges at
2814661Sksewell@umich.edu         * @param _xbar the crossbar this layer belongs to
2824661Sksewell@umich.edu         * @param _name the layer's name
2835222Sksewell@umich.edu         */
2844661Sksewell@umich.edu        RespLayer(SlavePort& _port, BaseXBar& _xbar, const std::string& _name) :
2855222Sksewell@umich.edu            Layer(_port, _xbar, _name) {}
2864661Sksewell@umich.edu
2875222Sksewell@umich.edu      protected:
2884661Sksewell@umich.edu
2894661Sksewell@umich.edu        void sendRetry(MasterPort* retry_port)
2905222Sksewell@umich.edu        { retry_port->sendRetryResp(); }
2914661Sksewell@umich.edu    };
2924661Sksewell@umich.edu
2934661Sksewell@umich.edu    class SnoopRespLayer : public Layer<SlavePort,MasterPort>
2944661Sksewell@umich.edu    {
2954661Sksewell@umich.edu      public:
2964661Sksewell@umich.edu        /**
2974661Sksewell@umich.edu         * Create a snoop response layer and give it a name.
2984661Sksewell@umich.edu         *
2994661Sksewell@umich.edu         * @param _port destination port the layer converges at
3005222Sksewell@umich.edu         * @param _xbar the crossbar this layer belongs to
3014661Sksewell@umich.edu         * @param _name the layer's name
3025222Sksewell@umich.edu         */
3034661Sksewell@umich.edu        SnoopRespLayer(MasterPort& _port, BaseXBar& _xbar,
3044661Sksewell@umich.edu                       const std::string& _name) :
3054661Sksewell@umich.edu            Layer(_port, _xbar, _name) {}
3064661Sksewell@umich.edu
3074661Sksewell@umich.edu      protected:
3084661Sksewell@umich.edu
3094661Sksewell@umich.edu        void sendRetry(SlavePort* retry_port)
3104661Sksewell@umich.edu        { retry_port->sendRetrySnoopResp(); }
3115222Sksewell@umich.edu    };
3124661Sksewell@umich.edu
3134661Sksewell@umich.edu    /**
3144661Sksewell@umich.edu     * Cycles of front-end pipeline including the delay to accept the request
3154661Sksewell@umich.edu     * and to decode the address.
3164661Sksewell@umich.edu     */
3174661Sksewell@umich.edu    const Cycles frontendLatency;
3184661Sksewell@umich.edu    /** Cycles of forward latency */
3194661Sksewell@umich.edu    const Cycles forwardLatency;
3205222Sksewell@umich.edu    /** Cycles of response latency */
3214661Sksewell@umich.edu    const Cycles responseLatency;
3224661Sksewell@umich.edu    /** the width of the xbar in bytes */
3234661Sksewell@umich.edu    const uint32_t width;
3244661Sksewell@umich.edu
3254661Sksewell@umich.edu    AddrRangeMap<PortID> portMap;
3265222Sksewell@umich.edu
3274661Sksewell@umich.edu    /**
3284661Sksewell@umich.edu     * Remember where request packets came from so that we can route
3294661Sksewell@umich.edu     * responses to the appropriate port. This relies on the fact that
3304661Sksewell@umich.edu     * the underlying Request pointer inside the Packet stays
3314661Sksewell@umich.edu     * constant.
3325222Sksewell@umich.edu     */
3334661Sksewell@umich.edu    m5::unordered_map<RequestPtr, PortID> routeTo;
3345222Sksewell@umich.edu
3354661Sksewell@umich.edu    /** all contigous ranges seen by this crossbar */
3364661Sksewell@umich.edu    AddrRangeList xbarRanges;
3374661Sksewell@umich.edu
3384661Sksewell@umich.edu    AddrRange defaultRange;
3394661Sksewell@umich.edu
3404661Sksewell@umich.edu    /**
3414661Sksewell@umich.edu     * Function called by the port when the crossbar is recieving a
3424661Sksewell@umich.edu     * range change.
3435222Sksewell@umich.edu     *
3444661Sksewell@umich.edu     * @param master_port_id id of the port that received the change
3455222Sksewell@umich.edu     */
3464661Sksewell@umich.edu    void recvRangeChange(PortID master_port_id);
3474661Sksewell@umich.edu
3484661Sksewell@umich.edu    /** Find which port connected to this crossbar (if any) should be
3494661Sksewell@umich.edu     * given a packet with this address.
3505222Sksewell@umich.edu     *
3514661Sksewell@umich.edu     * @param addr Address to find port for.
3524661Sksewell@umich.edu     * @return id of port that the packet should be sent out of.
3534661Sksewell@umich.edu     */
3544661Sksewell@umich.edu    PortID findPort(Addr addr);
3554661Sksewell@umich.edu
3564661Sksewell@umich.edu    // Cache for the findPort function storing recently used ports from portMap
3574661Sksewell@umich.edu    struct PortCache {
3584661Sksewell@umich.edu        bool valid;
3595222Sksewell@umich.edu        PortID id;
3604661Sksewell@umich.edu        AddrRange range;
3614661Sksewell@umich.edu    };
3624661Sksewell@umich.edu
3634661Sksewell@umich.edu    PortCache portCache[3];
3644661Sksewell@umich.edu
3654661Sksewell@umich.edu    // Checks the cache and returns the id of the port that has the requested
3664661Sksewell@umich.edu    // address within its range
3674661Sksewell@umich.edu    inline PortID checkPortCache(Addr addr) const {
3684661Sksewell@umich.edu        if (portCache[0].valid && portCache[0].range.contains(addr)) {
3695222Sksewell@umich.edu            return portCache[0].id;
3704661Sksewell@umich.edu        }
3715222Sksewell@umich.edu        if (portCache[1].valid && portCache[1].range.contains(addr)) {
3724661Sksewell@umich.edu            return portCache[1].id;
3735222Sksewell@umich.edu        }
3744661Sksewell@umich.edu        if (portCache[2].valid && portCache[2].range.contains(addr)) {
3754661Sksewell@umich.edu            return portCache[2].id;
3764661Sksewell@umich.edu        }
3774661Sksewell@umich.edu
3785222Sksewell@umich.edu        return InvalidPortID;
3795222Sksewell@umich.edu    }
3804661Sksewell@umich.edu
3814661Sksewell@umich.edu    // Clears the earliest entry of the cache and inserts a new port entry
3824661Sksewell@umich.edu    inline void updatePortCache(short id, const AddrRange& range) {
3834661Sksewell@umich.edu        portCache[2].valid = portCache[1].valid;
3844661Sksewell@umich.edu        portCache[2].id    = portCache[1].id;
3852023SN/A        portCache[2].range = portCache[1].range;
3862023SN/A
3872447SN/A        portCache[1].valid = portCache[0].valid;
3882447SN/A        portCache[1].id    = portCache[0].id;
3892028SN/A        portCache[1].range = portCache[0].range;
390
391        portCache[0].valid = true;
392        portCache[0].id    = id;
393        portCache[0].range = range;
394    }
395
396    // Clears the cache. Needs to be called in constructor.
397    inline void clearPortCache() {
398        portCache[2].valid = false;
399        portCache[1].valid = false;
400        portCache[0].valid = false;
401    }
402
403    /**
404     * Return the address ranges the crossbar is responsible for.
405     *
406     * @return a list of non-overlapping address ranges
407     */
408    AddrRangeList getAddrRanges() const;
409
410    /**
411     * Calculate the timing parameters for the packet. Updates the
412     * headerDelay and payloadDelay fields of the packet
413     * object with the relative number of ticks required to transmit
414     * the header and the payload, respectively.
415     *
416     * @param pkt Packet to populate with timings
417     * @param header_delay Header delay to be added
418     */
419    void calcPacketTiming(PacketPtr pkt, Tick header_delay);
420
421    /**
422     * Remember for each of the master ports of the crossbar if we got
423     * an address range from the connected slave. For convenience,
424     * also keep track of if we got ranges from all the slave modules
425     * or not.
426     */
427    std::vector<bool> gotAddrRanges;
428    bool gotAllAddrRanges;
429
430    /** The master and slave ports of the crossbar */
431    std::vector<QueuedSlavePort*> slavePorts;
432    std::vector<MasterPort*> masterPorts;
433
434    /** Port that handles requests that don't match any of the interfaces.*/
435    PortID defaultPortID;
436
437    /** If true, use address range provided by default device.  Any
438       address not handled by another port and not in default device's
439       range will cause a fatal error.  If false, just send all
440       addresses not handled by another port to default device. */
441    const bool useDefaultRange;
442
443    BaseXBar(const BaseXBarParams *p);
444
445    virtual ~BaseXBar();
446
447    /**
448     * Stats for transaction distribution and data passing through the
449     * crossbar. The transaction distribution is globally counting
450     * different types of commands. The packet count and total packet
451     * size are two-dimensional vectors that are indexed by the
452     * slave port and master port id (thus the neighbouring master and
453     * neighbouring slave), summing up both directions (request and
454     * response).
455     */
456    Stats::Vector transDist;
457    Stats::Vector2d pktCount;
458    Stats::Vector2d pktSize;
459
460  public:
461
462    virtual void init();
463
464    /** A function used to return the port associated with this object. */
465    BaseMasterPort& getMasterPort(const std::string& if_name,
466                                  PortID idx = InvalidPortID);
467    BaseSlavePort& getSlavePort(const std::string& if_name,
468                                PortID idx = InvalidPortID);
469
470    virtual unsigned int drain(DrainManager *dm) = 0;
471
472    virtual void regStats();
473
474};
475
476#endif //__MEM_XBAR_HH__
477