112802Sandreas.sandberg@arm.com/*
212802Sandreas.sandberg@arm.com * Copyright (c) 2018 ARM Limited
312802Sandreas.sandberg@arm.com * All rights reserved
412802Sandreas.sandberg@arm.com *
512802Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall
612802Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual
712802Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating
812802Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software
912802Sandreas.sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
1012802Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated
1112802Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
1212802Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form.
1312802Sandreas.sandberg@arm.com *
1412802Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
1512802Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
1612802Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
1712802Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
1812802Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
1912802Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
2012802Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
2112802Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
2212802Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
2312802Sandreas.sandberg@arm.com * this software without specific prior written permission.
2412802Sandreas.sandberg@arm.com *
2512802Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2612802Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2712802Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2812802Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2912802Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3012802Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3112802Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3212802Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3312802Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3412802Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3512802Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3612802Sandreas.sandberg@arm.com *
3712802Sandreas.sandberg@arm.com * Authors: Andreas Sandberg
3812802Sandreas.sandberg@arm.com */
3912802Sandreas.sandberg@arm.com
4012802Sandreas.sandberg@arm.com#ifndef __MEM_MEM_DELAY_HH__
4112802Sandreas.sandberg@arm.com#define __MEM_MEM_DELAY_HH__
4212802Sandreas.sandberg@arm.com
4312802Sandreas.sandberg@arm.com#include "mem/qport.hh"
4413892Sgabeblack@google.com#include "sim/clocked_object.hh"
4512802Sandreas.sandberg@arm.com
4612802Sandreas.sandberg@arm.comstruct MemDelayParams;
4712802Sandreas.sandberg@arm.comstruct SimpleMemDelayParams;
4812802Sandreas.sandberg@arm.com
4912802Sandreas.sandberg@arm.com/**
5012802Sandreas.sandberg@arm.com * This abstract component provides a mechanism to delay
5112802Sandreas.sandberg@arm.com * packets. It can be spliced between arbitrary ports of the memory
5212802Sandreas.sandberg@arm.com * system and delays packets that pass through it.
5312802Sandreas.sandberg@arm.com *
5412802Sandreas.sandberg@arm.com * Specialisations of this abstract class should override at least one
5512802Sandreas.sandberg@arm.com * of delayReq, delayResp, deleySnoopReq, delaySnoopResp. These
5612802Sandreas.sandberg@arm.com * methods receive a PacketPtr as their argument and return a delay in
5712802Sandreas.sandberg@arm.com * Ticks. The base class implements an infinite buffer to hold delayed
5812802Sandreas.sandberg@arm.com * packets until they are ready. The intention is to use this
5912802Sandreas.sandberg@arm.com * component for rapid prototyping of other memory system components
6012802Sandreas.sandberg@arm.com * that introduce a packet processing delays.
6112802Sandreas.sandberg@arm.com *
6212802Sandreas.sandberg@arm.com * NOTE: Packets may be reordered if the delays aren't constant.
6312802Sandreas.sandberg@arm.com */
6413892Sgabeblack@google.comclass MemDelay : public ClockedObject
6512802Sandreas.sandberg@arm.com{
6612802Sandreas.sandberg@arm.com
6712802Sandreas.sandberg@arm.com  public:
6812802Sandreas.sandberg@arm.com    MemDelay(const MemDelayParams *params);
6912802Sandreas.sandberg@arm.com
7012802Sandreas.sandberg@arm.com    void init() override;
7112802Sandreas.sandberg@arm.com
7213784Sgabeblack@google.com  protected: // Port interface
7313784Sgabeblack@google.com    Port &getPort(const std::string &if_name,
7413784Sgabeblack@google.com                  PortID idx=InvalidPortID) override;
7512802Sandreas.sandberg@arm.com
7612802Sandreas.sandberg@arm.com    class MasterPort : public QueuedMasterPort
7712802Sandreas.sandberg@arm.com    {
7812802Sandreas.sandberg@arm.com      public:
7912802Sandreas.sandberg@arm.com        MasterPort(const std::string &_name, MemDelay &_parent);
8012802Sandreas.sandberg@arm.com
8112802Sandreas.sandberg@arm.com      protected:
8212802Sandreas.sandberg@arm.com        bool recvTimingResp(PacketPtr pkt) override;
8312802Sandreas.sandberg@arm.com
8412802Sandreas.sandberg@arm.com        void recvFunctionalSnoop(PacketPtr pkt) override;
8512802Sandreas.sandberg@arm.com
8612802Sandreas.sandberg@arm.com        Tick recvAtomicSnoop(PacketPtr pkt) override;
8712802Sandreas.sandberg@arm.com
8812802Sandreas.sandberg@arm.com        void recvTimingSnoopReq(PacketPtr pkt) override;
8912802Sandreas.sandberg@arm.com
9012802Sandreas.sandberg@arm.com        void recvRangeChange() override {
9112802Sandreas.sandberg@arm.com            parent.slavePort.sendRangeChange();
9212802Sandreas.sandberg@arm.com        }
9312802Sandreas.sandberg@arm.com
9412802Sandreas.sandberg@arm.com        bool isSnooping() const override {
9512802Sandreas.sandberg@arm.com            return parent.slavePort.isSnooping();
9612802Sandreas.sandberg@arm.com        }
9712802Sandreas.sandberg@arm.com
9812802Sandreas.sandberg@arm.com      private:
9912802Sandreas.sandberg@arm.com        MemDelay& parent;
10012802Sandreas.sandberg@arm.com    };
10112802Sandreas.sandberg@arm.com
10212802Sandreas.sandberg@arm.com    class SlavePort : public QueuedSlavePort
10312802Sandreas.sandberg@arm.com    {
10412802Sandreas.sandberg@arm.com      public:
10512802Sandreas.sandberg@arm.com        SlavePort(const std::string &_name, MemDelay &_parent);
10612802Sandreas.sandberg@arm.com
10712802Sandreas.sandberg@arm.com      protected:
10812802Sandreas.sandberg@arm.com        Tick recvAtomic(PacketPtr pkt) override;
10912802Sandreas.sandberg@arm.com        bool recvTimingReq(PacketPtr pkt) override;
11012802Sandreas.sandberg@arm.com        void recvFunctional(PacketPtr pkt) override;
11112802Sandreas.sandberg@arm.com        bool recvTimingSnoopResp(PacketPtr pkt) override;
11212802Sandreas.sandberg@arm.com
11312802Sandreas.sandberg@arm.com        AddrRangeList getAddrRanges() const override {
11412802Sandreas.sandberg@arm.com            return parent.masterPort.getAddrRanges();
11512802Sandreas.sandberg@arm.com        }
11612802Sandreas.sandberg@arm.com
11712802Sandreas.sandberg@arm.com        bool tryTiming(PacketPtr pkt) override { return true; }
11812802Sandreas.sandberg@arm.com
11912802Sandreas.sandberg@arm.com      private:
12012802Sandreas.sandberg@arm.com
12112802Sandreas.sandberg@arm.com        MemDelay& parent;
12212802Sandreas.sandberg@arm.com
12312802Sandreas.sandberg@arm.com    };
12412802Sandreas.sandberg@arm.com
12512823Srmk35@cl.cam.ac.uk    bool trySatisfyFunctional(PacketPtr pkt);
12612802Sandreas.sandberg@arm.com
12712802Sandreas.sandberg@arm.com    MasterPort masterPort;
12812802Sandreas.sandberg@arm.com    SlavePort slavePort;
12912802Sandreas.sandberg@arm.com
13012802Sandreas.sandberg@arm.com    ReqPacketQueue reqQueue;
13112802Sandreas.sandberg@arm.com    RespPacketQueue respQueue;
13212802Sandreas.sandberg@arm.com    SnoopRespPacketQueue snoopRespQueue;
13312802Sandreas.sandberg@arm.com
13412802Sandreas.sandberg@arm.com  protected:
13512802Sandreas.sandberg@arm.com    /**
13612802Sandreas.sandberg@arm.com     * Delay a request by some number of ticks.
13712802Sandreas.sandberg@arm.com     *
13812802Sandreas.sandberg@arm.com     * @return Ticks to delay packet.
13912802Sandreas.sandberg@arm.com     */
14012802Sandreas.sandberg@arm.com    virtual Tick delayReq(PacketPtr pkt) { return 0; }
14112802Sandreas.sandberg@arm.com
14212802Sandreas.sandberg@arm.com    /**
14312802Sandreas.sandberg@arm.com     * Delay a response by some number of ticks.
14412802Sandreas.sandberg@arm.com     *
14512802Sandreas.sandberg@arm.com     * @return Ticks to delay packet.
14612802Sandreas.sandberg@arm.com     */
14712802Sandreas.sandberg@arm.com    virtual Tick delayResp(PacketPtr pkt) { return 0; }
14812802Sandreas.sandberg@arm.com
14912802Sandreas.sandberg@arm.com    /**
15012802Sandreas.sandberg@arm.com     * Delay a snoop response by some number of ticks.
15112802Sandreas.sandberg@arm.com     *
15212802Sandreas.sandberg@arm.com     * @return Ticks to delay packet.
15312802Sandreas.sandberg@arm.com     */
15412802Sandreas.sandberg@arm.com    virtual Tick delaySnoopResp(PacketPtr pkt) { return 0; }
15512802Sandreas.sandberg@arm.com};
15612802Sandreas.sandberg@arm.com
15712802Sandreas.sandberg@arm.com/**
15812802Sandreas.sandberg@arm.com * Delay packets by a constant time. Delays can be specified
15912802Sandreas.sandberg@arm.com * separately for read requests, read responses, write requests, and
16012802Sandreas.sandberg@arm.com * write responses.
16112802Sandreas.sandberg@arm.com *
16212802Sandreas.sandberg@arm.com * This class does not delay snoops or requests/responses that are
16312802Sandreas.sandberg@arm.com * neither reads or writes.
16412802Sandreas.sandberg@arm.com */
16512802Sandreas.sandberg@arm.comclass SimpleMemDelay : public MemDelay
16612802Sandreas.sandberg@arm.com{
16712802Sandreas.sandberg@arm.com  public:
16812802Sandreas.sandberg@arm.com    SimpleMemDelay(const SimpleMemDelayParams *params);
16912802Sandreas.sandberg@arm.com
17012802Sandreas.sandberg@arm.com  protected:
17112802Sandreas.sandberg@arm.com    Tick delayReq(PacketPtr pkt) override;
17212802Sandreas.sandberg@arm.com    Tick delayResp(PacketPtr pkt) override;
17312802Sandreas.sandberg@arm.com
17412802Sandreas.sandberg@arm.com  protected: // Params
17512802Sandreas.sandberg@arm.com    const Tick readReqDelay;
17612802Sandreas.sandberg@arm.com    const Tick readRespDelay;
17712802Sandreas.sandberg@arm.com
17812802Sandreas.sandberg@arm.com    const Tick writeReqDelay;
17912802Sandreas.sandberg@arm.com    const Tick writeRespDelay;
18012802Sandreas.sandberg@arm.com};
18112802Sandreas.sandberg@arm.com
18212802Sandreas.sandberg@arm.com#endif //__MEM_MEM_DELAY_HH__
183