dram_ctrl.hh revision 9567
111507SCurtis.Dunham@arm.com/*
211507SCurtis.Dunham@arm.com * Copyright (c) 2012 ARM Limited
311954Sgabeblack@google.com * All rights reserved
411954Sgabeblack@google.com *
511954Sgabeblack@google.com * The license below extends only to copyright in the software and shall
611954Sgabeblack@google.com * not be construed as granting a license to any other intellectual
711960Sgabeblack@google.com * property including but not limited to intellectual property relating
811960Sgabeblack@google.com * to a hardware implementation of the functionality of the software
911960Sgabeblack@google.com * licensed hereunder.  You may use the software subject to the license
1011960Sgabeblack@google.com * terms below provided that you ensure that this notice is replicated
1111960Sgabeblack@google.com * unmodified and in its entirety in all distributions of the software,
1211954Sgabeblack@google.com * modified or unmodified, in source code or in binary form.
1311954Sgabeblack@google.com *
1411954Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
1511954Sgabeblack@google.com * modification, are permitted provided that the following conditions are
1611954Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
1711954Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
1811954Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1911954Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
2011954Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
2111954Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
2211954Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
2311954Sgabeblack@google.com * this software without specific prior written permission.
2411954Sgabeblack@google.com *
2511954Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2611954Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2711954Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2811954Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2911954Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3011954Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3111954Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3211954Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3311954Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3411954Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3511954Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3611954Sgabeblack@google.com *
3711954Sgabeblack@google.com * Authors: Andreas Hansson
3811954Sgabeblack@google.com *          Ani Udipi
3911954Sgabeblack@google.com */
4011954Sgabeblack@google.com
4111954Sgabeblack@google.com/**
4211954Sgabeblack@google.com * @file
4311954Sgabeblack@google.com * SimpleDRAM declaration
4411954Sgabeblack@google.com */
4511954Sgabeblack@google.com
4611954Sgabeblack@google.com#ifndef __MEM_SIMPLE_DRAM_HH__
4711954Sgabeblack@google.com#define __MEM_SIMPLE_DRAM_HH__
4811954Sgabeblack@google.com
4911954Sgabeblack@google.com#include <deque>
5011954Sgabeblack@google.com
5111954Sgabeblack@google.com#include "base/statistics.hh"
5211954Sgabeblack@google.com#include "enums/AddrMap.hh"
5311954Sgabeblack@google.com#include "enums/MemSched.hh"
5411954Sgabeblack@google.com#include "enums/PageManage.hh"
5511954Sgabeblack@google.com#include "mem/abstract_mem.hh"
5611954Sgabeblack@google.com#include "mem/qport.hh"
5711954Sgabeblack@google.com#include "params/SimpleDRAM.hh"
5811954Sgabeblack@google.com#include "sim/eventq.hh"
5911954Sgabeblack@google.com
6011954Sgabeblack@google.com/**
6111954Sgabeblack@google.com * The simple DRAM is a basic single-channel memory controller aiming
6211954Sgabeblack@google.com * to mimic a high-level DRAM controller and the most important timing
6311954Sgabeblack@google.com * constraints associated with the DRAM. The focus is really on
6411954Sgabeblack@google.com * modelling the impact on the system rather than the DRAM itself,
6511954Sgabeblack@google.com * hence the focus is on the controller model and not on the
6611954Sgabeblack@google.com * memory. By adhering to the correct timing constraints, ultimately
6711954Sgabeblack@google.com * there is no need for a memory model in addition to the controller
6811954Sgabeblack@google.com * model.
6911954Sgabeblack@google.com *
7011954Sgabeblack@google.com * As a basic design principle, this controller is not cycle callable,
7111954Sgabeblack@google.com * but instead uses events to decide when new decisions can be made,
7211954Sgabeblack@google.com * when resources become available, when things are to be considered
7311954Sgabeblack@google.com * done, and when to send things back. Through these simple
7411954Sgabeblack@google.com * principles, we achieve a performant model that is not
7511954Sgabeblack@google.com * cycle-accurate, but enables us to evaluate the system impact of a
7611954Sgabeblack@google.com * wide range of memory technologies, and also collect statistics
7711954Sgabeblack@google.com * about the use of the memory.
7811954Sgabeblack@google.com */
7911954Sgabeblack@google.comclass SimpleDRAM : public AbstractMemory
8011954Sgabeblack@google.com{
8111954Sgabeblack@google.com
8211954Sgabeblack@google.com  private:
8311954Sgabeblack@google.com
8411954Sgabeblack@google.com    // For now, make use of a queued slave port to avoid dealing with
8511954Sgabeblack@google.com    // flow control for the responses being sent back
8611954Sgabeblack@google.com    class MemoryPort : public QueuedSlavePort
8711954Sgabeblack@google.com    {
8811954Sgabeblack@google.com
8911954Sgabeblack@google.com        SlavePacketQueue queue;
9011954Sgabeblack@google.com        SimpleDRAM& memory;
9111954Sgabeblack@google.com
9211954Sgabeblack@google.com      public:
9311954Sgabeblack@google.com
9411954Sgabeblack@google.com        MemoryPort(const std::string& name, SimpleDRAM& _memory);
9511954Sgabeblack@google.com
9611954Sgabeblack@google.com      protected:
9711954Sgabeblack@google.com
9811954Sgabeblack@google.com        Tick recvAtomic(PacketPtr pkt);
9911954Sgabeblack@google.com
10011954Sgabeblack@google.com        void recvFunctional(PacketPtr pkt);
10111954Sgabeblack@google.com
10211954Sgabeblack@google.com        bool recvTimingReq(PacketPtr);
10311954Sgabeblack@google.com
10411954Sgabeblack@google.com        virtual AddrRangeList getAddrRanges() const;
10511954Sgabeblack@google.com
10611954Sgabeblack@google.com    };
10711954Sgabeblack@google.com
10811954Sgabeblack@google.com    /**
10911954Sgabeblack@google.com     * Our incoming port, for a multi-ported controller add a crossbar
11011954Sgabeblack@google.com     * in front of it
11111954Sgabeblack@google.com     */
11211954Sgabeblack@google.com    MemoryPort port;
11311954Sgabeblack@google.com
11411954Sgabeblack@google.com    /**
11511954Sgabeblack@google.com     * Remember if we have to retry a request when available.
11611954Sgabeblack@google.com     */
11711954Sgabeblack@google.com    bool retryRdReq;
11811954Sgabeblack@google.com    bool retryWrReq;
11911954Sgabeblack@google.com
12011954Sgabeblack@google.com    /**
12111954Sgabeblack@google.com     * Remember that a row buffer hit occured
12211954Sgabeblack@google.com     */
12311954Sgabeblack@google.com    bool rowHitFlag;
12411954Sgabeblack@google.com
12511954Sgabeblack@google.com    /**
12611954Sgabeblack@google.com     * Use this flag to shutoff reads, i.e. do not schedule any reads
12711954Sgabeblack@google.com     * beyond those already done so that we can turn the bus around
12811954Sgabeblack@google.com     * and do a few writes, or refresh, or whatever
12911954Sgabeblack@google.com     */
13011954Sgabeblack@google.com    bool stopReads;
13111954Sgabeblack@google.com
13211954Sgabeblack@google.com    /** List to keep track of activate ticks */
13311954Sgabeblack@google.com    std::deque<Tick> actTicks;
13411954Sgabeblack@google.com
13511954Sgabeblack@google.com    /**
13611954Sgabeblack@google.com     * A basic class to track the bank state indirectly via
13711954Sgabeblack@google.com     * times "freeAt" and "tRASDoneAt" and what page is currently open
13811954Sgabeblack@google.com     */
13911954Sgabeblack@google.com    class Bank
14011954Sgabeblack@google.com    {
14111954Sgabeblack@google.com
14211954Sgabeblack@google.com      public:
14311954Sgabeblack@google.com
14411954Sgabeblack@google.com        static const uint32_t INVALID_ROW = -1;
14511954Sgabeblack@google.com
14611954Sgabeblack@google.com        uint32_t openRow;
14711954Sgabeblack@google.com
14811954Sgabeblack@google.com        Tick freeAt;
14911954Sgabeblack@google.com        Tick tRASDoneAt;
15011954Sgabeblack@google.com
15111954Sgabeblack@google.com        Bank() : openRow(INVALID_ROW), freeAt(0), tRASDoneAt(0)
15211954Sgabeblack@google.com        { }
15311954Sgabeblack@google.com    };
15411954Sgabeblack@google.com
15511954Sgabeblack@google.com    /**
15611954Sgabeblack@google.com     * A DRAM packet stores packets along with the timestamp of when
15711954Sgabeblack@google.com     * the packet entered the queue, and also the decoded address.
15811954Sgabeblack@google.com     */
15911954Sgabeblack@google.com    class DRAMPacket {
16011954Sgabeblack@google.com
16111954Sgabeblack@google.com      public:
16211954Sgabeblack@google.com
16311954Sgabeblack@google.com        /** When did request enter the controller */
16411954Sgabeblack@google.com        const Tick entryTime;
16511954Sgabeblack@google.com
16611954Sgabeblack@google.com        /** When will request leave the controller */
16711954Sgabeblack@google.com        Tick readyTime;
16811954Sgabeblack@google.com
16911954Sgabeblack@google.com        /** This comes from the outside world */
17011954Sgabeblack@google.com        const PacketPtr pkt;
17111954Sgabeblack@google.com
17211954Sgabeblack@google.com        /** Will be populated by address decoder */
17311954Sgabeblack@google.com        const uint8_t rank;
17411954Sgabeblack@google.com        const uint16_t bank;
17511954Sgabeblack@google.com        const uint16_t row;
17611954Sgabeblack@google.com        const Addr addr;
17711954Sgabeblack@google.com        Bank& bank_ref;
17811954Sgabeblack@google.com
17911954Sgabeblack@google.com        DRAMPacket(PacketPtr _pkt, uint8_t _rank,
18011954Sgabeblack@google.com                   uint16_t _bank, uint16_t _row, Addr _addr, Bank& _bank_ref)
18111954Sgabeblack@google.com            : entryTime(curTick()), readyTime(curTick()),
18211954Sgabeblack@google.com              pkt(_pkt), rank(_rank), bank(_bank), row(_row), addr(_addr),
18311954Sgabeblack@google.com              bank_ref(_bank_ref)
18411954Sgabeblack@google.com        { }
18511954Sgabeblack@google.com
18611954Sgabeblack@google.com    };
18711954Sgabeblack@google.com
18811954Sgabeblack@google.com    /**
18911954Sgabeblack@google.com     * Bunch of things requires to setup "events" in gem5
19011954Sgabeblack@google.com     * When event "writeEvent" occurs for example, the method
19111954Sgabeblack@google.com     * processWriteEvent is called; no parameters are allowed
19211954Sgabeblack@google.com     * in these methods
19311954Sgabeblack@google.com     */
19411954Sgabeblack@google.com    void processWriteEvent();
19511954Sgabeblack@google.com    EventWrapper<SimpleDRAM, &SimpleDRAM::processWriteEvent> writeEvent;
19611954Sgabeblack@google.com
19711954Sgabeblack@google.com    void processRespondEvent();
19811954Sgabeblack@google.com    EventWrapper<SimpleDRAM, &SimpleDRAM::processRespondEvent> respondEvent;
19911954Sgabeblack@google.com
20011954Sgabeblack@google.com    void processRefreshEvent();
20111954Sgabeblack@google.com    EventWrapper<SimpleDRAM, &SimpleDRAM::processRefreshEvent> refreshEvent;
20211954Sgabeblack@google.com
20311954Sgabeblack@google.com    void processNextReqEvent();
20411954Sgabeblack@google.com    EventWrapper<SimpleDRAM,&SimpleDRAM::processNextReqEvent> nextReqEvent;
20511954Sgabeblack@google.com
20611954Sgabeblack@google.com
20711954Sgabeblack@google.com    /**
20811954Sgabeblack@google.com     * Check if the read queue has room for more entries
20911954Sgabeblack@google.com     *
21011954Sgabeblack@google.com     * @return true if read queue is full, false otherwise
21111954Sgabeblack@google.com     */
21211954Sgabeblack@google.com    bool readQueueFull() const;
21311954Sgabeblack@google.com
21411954Sgabeblack@google.com    /**
21511954Sgabeblack@google.com     * Check if the write queue has room for more entries
21611954Sgabeblack@google.com     *
21711954Sgabeblack@google.com     * @return true if write queue is full, false otherwise
21811954Sgabeblack@google.com     */
21911954Sgabeblack@google.com    bool writeQueueFull() const;
22011954Sgabeblack@google.com
22111954Sgabeblack@google.com    /**
22211954Sgabeblack@google.com     * When a new read comes in, first check if the write q has a
22311954Sgabeblack@google.com     * pending request to the same address.\ If not, decode the
22411954Sgabeblack@google.com     * address to populate rank/bank/row, create a "dram_pkt", and
22511954Sgabeblack@google.com     * push it to the back of the read queue.\ If this is the only
22611954Sgabeblack@google.com     * read request in the system, schedule an event to start
22711954Sgabeblack@google.com     * servicing it.
22811954Sgabeblack@google.com     *
22911954Sgabeblack@google.com     * @param pkt The request packet from the outside world
23011954Sgabeblack@google.com     */
23111954Sgabeblack@google.com    void addToReadQueue(PacketPtr pkt);
23211954Sgabeblack@google.com
23311954Sgabeblack@google.com    /**
23411954Sgabeblack@google.com     * Decode the incoming pkt, create a dram_pkt and push to the
23511954Sgabeblack@google.com     * back of the write queue. \If the write q length is more than
23611954Sgabeblack@google.com     * the threshold specified by the user, ie the queue is beginning
23711954Sgabeblack@google.com     * to get full, stop reads, and start draining writes.
23811954Sgabeblack@google.com     *
23911954Sgabeblack@google.com     * @param pkt The request packet from the outside world
24011954Sgabeblack@google.com     */
24111954Sgabeblack@google.com    void addToWriteQueue(PacketPtr pkt);
24211954Sgabeblack@google.com
24311954Sgabeblack@google.com    /**
24411954Sgabeblack@google.com     * Actually do the DRAM access - figure out the latency it
24511954Sgabeblack@google.com     * will take to service the req based on bank state, channel state etc
24611954Sgabeblack@google.com     * and then update those states to account for this request.\ Based
24711954Sgabeblack@google.com     * on this, update the packet's "readyTime" and move it to the
24811954Sgabeblack@google.com     * response q from where it will eventually go back to the outside
24911954Sgabeblack@google.com     * world.
25011954Sgabeblack@google.com     *
25111954Sgabeblack@google.com     * @param pkt The DRAM packet created from the outside world pkt
25211954Sgabeblack@google.com     */
25311954Sgabeblack@google.com    void doDRAMAccess(DRAMPacket* dram_pkt);
25411954Sgabeblack@google.com
25511954Sgabeblack@google.com    /**
25611954Sgabeblack@google.com     * Check when the channel is free to turnaround, add turnaround
25711954Sgabeblack@google.com     * delay and schedule a whole bunch of writes.
25811954Sgabeblack@google.com     */
25911954Sgabeblack@google.com    void triggerWrites();
26011954Sgabeblack@google.com
26111954Sgabeblack@google.com    /**
26211954Sgabeblack@google.com     * When a packet reaches its "readyTime" in the response Q,
26311954Sgabeblack@google.com     * use the "access()" method in AbstractMemory to actually
26411954Sgabeblack@google.com     * create the response packet, and send it back to the outside
26511954Sgabeblack@google.com     * world requestor.
26611954Sgabeblack@google.com     *
26711954Sgabeblack@google.com     * @param pkt The packet from the outside world
26811954Sgabeblack@google.com     */
26911954Sgabeblack@google.com    void accessAndRespond(PacketPtr pkt);
27011954Sgabeblack@google.com
27111954Sgabeblack@google.com    /**
27211954Sgabeblack@google.com     * Address decoder to figure out physical mapping onto ranks,
27311954Sgabeblack@google.com     * banks, and rows.
27411954Sgabeblack@google.com     *
27511954Sgabeblack@google.com     * @param pkt The packet from the outside world
27611954Sgabeblack@google.com     * @return A DRAMPacket pointer with the decoded information
27711954Sgabeblack@google.com     */
27811954Sgabeblack@google.com    DRAMPacket* decodeAddr(PacketPtr pkt);
27911954Sgabeblack@google.com
28011954Sgabeblack@google.com    /**
28111954Sgabeblack@google.com     * The memory schduler/arbiter - picks which read request needs to
28211954Sgabeblack@google.com     * go next, based on the specified policy such as FCFS or FR-FCFS
28311954Sgabeblack@google.com     * and moves it to the head of the read queue.
28411954Sgabeblack@google.com     *
28511954Sgabeblack@google.com     * @return True if a request was chosen and false if queue is empty
28611954Sgabeblack@google.com     */
28711954Sgabeblack@google.com    bool chooseNextRead();
28811954Sgabeblack@google.com
28911954Sgabeblack@google.com    /**
29011954Sgabeblack@google.com     * Calls chooseNextReq() to pick the right request, then calls
29111954Sgabeblack@google.com     * doDRAMAccess on that request in order to actually service
29211954Sgabeblack@google.com     * that request
29311954Sgabeblack@google.com     */
29411954Sgabeblack@google.com    void scheduleNextReq();
29511954Sgabeblack@google.com
29611954Sgabeblack@google.com    /**
29711954Sgabeblack@google.com     *Looks at the state of the banks, channels, row buffer hits etc
29811954Sgabeblack@google.com     * to estimate how long a request will take to complete.
29911954Sgabeblack@google.com     *
30011954Sgabeblack@google.com     * @param dram_pkt The request for which we want to estimate latency
30111954Sgabeblack@google.com     * @param inTime The tick at which you want to probe the memory
30211954Sgabeblack@google.com     *
30311954Sgabeblack@google.com     * @return A pair of ticks, one indicating how many ticks *after*
30411954Sgabeblack@google.com     *         inTime the request require, and the other indicating how
30511954Sgabeblack@google.com     *         much of that was just the bank access time, ignoring the
30611954Sgabeblack@google.com     *         ticks spent simply waiting for resources to become free
30711954Sgabeblack@google.com     */
30811954Sgabeblack@google.com    std::pair<Tick, Tick> estimateLatency(DRAMPacket* dram_pkt, Tick inTime);
30911954Sgabeblack@google.com
31011954Sgabeblack@google.com    /**
31111954Sgabeblack@google.com     * Move the request at the head of the read queue to the response
31211954Sgabeblack@google.com     * queue, sorting by readyTime.\ If it is the only packet in the
31311954Sgabeblack@google.com     * response queue, schedule a respond event to send it back to the
31411954Sgabeblack@google.com     * outside world
31511954Sgabeblack@google.com     */
31611954Sgabeblack@google.com    void moveToRespQ();
31711954Sgabeblack@google.com
31811954Sgabeblack@google.com    /**
31911954Sgabeblack@google.com     * Scheduling policy within the write queue
32011954Sgabeblack@google.com     */
32111954Sgabeblack@google.com    void chooseNextWrite();
32211954Sgabeblack@google.com
32311954Sgabeblack@google.com    /**
32411954Sgabeblack@google.com     * Looking at all banks, determine the moment in time when they
32511954Sgabeblack@google.com     * are all free.
32611954Sgabeblack@google.com     *
32711954Sgabeblack@google.com     * @return The tick when all banks are free
32811954Sgabeblack@google.com     */
32911954Sgabeblack@google.com    Tick maxBankFreeAt() const;
33011954Sgabeblack@google.com
33111954Sgabeblack@google.com
33211954Sgabeblack@google.com    /**
33311954Sgabeblack@google.com     * Keep track of when row activations happen, in order to enforce
33411954Sgabeblack@google.com     * the maximum number of activations in the activation window. The
33511954Sgabeblack@google.com     * method updates the time that the banks become available based
33611954Sgabeblack@google.com     * on the current limits.
33711954Sgabeblack@google.com     */
33811954Sgabeblack@google.com    void recordActivate(Tick act_tick);
33911954Sgabeblack@google.com
34011954Sgabeblack@google.com    void printParams() const;
34111954Sgabeblack@google.com    void printQs() const;
34211954Sgabeblack@google.com
34311954Sgabeblack@google.com    /**
34411954Sgabeblack@google.com     * The controller's main read and write queues
34511954Sgabeblack@google.com     */
34611954Sgabeblack@google.com    std::list<DRAMPacket*> readQueue;
34711954Sgabeblack@google.com    std::list<DRAMPacket*> writeQueue;
34811954Sgabeblack@google.com
34911954Sgabeblack@google.com    /**
35011954Sgabeblack@google.com     * Response queue where read packets wait after we're done working
35111954Sgabeblack@google.com     * with them, but it's not time to send the response yet. The
35211954Sgabeblack@google.com     * responses are stored seperately mostly to keep the code clean
35311954Sgabeblack@google.com     * and help with events scheduling. For all logical purposes such
35411954Sgabeblack@google.com     * as sizing the read queue, this and the main read queue need to
35511954Sgabeblack@google.com     * be added together.
35611954Sgabeblack@google.com     */
35711954Sgabeblack@google.com    std::list<DRAMPacket*> respQueue;
35811954Sgabeblack@google.com
35911954Sgabeblack@google.com    /**
36011954Sgabeblack@google.com     * If we need to drain, keep the drain manager around until we're
36111954Sgabeblack@google.com     * done here.
36211954Sgabeblack@google.com     */
36311954Sgabeblack@google.com    DrainManager *drainManager;
36411954Sgabeblack@google.com
36511954Sgabeblack@google.com    /**
36611954Sgabeblack@google.com     * Multi-dimensional vector of banks, first dimension is ranks,
36711954Sgabeblack@google.com     * second is bank
36811954Sgabeblack@google.com     */
36911954Sgabeblack@google.com    std::vector<std::vector<Bank> > banks;
37011954Sgabeblack@google.com
37111954Sgabeblack@google.com    /**
37211954Sgabeblack@google.com     * The following are basic design parameters of the memory
37311954Sgabeblack@google.com     * controller, and are initialized based on parameter values. The
37411954Sgabeblack@google.com     * bytesPerCacheLine is based on the neighbouring ports cache line
37511954Sgabeblack@google.com     * size and thus determined outside the constructor. Similarly,
37611954Sgabeblack@google.com     * the rowsPerBank is determined based on the capacity, number of
37711954Sgabeblack@google.com     * ranks and banks, the cache line size, and the row buffer size.
37811954Sgabeblack@google.com     */
37911954Sgabeblack@google.com    uint32_t bytesPerCacheLine;
38011954Sgabeblack@google.com    const uint32_t linesPerRowBuffer;
38111954Sgabeblack@google.com    const uint32_t ranksPerChannel;
38211954Sgabeblack@google.com    const uint32_t banksPerRank;
38311954Sgabeblack@google.com    const uint32_t channels;
38411954Sgabeblack@google.com    uint32_t rowsPerBank;
38511954Sgabeblack@google.com    const uint32_t readBufferSize;
38611954Sgabeblack@google.com    const uint32_t writeBufferSize;
38711954Sgabeblack@google.com    const double writeThresholdPerc;
38811954Sgabeblack@google.com    uint32_t writeThreshold;
38911954Sgabeblack@google.com
39011954Sgabeblack@google.com    /**
39111954Sgabeblack@google.com     * Basic memory timing parameters initialized based on parameter
39211954Sgabeblack@google.com     * values.
39311954Sgabeblack@google.com     */
39411954Sgabeblack@google.com    const Tick tWTR;
39511954Sgabeblack@google.com    const Tick tBURST;
39611954Sgabeblack@google.com    const Tick tRCD;
39711954Sgabeblack@google.com    const Tick tCL;
39811954Sgabeblack@google.com    const Tick tRP;
39911954Sgabeblack@google.com    const Tick tRFC;
40011954Sgabeblack@google.com    const Tick tREFI;
40111954Sgabeblack@google.com    const Tick tXAW;
40211954Sgabeblack@google.com    const uint32_t activationLimit;
40311954Sgabeblack@google.com
40411954Sgabeblack@google.com    /**
40511954Sgabeblack@google.com     * Memory controller configuration initialized based on parameter
40611954Sgabeblack@google.com     * values.
40711954Sgabeblack@google.com     */
40811954Sgabeblack@google.com    Enums::MemSched memSchedPolicy;
40911954Sgabeblack@google.com    Enums::AddrMap addrMapping;
41011954Sgabeblack@google.com    Enums::PageManage pageMgmt;
41111954Sgabeblack@google.com
41211954Sgabeblack@google.com    /**
41311954Sgabeblack@google.com     * Till when has the main data bus been spoken for already?
41411954Sgabeblack@google.com     */
41511954Sgabeblack@google.com    Tick busBusyUntil;
41611954Sgabeblack@google.com
41711954Sgabeblack@google.com    Tick writeStartTime;
41811954Sgabeblack@google.com    Tick prevArrival;
41911954Sgabeblack@google.com    int numReqs;
42011954Sgabeblack@google.com
42111954Sgabeblack@google.com    // All statistics that the model needs to capture
42211954Sgabeblack@google.com    Stats::Scalar readReqs;
42311954Sgabeblack@google.com    Stats::Scalar writeReqs;
42411954Sgabeblack@google.com    Stats::Scalar cpuReqs;
42511954Sgabeblack@google.com    Stats::Scalar bytesRead;
42611954Sgabeblack@google.com    Stats::Scalar bytesWritten;
42711954Sgabeblack@google.com    Stats::Scalar bytesConsumedRd;
42811954Sgabeblack@google.com    Stats::Scalar bytesConsumedWr;
42911954Sgabeblack@google.com    Stats::Scalar servicedByWrQ;
43011954Sgabeblack@google.com    Stats::Scalar neitherReadNorWrite;
43111954Sgabeblack@google.com    Stats::Vector perBankRdReqs;
43211954Sgabeblack@google.com    Stats::Vector perBankWrReqs;
43311954Sgabeblack@google.com    Stats::Scalar numRdRetry;
43411954Sgabeblack@google.com    Stats::Scalar numWrRetry;
43511954Sgabeblack@google.com    Stats::Scalar totGap;
43611954Sgabeblack@google.com    Stats::Vector readPktSize;
43711954Sgabeblack@google.com    Stats::Vector writePktSize;
43811954Sgabeblack@google.com    Stats::Vector rdQLenPdf;
43911954Sgabeblack@google.com    Stats::Vector wrQLenPdf;
44011954Sgabeblack@google.com
44111954Sgabeblack@google.com
44211954Sgabeblack@google.com    // Latencies summed over all requests
44311954Sgabeblack@google.com    Stats::Scalar totQLat;
44411954Sgabeblack@google.com    Stats::Scalar totMemAccLat;
44511954Sgabeblack@google.com    Stats::Scalar totBusLat;
44611954Sgabeblack@google.com    Stats::Scalar totBankLat;
44711954Sgabeblack@google.com
44811954Sgabeblack@google.com    // Average latencies per request
44911954Sgabeblack@google.com    Stats::Formula avgQLat;
45011954Sgabeblack@google.com    Stats::Formula avgBankLat;
45111955Sgabeblack@google.com    Stats::Formula avgBusLat;
45211954Sgabeblack@google.com    Stats::Formula avgMemAccLat;
45311954Sgabeblack@google.com
45411954Sgabeblack@google.com    // Average bandwidth
45511954Sgabeblack@google.com    Stats::Formula avgRdBW;
45611954Sgabeblack@google.com    Stats::Formula avgWrBW;
45711954Sgabeblack@google.com    Stats::Formula avgConsumedRdBW;
45811954Sgabeblack@google.com    Stats::Formula avgConsumedWrBW;
45911954Sgabeblack@google.com    Stats::Formula peakBW;
46011954Sgabeblack@google.com    Stats::Formula busUtil;
46111960Sgabeblack@google.com
46211954Sgabeblack@google.com    // Average queue lengths
46311954Sgabeblack@google.com    Stats::Average avgRdQLen;
46411954Sgabeblack@google.com    Stats::Average avgWrQLen;
46511954Sgabeblack@google.com
46611954Sgabeblack@google.com    // Row hit count and rate
46711954Sgabeblack@google.com    Stats::Scalar readRowHits;
46811954Sgabeblack@google.com    Stats::Scalar writeRowHits;
46911954Sgabeblack@google.com    Stats::Formula readRowHitRate;
47011954Sgabeblack@google.com    Stats::Formula writeRowHitRate;
47111954Sgabeblack@google.com    Stats::Formula avgGap;
47211954Sgabeblack@google.com
47311954Sgabeblack@google.com    /** @todo this is a temporary workaround until the 4-phase code is
47411954Sgabeblack@google.com     * committed. upstream caches needs this packet until true is returned, so
47511954Sgabeblack@google.com     * hold onto it for deletion until a subsequent call
47611954Sgabeblack@google.com     */
47711954Sgabeblack@google.com    std::vector<PacketPtr> pendingDelete;
47811954Sgabeblack@google.com
47911954Sgabeblack@google.com  public:
48011954Sgabeblack@google.com
48111954Sgabeblack@google.com    void regStats();
48211954Sgabeblack@google.com
48311954Sgabeblack@google.com    SimpleDRAM(const SimpleDRAMParams* p);
48411954Sgabeblack@google.com
48511954Sgabeblack@google.com    unsigned int drain(DrainManager* dm);
48611954Sgabeblack@google.com
48711954Sgabeblack@google.com    virtual BaseSlavePort& getSlavePort(const std::string& if_name,
48811954Sgabeblack@google.com                                        PortID idx = InvalidPortID);
48911954Sgabeblack@google.com
49011954Sgabeblack@google.com    virtual void init();
49111954Sgabeblack@google.com    virtual void startup();
49211954Sgabeblack@google.com
49311954Sgabeblack@google.com  protected:
49411954Sgabeblack@google.com
49511954Sgabeblack@google.com    Tick recvAtomic(PacketPtr pkt);
49611954Sgabeblack@google.com    void recvFunctional(PacketPtr pkt);
49711954Sgabeblack@google.com    bool recvTimingReq(PacketPtr pkt);
49811954Sgabeblack@google.com
49911954Sgabeblack@google.com};
50011954Sgabeblack@google.com
50111954Sgabeblack@google.com#endif //__MEM_SIMPLE_DRAM_HH__
50211954Sgabeblack@google.com