dram_ctrl.hh revision 11555
19243SN/A/*
210889Sandreas.hansson@arm.com * Copyright (c) 2012-2015 ARM Limited
39243SN/A * All rights reserved
49243SN/A *
59243SN/A * The license below extends only to copyright in the software and shall
69243SN/A * not be construed as granting a license to any other intellectual
79243SN/A * property including but not limited to intellectual property relating
89243SN/A * to a hardware implementation of the functionality of the software
99243SN/A * licensed hereunder.  You may use the software subject to the license
109243SN/A * terms below provided that you ensure that this notice is replicated
119243SN/A * unmodified and in its entirety in all distributions of the software,
129243SN/A * modified or unmodified, in source code or in binary form.
139243SN/A *
149831SN/A * Copyright (c) 2013 Amin Farmahini-Farahani
159831SN/A * All rights reserved.
169831SN/A *
179243SN/A * Redistribution and use in source and binary forms, with or without
189243SN/A * modification, are permitted provided that the following conditions are
199243SN/A * met: redistributions of source code must retain the above copyright
209243SN/A * notice, this list of conditions and the following disclaimer;
219243SN/A * redistributions in binary form must reproduce the above copyright
229243SN/A * notice, this list of conditions and the following disclaimer in the
239243SN/A * documentation and/or other materials provided with the distribution;
249243SN/A * neither the name of the copyright holders nor the names of its
259243SN/A * contributors may be used to endorse or promote products derived from
269243SN/A * this software without specific prior written permission.
279243SN/A *
289243SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
299243SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
309243SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
319243SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
329243SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
339243SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
349243SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
359243SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
369243SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
379243SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
389243SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
399243SN/A *
409243SN/A * Authors: Andreas Hansson
419243SN/A *          Ani Udipi
429967SN/A *          Neha Agarwal
4310618SOmar.Naji@arm.com *          Omar Naji
4411555Sjungma@eit.uni-kl.de *          Matthias Jung
459243SN/A */
469243SN/A
479243SN/A/**
489243SN/A * @file
4910146Sandreas.hansson@arm.com * DRAMCtrl declaration
509243SN/A */
519243SN/A
5210146Sandreas.hansson@arm.com#ifndef __MEM_DRAM_CTRL_HH__
5310146Sandreas.hansson@arm.com#define __MEM_DRAM_CTRL_HH__
549243SN/A
559488SN/A#include <deque>
5610618SOmar.Naji@arm.com#include <string>
5710889Sandreas.hansson@arm.com#include <unordered_set>
589488SN/A
599243SN/A#include "base/statistics.hh"
609243SN/A#include "enums/AddrMap.hh"
619243SN/A#include "enums/MemSched.hh"
629243SN/A#include "enums/PageManage.hh"
639243SN/A#include "mem/abstract_mem.hh"
649243SN/A#include "mem/qport.hh"
6510146Sandreas.hansson@arm.com#include "params/DRAMCtrl.hh"
669243SN/A#include "sim/eventq.hh"
6710432SOmar.Naji@arm.com#include "mem/drampower.hh"
689243SN/A
699243SN/A/**
7010287Sandreas.hansson@arm.com * The DRAM controller is a single-channel memory controller capturing
7110287Sandreas.hansson@arm.com * the most important timing constraints associated with a
7210287Sandreas.hansson@arm.com * contemporary DRAM. For multi-channel memory systems, the controller
7310287Sandreas.hansson@arm.com * is combined with a crossbar model, with the channel address
7410287Sandreas.hansson@arm.com * interleaving taking part in the crossbar.
759243SN/A *
7610287Sandreas.hansson@arm.com * As a basic design principle, this controller
7710287Sandreas.hansson@arm.com * model is not cycle callable, but instead uses events to: 1) decide
7810287Sandreas.hansson@arm.com * when new decisions can be made, 2) when resources become available,
7910287Sandreas.hansson@arm.com * 3) when things are to be considered done, and 4) when to send
8010287Sandreas.hansson@arm.com * things back. Through these simple principles, the model delivers
8110287Sandreas.hansson@arm.com * high performance, and lots of flexibility, allowing users to
8210287Sandreas.hansson@arm.com * evaluate the system impact of a wide range of memory technologies,
8310287Sandreas.hansson@arm.com * such as DDR3/4, LPDDR2/3/4, WideIO1/2, HBM and HMC.
8410287Sandreas.hansson@arm.com *
8510287Sandreas.hansson@arm.com * For more details, please see Hansson et al, "Simulating DRAM
8610287Sandreas.hansson@arm.com * controllers for future system architecture exploration",
8710287Sandreas.hansson@arm.com * Proc. ISPASS, 2014. If you use this model as part of your research
8810287Sandreas.hansson@arm.com * please cite the paper.
899243SN/A */
9010146Sandreas.hansson@arm.comclass DRAMCtrl : public AbstractMemory
919243SN/A{
929243SN/A
939243SN/A  private:
949243SN/A
959243SN/A    // For now, make use of a queued slave port to avoid dealing with
969243SN/A    // flow control for the responses being sent back
979243SN/A    class MemoryPort : public QueuedSlavePort
989243SN/A    {
999243SN/A
10010713Sandreas.hansson@arm.com        RespPacketQueue queue;
10110146Sandreas.hansson@arm.com        DRAMCtrl& memory;
1029243SN/A
1039243SN/A      public:
1049243SN/A
10510146Sandreas.hansson@arm.com        MemoryPort(const std::string& name, DRAMCtrl& _memory);
1069243SN/A
1079243SN/A      protected:
1089243SN/A
1099243SN/A        Tick recvAtomic(PacketPtr pkt);
1109243SN/A
1119243SN/A        void recvFunctional(PacketPtr pkt);
1129243SN/A
1139243SN/A        bool recvTimingReq(PacketPtr);
1149243SN/A
1159243SN/A        virtual AddrRangeList getAddrRanges() const;
1169243SN/A
1179243SN/A    };
1189243SN/A
1199243SN/A    /**
1209243SN/A     * Our incoming port, for a multi-ported controller add a crossbar
1219243SN/A     * in front of it
1229243SN/A     */
1239243SN/A    MemoryPort port;
1249243SN/A
1259243SN/A    /**
12610619Sandreas.hansson@arm.com     * Remeber if the memory system is in timing mode
12710619Sandreas.hansson@arm.com     */
12810619Sandreas.hansson@arm.com    bool isTimingMode;
12910619Sandreas.hansson@arm.com
13010619Sandreas.hansson@arm.com    /**
1319243SN/A     * Remember if we have to retry a request when available.
1329243SN/A     */
1339243SN/A    bool retryRdReq;
1349243SN/A    bool retryWrReq;
1359243SN/A
1369243SN/A    /**
13710206Sandreas.hansson@arm.com     * Bus state used to control the read/write switching and drive
13810206Sandreas.hansson@arm.com     * the scheduling of the next request.
1399243SN/A     */
14010206Sandreas.hansson@arm.com    enum BusState {
14110206Sandreas.hansson@arm.com        READ = 0,
14210206Sandreas.hansson@arm.com        READ_TO_WRITE,
14310206Sandreas.hansson@arm.com        WRITE,
14410206Sandreas.hansson@arm.com        WRITE_TO_READ
14510206Sandreas.hansson@arm.com    };
14610206Sandreas.hansson@arm.com
14710206Sandreas.hansson@arm.com    BusState busState;
1489243SN/A
1499243SN/A    /**
15010210Sandreas.hansson@arm.com     * A basic class to track the bank state, i.e. what row is
15110210Sandreas.hansson@arm.com     * currently open (if any), when is the bank free to accept a new
15210211Sandreas.hansson@arm.com     * column (read/write) command, when can it be precharged, and
15310211Sandreas.hansson@arm.com     * when can it be activated.
15410210Sandreas.hansson@arm.com     *
15510210Sandreas.hansson@arm.com     * The bank also keeps track of how many bytes have been accessed
15610210Sandreas.hansson@arm.com     * in the open row since it was opened.
1579243SN/A     */
1589243SN/A    class Bank
1599243SN/A    {
1609243SN/A
1619243SN/A      public:
1629243SN/A
16310207Sandreas.hansson@arm.com        static const uint32_t NO_ROW = -1;
1649243SN/A
1659243SN/A        uint32_t openRow;
16610246Sandreas.hansson@arm.com        uint8_t bank;
16710394Swendy.elsasser@arm.com        uint8_t bankgr;
1689243SN/A
16910211Sandreas.hansson@arm.com        Tick colAllowedAt;
17010210Sandreas.hansson@arm.com        Tick preAllowedAt;
1719969SN/A        Tick actAllowedAt;
1729243SN/A
17310141SN/A        uint32_t rowAccesses;
1749727SN/A        uint32_t bytesAccessed;
1759727SN/A
1769727SN/A        Bank() :
17710618SOmar.Naji@arm.com            openRow(NO_ROW), bank(0), bankgr(0),
17810246Sandreas.hansson@arm.com            colAllowedAt(0), preAllowedAt(0), actAllowedAt(0),
17910141SN/A            rowAccesses(0), bytesAccessed(0)
1809243SN/A        { }
1819243SN/A    };
1829243SN/A
18310618SOmar.Naji@arm.com
18410618SOmar.Naji@arm.com    /**
18510618SOmar.Naji@arm.com     * Rank class includes a vector of banks. Refresh and Power state
18610618SOmar.Naji@arm.com     * machines are defined per rank. Events required to change the
18710618SOmar.Naji@arm.com     * state of the refresh and power state machine are scheduled per
18810618SOmar.Naji@arm.com     * rank. This class allows the implementation of rank-wise refresh
18910618SOmar.Naji@arm.com     * and rank-wise power-down.
19010618SOmar.Naji@arm.com     */
19110618SOmar.Naji@arm.com    class Rank : public EventManager
19210618SOmar.Naji@arm.com    {
19310618SOmar.Naji@arm.com
19410618SOmar.Naji@arm.com      private:
19510618SOmar.Naji@arm.com
19610618SOmar.Naji@arm.com        /**
19710618SOmar.Naji@arm.com         * The power state captures the different operational states of
19810618SOmar.Naji@arm.com         * the DRAM and interacts with the bus read/write state machine,
19910618SOmar.Naji@arm.com         * and the refresh state machine. In the idle state all banks are
20010618SOmar.Naji@arm.com         * precharged. From there we either go to an auto refresh (as
20110618SOmar.Naji@arm.com         * determined by the refresh state machine), or to a precharge
20210618SOmar.Naji@arm.com         * power down mode. From idle the memory can also go to the active
20310618SOmar.Naji@arm.com         * state (with one or more banks active), and in turn from there
20410618SOmar.Naji@arm.com         * to active power down. At the moment we do not capture the deep
20510618SOmar.Naji@arm.com         * power down and self-refresh state.
20610618SOmar.Naji@arm.com         */
20710618SOmar.Naji@arm.com        enum PowerState {
20810618SOmar.Naji@arm.com            PWR_IDLE = 0,
20910618SOmar.Naji@arm.com            PWR_REF,
21010618SOmar.Naji@arm.com            PWR_PRE_PDN,
21110618SOmar.Naji@arm.com            PWR_ACT,
21210618SOmar.Naji@arm.com            PWR_ACT_PDN
21310618SOmar.Naji@arm.com        };
21410618SOmar.Naji@arm.com
21510618SOmar.Naji@arm.com        /**
21610618SOmar.Naji@arm.com         * The refresh state is used to control the progress of the
21710618SOmar.Naji@arm.com         * refresh scheduling. When normal operation is in progress the
21810618SOmar.Naji@arm.com         * refresh state is idle. From there, it progresses to the refresh
21910618SOmar.Naji@arm.com         * drain state once tREFI has passed. The refresh drain state
22010618SOmar.Naji@arm.com         * captures the DRAM row active state, as it will stay there until
22110618SOmar.Naji@arm.com         * all ongoing accesses complete. Thereafter all banks are
22210618SOmar.Naji@arm.com         * precharged, and lastly, the DRAM is refreshed.
22310618SOmar.Naji@arm.com         */
22410618SOmar.Naji@arm.com        enum RefreshState {
22510618SOmar.Naji@arm.com            REF_IDLE = 0,
22610618SOmar.Naji@arm.com            REF_DRAIN,
22710618SOmar.Naji@arm.com            REF_PRE,
22810618SOmar.Naji@arm.com            REF_RUN
22910618SOmar.Naji@arm.com        };
23010618SOmar.Naji@arm.com
23110618SOmar.Naji@arm.com        /**
23210618SOmar.Naji@arm.com         * A reference to the parent DRAMCtrl instance
23310618SOmar.Naji@arm.com         */
23410618SOmar.Naji@arm.com        DRAMCtrl& memory;
23510618SOmar.Naji@arm.com
23610618SOmar.Naji@arm.com        /**
23710618SOmar.Naji@arm.com         * Since we are taking decisions out of order, we need to keep
23810618SOmar.Naji@arm.com         * track of what power transition is happening at what time, such
23910618SOmar.Naji@arm.com         * that we can go back in time and change history. For example, if
24010618SOmar.Naji@arm.com         * we precharge all banks and schedule going to the idle state, we
24110618SOmar.Naji@arm.com         * might at a later point decide to activate a bank before the
24210618SOmar.Naji@arm.com         * transition to idle would have taken place.
24310618SOmar.Naji@arm.com         */
24410618SOmar.Naji@arm.com        PowerState pwrStateTrans;
24510618SOmar.Naji@arm.com
24610618SOmar.Naji@arm.com        /**
24710618SOmar.Naji@arm.com         * Current power state.
24810618SOmar.Naji@arm.com         */
24910618SOmar.Naji@arm.com        PowerState pwrState;
25010618SOmar.Naji@arm.com
25110618SOmar.Naji@arm.com        /**
25210618SOmar.Naji@arm.com         * Track when we transitioned to the current power state
25310618SOmar.Naji@arm.com         */
25410618SOmar.Naji@arm.com        Tick pwrStateTick;
25510618SOmar.Naji@arm.com
25610618SOmar.Naji@arm.com        /**
25710618SOmar.Naji@arm.com         * current refresh state
25810618SOmar.Naji@arm.com         */
25910618SOmar.Naji@arm.com        RefreshState refreshState;
26010618SOmar.Naji@arm.com
26110618SOmar.Naji@arm.com        /**
26210618SOmar.Naji@arm.com         * Keep track of when a refresh is due.
26310618SOmar.Naji@arm.com         */
26410618SOmar.Naji@arm.com        Tick refreshDueAt;
26510618SOmar.Naji@arm.com
26610618SOmar.Naji@arm.com        /*
26710618SOmar.Naji@arm.com         * Command energies
26810618SOmar.Naji@arm.com         */
26910618SOmar.Naji@arm.com        Stats::Scalar actEnergy;
27010618SOmar.Naji@arm.com        Stats::Scalar preEnergy;
27110618SOmar.Naji@arm.com        Stats::Scalar readEnergy;
27210618SOmar.Naji@arm.com        Stats::Scalar writeEnergy;
27310618SOmar.Naji@arm.com        Stats::Scalar refreshEnergy;
27410618SOmar.Naji@arm.com
27510618SOmar.Naji@arm.com        /*
27610618SOmar.Naji@arm.com         * Active Background Energy
27710618SOmar.Naji@arm.com         */
27810618SOmar.Naji@arm.com        Stats::Scalar actBackEnergy;
27910618SOmar.Naji@arm.com
28010618SOmar.Naji@arm.com        /*
28110618SOmar.Naji@arm.com         * Precharge Background Energy
28210618SOmar.Naji@arm.com         */
28310618SOmar.Naji@arm.com        Stats::Scalar preBackEnergy;
28410618SOmar.Naji@arm.com
28510618SOmar.Naji@arm.com        Stats::Scalar totalEnergy;
28610618SOmar.Naji@arm.com        Stats::Scalar averagePower;
28710618SOmar.Naji@arm.com
28810618SOmar.Naji@arm.com        /**
28910618SOmar.Naji@arm.com         * Track time spent in each power state.
29010618SOmar.Naji@arm.com         */
29110618SOmar.Naji@arm.com        Stats::Vector pwrStateTime;
29210618SOmar.Naji@arm.com
29310618SOmar.Naji@arm.com        /**
29410618SOmar.Naji@arm.com         * Function to update Power Stats
29510618SOmar.Naji@arm.com         */
29610618SOmar.Naji@arm.com        void updatePowerStats();
29710618SOmar.Naji@arm.com
29810618SOmar.Naji@arm.com        /**
29910618SOmar.Naji@arm.com         * Schedule a power state transition in the future, and
30010618SOmar.Naji@arm.com         * potentially override an already scheduled transition.
30110618SOmar.Naji@arm.com         *
30210618SOmar.Naji@arm.com         * @param pwr_state Power state to transition to
30310618SOmar.Naji@arm.com         * @param tick Tick when transition should take place
30410618SOmar.Naji@arm.com         */
30510618SOmar.Naji@arm.com        void schedulePowerEvent(PowerState pwr_state, Tick tick);
30610618SOmar.Naji@arm.com
30710618SOmar.Naji@arm.com      public:
30810618SOmar.Naji@arm.com
30910618SOmar.Naji@arm.com        /**
31010618SOmar.Naji@arm.com         * Current Rank index
31110618SOmar.Naji@arm.com         */
31210618SOmar.Naji@arm.com        uint8_t rank;
31310618SOmar.Naji@arm.com
31410618SOmar.Naji@arm.com        /**
31510618SOmar.Naji@arm.com         * One DRAMPower instance per rank
31610618SOmar.Naji@arm.com         */
31710618SOmar.Naji@arm.com        DRAMPower power;
31810618SOmar.Naji@arm.com
31910618SOmar.Naji@arm.com        /**
32010618SOmar.Naji@arm.com         * Vector of Banks. Each rank is made of several devices which in
32110618SOmar.Naji@arm.com         * term are made from several banks.
32210618SOmar.Naji@arm.com         */
32310618SOmar.Naji@arm.com        std::vector<Bank> banks;
32410618SOmar.Naji@arm.com
32510618SOmar.Naji@arm.com        /**
32610618SOmar.Naji@arm.com         *  To track number of banks which are currently active for
32710618SOmar.Naji@arm.com         *  this rank.
32810618SOmar.Naji@arm.com         */
32910618SOmar.Naji@arm.com        unsigned int numBanksActive;
33010618SOmar.Naji@arm.com
33110618SOmar.Naji@arm.com        /** List to keep track of activate ticks */
33210618SOmar.Naji@arm.com        std::deque<Tick> actTicks;
33310618SOmar.Naji@arm.com
33410618SOmar.Naji@arm.com        Rank(DRAMCtrl& _memory, const DRAMCtrlParams* _p);
33510618SOmar.Naji@arm.com
33610618SOmar.Naji@arm.com        const std::string name() const
33710618SOmar.Naji@arm.com        {
33810618SOmar.Naji@arm.com            return csprintf("%s_%d", memory.name(), rank);
33910618SOmar.Naji@arm.com        }
34010618SOmar.Naji@arm.com
34110618SOmar.Naji@arm.com        /**
34210618SOmar.Naji@arm.com         * Kick off accounting for power and refresh states and
34310618SOmar.Naji@arm.com         * schedule initial refresh.
34410618SOmar.Naji@arm.com         *
34510618SOmar.Naji@arm.com         * @param ref_tick Tick for first refresh
34610618SOmar.Naji@arm.com         */
34710618SOmar.Naji@arm.com        void startup(Tick ref_tick);
34810618SOmar.Naji@arm.com
34910618SOmar.Naji@arm.com        /**
35010619Sandreas.hansson@arm.com         * Stop the refresh events.
35110619Sandreas.hansson@arm.com         */
35210619Sandreas.hansson@arm.com        void suspend();
35310619Sandreas.hansson@arm.com
35410619Sandreas.hansson@arm.com        /**
35510618SOmar.Naji@arm.com         * Check if the current rank is available for scheduling.
35610618SOmar.Naji@arm.com         *
35710618SOmar.Naji@arm.com         * @param Return true if the rank is idle from a refresh point of view
35810618SOmar.Naji@arm.com         */
35910618SOmar.Naji@arm.com        bool isAvailable() const { return refreshState == REF_IDLE; }
36010618SOmar.Naji@arm.com
36110618SOmar.Naji@arm.com        /**
36210618SOmar.Naji@arm.com         * Let the rank check if it was waiting for requests to drain
36310618SOmar.Naji@arm.com         * to allow it to transition states.
36410618SOmar.Naji@arm.com         */
36510618SOmar.Naji@arm.com        void checkDrainDone();
36610618SOmar.Naji@arm.com
36710618SOmar.Naji@arm.com        /*
36810618SOmar.Naji@arm.com         * Function to register Stats
36910618SOmar.Naji@arm.com         */
37010618SOmar.Naji@arm.com        void regStats();
37110618SOmar.Naji@arm.com
37210618SOmar.Naji@arm.com        void processActivateEvent();
37310618SOmar.Naji@arm.com        EventWrapper<Rank, &Rank::processActivateEvent>
37410618SOmar.Naji@arm.com        activateEvent;
37510618SOmar.Naji@arm.com
37610618SOmar.Naji@arm.com        void processPrechargeEvent();
37710618SOmar.Naji@arm.com        EventWrapper<Rank, &Rank::processPrechargeEvent>
37810618SOmar.Naji@arm.com        prechargeEvent;
37910618SOmar.Naji@arm.com
38010618SOmar.Naji@arm.com        void processRefreshEvent();
38110618SOmar.Naji@arm.com        EventWrapper<Rank, &Rank::processRefreshEvent>
38210618SOmar.Naji@arm.com        refreshEvent;
38310618SOmar.Naji@arm.com
38410618SOmar.Naji@arm.com        void processPowerEvent();
38510618SOmar.Naji@arm.com        EventWrapper<Rank, &Rank::processPowerEvent>
38610618SOmar.Naji@arm.com        powerEvent;
38710618SOmar.Naji@arm.com
38810618SOmar.Naji@arm.com    };
38910618SOmar.Naji@arm.com
3909243SN/A    /**
3919831SN/A     * A burst helper helps organize and manage a packet that is larger than
3929831SN/A     * the DRAM burst size. A system packet that is larger than the burst size
3939831SN/A     * is split into multiple DRAM packets and all those DRAM packets point to
3949831SN/A     * a single burst helper such that we know when the whole packet is served.
3959831SN/A     */
3969831SN/A    class BurstHelper {
3979831SN/A
3989831SN/A      public:
3999831SN/A
4009831SN/A        /** Number of DRAM bursts requred for a system packet **/
4019831SN/A        const unsigned int burstCount;
4029831SN/A
4039831SN/A        /** Number of DRAM bursts serviced so far for a system packet **/
4049831SN/A        unsigned int burstsServiced;
4059831SN/A
4069831SN/A        BurstHelper(unsigned int _burstCount)
4079831SN/A            : burstCount(_burstCount), burstsServiced(0)
40810618SOmar.Naji@arm.com        { }
4099831SN/A    };
4109831SN/A
4119831SN/A    /**
4129243SN/A     * A DRAM packet stores packets along with the timestamp of when
4139243SN/A     * the packet entered the queue, and also the decoded address.
4149243SN/A     */
4159243SN/A    class DRAMPacket {
4169243SN/A
4179243SN/A      public:
4189243SN/A
4199243SN/A        /** When did request enter the controller */
4209243SN/A        const Tick entryTime;
4219243SN/A
4229243SN/A        /** When will request leave the controller */
4239243SN/A        Tick readyTime;
4249243SN/A
4259243SN/A        /** This comes from the outside world */
4269243SN/A        const PacketPtr pkt;
4279243SN/A
4289966SN/A        const bool isRead;
4299966SN/A
4309243SN/A        /** Will be populated by address decoder */
4319243SN/A        const uint8_t rank;
4329967SN/A        const uint8_t bank;
43310245Sandreas.hansson@arm.com        const uint32_t row;
4349831SN/A
4359831SN/A        /**
4369967SN/A         * Bank id is calculated considering banks in all the ranks
4379967SN/A         * eg: 2 ranks each with 8 banks, then bankId = 0 --> rank0, bank0 and
4389967SN/A         * bankId = 8 --> rank1, bank0
4399967SN/A         */
4409967SN/A        const uint16_t bankId;
4419967SN/A
4429967SN/A        /**
4439831SN/A         * The starting address of the DRAM packet.
4449831SN/A         * This address could be unaligned to burst size boundaries. The
4459831SN/A         * reason is to keep the address offset so we can accurately check
4469831SN/A         * incoming read packets with packets in the write queue.
4479831SN/A         */
4489832SN/A        Addr addr;
4499831SN/A
4509831SN/A        /**
4519831SN/A         * The size of this dram packet in bytes
4529831SN/A         * It is always equal or smaller than DRAM burst size
4539831SN/A         */
4549832SN/A        unsigned int size;
4559831SN/A
4569831SN/A        /**
4579831SN/A         * A pointer to the BurstHelper if this DRAMPacket is a split packet
4589831SN/A         * If not a split packet (common case), this is set to NULL
4599831SN/A         */
4609831SN/A        BurstHelper* burstHelper;
4619967SN/A        Bank& bankRef;
46210618SOmar.Naji@arm.com        Rank& rankRef;
4639243SN/A
4649967SN/A        DRAMPacket(PacketPtr _pkt, bool is_read, uint8_t _rank, uint8_t _bank,
46510245Sandreas.hansson@arm.com                   uint32_t _row, uint16_t bank_id, Addr _addr,
46610618SOmar.Naji@arm.com                   unsigned int _size, Bank& bank_ref, Rank& rank_ref)
4679243SN/A            : entryTime(curTick()), readyTime(curTick()),
4689967SN/A              pkt(_pkt), isRead(is_read), rank(_rank), bank(_bank), row(_row),
4699967SN/A              bankId(bank_id), addr(_addr), size(_size), burstHelper(NULL),
47010618SOmar.Naji@arm.com              bankRef(bank_ref), rankRef(rank_ref)
4719243SN/A        { }
4729243SN/A
4739243SN/A    };
4749243SN/A
4759243SN/A    /**
4769243SN/A     * Bunch of things requires to setup "events" in gem5
47710206Sandreas.hansson@arm.com     * When event "respondEvent" occurs for example, the method
47810206Sandreas.hansson@arm.com     * processRespondEvent is called; no parameters are allowed
4799243SN/A     * in these methods
4809243SN/A     */
48110208Sandreas.hansson@arm.com    void processNextReqEvent();
48210208Sandreas.hansson@arm.com    EventWrapper<DRAMCtrl,&DRAMCtrl::processNextReqEvent> nextReqEvent;
48310208Sandreas.hansson@arm.com
4849243SN/A    void processRespondEvent();
48510146Sandreas.hansson@arm.com    EventWrapper<DRAMCtrl, &DRAMCtrl::processRespondEvent> respondEvent;
4869243SN/A
4879243SN/A    /**
4889243SN/A     * Check if the read queue has room for more entries
4899243SN/A     *
4909831SN/A     * @param pktCount The number of entries needed in the read queue
4919243SN/A     * @return true if read queue is full, false otherwise
4929243SN/A     */
4939831SN/A    bool readQueueFull(unsigned int pktCount) const;
4949243SN/A
4959243SN/A    /**
4969243SN/A     * Check if the write queue has room for more entries
4979243SN/A     *
4989831SN/A     * @param pktCount The number of entries needed in the write queue
4999243SN/A     * @return true if write queue is full, false otherwise
5009243SN/A     */
5019831SN/A    bool writeQueueFull(unsigned int pktCount) const;
5029243SN/A
5039243SN/A    /**
5049243SN/A     * When a new read comes in, first check if the write q has a
5059243SN/A     * pending request to the same address.\ If not, decode the
5069831SN/A     * address to populate rank/bank/row, create one or mutliple
5079831SN/A     * "dram_pkt", and push them to the back of the read queue.\
5089831SN/A     * If this is the only
5099243SN/A     * read request in the system, schedule an event to start
5109243SN/A     * servicing it.
5119243SN/A     *
5129243SN/A     * @param pkt The request packet from the outside world
5139831SN/A     * @param pktCount The number of DRAM bursts the pkt
5149831SN/A     * translate to. If pkt size is larger then one full burst,
5159831SN/A     * then pktCount is greater than one.
5169243SN/A     */
5179831SN/A    void addToReadQueue(PacketPtr pkt, unsigned int pktCount);
5189243SN/A
5199243SN/A    /**
5209243SN/A     * Decode the incoming pkt, create a dram_pkt and push to the
5219243SN/A     * back of the write queue. \If the write q length is more than
5229243SN/A     * the threshold specified by the user, ie the queue is beginning
5239243SN/A     * to get full, stop reads, and start draining writes.
5249243SN/A     *
5259243SN/A     * @param pkt The request packet from the outside world
5269831SN/A     * @param pktCount The number of DRAM bursts the pkt
5279831SN/A     * translate to. If pkt size is larger then one full burst,
5289831SN/A     * then pktCount is greater than one.
5299243SN/A     */
5309831SN/A    void addToWriteQueue(PacketPtr pkt, unsigned int pktCount);
5319243SN/A
5329243SN/A    /**
5339243SN/A     * Actually do the DRAM access - figure out the latency it
5349243SN/A     * will take to service the req based on bank state, channel state etc
5359243SN/A     * and then update those states to account for this request.\ Based
5369243SN/A     * on this, update the packet's "readyTime" and move it to the
5379243SN/A     * response q from where it will eventually go back to the outside
5389243SN/A     * world.
5399243SN/A     *
5409243SN/A     * @param pkt The DRAM packet created from the outside world pkt
5419243SN/A     */
5429243SN/A    void doDRAMAccess(DRAMPacket* dram_pkt);
5439243SN/A
5449243SN/A    /**
5459243SN/A     * When a packet reaches its "readyTime" in the response Q,
5469243SN/A     * use the "access()" method in AbstractMemory to actually
5479243SN/A     * create the response packet, and send it back to the outside
5489243SN/A     * world requestor.
5499243SN/A     *
5509243SN/A     * @param pkt The packet from the outside world
5519726SN/A     * @param static_latency Static latency to add before sending the packet
5529243SN/A     */
5539726SN/A    void accessAndRespond(PacketPtr pkt, Tick static_latency);
5549243SN/A
5559243SN/A    /**
5569243SN/A     * Address decoder to figure out physical mapping onto ranks,
5579831SN/A     * banks, and rows. This function is called multiple times on the same
5589831SN/A     * system packet if the pakcet is larger than burst of the memory. The
5599831SN/A     * dramPktAddr is used for the offset within the packet.
5609243SN/A     *
5619243SN/A     * @param pkt The packet from the outside world
5629831SN/A     * @param dramPktAddr The starting address of the DRAM packet
5639831SN/A     * @param size The size of the DRAM packet in bytes
5649966SN/A     * @param isRead Is the request for a read or a write to DRAM
5659243SN/A     * @return A DRAMPacket pointer with the decoded information
5669243SN/A     */
56710143SN/A    DRAMPacket* decodeAddr(PacketPtr pkt, Addr dramPktAddr, unsigned int size,
56810143SN/A                           bool isRead);
5699243SN/A
5709243SN/A    /**
57110206Sandreas.hansson@arm.com     * The memory schduler/arbiter - picks which request needs to
5729567SN/A     * go next, based on the specified policy such as FCFS or FR-FCFS
57310206Sandreas.hansson@arm.com     * and moves it to the head of the queue.
57410393Swendy.elsasser@arm.com     * Prioritizes accesses to the same rank as previous burst unless
57510393Swendy.elsasser@arm.com     * controller is switching command type.
57610393Swendy.elsasser@arm.com     *
57710393Swendy.elsasser@arm.com     * @param queue Queued requests to consider
57810890Swendy.elsasser@arm.com     * @param extra_col_delay Any extra delay due to a read/write switch
57910618SOmar.Naji@arm.com     * @return true if a packet is scheduled to a rank which is available else
58010618SOmar.Naji@arm.com     * false
5819243SN/A     */
58210890Swendy.elsasser@arm.com    bool chooseNext(std::deque<DRAMPacket*>& queue, Tick extra_col_delay);
5839243SN/A
5849243SN/A    /**
5859974SN/A     * For FR-FCFS policy reorder the read/write queue depending on row buffer
58610890Swendy.elsasser@arm.com     * hits and earliest bursts available in DRAM
58710393Swendy.elsasser@arm.com     *
58810393Swendy.elsasser@arm.com     * @param queue Queued requests to consider
58910890Swendy.elsasser@arm.com     * @param extra_col_delay Any extra delay due to a read/write switch
59010618SOmar.Naji@arm.com     * @return true if a packet is scheduled to a rank which is available else
59110618SOmar.Naji@arm.com     * false
5929974SN/A     */
59310890Swendy.elsasser@arm.com    bool reorderQueue(std::deque<DRAMPacket*>& queue, Tick extra_col_delay);
5949974SN/A
5959974SN/A    /**
59610211Sandreas.hansson@arm.com     * Find which are the earliest banks ready to issue an activate
59710211Sandreas.hansson@arm.com     * for the enqueued requests. Assumes maximum of 64 banks per DIMM
59810393Swendy.elsasser@arm.com     * Also checks if the bank is already prepped.
5999967SN/A     *
60010393Swendy.elsasser@arm.com     * @param queue Queued requests to consider
60110890Swendy.elsasser@arm.com     * @param time of seamless burst command
6029967SN/A     * @return One-hot encoded mask of bank indices
60310890Swendy.elsasser@arm.com     * @return boolean indicating burst can issue seamlessly, with no gaps
6049967SN/A     */
60510890Swendy.elsasser@arm.com    std::pair<uint64_t, bool> minBankPrep(const std::deque<DRAMPacket*>& queue,
60610890Swendy.elsasser@arm.com                                          Tick min_col_at) const;
6079488SN/A
6089488SN/A    /**
6099488SN/A     * Keep track of when row activations happen, in order to enforce
6109488SN/A     * the maximum number of activations in the activation window. The
6119488SN/A     * method updates the time that the banks become available based
6129488SN/A     * on the current limits.
61310210Sandreas.hansson@arm.com     *
61410618SOmar.Naji@arm.com     * @param rank_ref Reference to the rank
61510618SOmar.Naji@arm.com     * @param bank_ref Reference to the bank
61610210Sandreas.hansson@arm.com     * @param act_tick Time when the activation takes place
61710210Sandreas.hansson@arm.com     * @param row Index of the row
6189488SN/A     */
61910618SOmar.Naji@arm.com    void activateBank(Rank& rank_ref, Bank& bank_ref, Tick act_tick,
62010618SOmar.Naji@arm.com                      uint32_t row);
62110207Sandreas.hansson@arm.com
62210207Sandreas.hansson@arm.com    /**
62310207Sandreas.hansson@arm.com     * Precharge a given bank and also update when the precharge is
62410207Sandreas.hansson@arm.com     * done. This will also deal with any stats related to the
62510207Sandreas.hansson@arm.com     * accesses to the open page.
62610207Sandreas.hansson@arm.com     *
62710618SOmar.Naji@arm.com     * @param rank_ref The rank to precharge
62810247Sandreas.hansson@arm.com     * @param bank_ref The bank to precharge
62910211Sandreas.hansson@arm.com     * @param pre_at Time when the precharge takes place
63010247Sandreas.hansson@arm.com     * @param trace Is this an auto precharge then do not add to trace
63110207Sandreas.hansson@arm.com     */
63210618SOmar.Naji@arm.com    void prechargeBank(Rank& rank_ref, Bank& bank_ref,
63310618SOmar.Naji@arm.com                       Tick pre_at, bool trace = true);
6349488SN/A
63510143SN/A    /**
63610143SN/A     * Used for debugging to observe the contents of the queues.
63710143SN/A     */
6389243SN/A    void printQs() const;
6399243SN/A
6409243SN/A    /**
64110889Sandreas.hansson@arm.com     * Burst-align an address.
64210889Sandreas.hansson@arm.com     *
64310889Sandreas.hansson@arm.com     * @param addr The potentially unaligned address
64410889Sandreas.hansson@arm.com     *
64510889Sandreas.hansson@arm.com     * @return An address aligned to a DRAM burst
64610889Sandreas.hansson@arm.com     */
64710889Sandreas.hansson@arm.com    Addr burstAlign(Addr addr) const { return (addr & ~(Addr(burstSize - 1))); }
64810889Sandreas.hansson@arm.com
64910889Sandreas.hansson@arm.com    /**
6509243SN/A     * The controller's main read and write queues
6519243SN/A     */
6529833SN/A    std::deque<DRAMPacket*> readQueue;
6539833SN/A    std::deque<DRAMPacket*> writeQueue;
6549243SN/A
6559243SN/A    /**
65610889Sandreas.hansson@arm.com     * To avoid iterating over the write queue to check for
65710889Sandreas.hansson@arm.com     * overlapping transactions, maintain a set of burst addresses
65810889Sandreas.hansson@arm.com     * that are currently queued. Since we merge writes to the same
65910889Sandreas.hansson@arm.com     * location we never have more than one address to the same burst
66010889Sandreas.hansson@arm.com     * address.
66110889Sandreas.hansson@arm.com     */
66210889Sandreas.hansson@arm.com    std::unordered_set<Addr> isInWriteQueue;
66310889Sandreas.hansson@arm.com
66410889Sandreas.hansson@arm.com    /**
6659243SN/A     * Response queue where read packets wait after we're done working
6669567SN/A     * with them, but it's not time to send the response yet. The
6679567SN/A     * responses are stored seperately mostly to keep the code clean
6689567SN/A     * and help with events scheduling. For all logical purposes such
6699567SN/A     * as sizing the read queue, this and the main read queue need to
6709567SN/A     * be added together.
6719243SN/A     */
6729833SN/A    std::deque<DRAMPacket*> respQueue;
6739243SN/A
6749567SN/A    /**
67510618SOmar.Naji@arm.com     * Vector of ranks
6769243SN/A     */
67710618SOmar.Naji@arm.com    std::vector<Rank*> ranks;
6789243SN/A
6799243SN/A    /**
6809243SN/A     * The following are basic design parameters of the memory
6819831SN/A     * controller, and are initialized based on parameter values.
6829831SN/A     * The rowsPerBank is determined based on the capacity, number of
6839831SN/A     * ranks and banks, the burst size, and the row buffer size.
6849243SN/A     */
68510489SOmar.Naji@arm.com    const uint32_t deviceSize;
6869831SN/A    const uint32_t deviceBusWidth;
6879831SN/A    const uint32_t burstLength;
6889831SN/A    const uint32_t deviceRowBufferSize;
6899831SN/A    const uint32_t devicesPerRank;
6909831SN/A    const uint32_t burstSize;
6919831SN/A    const uint32_t rowBufferSize;
69210140SN/A    const uint32_t columnsPerRowBuffer;
69310286Sandreas.hansson@arm.com    const uint32_t columnsPerStripe;
6949243SN/A    const uint32_t ranksPerChannel;
69510394Swendy.elsasser@arm.com    const uint32_t bankGroupsPerRank;
69610394Swendy.elsasser@arm.com    const bool bankGroupArch;
6979243SN/A    const uint32_t banksPerRank;
6989566SN/A    const uint32_t channels;
6999243SN/A    uint32_t rowsPerBank;
7009243SN/A    const uint32_t readBufferSize;
7019243SN/A    const uint32_t writeBufferSize;
70210140SN/A    const uint32_t writeHighThreshold;
70310140SN/A    const uint32_t writeLowThreshold;
70410140SN/A    const uint32_t minWritesPerSwitch;
70510140SN/A    uint32_t writesThisTime;
70610147Sandreas.hansson@arm.com    uint32_t readsThisTime;
7079243SN/A
7089243SN/A    /**
7099243SN/A     * Basic memory timing parameters initialized based on parameter
7109243SN/A     * values.
7119243SN/A     */
71210286Sandreas.hansson@arm.com    const Tick M5_CLASS_VAR_USED tCK;
7139243SN/A    const Tick tWTR;
71410206Sandreas.hansson@arm.com    const Tick tRTW;
71510393Swendy.elsasser@arm.com    const Tick tCS;
7169243SN/A    const Tick tBURST;
71710394Swendy.elsasser@arm.com    const Tick tCCD_L;
7189243SN/A    const Tick tRCD;
7199243SN/A    const Tick tCL;
7209243SN/A    const Tick tRP;
7219963SN/A    const Tick tRAS;
72210210Sandreas.hansson@arm.com    const Tick tWR;
72310212Sandreas.hansson@arm.com    const Tick tRTP;
7249243SN/A    const Tick tRFC;
7259243SN/A    const Tick tREFI;
7269971SN/A    const Tick tRRD;
72710394Swendy.elsasser@arm.com    const Tick tRRD_L;
7289488SN/A    const Tick tXAW;
7299488SN/A    const uint32_t activationLimit;
7309243SN/A
7319243SN/A    /**
7329243SN/A     * Memory controller configuration initialized based on parameter
7339243SN/A     * values.
7349243SN/A     */
7359243SN/A    Enums::MemSched memSchedPolicy;
7369243SN/A    Enums::AddrMap addrMapping;
7379243SN/A    Enums::PageManage pageMgmt;
7389243SN/A
7399243SN/A    /**
74010141SN/A     * Max column accesses (read and write) per row, before forefully
74110141SN/A     * closing it.
74210141SN/A     */
74310141SN/A    const uint32_t maxAccessesPerRow;
74410141SN/A
74510141SN/A    /**
7469726SN/A     * Pipeline latency of the controller frontend. The frontend
7479726SN/A     * contribution is added to writes (that complete when they are in
7489726SN/A     * the write buffer) and reads that are serviced the write buffer.
7499726SN/A     */
7509726SN/A    const Tick frontendLatency;
7519726SN/A
7529726SN/A    /**
7539726SN/A     * Pipeline latency of the backend and PHY. Along with the
7549726SN/A     * frontend contribution, this latency is added to reads serviced
7559726SN/A     * by the DRAM.
7569726SN/A     */
7579726SN/A    const Tick backendLatency;
7589726SN/A
7599726SN/A    /**
7609243SN/A     * Till when has the main data bus been spoken for already?
7619243SN/A     */
7629243SN/A    Tick busBusyUntil;
7639243SN/A
7649243SN/A    Tick prevArrival;
7659243SN/A
76610206Sandreas.hansson@arm.com    /**
76710206Sandreas.hansson@arm.com     * The soonest you have to start thinking about the next request
76810206Sandreas.hansson@arm.com     * is the longest access time that can occur before
76910206Sandreas.hansson@arm.com     * busBusyUntil. Assuming you need to precharge, open a new row,
77010206Sandreas.hansson@arm.com     * and access, it is tRP + tRCD + tCL.
77110206Sandreas.hansson@arm.com     */
77210206Sandreas.hansson@arm.com    Tick nextReqTime;
7739972SN/A
7749243SN/A    // All statistics that the model needs to capture
7759243SN/A    Stats::Scalar readReqs;
7769243SN/A    Stats::Scalar writeReqs;
7779831SN/A    Stats::Scalar readBursts;
7789831SN/A    Stats::Scalar writeBursts;
7799975SN/A    Stats::Scalar bytesReadDRAM;
7809975SN/A    Stats::Scalar bytesReadWrQ;
7819243SN/A    Stats::Scalar bytesWritten;
7829977SN/A    Stats::Scalar bytesReadSys;
7839977SN/A    Stats::Scalar bytesWrittenSys;
7849243SN/A    Stats::Scalar servicedByWrQ;
7859977SN/A    Stats::Scalar mergedWrBursts;
7869243SN/A    Stats::Scalar neitherReadNorWrite;
7879977SN/A    Stats::Vector perBankRdBursts;
7889977SN/A    Stats::Vector perBankWrBursts;
7899243SN/A    Stats::Scalar numRdRetry;
7909243SN/A    Stats::Scalar numWrRetry;
7919243SN/A    Stats::Scalar totGap;
7929243SN/A    Stats::Vector readPktSize;
7939243SN/A    Stats::Vector writePktSize;
7949243SN/A    Stats::Vector rdQLenPdf;
7959243SN/A    Stats::Vector wrQLenPdf;
7969727SN/A    Stats::Histogram bytesPerActivate;
79710147Sandreas.hansson@arm.com    Stats::Histogram rdPerTurnAround;
79810147Sandreas.hansson@arm.com    Stats::Histogram wrPerTurnAround;
7999243SN/A
8009243SN/A    // Latencies summed over all requests
8019243SN/A    Stats::Scalar totQLat;
8029243SN/A    Stats::Scalar totMemAccLat;
8039243SN/A    Stats::Scalar totBusLat;
8049243SN/A
8059243SN/A    // Average latencies per request
8069243SN/A    Stats::Formula avgQLat;
8079243SN/A    Stats::Formula avgBusLat;
8089243SN/A    Stats::Formula avgMemAccLat;
8099243SN/A
8109243SN/A    // Average bandwidth
8119243SN/A    Stats::Formula avgRdBW;
8129243SN/A    Stats::Formula avgWrBW;
8139977SN/A    Stats::Formula avgRdBWSys;
8149977SN/A    Stats::Formula avgWrBWSys;
8159243SN/A    Stats::Formula peakBW;
8169243SN/A    Stats::Formula busUtil;
8179975SN/A    Stats::Formula busUtilRead;
8189975SN/A    Stats::Formula busUtilWrite;
8199243SN/A
8209243SN/A    // Average queue lengths
8219243SN/A    Stats::Average avgRdQLen;
8229243SN/A    Stats::Average avgWrQLen;
8239243SN/A
8249243SN/A    // Row hit count and rate
8259243SN/A    Stats::Scalar readRowHits;
8269243SN/A    Stats::Scalar writeRowHits;
8279243SN/A    Stats::Formula readRowHitRate;
8289243SN/A    Stats::Formula writeRowHitRate;
8299243SN/A    Stats::Formula avgGap;
8309243SN/A
8319975SN/A    // DRAM Power Calculation
8329975SN/A    Stats::Formula pageHitRate;
8339975SN/A
83410393Swendy.elsasser@arm.com    // Holds the value of the rank of burst issued
83510393Swendy.elsasser@arm.com    uint8_t activeRank;
83610393Swendy.elsasser@arm.com
83710432SOmar.Naji@arm.com    // timestamp offset
83810432SOmar.Naji@arm.com    uint64_t timeStampOffset;
83910432SOmar.Naji@arm.com
84011190Sandreas.hansson@arm.com    /**
84111190Sandreas.hansson@arm.com     * Upstream caches need this packet until true is returned, so
84211190Sandreas.hansson@arm.com     * hold it for deletion until a subsequent call
8439349SN/A     */
84411190Sandreas.hansson@arm.com    std::unique_ptr<Packet> pendingDelete;
8459349SN/A
84610432SOmar.Naji@arm.com    /**
84710618SOmar.Naji@arm.com     * This function increments the energy when called. If stats are
84810618SOmar.Naji@arm.com     * dumped periodically, note accumulated energy values will
84910618SOmar.Naji@arm.com     * appear in the stats (even if the stats are reset). This is a
85010618SOmar.Naji@arm.com     * result of the energy values coming from DRAMPower, and there
85110618SOmar.Naji@arm.com     * is currently no support for resetting the state.
85210618SOmar.Naji@arm.com     *
85310618SOmar.Naji@arm.com     * @param rank Currrent rank
85410618SOmar.Naji@arm.com     */
85510618SOmar.Naji@arm.com    void updatePowerStats(Rank& rank_ref);
85610432SOmar.Naji@arm.com
85710432SOmar.Naji@arm.com    /**
85810432SOmar.Naji@arm.com     * Function for sorting commands in the command list of DRAMPower.
85910432SOmar.Naji@arm.com     *
86010432SOmar.Naji@arm.com     * @param a Memory Command in command list of DRAMPower library
86110432SOmar.Naji@arm.com     * @param next Memory Command in command list of DRAMPower
86210432SOmar.Naji@arm.com     * @return true if timestamp of Command 1 < timestamp of Command 2
86310432SOmar.Naji@arm.com     */
86410432SOmar.Naji@arm.com    static bool sortTime(const Data::MemCommand& m1,
86510432SOmar.Naji@arm.com                         const Data::MemCommand& m2) {
86611555Sjungma@eit.uni-kl.de        return m1.getTimeInt64() < m2.getTimeInt64();
86710432SOmar.Naji@arm.com    };
86810432SOmar.Naji@arm.com
86910432SOmar.Naji@arm.com
8709243SN/A  public:
8719243SN/A
87211169Sandreas.hansson@arm.com    void regStats() override;
8739243SN/A
87410146Sandreas.hansson@arm.com    DRAMCtrl(const DRAMCtrlParams* p);
8759243SN/A
87611168Sandreas.hansson@arm.com    DrainState drain() override;
8779243SN/A
8789294SN/A    virtual BaseSlavePort& getSlavePort(const std::string& if_name,
87911169Sandreas.hansson@arm.com                                        PortID idx = InvalidPortID) override;
8809243SN/A
88111168Sandreas.hansson@arm.com    virtual void init() override;
88211168Sandreas.hansson@arm.com    virtual void startup() override;
88311168Sandreas.hansson@arm.com    virtual void drainResume() override;
8849243SN/A
8859243SN/A  protected:
8869243SN/A
8879243SN/A    Tick recvAtomic(PacketPtr pkt);
8889243SN/A    void recvFunctional(PacketPtr pkt);
8899243SN/A    bool recvTimingReq(PacketPtr pkt);
8909243SN/A
8919243SN/A};
8929243SN/A
89310146Sandreas.hansson@arm.com#endif //__MEM_DRAM_CTRL_HH__
894