110066Sandreas.hansson@arm.com/*
210066Sandreas.hansson@arm.com * Copyright (c) 2013 ARM Limited
310066Sandreas.hansson@arm.com * All rights reserved
410066Sandreas.hansson@arm.com *
510066Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall
610066Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
710066Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
810066Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
910066Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
1010066Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
1110066Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
1210066Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
1310066Sandreas.hansson@arm.com *
1410066Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
1510066Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
1610066Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
1710066Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
1810066Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
1910066Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
2010066Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
2110066Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
2210066Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
2310066Sandreas.hansson@arm.com * this software without specific prior written permission.
2410066Sandreas.hansson@arm.com *
2510066Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2610066Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2710066Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2810066Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2910066Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3010066Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3110066Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210066Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3310066Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3410066Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3510066Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3610066Sandreas.hansson@arm.com *
3710066Sandreas.hansson@arm.com * Authors: Andreas Hansson
3810066Sandreas.hansson@arm.com */
3910066Sandreas.hansson@arm.com
4010066Sandreas.hansson@arm.com/**
4110066Sandreas.hansson@arm.com * @file
4210066Sandreas.hansson@arm.com * DRAMSim2
4310066Sandreas.hansson@arm.com */
4410066Sandreas.hansson@arm.com#ifndef __MEM_DRAMSIM2_HH__
4510066Sandreas.hansson@arm.com#define __MEM_DRAMSIM2_HH__
4610066Sandreas.hansson@arm.com
4710066Sandreas.hansson@arm.com#include <queue>
4811168Sandreas.hansson@arm.com#include <unordered_map>
4910066Sandreas.hansson@arm.com
5010066Sandreas.hansson@arm.com#include "mem/abstract_mem.hh"
5110066Sandreas.hansson@arm.com#include "mem/dramsim2_wrapper.hh"
5210066Sandreas.hansson@arm.com#include "mem/qport.hh"
5310066Sandreas.hansson@arm.com#include "params/DRAMSim2.hh"
5410066Sandreas.hansson@arm.com
5510066Sandreas.hansson@arm.comclass DRAMSim2 : public AbstractMemory
5610066Sandreas.hansson@arm.com{
5710066Sandreas.hansson@arm.com  private:
5810066Sandreas.hansson@arm.com
5910066Sandreas.hansson@arm.com    /**
6010066Sandreas.hansson@arm.com     * The memory port has to deal with its own flow control to avoid
6110066Sandreas.hansson@arm.com     * having unbounded storage that is implicitly created in the port
6210066Sandreas.hansson@arm.com     * itself.
6310066Sandreas.hansson@arm.com     */
6410066Sandreas.hansson@arm.com    class MemoryPort : public SlavePort
6510066Sandreas.hansson@arm.com    {
6610066Sandreas.hansson@arm.com
6710066Sandreas.hansson@arm.com      private:
6810066Sandreas.hansson@arm.com
6910066Sandreas.hansson@arm.com        DRAMSim2& memory;
7010066Sandreas.hansson@arm.com
7110066Sandreas.hansson@arm.com      public:
7210066Sandreas.hansson@arm.com
7310066Sandreas.hansson@arm.com        MemoryPort(const std::string& _name, DRAMSim2& _memory);
7410066Sandreas.hansson@arm.com
7510066Sandreas.hansson@arm.com      protected:
7610066Sandreas.hansson@arm.com
7710066Sandreas.hansson@arm.com        Tick recvAtomic(PacketPtr pkt);
7810066Sandreas.hansson@arm.com
7910066Sandreas.hansson@arm.com        void recvFunctional(PacketPtr pkt);
8010066Sandreas.hansson@arm.com
8110066Sandreas.hansson@arm.com        bool recvTimingReq(PacketPtr pkt);
8210066Sandreas.hansson@arm.com
8310713Sandreas.hansson@arm.com        void recvRespRetry();
8410066Sandreas.hansson@arm.com
8510066Sandreas.hansson@arm.com        AddrRangeList getAddrRanges() const;
8610066Sandreas.hansson@arm.com
8710066Sandreas.hansson@arm.com    };
8810066Sandreas.hansson@arm.com
8910066Sandreas.hansson@arm.com    MemoryPort port;
9010066Sandreas.hansson@arm.com
9110066Sandreas.hansson@arm.com    /**
9210066Sandreas.hansson@arm.com     * The actual DRAMSim2 wrapper
9310066Sandreas.hansson@arm.com     */
9410066Sandreas.hansson@arm.com    DRAMSim2Wrapper wrapper;
9510066Sandreas.hansson@arm.com
9610066Sandreas.hansson@arm.com    /**
9710066Sandreas.hansson@arm.com     * Is the connected port waiting for a retry from us
9810066Sandreas.hansson@arm.com     */
9910066Sandreas.hansson@arm.com    bool retryReq;
10010066Sandreas.hansson@arm.com
10110066Sandreas.hansson@arm.com    /**
10210066Sandreas.hansson@arm.com     * Are we waiting for a retry for sending a response.
10310066Sandreas.hansson@arm.com     */
10410066Sandreas.hansson@arm.com    bool retryResp;
10510066Sandreas.hansson@arm.com
10610066Sandreas.hansson@arm.com    /**
10710296Sandreas.hansson@arm.com     * Keep track of when the wrapper is started.
10810296Sandreas.hansson@arm.com     */
10910296Sandreas.hansson@arm.com    Tick startTick;
11010296Sandreas.hansson@arm.com
11110296Sandreas.hansson@arm.com    /**
11210066Sandreas.hansson@arm.com     * Keep track of what packets are outstanding per
11310066Sandreas.hansson@arm.com     * address, and do so separately for reads and writes. This is
11410066Sandreas.hansson@arm.com     * done so that we can return the right packet on completion from
11510066Sandreas.hansson@arm.com     * DRAMSim.
11610066Sandreas.hansson@arm.com     */
11711168Sandreas.hansson@arm.com    std::unordered_map<Addr, std::queue<PacketPtr> > outstandingReads;
11811168Sandreas.hansson@arm.com    std::unordered_map<Addr, std::queue<PacketPtr> > outstandingWrites;
11910066Sandreas.hansson@arm.com
12010066Sandreas.hansson@arm.com    /**
12110066Sandreas.hansson@arm.com     * Count the number of outstanding transactions so that we can
12210066Sandreas.hansson@arm.com     * block any further requests until there is space in DRAMSim2 and
12310066Sandreas.hansson@arm.com     * the sending queue we need to buffer the response packets.
12410066Sandreas.hansson@arm.com     */
12510066Sandreas.hansson@arm.com    unsigned int nbrOutstandingReads;
12610066Sandreas.hansson@arm.com    unsigned int nbrOutstandingWrites;
12710066Sandreas.hansson@arm.com
12810066Sandreas.hansson@arm.com    /**
12910066Sandreas.hansson@arm.com     * Queue to hold response packets until we can send them
13010066Sandreas.hansson@arm.com     * back. This is needed as DRAMSim2 unconditionally passes
13110066Sandreas.hansson@arm.com     * responses back without any flow control.
13210066Sandreas.hansson@arm.com     */
13310066Sandreas.hansson@arm.com    std::deque<PacketPtr> responseQueue;
13410066Sandreas.hansson@arm.com
13510066Sandreas.hansson@arm.com    unsigned int nbrOutstanding() const;
13610066Sandreas.hansson@arm.com
13710066Sandreas.hansson@arm.com    /**
13810066Sandreas.hansson@arm.com     * When a packet is ready, use the "access()" method in
13910066Sandreas.hansson@arm.com     * AbstractMemory to actually create the response packet, and send
14010066Sandreas.hansson@arm.com     * it back to the outside world requestor.
14110066Sandreas.hansson@arm.com     *
14210066Sandreas.hansson@arm.com     * @param pkt The packet from the outside world
14310066Sandreas.hansson@arm.com     */
14410066Sandreas.hansson@arm.com    void accessAndRespond(PacketPtr pkt);
14510066Sandreas.hansson@arm.com
14610066Sandreas.hansson@arm.com    void sendResponse();
14710066Sandreas.hansson@arm.com
14810066Sandreas.hansson@arm.com    /**
14910066Sandreas.hansson@arm.com     * Event to schedule sending of responses
15010066Sandreas.hansson@arm.com     */
15112084Sspwilson2@wisc.edu    EventFunctionWrapper sendResponseEvent;
15210066Sandreas.hansson@arm.com
15310066Sandreas.hansson@arm.com    /**
15410066Sandreas.hansson@arm.com     * Progress the controller one clock cycle.
15510066Sandreas.hansson@arm.com     */
15610066Sandreas.hansson@arm.com    void tick();
15710066Sandreas.hansson@arm.com
15810066Sandreas.hansson@arm.com    /**
15910066Sandreas.hansson@arm.com     * Event to schedule clock ticks
16010066Sandreas.hansson@arm.com     */
16112084Sspwilson2@wisc.edu    EventFunctionWrapper tickEvent;
16210066Sandreas.hansson@arm.com
16311190Sandreas.hansson@arm.com    /**
16411190Sandreas.hansson@arm.com     * Upstream caches need this packet until true is returned, so
16511190Sandreas.hansson@arm.com     * hold it for deletion until a subsequent call
16610066Sandreas.hansson@arm.com     */
16711190Sandreas.hansson@arm.com    std::unique_ptr<Packet> pendingDelete;
16810066Sandreas.hansson@arm.com
16910066Sandreas.hansson@arm.com  public:
17010066Sandreas.hansson@arm.com
17110066Sandreas.hansson@arm.com    typedef DRAMSim2Params Params;
17210066Sandreas.hansson@arm.com    DRAMSim2(const Params *p);
17310066Sandreas.hansson@arm.com
17410066Sandreas.hansson@arm.com    /**
17510066Sandreas.hansson@arm.com     * Read completion callback.
17610066Sandreas.hansson@arm.com     *
17710066Sandreas.hansson@arm.com     * @param id Channel id of the responder
17810066Sandreas.hansson@arm.com     * @param addr Address of the request
17910066Sandreas.hansson@arm.com     * @param cycle Internal cycle count of DRAMSim2
18010066Sandreas.hansson@arm.com     */
18110066Sandreas.hansson@arm.com    void readComplete(unsigned id, uint64_t addr, uint64_t cycle);
18210066Sandreas.hansson@arm.com
18310066Sandreas.hansson@arm.com    /**
18410066Sandreas.hansson@arm.com     * Write completion callback.
18510066Sandreas.hansson@arm.com     *
18610066Sandreas.hansson@arm.com     * @param id Channel id of the responder
18710066Sandreas.hansson@arm.com     * @param addr Address of the request
18810066Sandreas.hansson@arm.com     * @param cycle Internal cycle count of DRAMSim2
18910066Sandreas.hansson@arm.com     */
19010066Sandreas.hansson@arm.com    void writeComplete(unsigned id, uint64_t addr, uint64_t cycle);
19110066Sandreas.hansson@arm.com
19211168Sandreas.hansson@arm.com    DrainState drain() override;
19310066Sandreas.hansson@arm.com
19413784Sgabeblack@google.com    Port &getPort(const std::string &if_name,
19513784Sgabeblack@google.com                  PortID idx=InvalidPortID) override;
19610066Sandreas.hansson@arm.com
19711169Sandreas.hansson@arm.com    void init() override;
19811169Sandreas.hansson@arm.com    void startup() override;
19910066Sandreas.hansson@arm.com
20010066Sandreas.hansson@arm.com  protected:
20110066Sandreas.hansson@arm.com
20210066Sandreas.hansson@arm.com    Tick recvAtomic(PacketPtr pkt);
20310066Sandreas.hansson@arm.com    void recvFunctional(PacketPtr pkt);
20410066Sandreas.hansson@arm.com    bool recvTimingReq(PacketPtr pkt);
20510713Sandreas.hansson@arm.com    void recvRespRetry();
20610066Sandreas.hansson@arm.com
20710066Sandreas.hansson@arm.com};
20810066Sandreas.hansson@arm.com
20910066Sandreas.hansson@arm.com#endif // __MEM_DRAMSIM2_HH__
210