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