serial_link.hh revision 12823
12929Sktlim@umich.edu/*
22929Sktlim@umich.edu * Copyright (c) 2011-2013 ARM Limited
32932Sktlim@umich.edu * All rights reserved
42929Sktlim@umich.edu *
52929Sktlim@umich.edu * The license below extends only to copyright in the software and shall
62929Sktlim@umich.edu * not be construed as granting a license to any other intellectual
72929Sktlim@umich.edu * property including but not limited to intellectual property relating
82929Sktlim@umich.edu * to a hardware implementation of the functionality of the software
92929Sktlim@umich.edu * licensed hereunder.  You may use the software subject to the license
102929Sktlim@umich.edu * terms below provided that you ensure that this notice is replicated
112929Sktlim@umich.edu * unmodified and in its entirety in all distributions of the software,
122929Sktlim@umich.edu * modified or unmodified, in source code or in binary form.
132929Sktlim@umich.edu *
142929Sktlim@umich.edu * Copyright (c) 2006 The Regents of The University of Michigan
152929Sktlim@umich.edu * Copyright (c) 2015 The University of Bologna
162929Sktlim@umich.edu * All rights reserved.
172929Sktlim@umich.edu *
182929Sktlim@umich.edu * Redistribution and use in source and binary forms, with or without
192929Sktlim@umich.edu * modification, are permitted provided that the following conditions are
202929Sktlim@umich.edu * met: redistributions of source code must retain the above copyright
212929Sktlim@umich.edu * notice, this list of conditions and the following disclaimer;
222929Sktlim@umich.edu * redistributions in binary form must reproduce the above copyright
232929Sktlim@umich.edu * notice, this list of conditions and the following disclaimer in the
242929Sktlim@umich.edu * documentation and/or other materials provided with the distribution;
252929Sktlim@umich.edu * neither the name of the copyright holders nor the names of its
262929Sktlim@umich.edu * contributors may be used to endorse or promote products derived from
272929Sktlim@umich.edu * this software without specific prior written permission.
282932Sktlim@umich.edu *
292932Sktlim@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
302932Sktlim@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
312929Sktlim@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
326007Ssteve.reinhardt@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
332929Sktlim@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
342929Sktlim@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
352929Sktlim@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
362929Sktlim@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
372929Sktlim@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
382929Sktlim@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
392929Sktlim@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
402929Sktlim@umich.edu *
412929Sktlim@umich.edu * Authors: Ali Saidi
422929Sktlim@umich.edu *          Steve Reinhardt
432929Sktlim@umich.edu *          Andreas Hansson
442929Sktlim@umich.edu *          Erfan Azarkhish
452929Sktlim@umich.edu */
462929Sktlim@umich.edu
476007Ssteve.reinhardt@amd.com/**
486007Ssteve.reinhardt@amd.com * @file
496007Ssteve.reinhardt@amd.com * Declaration of the SerialLink Class, modeling Hybrid-Memory-Cube's serial
506007Ssteve.reinhardt@amd.com * interface.
516007Ssteve.reinhardt@amd.com */
526007Ssteve.reinhardt@amd.com
536007Ssteve.reinhardt@amd.com#ifndef __MEM_SERIAL_LINK_HH__
546007Ssteve.reinhardt@amd.com#define __MEM_SERIAL_LINK_HH__
556007Ssteve.reinhardt@amd.com
566007Ssteve.reinhardt@amd.com#include <deque>
576007Ssteve.reinhardt@amd.com
586007Ssteve.reinhardt@amd.com#include "base/types.hh"
596007Ssteve.reinhardt@amd.com#include "mem/mem_object.hh"
606007Ssteve.reinhardt@amd.com#include "params/SerialLink.hh"
616007Ssteve.reinhardt@amd.com
626007Ssteve.reinhardt@amd.com/**
636007Ssteve.reinhardt@amd.com * SerialLink is a simple variation of the Bridge class, with the ability to
646007Ssteve.reinhardt@amd.com * account for the latency of packet serialization. We assume that the
656007Ssteve.reinhardt@amd.com * serializer component at the transmitter side does not need to receive the
666007Ssteve.reinhardt@amd.com * whole packet to start the serialization. But the deserializer waits for the
676007Ssteve.reinhardt@amd.com * complete packet to check its integrity first.
686007Ssteve.reinhardt@amd.com  */
696007Ssteve.reinhardt@amd.comclass SerialLink : public MemObject
706007Ssteve.reinhardt@amd.com{
716007Ssteve.reinhardt@amd.com  protected:
726007Ssteve.reinhardt@amd.com
736007Ssteve.reinhardt@amd.com    /**
746007Ssteve.reinhardt@amd.com     * A deferred packet stores a packet along with its scheduled
756007Ssteve.reinhardt@amd.com     * transmission time
762929Sktlim@umich.edu     */
772929Sktlim@umich.edu    class DeferredPacket
782929Sktlim@umich.edu    {
796007Ssteve.reinhardt@amd.com
806007Ssteve.reinhardt@amd.com      public:
816007Ssteve.reinhardt@amd.com
826007Ssteve.reinhardt@amd.com        const Tick tick;
836007Ssteve.reinhardt@amd.com        const PacketPtr pkt;
846007Ssteve.reinhardt@amd.com
852929Sktlim@umich.edu        DeferredPacket(PacketPtr _pkt, Tick _tick) : tick(_tick), pkt(_pkt)
862929Sktlim@umich.edu        { }
872929Sktlim@umich.edu    };
882929Sktlim@umich.edu
892929Sktlim@umich.edu    // Forward declaration to allow the slave port to have a pointer
906011Ssteve.reinhardt@amd.com    class SerialLinkMasterPort;
916007Ssteve.reinhardt@amd.com
926007Ssteve.reinhardt@amd.com    /**
936007Ssteve.reinhardt@amd.com     * The port on the side that receives requests and sends
946007Ssteve.reinhardt@amd.com     * responses. The slave port has a set of address ranges that it
956007Ssteve.reinhardt@amd.com     * is responsible for. The slave port also has a buffer for the
966007Ssteve.reinhardt@amd.com     * responses not yet sent.
976007Ssteve.reinhardt@amd.com     */
986007Ssteve.reinhardt@amd.com    class SerialLinkSlavePort : public SlavePort
996007Ssteve.reinhardt@amd.com    {
1006007Ssteve.reinhardt@amd.com
1016007Ssteve.reinhardt@amd.com      private:
1026007Ssteve.reinhardt@amd.com
1036007Ssteve.reinhardt@amd.com        /** The serial_link to which this port belongs. */
1046007Ssteve.reinhardt@amd.com        SerialLink& serial_link;
1056011Ssteve.reinhardt@amd.com
1066007Ssteve.reinhardt@amd.com        /**
1076007Ssteve.reinhardt@amd.com         * Master port on the other side of the serial_link.
1086007Ssteve.reinhardt@amd.com         */
1096007Ssteve.reinhardt@amd.com        SerialLinkMasterPort& masterPort;
1106007Ssteve.reinhardt@amd.com
1116007Ssteve.reinhardt@amd.com        /** Minimum request delay though this serial_link. */
1126007Ssteve.reinhardt@amd.com        const Cycles delay;
1136011Ssteve.reinhardt@amd.com
1146007Ssteve.reinhardt@amd.com        /** Address ranges to pass through the serial_link */
1156007Ssteve.reinhardt@amd.com        const AddrRangeList ranges;
1166007Ssteve.reinhardt@amd.com
1176007Ssteve.reinhardt@amd.com        /**
1186007Ssteve.reinhardt@amd.com         * Response packet queue. Response packets are held in this
1196007Ssteve.reinhardt@amd.com         * queue for a specified delay to model the processing delay
1206007Ssteve.reinhardt@amd.com         * of the serial_link. We use a deque as we need to iterate over
1216011Ssteve.reinhardt@amd.com         * the items for functional accesses.
1226007Ssteve.reinhardt@amd.com         */
1236007Ssteve.reinhardt@amd.com        std::deque<DeferredPacket> transmitList;
1246007Ssteve.reinhardt@amd.com
1256007Ssteve.reinhardt@amd.com        /** Counter to track the outstanding responses. */
1266007Ssteve.reinhardt@amd.com        unsigned int outstandingResponses;
1276008Ssteve.reinhardt@amd.com
1286007Ssteve.reinhardt@amd.com        /** If we should send a retry when space becomes available. */
1296008Ssteve.reinhardt@amd.com        bool retryReq;
1306008Ssteve.reinhardt@amd.com
1316008Ssteve.reinhardt@amd.com        /** Max queue size for reserved responses. */
1326008Ssteve.reinhardt@amd.com        unsigned int respQueueLimit;
1336008Ssteve.reinhardt@amd.com
1346008Ssteve.reinhardt@amd.com        /**
1356008Ssteve.reinhardt@amd.com         * Is this side blocked from accepting new response packets.
1366007Ssteve.reinhardt@amd.com         *
1376007Ssteve.reinhardt@amd.com         * @return true if the reserved space has reached the set limit
1386007Ssteve.reinhardt@amd.com         */
1396007Ssteve.reinhardt@amd.com        bool respQueueFull() const;
1406007Ssteve.reinhardt@amd.com
1412929Sktlim@umich.edu        /**
1422929Sktlim@umich.edu         * Handle send event, scheduled when the packet at the head of
1432929Sktlim@umich.edu         * the response queue is ready to transmit (for timing
1442929Sktlim@umich.edu         * accesses only).
1456007Ssteve.reinhardt@amd.com         */
1466007Ssteve.reinhardt@amd.com        void trySendTiming();
1472929Sktlim@umich.edu
1482929Sktlim@umich.edu        /** Send event for the response queue. */
1492929Sktlim@umich.edu        EventFunctionWrapper sendEvent;
1502929Sktlim@umich.edu
1516007Ssteve.reinhardt@amd.com      public:
1526007Ssteve.reinhardt@amd.com
1532929Sktlim@umich.edu        /**
1542929Sktlim@umich.edu         * Constructor for the SerialLinkSlavePort.
1556007Ssteve.reinhardt@amd.com         *
1562929Sktlim@umich.edu         * @param _name the port name including the owner
1572929Sktlim@umich.edu         * @param _serial_link the structural owner
1582929Sktlim@umich.edu         * @param _masterPort the master port on the other side of the
1592929Sktlim@umich.edu         * serial_link
1602929Sktlim@umich.edu         * @param _delay the delay in cycles from receiving to sending
1612929Sktlim@umich.edu         * @param _resp_limit the size of the response queue
1622929Sktlim@umich.edu         * @param _ranges a number of address ranges to forward
1634937Sstever@gmail.com         */
1644937Sstever@gmail.com        SerialLinkSlavePort(const std::string& _name, SerialLink&
1654937Sstever@gmail.com                        _serial_link, SerialLinkMasterPort& _masterPort,
1664937Sstever@gmail.com                        Cycles _delay, int _resp_limit, const
1674937Sstever@gmail.com                        std::vector<AddrRange>& _ranges);
1684937Sstever@gmail.com
1694937Sstever@gmail.com        /**
1704937Sstever@gmail.com         * Queue a response packet to be sent out later and also schedule
1714937Sstever@gmail.com         * a send if necessary.
1725773Snate@binkert.org         *
1734937Sstever@gmail.com         * @param pkt a response to send out after a delay
1744937Sstever@gmail.com         * @param when tick when response packet should be sent
1754937Sstever@gmail.com         */
1762929Sktlim@umich.edu        void schedTimingResp(PacketPtr pkt, Tick when);
1772929Sktlim@umich.edu
1782929Sktlim@umich.edu        /**
1795773Snate@binkert.org         * Retry any stalled request that we have failed to accept at
1802929Sktlim@umich.edu         * an earlier point in time. This call will do nothing if no
1812929Sktlim@umich.edu         * request is waiting.
1822929Sktlim@umich.edu         */
1832929Sktlim@umich.edu        void retryStalledReq();
1842929Sktlim@umich.edu
1852929Sktlim@umich.edu      protected:
1864937Sstever@gmail.com
1874937Sstever@gmail.com        /** When receiving a timing request from the peer port,
1884937Sstever@gmail.com            pass it to the serial_link. */
1894937Sstever@gmail.com        bool recvTimingReq(PacketPtr pkt);
1904937Sstever@gmail.com
1914937Sstever@gmail.com        /** When receiving a retry request from the peer port,
1924937Sstever@gmail.com            pass it to the serial_link. */
1934937Sstever@gmail.com        void recvRespRetry();
1944937Sstever@gmail.com
1954937Sstever@gmail.com        /** When receiving a Atomic requestfrom the peer port,
1964937Sstever@gmail.com            pass it to the serial_link. */
1974937Sstever@gmail.com        Tick recvAtomic(PacketPtr pkt);
1984937Sstever@gmail.com
1994937Sstever@gmail.com        /** When receiving a Functional request from the peer port,
2004937Sstever@gmail.com            pass it to the serial_link. */
2012929Sktlim@umich.edu        void recvFunctional(PacketPtr pkt);
2022929Sktlim@umich.edu
2032929Sktlim@umich.edu        /** When receiving a address range request the peer port,
2042929Sktlim@umich.edu            pass it to the serial_link. */
2052929Sktlim@umich.edu        AddrRangeList getAddrRanges() const;
2062929Sktlim@umich.edu    };
2072929Sktlim@umich.edu
2086011Ssteve.reinhardt@amd.com
2092929Sktlim@umich.edu    /**
2102929Sktlim@umich.edu     * Port on the side that forwards requests and receives
2112929Sktlim@umich.edu     * responses. The master port has a buffer for the requests not
2122929Sktlim@umich.edu     * yet sent.
2132929Sktlim@umich.edu     */
2142929Sktlim@umich.edu    class SerialLinkMasterPort : public MasterPort
2152929Sktlim@umich.edu    {
2162929Sktlim@umich.edu
2172997Sstever@eecs.umich.edu      private:
2182997Sstever@eecs.umich.edu
2192929Sktlim@umich.edu        /** The serial_link to which this port belongs. */
2202997Sstever@eecs.umich.edu        SerialLink& serial_link;
2212997Sstever@eecs.umich.edu
2222929Sktlim@umich.edu        /**
2232997Sstever@eecs.umich.edu         * The slave port on the other side of the serial_link.
2242997Sstever@eecs.umich.edu         */
2252997Sstever@eecs.umich.edu        SerialLinkSlavePort& slavePort;
2262929Sktlim@umich.edu
2272997Sstever@eecs.umich.edu        /** Minimum delay though this serial_link. */
2282997Sstever@eecs.umich.edu        const Cycles delay;
2292997Sstever@eecs.umich.edu
2302997Sstever@eecs.umich.edu        /**
2315773Snate@binkert.org         * Request packet queue. Request packets are held in this
2325773Snate@binkert.org         * queue for a specified delay to model the processing delay
2332997Sstever@eecs.umich.edu         * of the serial_link.  We use a deque as we need to iterate over
2342997Sstever@eecs.umich.edu         * the items for functional accesses.
2356007Ssteve.reinhardt@amd.com         */
2366007Ssteve.reinhardt@amd.com        std::deque<DeferredPacket> transmitList;
2372997Sstever@eecs.umich.edu
2382929Sktlim@umich.edu        /** Max queue size for request packets */
2392997Sstever@eecs.umich.edu        const unsigned int reqQueueLimit;
2402997Sstever@eecs.umich.edu
2412997Sstever@eecs.umich.edu        /**
2422997Sstever@eecs.umich.edu         * Handle send event, scheduled when the packet at the head of
2432997Sstever@eecs.umich.edu         * the outbound queue is ready to transmit (for timing
2442997Sstever@eecs.umich.edu         * accesses only).
2452997Sstever@eecs.umich.edu         */
2462929Sktlim@umich.edu        void trySendTiming();
2472997Sstever@eecs.umich.edu
2482929Sktlim@umich.edu        /** Send event for the request queue. */
2492929Sktlim@umich.edu        EventFunctionWrapper sendEvent;
2503005Sstever@eecs.umich.edu
2513005Sstever@eecs.umich.edu      public:
2523005Sstever@eecs.umich.edu
2533005Sstever@eecs.umich.edu        /**
2546025Snate@binkert.org         * Constructor for the SerialLinkMasterPort.
2556025Snate@binkert.org         *
2566025Snate@binkert.org         * @param _name the port name including the owner
2576025Snate@binkert.org         * @param _serial_link the structural owner
2586025Snate@binkert.org         * @param _slavePort the slave port on the other side of the
2596025Snate@binkert.org         * serial_link
2604130Ssaidi@eecs.umich.edu         * @param _delay the delay in cycles from receiving to sending
2614130Ssaidi@eecs.umich.edu         * @param _req_limit the size of the request queue
2624130Ssaidi@eecs.umich.edu         */
2633691Shsul@eecs.umich.edu        SerialLinkMasterPort(const std::string& _name, SerialLink&
2643005Sstever@eecs.umich.edu                         _serial_link, SerialLinkSlavePort& _slavePort, Cycles
2655721Shsul@eecs.umich.edu                         _delay, int _req_limit);
2666194Sksewell@umich.edu
2676928SBrad.Beckmann@amd.com        /**
2683005Sstever@eecs.umich.edu         * Is this side blocked from accepting new request packets.
2696168Snate@binkert.org         *
2706928SBrad.Beckmann@amd.com         * @return true if the occupied space has reached the set limit
2716928SBrad.Beckmann@amd.com         */
2726928SBrad.Beckmann@amd.com        bool reqQueueFull() const;
2736928SBrad.Beckmann@amd.com
2746928SBrad.Beckmann@amd.com        /**
2756928SBrad.Beckmann@amd.com         * Queue a request packet to be sent out later and also schedule
2766928SBrad.Beckmann@amd.com         * a send if necessary.
2776928SBrad.Beckmann@amd.com         *
2786928SBrad.Beckmann@amd.com         * @param pkt a request to send out after a delay
2796928SBrad.Beckmann@amd.com         * @param when tick when response packet should be sent
2806928SBrad.Beckmann@amd.com         */
2816928SBrad.Beckmann@amd.com        void schedTimingReq(PacketPtr pkt, Tick when);
2826928SBrad.Beckmann@amd.com
2836928SBrad.Beckmann@amd.com        /**
2846166Ssteve.reinhardt@amd.com         * Check a functional request against the packets in our
2852929Sktlim@umich.edu         * request queue.
2862929Sktlim@umich.edu         *
2873005Sstever@eecs.umich.edu         * @param pkt packet to check against
2882997Sstever@eecs.umich.edu         *
2892997Sstever@eecs.umich.edu         * @return true if we find a match
2906293Ssteve.reinhardt@amd.com         */
2916293Ssteve.reinhardt@amd.com        bool trySatisfyFunctional(PacketPtr pkt);
2922929Sktlim@umich.edu
293      protected:
294
295        /** When receiving a timing request from the peer port,
296            pass it to the serial_link. */
297        bool recvTimingResp(PacketPtr pkt);
298
299        /** When receiving a retry request from the peer port,
300            pass it to the serial_link. */
301        void recvReqRetry();
302    };
303
304    /** Slave port of the serial_link. */
305    SerialLinkSlavePort slavePort;
306
307    /** Master port of the serial_link. */
308    SerialLinkMasterPort masterPort;
309
310    /** Number of parallel lanes in this serial link */
311    unsigned num_lanes;
312
313    /** Speed of each link (Gb/s) in this serial link */
314    uint64_t link_speed;
315
316  public:
317
318    virtual BaseMasterPort& getMasterPort(const std::string& if_name,
319                                          PortID idx = InvalidPortID);
320    virtual BaseSlavePort& getSlavePort(const std::string& if_name,
321                                        PortID idx = InvalidPortID);
322
323    virtual void init();
324
325    typedef SerialLinkParams Params;
326
327    SerialLink(SerialLinkParams *p);
328};
329
330#endif //__MEM_SERIAL_LINK_HH__
331