xbar.hh revision 10405
11689SN/A/*
214025Sgiacomo.gabrielli@arm.com * Copyright (c) 2011-2014 ARM Limited
312109SRekai.GonzalezAlberquilla@arm.com * All rights reserved
412109SRekai.GonzalezAlberquilla@arm.com *
512109SRekai.GonzalezAlberquilla@arm.com * The license below extends only to copyright in the software and shall
612109SRekai.GonzalezAlberquilla@arm.com * not be construed as granting a license to any other intellectual
712109SRekai.GonzalezAlberquilla@arm.com * property including but not limited to intellectual property relating
812109SRekai.GonzalezAlberquilla@arm.com * to a hardware implementation of the functionality of the software
912109SRekai.GonzalezAlberquilla@arm.com * licensed hereunder.  You may use the software subject to the license
1012109SRekai.GonzalezAlberquilla@arm.com * terms below provided that you ensure that this notice is replicated
1112109SRekai.GonzalezAlberquilla@arm.com * unmodified and in its entirety in all distributions of the software,
1212109SRekai.GonzalezAlberquilla@arm.com * modified or unmodified, in source code or in binary form.
1312109SRekai.GonzalezAlberquilla@arm.com *
141689SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
159919Ssteve.reinhardt@amd.com * All rights reserved.
161689SN/A *
171689SN/A * Redistribution and use in source and binary forms, with or without
181689SN/A * modification, are permitted provided that the following conditions are
191689SN/A * met: redistributions of source code must retain the above copyright
201689SN/A * notice, this list of conditions and the following disclaimer;
211689SN/A * redistributions in binary form must reproduce the above copyright
221689SN/A * notice, this list of conditions and the following disclaimer in the
231689SN/A * documentation and/or other materials provided with the distribution;
241689SN/A * neither the name of the copyright holders nor the names of its
251689SN/A * contributors may be used to endorse or promote products derived from
261689SN/A * this software without specific prior written permission.
271689SN/A *
281689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
291689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
301689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
311689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
321689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
331689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
341689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
351689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
361689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
371689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
381689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
391689SN/A *
402665Ssaidi@eecs.umich.edu * Authors: Ron Dreslinski
412665Ssaidi@eecs.umich.edu *          Ali Saidi
421689SN/A *          Andreas Hansson
431689SN/A *          William Wang
442292SN/A */
452292SN/A
461060SN/A/**
471060SN/A * @file
481060SN/A * Declaration of an abstract crossbar base class.
4912105Snathanael.premillieu@arm.com */
501060SN/A
5112334Sgabeblack@google.com#ifndef __MEM_XBAR_HH__
521684SN/A#define __MEM_XBAR_HH__
531717SN/A
549919Ssteve.reinhardt@amd.com#include <deque>
558232Snate@binkert.org
561060SN/A#include "base/addr_range_map.hh"
571060SN/A#include "base/types.hh"
589919Ssteve.reinhardt@amd.com#include "mem/mem_object.hh"
599919Ssteve.reinhardt@amd.com#include "params/BaseXBar.hh"
609919Ssteve.reinhardt@amd.com#include "sim/stats.hh"
619919Ssteve.reinhardt@amd.com
629919Ssteve.reinhardt@amd.com/**
639919Ssteve.reinhardt@amd.com * The base crossbar contains the common elements of the non-coherent
649919Ssteve.reinhardt@amd.com * and coherent crossbar. It is an abstract class that does not have
659919Ssteve.reinhardt@amd.com * any of the functionality relating to the actual reception and
669919Ssteve.reinhardt@amd.com * transmission of packets, as this is left for the subclasses.
679919Ssteve.reinhardt@amd.com *
689919Ssteve.reinhardt@amd.com * The BaseXBar is responsible for the basic flow control (busy or
6912105Snathanael.premillieu@arm.com * not), the administration of retries, and the address decoding.
709919Ssteve.reinhardt@amd.com */
719919Ssteve.reinhardt@amd.comclass BaseXBar : public MemObject
729919Ssteve.reinhardt@amd.com{
739919Ssteve.reinhardt@amd.com
749919Ssteve.reinhardt@amd.com  protected:
759919Ssteve.reinhardt@amd.com
7612105Snathanael.premillieu@arm.com    /**
779919Ssteve.reinhardt@amd.com     * A layer is an internal crossbar arbitration point with its own
7812109SRekai.GonzalezAlberquilla@arm.com     * flow control. Each layer is a converging multiplexer tree. By
7912109SRekai.GonzalezAlberquilla@arm.com     * instantiating one layer per destination port (and per packet
8012109SRekai.GonzalezAlberquilla@arm.com     * type, i.e. request, response, snoop request and snoop
8112109SRekai.GonzalezAlberquilla@arm.com     * response), we model full crossbar structures like AXI, ACE,
8214025Sgiacomo.gabrielli@arm.com     * PCIe, etc.
8314025Sgiacomo.gabrielli@arm.com     *
8414025Sgiacomo.gabrielli@arm.com     * The template parameter, PortClass, indicates the destination
8512109SRekai.GonzalezAlberquilla@arm.com     * port type for the layer. The retry list holds either master
8612109SRekai.GonzalezAlberquilla@arm.com     * ports or slave ports, depending on the direction of the
879919Ssteve.reinhardt@amd.com     * layer. Thus, a request layer has a retry list containing slave
8812105Snathanael.premillieu@arm.com     * ports, whereas a response layer holds master ports.
899919Ssteve.reinhardt@amd.com     */
909919Ssteve.reinhardt@amd.com    template <typename SrcType, typename DstType>
9112105Snathanael.premillieu@arm.com    class Layer : public Drainable
929919Ssteve.reinhardt@amd.com    {
939919Ssteve.reinhardt@amd.com
949919Ssteve.reinhardt@amd.com      public:
959919Ssteve.reinhardt@amd.com
969919Ssteve.reinhardt@amd.com        /**
979919Ssteve.reinhardt@amd.com         * Create a layer and give it a name. The layer uses
989919Ssteve.reinhardt@amd.com         * the crossbar an event manager.
999919Ssteve.reinhardt@amd.com         *
1009919Ssteve.reinhardt@amd.com         * @param _port destination port the layer converges at
1019919Ssteve.reinhardt@amd.com         * @param _xbar the crossbar this layer belongs to
1029919Ssteve.reinhardt@amd.com         * @param _name the layer's name
1039919Ssteve.reinhardt@amd.com         */
1049919Ssteve.reinhardt@amd.com        Layer(DstType& _port, BaseXBar& _xbar, const std::string& _name);
1051060SN/A
1061060SN/A        /**
1071060SN/A         * Drain according to the normal semantics, so that the crossbar
1081060SN/A         * can tell the layer to drain, and pass an event to signal
1091060SN/A         * back when drained.
1101060SN/A         *
1111060SN/A         * @param de drain event to call once drained
1122292SN/A         *
1132292SN/A         * @return 1 if busy or waiting to retry, or 0 if idle
1142292SN/A         */
1151060SN/A        unsigned int drain(DrainManager *dm);
1161060SN/A
1179919Ssteve.reinhardt@amd.com        /**
1181060SN/A         * Get the crossbar layer's name
1191060SN/A         */
1209919Ssteve.reinhardt@amd.com        const std::string name() const { return xbar.name() + _name; }
1219919Ssteve.reinhardt@amd.com
1229919Ssteve.reinhardt@amd.com
1239919Ssteve.reinhardt@amd.com        /**
1249919Ssteve.reinhardt@amd.com         * Determine if the layer accepts a packet from a specific
1251060SN/A         * port. If not, the port in question is also added to the
1269919Ssteve.reinhardt@amd.com         * retry list. In either case the state of the layer is
1271060SN/A         * updated accordingly.
1281060SN/A         *
1299919Ssteve.reinhardt@amd.com         * @param port Source port presenting the packet
1301060SN/A         *
13112109SRekai.GonzalezAlberquilla@arm.com         * @return True if the layer accepts the packet
13212109SRekai.GonzalezAlberquilla@arm.com         */
13312109SRekai.GonzalezAlberquilla@arm.com        bool tryTiming(SrcType* src_port);
13412109SRekai.GonzalezAlberquilla@arm.com
13512109SRekai.GonzalezAlberquilla@arm.com        /**
13612109SRekai.GonzalezAlberquilla@arm.com         * Deal with a destination port accepting a packet by potentially
13712109SRekai.GonzalezAlberquilla@arm.com         * removing the source port from the retry list (if retrying) and
13812109SRekai.GonzalezAlberquilla@arm.com         * occupying the layer accordingly.
13912109SRekai.GonzalezAlberquilla@arm.com         *
14013610Sgiacomo.gabrielli@arm.com         * @param busy_time Time to spend as a result of a successful send
14113610Sgiacomo.gabrielli@arm.com         */
14213610Sgiacomo.gabrielli@arm.com        void succeededTiming(Tick busy_time);
1439920Syasuko.eckert@amd.com
1449920Syasuko.eckert@amd.com        /**
1459920Syasuko.eckert@amd.com         * Deal with a destination port not accepting a packet by
1469919Ssteve.reinhardt@amd.com         * potentially adding the source port to the retry list (if
1479919Ssteve.reinhardt@amd.com         * not already at the front) and occupying the layer
1489919Ssteve.reinhardt@amd.com         * accordingly.
1499919Ssteve.reinhardt@amd.com         *
1509919Ssteve.reinhardt@amd.com         * @param src_port Source port
1511060SN/A         * @param busy_time Time to spend as a result of a failed send
1529919Ssteve.reinhardt@amd.com         */
1539919Ssteve.reinhardt@amd.com        void failedTiming(SrcType* src_port, Tick busy_time);
1549919Ssteve.reinhardt@amd.com
1559919Ssteve.reinhardt@amd.com        /** Occupy the layer until until */
1569919Ssteve.reinhardt@amd.com        void occupyLayer(Tick until);
1579919Ssteve.reinhardt@amd.com
1581060SN/A        /**
1591060SN/A         * Send a retry to the port at the head of waitingForLayer. The
1602292SN/A         * caller must ensure that the list is not empty.
1612292SN/A         */
1629919Ssteve.reinhardt@amd.com        void retryWaiting();
1639919Ssteve.reinhardt@amd.com
1642292SN/A        /**
1659919Ssteve.reinhardt@amd.com         * Handle a retry from a neighbouring module. This wraps
1669919Ssteve.reinhardt@amd.com         * retryWaiting by verifying that there are ports waiting
1672292SN/A         * before calling retryWaiting.
1689919Ssteve.reinhardt@amd.com         */
1691060SN/A        void recvRetry();
1702292SN/A
1719919Ssteve.reinhardt@amd.com        /**
1722292SN/A         * Register stats for the layer
1739920Syasuko.eckert@amd.com         */
1749920Syasuko.eckert@amd.com        void regStats();
1759920Syasuko.eckert@amd.com
1762292SN/A      private:
17712105Snathanael.premillieu@arm.com
1781060SN/A        /** The destination port this layer converges at. */
1792292SN/A        DstType& port;
18012105Snathanael.premillieu@arm.com
1811060SN/A        /** The crossbar this layer is a part of. */
18212109SRekai.GonzalezAlberquilla@arm.com        BaseXBar& xbar;
18312109SRekai.GonzalezAlberquilla@arm.com
18412109SRekai.GonzalezAlberquilla@arm.com        /** A name for this layer. */
18512109SRekai.GonzalezAlberquilla@arm.com        std::string _name;
18612109SRekai.GonzalezAlberquilla@arm.com
18712109SRekai.GonzalezAlberquilla@arm.com        /**
18813610Sgiacomo.gabrielli@arm.com         * We declare an enum to track the state of the layer. The
18913610Sgiacomo.gabrielli@arm.com         * starting point is an idle state where the layer is waiting
19013610Sgiacomo.gabrielli@arm.com         * for a packet to arrive. Upon arrival, the layer
1919920Syasuko.eckert@amd.com         * transitions to the busy state, where it remains either
19212105Snathanael.premillieu@arm.com         * until the packet transfer is done, or the header time is
1939920Syasuko.eckert@amd.com         * spent. Once the layer leaves the busy state, it can
1942292SN/A         * either go back to idle, if no packets have arrived while it
19512105Snathanael.premillieu@arm.com         * was busy, or the layer goes on to retry the first port
1961060SN/A         * in waitingForLayer. A similar transition takes place from
19712109SRekai.GonzalezAlberquilla@arm.com         * idle to retry if the layer receives a retry from one of
19812109SRekai.GonzalezAlberquilla@arm.com         * its connected ports. The retry state lasts until the port
19912109SRekai.GonzalezAlberquilla@arm.com         * in questions calls sendTiming and returns control to the
20012109SRekai.GonzalezAlberquilla@arm.com         * layer, or goes to a busy state if the port does not
2012292SN/A         * immediately react to the retry by calling sendTiming.
20212105Snathanael.premillieu@arm.com         */
2031060SN/A        enum State { IDLE, BUSY, RETRY };
2042292SN/A
20512105Snathanael.premillieu@arm.com        /** track the state of the layer */
2061060SN/A        State state;
20712109SRekai.GonzalezAlberquilla@arm.com
20812109SRekai.GonzalezAlberquilla@arm.com        /** manager to signal when drained */
20912109SRekai.GonzalezAlberquilla@arm.com        DrainManager *drainManager;
21012109SRekai.GonzalezAlberquilla@arm.com
21112109SRekai.GonzalezAlberquilla@arm.com        /**
21212109SRekai.GonzalezAlberquilla@arm.com         * A deque of ports that retry should be called on because
21312109SRekai.GonzalezAlberquilla@arm.com         * the original send was delayed due to a busy layer.
21412109SRekai.GonzalezAlberquilla@arm.com         */
21513610Sgiacomo.gabrielli@arm.com        std::deque<SrcType*> waitingForLayer;
21613610Sgiacomo.gabrielli@arm.com
21713610Sgiacomo.gabrielli@arm.com        /**
2189920Syasuko.eckert@amd.com         * Track who is waiting for the retry when receiving it from a
21912105Snathanael.premillieu@arm.com         * peer. If no port is waiting NULL is stored.
2209920Syasuko.eckert@amd.com         */
2212292SN/A        SrcType* waitingForPeer;
2229919Ssteve.reinhardt@amd.com
2231060SN/A        /**
2242292SN/A         * Release the layer after being occupied and return to an
2259919Ssteve.reinhardt@amd.com         * idle state where we proceed to send a retry to any
2261060SN/A         * potential waiting port, or drain if asked to do so.
22712109SRekai.GonzalezAlberquilla@arm.com         */
22812109SRekai.GonzalezAlberquilla@arm.com        void releaseLayer();
22912109SRekai.GonzalezAlberquilla@arm.com
23012109SRekai.GonzalezAlberquilla@arm.com        /** event used to schedule a release of the layer */
23112109SRekai.GonzalezAlberquilla@arm.com        EventWrapper<Layer, &Layer::releaseLayer> releaseEvent;
23212109SRekai.GonzalezAlberquilla@arm.com
23313610Sgiacomo.gabrielli@arm.com        /**
23413610Sgiacomo.gabrielli@arm.com         * Stats for occupancy and utilization. These stats capture
23513610Sgiacomo.gabrielli@arm.com         * the time the layer spends in the busy state and are thus only
2369920Syasuko.eckert@amd.com         * relevant when the memory system is in timing mode.
2379920Syasuko.eckert@amd.com         */
2389920Syasuko.eckert@amd.com        Stats::Scalar occupancy;
2392292SN/A        Stats::Formula utilization;
2409919Ssteve.reinhardt@amd.com
2411060SN/A    };
2422292SN/A
2439919Ssteve.reinhardt@amd.com    /** cycles of overhead per transaction */
2449920Syasuko.eckert@amd.com    const Cycles headerCycles;
24512109SRekai.GonzalezAlberquilla@arm.com    /** the width of the xbar in bytes */
24612109SRekai.GonzalezAlberquilla@arm.com    const uint32_t width;
24712109SRekai.GonzalezAlberquilla@arm.com
24813598Sgiacomo.travaglini@arm.com    AddrRangeMap<PortID> portMap;
24913598Sgiacomo.travaglini@arm.com
25013598Sgiacomo.travaglini@arm.com    /** all contigous ranges seen by this crossbar */
25113610Sgiacomo.gabrielli@arm.com    AddrRangeList xbarRanges;
25213610Sgiacomo.gabrielli@arm.com
25313610Sgiacomo.gabrielli@arm.com    AddrRange defaultRange;
2549920Syasuko.eckert@amd.com
2559920Syasuko.eckert@amd.com    /**
2561060SN/A     * Function called by the port when the crossbar is recieving a
2571060SN/A     * range change.
25812109SRekai.GonzalezAlberquilla@arm.com     *
25912109SRekai.GonzalezAlberquilla@arm.com     * @param master_port_id id of the port that received the change
26012109SRekai.GonzalezAlberquilla@arm.com     */
26112109SRekai.GonzalezAlberquilla@arm.com    void recvRangeChange(PortID master_port_id);
26212109SRekai.GonzalezAlberquilla@arm.com
26312109SRekai.GonzalezAlberquilla@arm.com    /** Find which port connected to this crossbar (if any) should be
26412109SRekai.GonzalezAlberquilla@arm.com     * given a packet with this address.
26512109SRekai.GonzalezAlberquilla@arm.com     *
26612109SRekai.GonzalezAlberquilla@arm.com     * @param addr Address to find port for.
26712109SRekai.GonzalezAlberquilla@arm.com     * @return id of port that the packet should be sent out of.
26812109SRekai.GonzalezAlberquilla@arm.com     */
26912109SRekai.GonzalezAlberquilla@arm.com    PortID findPort(Addr addr);
27012109SRekai.GonzalezAlberquilla@arm.com
27112109SRekai.GonzalezAlberquilla@arm.com    // Cache for the findPort function storing recently used ports from portMap
27212109SRekai.GonzalezAlberquilla@arm.com    struct PortCache {
27312109SRekai.GonzalezAlberquilla@arm.com        bool valid;
27412109SRekai.GonzalezAlberquilla@arm.com        PortID id;
27512109SRekai.GonzalezAlberquilla@arm.com        AddrRange range;
27612109SRekai.GonzalezAlberquilla@arm.com    };
27712109SRekai.GonzalezAlberquilla@arm.com
27812109SRekai.GonzalezAlberquilla@arm.com    PortCache portCache[3];
27912109SRekai.GonzalezAlberquilla@arm.com
28012109SRekai.GonzalezAlberquilla@arm.com    // Checks the cache and returns the id of the port that has the requested
28112109SRekai.GonzalezAlberquilla@arm.com    // address within its range
28212109SRekai.GonzalezAlberquilla@arm.com    inline PortID checkPortCache(Addr addr) const {
28312109SRekai.GonzalezAlberquilla@arm.com        if (portCache[0].valid && portCache[0].range.contains(addr)) {
28413610Sgiacomo.gabrielli@arm.com            return portCache[0].id;
28513610Sgiacomo.gabrielli@arm.com        }
28613610Sgiacomo.gabrielli@arm.com        if (portCache[1].valid && portCache[1].range.contains(addr)) {
28712109SRekai.GonzalezAlberquilla@arm.com            return portCache[1].id;
28812109SRekai.GonzalezAlberquilla@arm.com        }
28912109SRekai.GonzalezAlberquilla@arm.com        if (portCache[2].valid && portCache[2].range.contains(addr)) {
29012109SRekai.GonzalezAlberquilla@arm.com            return portCache[2].id;
29112109SRekai.GonzalezAlberquilla@arm.com        }
29212109SRekai.GonzalezAlberquilla@arm.com
29312109SRekai.GonzalezAlberquilla@arm.com        return InvalidPortID;
29412109SRekai.GonzalezAlberquilla@arm.com    }
29512109SRekai.GonzalezAlberquilla@arm.com
29612109SRekai.GonzalezAlberquilla@arm.com    // Clears the earliest entry of the cache and inserts a new port entry
2971060SN/A    inline void updatePortCache(short id, const AddrRange& range) {
29812105Snathanael.premillieu@arm.com        portCache[2].valid = portCache[1].valid;
2991060SN/A        portCache[2].id    = portCache[1].id;
30012106SRekai.GonzalezAlberquilla@arm.com        portCache[2].range = portCache[1].range;
30112106SRekai.GonzalezAlberquilla@arm.com
3021060SN/A        portCache[1].valid = portCache[0].valid;
3031060SN/A        portCache[1].id    = portCache[0].id;
30412106SRekai.GonzalezAlberquilla@arm.com        portCache[1].range = portCache[0].range;
30512105Snathanael.premillieu@arm.com
30612105Snathanael.premillieu@arm.com        portCache[0].valid = true;
30712105Snathanael.premillieu@arm.com        portCache[0].id    = id;
30812105Snathanael.premillieu@arm.com        portCache[0].range = range;
30912105Snathanael.premillieu@arm.com    }
31012105Snathanael.premillieu@arm.com
31112109SRekai.GonzalezAlberquilla@arm.com    // Clears the cache. Needs to be called in constructor.
31212109SRekai.GonzalezAlberquilla@arm.com    inline void clearPortCache() {
31312109SRekai.GonzalezAlberquilla@arm.com        portCache[2].valid = false;
31412109SRekai.GonzalezAlberquilla@arm.com        portCache[1].valid = false;
31512109SRekai.GonzalezAlberquilla@arm.com        portCache[0].valid = false;
31612109SRekai.GonzalezAlberquilla@arm.com    }
31713610Sgiacomo.gabrielli@arm.com
31813610Sgiacomo.gabrielli@arm.com    /**
31913610Sgiacomo.gabrielli@arm.com     * Return the address ranges the crossbar is responsible for.
32012105Snathanael.premillieu@arm.com     *
32112105Snathanael.premillieu@arm.com     * @return a list of non-overlapping address ranges
32212105Snathanael.premillieu@arm.com     */
32312105Snathanael.premillieu@arm.com    AddrRangeList getAddrRanges() const;
32412105Snathanael.premillieu@arm.com
32512106SRekai.GonzalezAlberquilla@arm.com    /**
3261060SN/A     * Calculate the timing parameters for the packet. Updates the
3275362Sksewell@umich.edu     * firstWordDelay and lastWordDelay fields of the packet
3285364Sksewell@umich.edu     * object with the relative number of ticks required to transmit
3295364Sksewell@umich.edu     * the header and the first word, and the last word, respectively.
3305364Sksewell@umich.edu     */
3315364Sksewell@umich.edu    void calcPacketTiming(PacketPtr pkt);
3325364Sksewell@umich.edu
3335364Sksewell@umich.edu    /**
3345364Sksewell@umich.edu     * Remember for each of the master ports of the crossbar if we got
3355364Sksewell@umich.edu     * an address range from the connected slave. For convenience,
3365364Sksewell@umich.edu     * also keep track of if we got ranges from all the slave modules
3375364Sksewell@umich.edu     * or not.
3385364Sksewell@umich.edu     */
3391060SN/A    std::vector<bool> gotAddrRanges;
3401060SN/A    bool gotAllAddrRanges;
3411060SN/A
3422292SN/A    /** The master and slave ports of the crossbar */
343    std::vector<SlavePort*> slavePorts;
344    std::vector<MasterPort*> masterPorts;
345
346    /** Port that handles requests that don't match any of the interfaces.*/
347    PortID defaultPortID;
348
349    /** If true, use address range provided by default device.  Any
350       address not handled by another port and not in default device's
351       range will cause a fatal error.  If false, just send all
352       addresses not handled by another port to default device. */
353    const bool useDefaultRange;
354
355    BaseXBar(const BaseXBarParams *p);
356
357    virtual ~BaseXBar();
358
359    /**
360     * Stats for transaction distribution and data passing through the
361     * crossbar. The transaction distribution is globally counting
362     * different types of commands. The packet count and total packet
363     * size are two-dimensional vectors that are indexed by the
364     * slave port and master port id (thus the neighbouring master and
365     * neighbouring slave), summing up both directions (request and
366     * response).
367     */
368    Stats::Vector transDist;
369    Stats::Vector2d pktCount;
370    Stats::Vector2d pktSize;
371
372  public:
373
374    virtual void init();
375
376    /** A function used to return the port associated with this object. */
377    BaseMasterPort& getMasterPort(const std::string& if_name,
378                                  PortID idx = InvalidPortID);
379    BaseSlavePort& getSlavePort(const std::string& if_name,
380                                PortID idx = InvalidPortID);
381
382    virtual unsigned int drain(DrainManager *dm) = 0;
383
384    virtual void regStats();
385
386};
387
388#endif //__MEM_XBAR_HH__
389