dram_ctrl.hh revision 12705
112531Sandreas.sandberg@arm.com/* 210037SARM gem5 Developers * Copyright (c) 2012-2017 ARM Limited 310037SARM gem5 Developers * All rights reserved 410037SARM gem5 Developers * 510037SARM gem5 Developers * The license below extends only to copyright in the software and shall 610037SARM gem5 Developers * not be construed as granting a license to any other intellectual 710037SARM gem5 Developers * property including but not limited to intellectual property relating 810037SARM gem5 Developers * to a hardware implementation of the functionality of the software 910037SARM gem5 Developers * licensed hereunder. You may use the software subject to the license 1010037SARM gem5 Developers * terms below provided that you ensure that this notice is replicated 1110037SARM gem5 Developers * unmodified and in its entirety in all distributions of the software, 1210037SARM gem5 Developers * modified or unmodified, in source code or in binary form. 1310037SARM gem5 Developers * 1410037SARM gem5 Developers * Copyright (c) 2013 Amin Farmahini-Farahani 1510037SARM gem5 Developers * All rights reserved. 1610037SARM gem5 Developers * 1710037SARM gem5 Developers * Redistribution and use in source and binary forms, with or without 1810037SARM gem5 Developers * modification, are permitted provided that the following conditions are 1910037SARM gem5 Developers * met: redistributions of source code must retain the above copyright 2010037SARM gem5 Developers * notice, this list of conditions and the following disclaimer; 2110037SARM gem5 Developers * redistributions in binary form must reproduce the above copyright 2210037SARM gem5 Developers * notice, this list of conditions and the following disclaimer in the 2310037SARM gem5 Developers * documentation and/or other materials provided with the distribution; 2410037SARM gem5 Developers * neither the name of the copyright holders nor the names of its 2510037SARM gem5 Developers * contributors may be used to endorse or promote products derived from 2610037SARM gem5 Developers * this software without specific prior written permission. 2710037SARM gem5 Developers * 2810037SARM gem5 Developers * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2910037SARM gem5 Developers * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3010037SARM gem5 Developers * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3110037SARM gem5 Developers * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3210037SARM gem5 Developers * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3310037SARM gem5 Developers * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3410037SARM gem5 Developers * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3510037SARM gem5 Developers * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3610037SARM gem5 Developers * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3710037SARM gem5 Developers * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3810037SARM gem5 Developers * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3910037SARM gem5 Developers * 4010037SARM gem5 Developers * Authors: Andreas Hansson 4110037SARM gem5 Developers * Ani Udipi 4210037SARM gem5 Developers * Neha Agarwal 4310037SARM gem5 Developers * Omar Naji 4410037SARM gem5 Developers * Matthias Jung 4510037SARM gem5 Developers * Wendy Elsasser 4610037SARM gem5 Developers * Radhika Jagtap 4710037SARM gem5 Developers */ 4810037SARM gem5 Developers 4911165SRekai.GonzalezAlberquilla@arm.com/** 5010037SARM gem5 Developers * @file 5110037SARM gem5 Developers * DRAMCtrl declaration 5211165SRekai.GonzalezAlberquilla@arm.com */ 5310037SARM gem5 Developers 5410037SARM gem5 Developers#ifndef __MEM_DRAM_CTRL_HH__ 5510037SARM gem5 Developers#define __MEM_DRAM_CTRL_HH__ 5610037SARM gem5 Developers 5710037SARM gem5 Developers#include <deque> 5810037SARM gem5 Developers#include <string> 5910037SARM gem5 Developers#include <unordered_set> 6010037SARM gem5 Developers 6110037SARM gem5 Developers#include "base/callback.hh" 6210037SARM gem5 Developers#include "base/statistics.hh" 6310037SARM gem5 Developers#include "enums/AddrMap.hh" 6410037SARM gem5 Developers#include "enums/MemSched.hh" 6510037SARM gem5 Developers#include "enums/PageManage.hh" 6610037SARM gem5 Developers#include "mem/abstract_mem.hh" 6710037SARM gem5 Developers#include "mem/qport.hh" 6810337SAndrew.Bardsley@arm.com#include "params/DRAMCtrl.hh" 6910037SARM gem5 Developers#include "sim/eventq.hh" 7010037SARM gem5 Developers#include "mem/drampower.hh" 7110037SARM gem5 Developers 7210037SARM gem5 Developers/** 7310037SARM gem5 Developers * The DRAM controller is a single-channel memory controller capturing 7410037SARM gem5 Developers * the most important timing constraints associated with a 7510037SARM gem5 Developers * contemporary DRAM. For multi-channel memory systems, the controller 7610037SARM gem5 Developers * is combined with a crossbar model, with the channel address 7710037SARM gem5 Developers * interleaving taking part in the crossbar. 7810037SARM gem5 Developers * 7910037SARM gem5 Developers * As a basic design principle, this controller 8010037SARM gem5 Developers * model is not cycle callable, but instead uses events to: 1) decide 8110037SARM gem5 Developers * when new decisions can be made, 2) when resources become available, 8210037SARM gem5 Developers * 3) when things are to be considered done, and 4) when to send 8310037SARM gem5 Developers * things back. Through these simple principles, the model delivers 8410037SARM gem5 Developers * high performance, and lots of flexibility, allowing users to 8510337SAndrew.Bardsley@arm.com * evaluate the system impact of a wide range of memory technologies, 8610037SARM gem5 Developers * such as DDR3/4, LPDDR2/3/4, WideIO1/2, HBM and HMC. 8710337SAndrew.Bardsley@arm.com * 8810037SARM gem5 Developers * For more details, please see Hansson et al, "Simulating DRAM 8910037SARM gem5 Developers * controllers for future system architecture exploration", 9010037SARM gem5 Developers * Proc. ISPASS, 2014. If you use this model as part of your research 9110037SARM gem5 Developers * please cite the paper. 9210037SARM gem5 Developers * 9310037SARM gem5 Developers * The low-power functionality implements a staggered powerdown 9410037SARM gem5 Developers * similar to that described in "Optimized Active and Power-Down Mode 9510037SARM gem5 Developers * Refresh Control in 3D-DRAMs" by Jung et al, VLSI-SoC, 2014. 9610037SARM gem5 Developers */ 9710037SARM gem5 Developersclass DRAMCtrl : public AbstractMemory 9810037SARM gem5 Developers{ 9910037SARM gem5 Developers 10010037SARM gem5 Developers private: 10110037SARM gem5 Developers 10210037SARM gem5 Developers // For now, make use of a queued slave port to avoid dealing with 10310037SARM gem5 Developers // flow control for the responses being sent back 10410037SARM gem5 Developers class MemoryPort : public QueuedSlavePort 10510037SARM gem5 Developers { 10610337SAndrew.Bardsley@arm.com 10710037SARM gem5 Developers RespPacketQueue queue; 10810037SARM gem5 Developers DRAMCtrl& memory; 10910037SARM gem5 Developers 11010337SAndrew.Bardsley@arm.com public: 11110037SARM gem5 Developers 11210037SARM gem5 Developers MemoryPort(const std::string& name, DRAMCtrl& _memory); 11310037SARM gem5 Developers 11410037SARM gem5 Developers protected: 11510037SARM gem5 Developers 11610037SARM gem5 Developers Tick recvAtomic(PacketPtr pkt); 11710037SARM gem5 Developers 11810037SARM gem5 Developers void recvFunctional(PacketPtr pkt); 11910037SARM gem5 Developers 12010037SARM gem5 Developers bool recvTimingReq(PacketPtr); 12110037SARM gem5 Developers 12210037SARM gem5 Developers virtual AddrRangeList getAddrRanges() const; 12310037SARM gem5 Developers 12410037SARM gem5 Developers }; 12510037SARM gem5 Developers 12610037SARM gem5 Developers /** 12710037SARM gem5 Developers * Our incoming port, for a multi-ported controller add a crossbar 12810037SARM gem5 Developers * in front of it 12910037SARM gem5 Developers */ 13010037SARM gem5 Developers MemoryPort port; 13110037SARM gem5 Developers 13210037SARM gem5 Developers /** 13310037SARM gem5 Developers * Remeber if the memory system is in timing mode 13410037SARM gem5 Developers */ 13510037SARM gem5 Developers bool isTimingMode; 13610037SARM gem5 Developers 13710037SARM gem5 Developers /** 13810037SARM gem5 Developers * Remember if we have to retry a request when available. 13910037SARM gem5 Developers */ 14010037SARM gem5 Developers bool retryRdReq; 14110037SARM gem5 Developers bool retryWrReq; 14210037SARM gem5 Developers 14310037SARM gem5 Developers /** 14410037SARM gem5 Developers * Bus state used to control the read/write switching and drive 14510037SARM gem5 Developers * the scheduling of the next request. 14610037SARM gem5 Developers */ 14710037SARM gem5 Developers enum BusState { 14810037SARM gem5 Developers READ = 0, 14910037SARM gem5 Developers WRITE, 15010037SARM gem5 Developers }; 15110037SARM gem5 Developers 15210337SAndrew.Bardsley@arm.com BusState busState; 15310037SARM gem5 Developers 15410037SARM gem5 Developers /* bus state for next request event triggered */ 15510037SARM gem5 Developers BusState busStateNext; 15610037SARM gem5 Developers 15710037SARM gem5 Developers /** 15810337SAndrew.Bardsley@arm.com * Simple structure to hold the values needed to keep track of 15910037SARM gem5 Developers * commands for DRAMPower 16010037SARM gem5 Developers */ 16110037SARM gem5 Developers struct Command { 16210037SARM gem5 Developers Data::MemCommand::cmds type; 16310337SAndrew.Bardsley@arm.com uint8_t bank; 16410037SARM gem5 Developers Tick timeStamp; 16510037SARM gem5 Developers 16610037SARM gem5 Developers constexpr Command(Data::MemCommand::cmds _type, uint8_t _bank, 16710337SAndrew.Bardsley@arm.com Tick time_stamp) 16810037SARM gem5 Developers : type(_type), bank(_bank), timeStamp(time_stamp) 16910337SAndrew.Bardsley@arm.com { } 17010037SARM gem5 Developers }; 17110037SARM gem5 Developers 17210037SARM gem5 Developers /** 17310037SARM gem5 Developers * A basic class to track the bank state, i.e. what row is 17410037SARM gem5 Developers * currently open (if any), when is the bank free to accept a new 17510037SARM gem5 Developers * column (read/write) command, when can it be precharged, and 17610037SARM gem5 Developers * when can it be activated. 17710337SAndrew.Bardsley@arm.com * 17810037SARM gem5 Developers * The bank also keeps track of how many bytes have been accessed 17910337SAndrew.Bardsley@arm.com * in the open row since it was opened. 18010037SARM gem5 Developers */ 18110337SAndrew.Bardsley@arm.com class Bank 18210037SARM gem5 Developers { 18310037SARM gem5 Developers 18410037SARM gem5 Developers public: 18510037SARM gem5 Developers 18610037SARM gem5 Developers static const uint32_t NO_ROW = -1; 18710037SARM gem5 Developers 18810037SARM gem5 Developers uint32_t openRow; 18910037SARM gem5 Developers uint8_t bank; 19010037SARM gem5 Developers uint8_t bankgr; 19110337SAndrew.Bardsley@arm.com 19210037SARM gem5 Developers Tick colAllowedAt; 19310037SARM gem5 Developers Tick preAllowedAt; 19410037SARM gem5 Developers Tick actAllowedAt; 19510037SARM gem5 Developers 19610037SARM gem5 Developers uint32_t rowAccesses; 19710037SARM gem5 Developers uint32_t bytesAccessed; 19810037SARM gem5 Developers 19910037SARM gem5 Developers Bank() : 20010037SARM gem5 Developers openRow(NO_ROW), bank(0), bankgr(0), 20110037SARM gem5 Developers colAllowedAt(0), preAllowedAt(0), actAllowedAt(0), 20210037SARM gem5 Developers rowAccesses(0), bytesAccessed(0) 20310037SARM gem5 Developers { } 20410037SARM gem5 Developers }; 20510037SARM gem5 Developers 20610037SARM gem5 Developers 20710037SARM gem5 Developers /** 20810037SARM gem5 Developers * The power state captures the different operational states of 20910037SARM gem5 Developers * the DRAM and interacts with the bus read/write state machine, 21010037SARM gem5 Developers * and the refresh state machine. 21110037SARM gem5 Developers * 21210037SARM gem5 Developers * PWR_IDLE : The idle state in which all banks are closed 21310037SARM gem5 Developers * From here can transition to: PWR_REF, PWR_ACT, 21410037SARM gem5 Developers * PWR_PRE_PDN 21510037SARM gem5 Developers * 21610037SARM gem5 Developers * PWR_REF : Auto-refresh state. Will transition when refresh is 21710037SARM gem5 Developers * complete based on power state prior to PWR_REF 21810037SARM gem5 Developers * From here can transition to: PWR_IDLE, PWR_PRE_PDN, 21910037SARM gem5 Developers * PWR_SREF 22010037SARM gem5 Developers * 22110037SARM gem5 Developers * PWR_SREF : Self-refresh state. Entered after refresh if 22210037SARM gem5 Developers * previous state was PWR_PRE_PDN 22310037SARM gem5 Developers * From here can transition to: PWR_IDLE 22410037SARM gem5 Developers * 22510037SARM gem5 Developers * PWR_PRE_PDN : Precharge power down state 22610037SARM gem5 Developers * From here can transition to: PWR_REF, PWR_IDLE 22710037SARM gem5 Developers * 22810037SARM gem5 Developers * PWR_ACT : Activate state in which one or more banks are open 22910037SARM gem5 Developers * From here can transition to: PWR_IDLE, PWR_ACT_PDN 23010037SARM gem5 Developers * 23110037SARM gem5 Developers * PWR_ACT_PDN : Activate power down state 23210037SARM gem5 Developers * From here can transition to: PWR_ACT 23310037SARM gem5 Developers */ 23410037SARM gem5 Developers enum PowerState { 23510037SARM gem5 Developers PWR_IDLE = 0, 23610037SARM gem5 Developers PWR_REF, 23710037SARM gem5 Developers PWR_SREF, 23810037SARM gem5 Developers PWR_PRE_PDN, 23910037SARM gem5 Developers PWR_ACT, 24010037SARM gem5 Developers PWR_ACT_PDN 24110037SARM gem5 Developers }; 24210037SARM gem5 Developers 24310037SARM gem5 Developers /** 24410037SARM gem5 Developers * The refresh state is used to control the progress of the 24512538Sgiacomo.travaglini@arm.com * refresh scheduling. When normal operation is in progress the 24610037SARM gem5 Developers * refresh state is idle. Once tREFI has elasped, a refresh event 24710037SARM gem5 Developers * is triggered to start the following STM transitions which are 24812538Sgiacomo.travaglini@arm.com * used to issue a refresh and return back to normal operation 24912538Sgiacomo.travaglini@arm.com * 25010037SARM gem5 Developers * REF_IDLE : IDLE state used during normal operation 25110037SARM gem5 Developers * From here can transition to: REF_DRAIN 25212538Sgiacomo.travaglini@arm.com * 25310037SARM gem5 Developers * REF_SREF_EXIT : Exiting a self-refresh; refresh event scheduled 25410037SARM gem5 Developers * after self-refresh exit completes 25512538Sgiacomo.travaglini@arm.com * From here can transition to: REF_DRAIN 25610037SARM gem5 Developers * 25712538Sgiacomo.travaglini@arm.com * REF_DRAIN : Drain state in which on going accesses complete. 25810037SARM gem5 Developers * From here can transition to: REF_PD_EXIT 25912538Sgiacomo.travaglini@arm.com * 26010037SARM gem5 Developers * REF_PD_EXIT : Evaluate pwrState and issue wakeup if needed 26112538Sgiacomo.travaglini@arm.com * Next state dependent on whether banks are open 26210037SARM gem5 Developers * From here can transition to: REF_PRE, REF_START 26312538Sgiacomo.travaglini@arm.com * 26410037SARM gem5 Developers * REF_PRE : Close (precharge) all open banks 26510037SARM gem5 Developers * From here can transition to: REF_START 26610037SARM gem5 Developers * 26710037SARM gem5 Developers * REF_START : Issue refresh command and update DRAMPower stats 26810037SARM gem5 Developers * From here can transition to: REF_RUN 26910037SARM gem5 Developers * 27010037SARM gem5 Developers * REF_RUN : Refresh running, waiting for tRFC to expire 27110037SARM gem5 Developers * From here can transition to: REF_IDLE, REF_SREF_EXIT 27210037SARM gem5 Developers */ 27310037SARM gem5 Developers enum RefreshState { 27410037SARM gem5 Developers REF_IDLE = 0, 27510037SARM gem5 Developers REF_DRAIN, 27610037SARM gem5 Developers REF_PD_EXIT, 27710037SARM gem5 Developers REF_SREF_EXIT, 27810037SARM gem5 Developers REF_PRE, 27910037SARM gem5 Developers REF_START, 28010037SARM gem5 Developers REF_RUN 28110037SARM gem5 Developers }; 28210037SARM gem5 Developers 28310037SARM gem5 Developers /** 28410037SARM gem5 Developers * Rank class includes a vector of banks. Refresh and Power state 28510037SARM gem5 Developers * machines are defined per rank. Events required to change the 28610037SARM gem5 Developers * state of the refresh and power state machine are scheduled per 28710037SARM gem5 Developers * rank. This class allows the implementation of rank-wise refresh 28810037SARM gem5 Developers * and rank-wise power-down. 28910037SARM gem5 Developers */ 29010037SARM gem5 Developers class Rank : public EventManager 29110037SARM gem5 Developers { 29210037SARM gem5 Developers 29310037SARM gem5 Developers private: 29410037SARM gem5 Developers 29510037SARM gem5 Developers /** 29610037SARM gem5 Developers * A reference to the parent DRAMCtrl instance 29710037SARM gem5 Developers */ 29810037SARM gem5 Developers DRAMCtrl& memory; 29910037SARM gem5 Developers 30010037SARM gem5 Developers /** 30110037SARM gem5 Developers * Since we are taking decisions out of order, we need to keep 30210037SARM gem5 Developers * track of what power transition is happening at what time 30310037SARM gem5 Developers */ 30410037SARM gem5 Developers PowerState pwrStateTrans; 30510037SARM gem5 Developers 30610037SARM gem5 Developers /** 30710037SARM gem5 Developers * Previous low-power state, which will be re-entered after refresh. 30810037SARM gem5 Developers */ 30910037SARM gem5 Developers PowerState pwrStatePostRefresh; 31010037SARM gem5 Developers 31110037SARM gem5 Developers /** 31210037SARM gem5 Developers * Track when we transitioned to the current power state 31310037SARM gem5 Developers */ 31410037SARM gem5 Developers Tick pwrStateTick; 31510037SARM gem5 Developers 31610037SARM gem5 Developers /** 31710037SARM gem5 Developers * Keep track of when a refresh is due. 31810037SARM gem5 Developers */ 31910037SARM gem5 Developers Tick refreshDueAt; 32010037SARM gem5 Developers 32110037SARM gem5 Developers /* 32210037SARM gem5 Developers * Command energies 32310037SARM gem5 Developers */ 32410037SARM gem5 Developers Stats::Scalar actEnergy; 32510037SARM gem5 Developers Stats::Scalar preEnergy; 32610037SARM gem5 Developers Stats::Scalar readEnergy; 32710037SARM gem5 Developers Stats::Scalar writeEnergy; 32810037SARM gem5 Developers Stats::Scalar refreshEnergy; 32910037SARM gem5 Developers 33010037SARM gem5 Developers /* 33110037SARM gem5 Developers * Active Background Energy 33210037SARM gem5 Developers */ 33310037SARM gem5 Developers Stats::Scalar actBackEnergy; 33410037SARM gem5 Developers 33510037SARM gem5 Developers /* 33610037SARM gem5 Developers * Precharge Background Energy 33710037SARM gem5 Developers */ 33810037SARM gem5 Developers Stats::Scalar preBackEnergy; 33910037SARM gem5 Developers 34010037SARM gem5 Developers /* 34110037SARM gem5 Developers * Active Power-Down Energy 34210037SARM gem5 Developers */ 34310037SARM gem5 Developers Stats::Scalar actPowerDownEnergy; 34410037SARM gem5 Developers 34510037SARM gem5 Developers /* 34610037SARM gem5 Developers * Precharge Power-Down Energy 34710037SARM gem5 Developers */ 34810037SARM gem5 Developers Stats::Scalar prePowerDownEnergy; 34910037SARM gem5 Developers 35010037SARM gem5 Developers /* 35110037SARM gem5 Developers * self Refresh Energy 35210037SARM gem5 Developers */ 35310037SARM gem5 Developers Stats::Scalar selfRefreshEnergy; 35410037SARM gem5 Developers 35510037SARM gem5 Developers Stats::Scalar totalEnergy; 35610037SARM gem5 Developers Stats::Scalar averagePower; 35712359Snikos.nikoleris@arm.com 35810037SARM gem5 Developers /** 35910037SARM gem5 Developers * Stat to track total DRAM idle time 36010037SARM gem5 Developers * 36110037SARM gem5 Developers */ 36210037SARM gem5 Developers Stats::Scalar totalIdleTime; 36310037SARM gem5 Developers 36410037SARM gem5 Developers /** 36510037SARM gem5 Developers * Track time spent in each power state. 36610037SARM gem5 Developers */ 36710037SARM gem5 Developers Stats::Vector pwrStateTime; 36810037SARM gem5 Developers 36910037SARM gem5 Developers /** 37010037SARM gem5 Developers * Function to update Power Stats 37110037SARM gem5 Developers */ 37210037SARM gem5 Developers void updatePowerStats(); 37310506SAli.Saidi@ARM.com 37412280Sgiacomo.travaglini@arm.com /** 37510506SAli.Saidi@ARM.com * Schedule a power state transition in the future, and 37610506SAli.Saidi@ARM.com * potentially override an already scheduled transition. 37710506SAli.Saidi@ARM.com * 37812280Sgiacomo.travaglini@arm.com * @param pwr_state Power state to transition to 37912359Snikos.nikoleris@arm.com * @param tick Tick when transition should take place 38012359Snikos.nikoleris@arm.com */ 38112359Snikos.nikoleris@arm.com void schedulePowerEvent(PowerState pwr_state, Tick tick); 38212359Snikos.nikoleris@arm.com 38312359Snikos.nikoleris@arm.com public: 38412359Snikos.nikoleris@arm.com 38512359Snikos.nikoleris@arm.com /** 38612359Snikos.nikoleris@arm.com * Current power state. 38712359Snikos.nikoleris@arm.com */ 38812359Snikos.nikoleris@arm.com PowerState pwrState; 38912359Snikos.nikoleris@arm.com 39012359Snikos.nikoleris@arm.com /** 39112359Snikos.nikoleris@arm.com * current refresh state 39212359Snikos.nikoleris@arm.com */ 39312280Sgiacomo.travaglini@arm.com RefreshState refreshState; 39410037SARM gem5 Developers 39510037SARM gem5 Developers /** 39610037SARM gem5 Developers * rank is in or transitioning to power-down or self-refresh 39710037SARM gem5 Developers */ 39810037SARM gem5 Developers bool inLowPowerState; 39910037SARM gem5 Developers 40010173SMitchell.Hayenga@ARM.com /** 40110173SMitchell.Hayenga@ARM.com * Current Rank index 40210173SMitchell.Hayenga@ARM.com */ 40310173SMitchell.Hayenga@ARM.com uint8_t rank; 40410173SMitchell.Hayenga@ARM.com 40510037SARM gem5 Developers /** 40610037SARM gem5 Developers * Track number of packets in read queue going to this rank 40710037SARM gem5 Developers */ 40810037SARM gem5 Developers uint32_t readEntries; 40910037SARM gem5 Developers 41010037SARM gem5 Developers /** 41110037SARM gem5 Developers * Track number of packets in write queue going to this rank 41210037SARM gem5 Developers */ 41310037SARM gem5 Developers uint32_t writeEntries; 41410037SARM gem5 Developers 41510037SARM gem5 Developers /** 41610037SARM gem5 Developers * Number of ACT, RD, and WR events currently scheduled 41710037SARM gem5 Developers * Incremented when a refresh event is started as well 41810037SARM gem5 Developers * Used to determine when a low-power state can be entered 41910037SARM gem5 Developers */ 42010037SARM gem5 Developers uint8_t outstandingEvents; 42110037SARM gem5 Developers 42210037SARM gem5 Developers /** 42310037SARM gem5 Developers * delay power-down and self-refresh exit until this requirement is met 42410037SARM gem5 Developers */ 42510037SARM gem5 Developers Tick wakeUpAllowedAt; 42610037SARM gem5 Developers 42710037SARM gem5 Developers /** 42810037SARM gem5 Developers * One DRAMPower instance per rank 42910037SARM gem5 Developers */ 43010037SARM gem5 Developers DRAMPower power; 43110037SARM gem5 Developers 43210037SARM gem5 Developers /** 43310037SARM gem5 Developers * List of comamnds issued, to be sent to DRAMPpower at refresh 43410037SARM gem5 Developers * and stats dump. Keep commands here since commands to different 43510037SARM gem5 Developers * banks are added out of order. Will only pass commands up to 43610037SARM gem5 Developers * curTick() to DRAMPower after sorting. 43710037SARM gem5 Developers */ 43810037SARM gem5 Developers std::vector<Command> cmdList; 43910037SARM gem5 Developers 44010037SARM gem5 Developers /** 44110037SARM gem5 Developers * Vector of Banks. Each rank is made of several devices which in 44210037SARM gem5 Developers * term are made from several banks. 44310037SARM gem5 Developers */ 44410037SARM gem5 Developers std::vector<Bank> banks; 44510037SARM gem5 Developers 44610037SARM gem5 Developers /** 44710037SARM gem5 Developers * To track number of banks which are currently active for 44810037SARM gem5 Developers * this rank. 44910037SARM gem5 Developers */ 45010037SARM gem5 Developers unsigned int numBanksActive; 45110037SARM gem5 Developers 45210037SARM gem5 Developers /** List to keep track of activate ticks */ 45310037SARM gem5 Developers std::deque<Tick> actTicks; 45410037SARM gem5 Developers 45510037SARM gem5 Developers Rank(DRAMCtrl& _memory, const DRAMCtrlParams* _p, int rank); 45610037SARM gem5 Developers 45710037SARM gem5 Developers const std::string name() const 45810037SARM gem5 Developers { 45910037SARM gem5 Developers return csprintf("%s_%d", memory.name(), rank); 46010037SARM gem5 Developers } 46110037SARM gem5 Developers 46210037SARM gem5 Developers /** 46310037SARM gem5 Developers * Kick off accounting for power and refresh states and 46410037SARM gem5 Developers * schedule initial refresh. 46510037SARM gem5 Developers * 46610037SARM gem5 Developers * @param ref_tick Tick for first refresh 46710037SARM gem5 Developers */ 46810037SARM gem5 Developers void startup(Tick ref_tick); 46910037SARM gem5 Developers 47010037SARM gem5 Developers /** 47110037SARM gem5 Developers * Stop the refresh events. 47210037SARM gem5 Developers */ 47310037SARM gem5 Developers void suspend(); 47410037SARM gem5 Developers 47510037SARM gem5 Developers /** 47610037SARM gem5 Developers * Check if there is no refresh and no preparation of refresh ongoing 47710037SARM gem5 Developers * i.e. the refresh state machine is in idle 47810037SARM gem5 Developers * 47910037SARM gem5 Developers * @param Return true if the rank is idle from a refresh point of view 48010037SARM gem5 Developers */ 48110037SARM gem5 Developers bool inRefIdleState() const { return refreshState == REF_IDLE; } 48210037SARM gem5 Developers 48310037SARM gem5 Developers /** 48410037SARM gem5 Developers * Check if the current rank has all banks closed and is not 48510037SARM gem5 Developers * in a low power state 48610037SARM gem5 Developers * 48710037SARM gem5 Developers * @param Return true if the rank is idle from a bank 48810037SARM gem5 Developers * and power point of view 48910037SARM gem5 Developers */ 49010037SARM gem5 Developers bool inPwrIdleState() const { return pwrState == PWR_IDLE; } 49110037SARM gem5 Developers 49210037SARM gem5 Developers /** 49310037SARM gem5 Developers * Trigger a self-refresh exit if there are entries enqueued 49410037SARM gem5 Developers * Exit if there are any read entries regardless of the bus state. 49510037SARM gem5 Developers * If we are currently issuing write commands, exit if we have any 49610037SARM gem5 Developers * write commands enqueued as well. 49710037SARM gem5 Developers * Could expand this in the future to analyze state of entire queue 49810037SARM gem5 Developers * if needed. 49910037SARM gem5 Developers * 50010037SARM gem5 Developers * @return boolean indicating self-refresh exit should be scheduled 50110037SARM gem5 Developers */ 50210037SARM gem5 Developers bool forceSelfRefreshExit() const { 50310037SARM gem5 Developers return (readEntries != 0) || 50410037SARM gem5 Developers ((memory.busStateNext == WRITE) && (writeEntries != 0)); 50510037SARM gem5 Developers } 50610037SARM gem5 Developers 50710037SARM gem5 Developers /** 50810037SARM gem5 Developers * Check if the command queue of current rank is idle 50910037SARM gem5 Developers * 51010037SARM gem5 Developers * @param Return true if the there are no commands in Q. 51110037SARM gem5 Developers * Bus direction determines queue checked. 51210037SARM gem5 Developers */ 51310037SARM gem5 Developers bool isQueueEmpty() const; 51410037SARM gem5 Developers 51510037SARM gem5 Developers /** 51610037SARM gem5 Developers * Let the rank check if it was waiting for requests to drain 51710037SARM gem5 Developers * to allow it to transition states. 51810037SARM gem5 Developers */ 51910037SARM gem5 Developers void checkDrainDone(); 52010037SARM gem5 Developers 52110037SARM gem5 Developers /** 52210037SARM gem5 Developers * Push command out of cmdList queue that are scheduled at 52310037SARM gem5 Developers * or before curTick() to DRAMPower library 52410037SARM gem5 Developers * All commands before curTick are guaranteed to be complete 52510037SARM gem5 Developers * and can safely be flushed. 52610037SARM gem5 Developers */ 52710037SARM gem5 Developers void flushCmdList(); 52810037SARM gem5 Developers 52910037SARM gem5 Developers /* 53010037SARM gem5 Developers * Function to register Stats 53110037SARM gem5 Developers */ 53210037SARM gem5 Developers void regStats(); 53310037SARM gem5 Developers 53410037SARM gem5 Developers /** 53510037SARM gem5 Developers * Computes stats just prior to dump event 53610037SARM gem5 Developers */ 53710037SARM gem5 Developers void computeStats(); 53810037SARM gem5 Developers 53910037SARM gem5 Developers /** 54010037SARM gem5 Developers * Reset stats on a stats event 54110037SARM gem5 Developers */ 54210037SARM gem5 Developers void resetStats(); 54310037SARM gem5 Developers 54410037SARM gem5 Developers /** 54510037SARM gem5 Developers * Schedule a transition to power-down (sleep) 54610037SARM gem5 Developers * 54710037SARM gem5 Developers * @param pwr_state Power state to transition to 54810037SARM gem5 Developers * @param tick Absolute tick when transition should take place 54910037SARM gem5 Developers */ 55010037SARM gem5 Developers void powerDownSleep(PowerState pwr_state, Tick tick); 55110037SARM gem5 Developers 55210037SARM gem5 Developers /** 55310037SARM gem5 Developers * schedule and event to wake-up from power-down or self-refresh 55410037SARM gem5 Developers * and update bank timing parameters 55510037SARM gem5 Developers * 55610037SARM gem5 Developers * @param exit_delay Relative tick defining the delay required between 55710037SARM gem5 Developers * low-power exit and the next command 55810037SARM gem5 Developers */ 55910037SARM gem5 Developers void scheduleWakeUpEvent(Tick exit_delay); 56010037SARM gem5 Developers 56110037SARM gem5 Developers void processWriteDoneEvent(); 56210037SARM gem5 Developers EventFunctionWrapper writeDoneEvent; 56310037SARM gem5 Developers 56410037SARM gem5 Developers void processActivateEvent(); 56510037SARM gem5 Developers EventFunctionWrapper activateEvent; 56610037SARM gem5 Developers 56710037SARM gem5 Developers void processPrechargeEvent(); 56810037SARM gem5 Developers EventFunctionWrapper prechargeEvent; 56910037SARM gem5 Developers 57010037SARM gem5 Developers void processRefreshEvent(); 57110037SARM gem5 Developers EventFunctionWrapper refreshEvent; 57210037SARM gem5 Developers 57310037SARM gem5 Developers void processPowerEvent(); 57410037SARM gem5 Developers EventFunctionWrapper powerEvent; 57510037SARM gem5 Developers 57610037SARM gem5 Developers void processWakeUpEvent(); 57710037SARM gem5 Developers EventFunctionWrapper wakeUpEvent; 57810037SARM gem5 Developers 57910037SARM gem5 Developers }; 58010037SARM gem5 Developers 58110037SARM gem5 Developers /** 58210037SARM gem5 Developers * Define the process to compute stats on a stats dump event, e.g. on 58310037SARM gem5 Developers * simulation exit or intermediate stats dump. This is defined per rank 58410037SARM gem5 Developers * as the per rank stats are based on state transition and periodically 58510037SARM gem5 Developers * updated, requiring re-sync at exit. 58610037SARM gem5 Developers */ 58710037SARM gem5 Developers class RankDumpCallback : public Callback 58810037SARM gem5 Developers { 58910037SARM gem5 Developers Rank *ranks; 59010037SARM gem5 Developers public: 59110037SARM gem5 Developers RankDumpCallback(Rank *r) : ranks(r) {} 59210037SARM gem5 Developers virtual void process() { ranks->computeStats(); }; 59310037SARM gem5 Developers }; 59410037SARM gem5 Developers 59510037SARM gem5 Developers /** Define a process to clear power lib counters on a stats reset */ 59610037SARM gem5 Developers class RankResetCallback : public Callback 59710037SARM gem5 Developers { 59810037SARM gem5 Developers private: 59910037SARM gem5 Developers /** Pointer to the rank, thus we instantiate per rank */ 60010037SARM gem5 Developers Rank *rank; 60110037SARM gem5 Developers 60210037SARM gem5 Developers public: 60310037SARM gem5 Developers RankResetCallback(Rank *r) : rank(r) {} 60410037SARM gem5 Developers virtual void process() { rank->resetStats(); }; 60510037SARM gem5 Developers }; 60610037SARM gem5 Developers 60710037SARM gem5 Developers /** Define a process to store the time on a stats reset */ 60810037SARM gem5 Developers class MemResetCallback : public Callback 60910037SARM gem5 Developers { 61010037SARM gem5 Developers private: 61110037SARM gem5 Developers /** A reference to the DRAMCtrl instance */ 61210037SARM gem5 Developers DRAMCtrl *mem; 61310037SARM gem5 Developers 61410037SARM gem5 Developers public: 61510037SARM gem5 Developers MemResetCallback(DRAMCtrl *_mem) : mem(_mem) {} 61610037SARM gem5 Developers virtual void process() { mem->lastStatsResetTick = curTick(); }; 61710037SARM gem5 Developers }; 61810037SARM gem5 Developers 61910037SARM gem5 Developers /** 62010037SARM gem5 Developers * A burst helper helps organize and manage a packet that is larger than 62110037SARM gem5 Developers * the DRAM burst size. A system packet that is larger than the burst size 62210037SARM gem5 Developers * is split into multiple DRAM packets and all those DRAM packets point to 62310037SARM gem5 Developers * a single burst helper such that we know when the whole packet is served. 62410037SARM gem5 Developers */ 62510037SARM gem5 Developers class BurstHelper { 62610037SARM gem5 Developers 62710037SARM gem5 Developers public: 62810037SARM gem5 Developers 62910037SARM gem5 Developers /** Number of DRAM bursts requred for a system packet **/ 63010037SARM gem5 Developers const unsigned int burstCount; 63110037SARM gem5 Developers 63210037SARM gem5 Developers /** Number of DRAM bursts serviced so far for a system packet **/ 63310037SARM gem5 Developers unsigned int burstsServiced; 63410037SARM gem5 Developers 63510037SARM gem5 Developers BurstHelper(unsigned int _burstCount) 63610037SARM gem5 Developers : burstCount(_burstCount), burstsServiced(0) 63710037SARM gem5 Developers { } 63810037SARM gem5 Developers }; 63910037SARM gem5 Developers 64010037SARM gem5 Developers /** 64110037SARM gem5 Developers * A DRAM packet stores packets along with the timestamp of when 64210037SARM gem5 Developers * the packet entered the queue, and also the decoded address. 64310037SARM gem5 Developers */ 64410037SARM gem5 Developers class DRAMPacket { 64510037SARM gem5 Developers 64610037SARM gem5 Developers public: 64710037SARM gem5 Developers 64810037SARM gem5 Developers /** When did request enter the controller */ 64910037SARM gem5 Developers const Tick entryTime; 65010037SARM gem5 Developers 65110037SARM gem5 Developers /** When will request leave the controller */ 65210037SARM gem5 Developers Tick readyTime; 65310037SARM gem5 Developers 65410037SARM gem5 Developers /** This comes from the outside world */ 65510037SARM gem5 Developers const PacketPtr pkt; 65610037SARM gem5 Developers 65710037SARM gem5 Developers const bool isRead; 65810037SARM gem5 Developers 65910037SARM gem5 Developers /** Will be populated by address decoder */ 66010037SARM gem5 Developers const uint8_t rank; 66110037SARM gem5 Developers const uint8_t bank; 66210037SARM gem5 Developers const uint32_t row; 66310037SARM gem5 Developers 66410037SARM gem5 Developers /** 66510037SARM gem5 Developers * Bank id is calculated considering banks in all the ranks 66610037SARM gem5 Developers * eg: 2 ranks each with 8 banks, then bankId = 0 --> rank0, bank0 and 66710037SARM gem5 Developers * bankId = 8 --> rank1, bank0 66810037SARM gem5 Developers */ 66910037SARM gem5 Developers const uint16_t bankId; 67010037SARM gem5 Developers 67110037SARM gem5 Developers /** 67210037SARM gem5 Developers * The starting address of the DRAM packet. 67310037SARM gem5 Developers * This address could be unaligned to burst size boundaries. The 67410037SARM gem5 Developers * reason is to keep the address offset so we can accurately check 67510037SARM gem5 Developers * incoming read packets with packets in the write queue. 67610037SARM gem5 Developers */ 67710037SARM gem5 Developers Addr addr; 67810037SARM gem5 Developers 67910037SARM gem5 Developers /** 68010037SARM gem5 Developers * The size of this dram packet in bytes 68110037SARM gem5 Developers * It is always equal or smaller than DRAM burst size 68210037SARM gem5 Developers */ 68310037SARM gem5 Developers unsigned int size; 68410037SARM gem5 Developers 68510037SARM gem5 Developers /** 68610037SARM gem5 Developers * A pointer to the BurstHelper if this DRAMPacket is a split packet 68710037SARM gem5 Developers * If not a split packet (common case), this is set to NULL 68810037SARM gem5 Developers */ 68910037SARM gem5 Developers BurstHelper* burstHelper; 69010037SARM gem5 Developers Bank& bankRef; 69110037SARM gem5 Developers Rank& rankRef; 69210037SARM gem5 Developers 69310037SARM gem5 Developers DRAMPacket(PacketPtr _pkt, bool is_read, uint8_t _rank, uint8_t _bank, 69410037SARM gem5 Developers uint32_t _row, uint16_t bank_id, Addr _addr, 69510037SARM gem5 Developers unsigned int _size, Bank& bank_ref, Rank& rank_ref) 69610037SARM gem5 Developers : entryTime(curTick()), readyTime(curTick()), 69710037SARM gem5 Developers pkt(_pkt), isRead(is_read), rank(_rank), bank(_bank), row(_row), 69810037SARM gem5 Developers bankId(bank_id), addr(_addr), size(_size), burstHelper(NULL), 69910037SARM gem5 Developers bankRef(bank_ref), rankRef(rank_ref) 70010037SARM gem5 Developers { } 70110037SARM gem5 Developers 70210037SARM gem5 Developers }; 70310037SARM gem5 Developers 70410037SARM gem5 Developers /** 70510037SARM gem5 Developers * Bunch of things requires to setup "events" in gem5 70610037SARM gem5 Developers * When event "respondEvent" occurs for example, the method 70710037SARM gem5 Developers * processRespondEvent is called; no parameters are allowed 70810037SARM gem5 Developers * in these methods 70910037SARM gem5 Developers */ 71010037SARM gem5 Developers void processNextReqEvent(); 71110037SARM gem5 Developers EventFunctionWrapper nextReqEvent; 71210037SARM gem5 Developers 71310037SARM gem5 Developers void processRespondEvent(); 71410037SARM gem5 Developers EventFunctionWrapper respondEvent; 71510037SARM gem5 Developers 71610037SARM gem5 Developers /** 71710037SARM gem5 Developers * Check if the read queue has room for more entries 71810037SARM gem5 Developers * 71910037SARM gem5 Developers * @param pktCount The number of entries needed in the read queue 72010037SARM gem5 Developers * @return true if read queue is full, false otherwise 72110037SARM gem5 Developers */ 72210037SARM gem5 Developers bool readQueueFull(unsigned int pktCount) const; 72310037SARM gem5 Developers 72410037SARM gem5 Developers /** 72510037SARM gem5 Developers * Check if the write queue has room for more entries 72610037SARM gem5 Developers * 72710037SARM gem5 Developers * @param pktCount The number of entries needed in the write queue 72810037SARM gem5 Developers * @return true if write queue is full, false otherwise 72910037SARM gem5 Developers */ 73010037SARM gem5 Developers bool writeQueueFull(unsigned int pktCount) const; 73110037SARM gem5 Developers 73210037SARM gem5 Developers /** 73310037SARM gem5 Developers * When a new read comes in, first check if the write q has a 73410037SARM gem5 Developers * pending request to the same address.\ If not, decode the 73510037SARM gem5 Developers * address to populate rank/bank/row, create one or mutliple 73610037SARM gem5 Developers * "dram_pkt", and push them to the back of the read queue.\ 73710037SARM gem5 Developers * If this is the only 73810037SARM gem5 Developers * read request in the system, schedule an event to start 73910037SARM gem5 Developers * servicing it. 74010037SARM gem5 Developers * 74110037SARM gem5 Developers * @param pkt The request packet from the outside world 74210037SARM gem5 Developers * @param pktCount The number of DRAM bursts the pkt 74310037SARM gem5 Developers * translate to. If pkt size is larger then one full burst, 74410037SARM gem5 Developers * then pktCount is greater than one. 74510037SARM gem5 Developers */ 74610037SARM gem5 Developers void addToReadQueue(PacketPtr pkt, unsigned int pktCount); 74710037SARM gem5 Developers 74810037SARM gem5 Developers /** 74910037SARM gem5 Developers * Decode the incoming pkt, create a dram_pkt and push to the 75010037SARM gem5 Developers * back of the write queue. \If the write q length is more than 75110037SARM gem5 Developers * the threshold specified by the user, ie the queue is beginning 75210037SARM gem5 Developers * to get full, stop reads, and start draining writes. 75310037SARM gem5 Developers * 75410037SARM gem5 Developers * @param pkt The request packet from the outside world 75510037SARM gem5 Developers * @param pktCount The number of DRAM bursts the pkt 75610037SARM gem5 Developers * translate to. If pkt size is larger then one full burst, 75710037SARM gem5 Developers * then pktCount is greater than one. 75810037SARM gem5 Developers */ 75910037SARM gem5 Developers void addToWriteQueue(PacketPtr pkt, unsigned int pktCount); 76010037SARM gem5 Developers 76110037SARM gem5 Developers /** 76210037SARM gem5 Developers * Actually do the DRAM access - figure out the latency it 76310037SARM gem5 Developers * will take to service the req based on bank state, channel state etc 76410037SARM gem5 Developers * and then update those states to account for this request.\ Based 76510037SARM gem5 Developers * on this, update the packet's "readyTime" and move it to the 76610037SARM gem5 Developers * response q from where it will eventually go back to the outside 76710037SARM gem5 Developers * world. 76810037SARM gem5 Developers * 76910037SARM gem5 Developers * @param pkt The DRAM packet created from the outside world pkt 77010037SARM gem5 Developers */ 77110037SARM gem5 Developers void doDRAMAccess(DRAMPacket* dram_pkt); 77210037SARM gem5 Developers 77310037SARM gem5 Developers /** 77410037SARM gem5 Developers * When a packet reaches its "readyTime" in the response Q, 77510037SARM gem5 Developers * use the "access()" method in AbstractMemory to actually 77610037SARM gem5 Developers * create the response packet, and send it back to the outside 77710037SARM gem5 Developers * world requestor. 77810037SARM gem5 Developers * 77910037SARM gem5 Developers * @param pkt The packet from the outside world 78010037SARM gem5 Developers * @param static_latency Static latency to add before sending the packet 78110037SARM gem5 Developers */ 78210037SARM gem5 Developers void accessAndRespond(PacketPtr pkt, Tick static_latency); 78310037SARM gem5 Developers 78410037SARM gem5 Developers /** 78510037SARM gem5 Developers * Address decoder to figure out physical mapping onto ranks, 78610037SARM gem5 Developers * banks, and rows. This function is called multiple times on the same 78710037SARM gem5 Developers * system packet if the pakcet is larger than burst of the memory. The 78810037SARM gem5 Developers * dramPktAddr is used for the offset within the packet. 78910037SARM gem5 Developers * 79010037SARM gem5 Developers * @param pkt The packet from the outside world 79110037SARM gem5 Developers * @param dramPktAddr The starting address of the DRAM packet 79210037SARM gem5 Developers * @param size The size of the DRAM packet in bytes 79310037SARM gem5 Developers * @param isRead Is the request for a read or a write to DRAM 79410037SARM gem5 Developers * @return A DRAMPacket pointer with the decoded information 79510037SARM gem5 Developers */ 79610037SARM gem5 Developers DRAMPacket* decodeAddr(PacketPtr pkt, Addr dramPktAddr, unsigned int size, 79710037SARM gem5 Developers bool isRead); 79810037SARM gem5 Developers 79910037SARM gem5 Developers /** 80010037SARM gem5 Developers * The memory schduler/arbiter - picks which request needs to 80110037SARM gem5 Developers * go next, based on the specified policy such as FCFS or FR-FCFS 80210037SARM gem5 Developers * and moves it to the head of the queue. 80310037SARM gem5 Developers * Prioritizes accesses to the same rank as previous burst unless 80410037SARM gem5 Developers * controller is switching command type. 80510037SARM gem5 Developers * 80610037SARM gem5 Developers * @param queue Queued requests to consider 80710037SARM gem5 Developers * @param extra_col_delay Any extra delay due to a read/write switch 80810037SARM gem5 Developers * @return true if a packet is scheduled to a rank which is available else 80910037SARM gem5 Developers * false 81010037SARM gem5 Developers */ 81110037SARM gem5 Developers bool chooseNext(std::deque<DRAMPacket*>& queue, Tick extra_col_delay); 81210037SARM gem5 Developers 81310037SARM gem5 Developers /** 81410037SARM gem5 Developers * For FR-FCFS policy reorder the read/write queue depending on row buffer 81510037SARM gem5 Developers * hits and earliest bursts available in DRAM 81610037SARM gem5 Developers * 81710037SARM gem5 Developers * @param queue Queued requests to consider 81810037SARM gem5 Developers * @param extra_col_delay Any extra delay due to a read/write switch 81910037SARM gem5 Developers * @return true if a packet is scheduled to a rank which is available else 82010037SARM gem5 Developers * false 82110037SARM gem5 Developers */ 82210037SARM gem5 Developers bool reorderQueue(std::deque<DRAMPacket*>& queue, Tick extra_col_delay); 82310037SARM gem5 Developers 82410037SARM gem5 Developers /** 82510037SARM gem5 Developers * Find which are the earliest banks ready to issue an activate 82610037SARM gem5 Developers * for the enqueued requests. Assumes maximum of 64 banks per DIMM 82710037SARM gem5 Developers * Also checks if the bank is already prepped. 82810037SARM gem5 Developers * 82910037SARM gem5 Developers * @param queue Queued requests to consider 83010037SARM gem5 Developers * @param time of seamless burst command 83110037SARM gem5 Developers * @return One-hot encoded mask of bank indices 83210037SARM gem5 Developers * @return boolean indicating burst can issue seamlessly, with no gaps 83310037SARM gem5 Developers */ 83410037SARM gem5 Developers std::pair<uint64_t, bool> minBankPrep(const std::deque<DRAMPacket*>& queue, 83510037SARM gem5 Developers Tick min_col_at) const; 83610037SARM gem5 Developers 83710037SARM gem5 Developers /** 83810037SARM gem5 Developers * Keep track of when row activations happen, in order to enforce 83910037SARM gem5 Developers * the maximum number of activations in the activation window. The 84010037SARM gem5 Developers * method updates the time that the banks become available based 84110037SARM gem5 Developers * on the current limits. 84210037SARM gem5 Developers * 84310037SARM gem5 Developers * @param rank_ref Reference to the rank 84410037SARM gem5 Developers * @param bank_ref Reference to the bank 84510037SARM gem5 Developers * @param act_tick Time when the activation takes place 84610037SARM gem5 Developers * @param row Index of the row 84710037SARM gem5 Developers */ 84810037SARM gem5 Developers void activateBank(Rank& rank_ref, Bank& bank_ref, Tick act_tick, 84910037SARM gem5 Developers uint32_t row); 85010037SARM gem5 Developers 85110037SARM gem5 Developers /** 85210037SARM gem5 Developers * Precharge a given bank and also update when the precharge is 85310037SARM gem5 Developers * done. This will also deal with any stats related to the 85410037SARM gem5 Developers * accesses to the open page. 85510037SARM gem5 Developers * 85610037SARM gem5 Developers * @param rank_ref The rank to precharge 85710037SARM gem5 Developers * @param bank_ref The bank to precharge 85810037SARM gem5 Developers * @param pre_at Time when the precharge takes place 85910037SARM gem5 Developers * @param trace Is this an auto precharge then do not add to trace 86010037SARM gem5 Developers */ 86110037SARM gem5 Developers void prechargeBank(Rank& rank_ref, Bank& bank_ref, 86210037SARM gem5 Developers Tick pre_at, bool trace = true); 86310037SARM gem5 Developers 86410037SARM gem5 Developers /** 86510037SARM gem5 Developers * Used for debugging to observe the contents of the queues. 86610037SARM gem5 Developers */ 86710037SARM gem5 Developers void printQs() const; 86810037SARM gem5 Developers 86910037SARM gem5 Developers /** 87010037SARM gem5 Developers * Burst-align an address. 87110037SARM gem5 Developers * 87210037SARM gem5 Developers * @param addr The potentially unaligned address 87310037SARM gem5 Developers * 87410037SARM gem5 Developers * @return An address aligned to a DRAM burst 87510037SARM gem5 Developers */ 87610037SARM gem5 Developers Addr burstAlign(Addr addr) const { return (addr & ~(Addr(burstSize - 1))); } 87710037SARM gem5 Developers 87810037SARM gem5 Developers /** 87910037SARM gem5 Developers * The controller's main read and write queues 88010037SARM gem5 Developers */ 88110037SARM gem5 Developers std::deque<DRAMPacket*> readQueue; 88210037SARM gem5 Developers std::deque<DRAMPacket*> writeQueue; 88310037SARM gem5 Developers 88410037SARM gem5 Developers /** 88510037SARM gem5 Developers * To avoid iterating over the write queue to check for 88610037SARM gem5 Developers * overlapping transactions, maintain a set of burst addresses 88710037SARM gem5 Developers * that are currently queued. Since we merge writes to the same 88810037SARM gem5 Developers * location we never have more than one address to the same burst 88910037SARM gem5 Developers * address. 89010037SARM gem5 Developers */ 89110037SARM gem5 Developers std::unordered_set<Addr> isInWriteQueue; 89210037SARM gem5 Developers 89310037SARM gem5 Developers /** 89410037SARM gem5 Developers * Response queue where read packets wait after we're done working 89510037SARM gem5 Developers * with them, but it's not time to send the response yet. The 89610037SARM gem5 Developers * responses are stored seperately mostly to keep the code clean 89710037SARM gem5 Developers * and help with events scheduling. For all logical purposes such 89810037SARM gem5 Developers * as sizing the read queue, this and the main read queue need to 89910037SARM gem5 Developers * be added together. 90010037SARM gem5 Developers */ 90110037SARM gem5 Developers std::deque<DRAMPacket*> respQueue; 90210037SARM gem5 Developers 90310037SARM gem5 Developers /** 90410037SARM gem5 Developers * Vector of ranks 90510037SARM gem5 Developers */ 90610037SARM gem5 Developers std::vector<Rank*> ranks; 90710037SARM gem5 Developers 90810037SARM gem5 Developers /** 90910037SARM gem5 Developers * The following are basic design parameters of the memory 91010037SARM gem5 Developers * controller, and are initialized based on parameter values. 91110037SARM gem5 Developers * The rowsPerBank is determined based on the capacity, number of 91210037SARM gem5 Developers * ranks and banks, the burst size, and the row buffer size. 91310037SARM gem5 Developers */ 91410037SARM gem5 Developers const uint32_t deviceSize; 91510037SARM gem5 Developers const uint32_t deviceBusWidth; 91610037SARM gem5 Developers const uint32_t burstLength; 91710037SARM gem5 Developers const uint32_t deviceRowBufferSize; 91810037SARM gem5 Developers const uint32_t devicesPerRank; 91910037SARM gem5 Developers const uint32_t burstSize; 92010037SARM gem5 Developers const uint32_t rowBufferSize; 92110037SARM gem5 Developers const uint32_t columnsPerRowBuffer; 92210037SARM gem5 Developers const uint32_t columnsPerStripe; 92310037SARM gem5 Developers const uint32_t ranksPerChannel; 92410037SARM gem5 Developers const uint32_t bankGroupsPerRank; 92510037SARM gem5 Developers const bool bankGroupArch; 92610037SARM gem5 Developers const uint32_t banksPerRank; 92710037SARM gem5 Developers const uint32_t channels; 92810037SARM gem5 Developers uint32_t rowsPerBank; 92910037SARM gem5 Developers const uint32_t readBufferSize; 93010037SARM gem5 Developers const uint32_t writeBufferSize; 93110037SARM gem5 Developers const uint32_t writeHighThreshold; 93210037SARM gem5 Developers const uint32_t writeLowThreshold; 93310037SARM gem5 Developers const uint32_t minWritesPerSwitch; 93410037SARM gem5 Developers uint32_t writesThisTime; 93510037SARM gem5 Developers uint32_t readsThisTime; 93610037SARM gem5 Developers 93710037SARM gem5 Developers /** 93810037SARM gem5 Developers * Basic memory timing parameters initialized based on parameter 93910037SARM gem5 Developers * values. 94010037SARM gem5 Developers */ 94110037SARM gem5 Developers const Tick M5_CLASS_VAR_USED tCK; 94210037SARM gem5 Developers const Tick tWTR; 94310037SARM gem5 Developers const Tick tRTW; 94410037SARM gem5 Developers const Tick tCS; 94510037SARM gem5 Developers const Tick tBURST; 94610037SARM gem5 Developers const Tick tCCD_L; 94710037SARM gem5 Developers const Tick tRCD; 94810037SARM gem5 Developers const Tick tCL; 94910037SARM gem5 Developers const Tick tRP; 95010037SARM gem5 Developers const Tick tRAS; 95110037SARM gem5 Developers const Tick tWR; 95210037SARM gem5 Developers const Tick tRTP; 95310037SARM gem5 Developers const Tick tRFC; 95410037SARM gem5 Developers const Tick tREFI; 95510037SARM gem5 Developers const Tick tRRD; 95610037SARM gem5 Developers const Tick tRRD_L; 95710037SARM gem5 Developers const Tick tXAW; 95810037SARM gem5 Developers const Tick tXP; 95910037SARM gem5 Developers const Tick tXS; 96010037SARM gem5 Developers const uint32_t activationLimit; 96110037SARM gem5 Developers 96210037SARM gem5 Developers /** 96310037SARM gem5 Developers * Memory controller configuration initialized based on parameter 96410037SARM gem5 Developers * values. 96510037SARM gem5 Developers */ 96610037SARM gem5 Developers Enums::MemSched memSchedPolicy; 96710037SARM gem5 Developers Enums::AddrMap addrMapping; 96810037SARM gem5 Developers Enums::PageManage pageMgmt; 96910037SARM gem5 Developers 97010037SARM gem5 Developers /** 97110037SARM gem5 Developers * Max column accesses (read and write) per row, before forefully 97210037SARM gem5 Developers * closing it. 97310037SARM gem5 Developers */ 97410037SARM gem5 Developers const uint32_t maxAccessesPerRow; 97510037SARM gem5 Developers 97610037SARM gem5 Developers /** 97710037SARM gem5 Developers * Pipeline latency of the controller frontend. The frontend 97810037SARM gem5 Developers * contribution is added to writes (that complete when they are in 97910037SARM gem5 Developers * the write buffer) and reads that are serviced the write buffer. 98010037SARM gem5 Developers */ 98110037SARM gem5 Developers const Tick frontendLatency; 98210037SARM gem5 Developers 98310037SARM gem5 Developers /** 98410037SARM gem5 Developers * Pipeline latency of the backend and PHY. Along with the 98510037SARM gem5 Developers * frontend contribution, this latency is added to reads serviced 98610037SARM gem5 Developers * by the DRAM. 98710037SARM gem5 Developers */ 98810037SARM gem5 Developers const Tick backendLatency; 98910037SARM gem5 Developers 99010037SARM gem5 Developers /** 99110037SARM gem5 Developers * Till when has the main data bus been spoken for already? 99210037SARM gem5 Developers */ 99310037SARM gem5 Developers Tick busBusyUntil; 99410037SARM gem5 Developers 99510037SARM gem5 Developers Tick prevArrival; 99610037SARM gem5 Developers 99710037SARM gem5 Developers /** 99810037SARM gem5 Developers * The soonest you have to start thinking about the next request 99910037SARM gem5 Developers * is the longest access time that can occur before 100010037SARM gem5 Developers * busBusyUntil. Assuming you need to precharge, open a new row, 100110037SARM gem5 Developers * and access, it is tRP + tRCD + tCL. 100210037SARM gem5 Developers */ 100310037SARM gem5 Developers Tick nextReqTime; 100410037SARM gem5 Developers 100510037SARM gem5 Developers // All statistics that the model needs to capture 100610037SARM gem5 Developers Stats::Scalar readReqs; 100710037SARM gem5 Developers Stats::Scalar writeReqs; 100810037SARM gem5 Developers Stats::Scalar readBursts; 100910037SARM gem5 Developers Stats::Scalar writeBursts; 101010037SARM gem5 Developers Stats::Scalar bytesReadDRAM; 101110037SARM gem5 Developers Stats::Scalar bytesReadWrQ; 101210037SARM gem5 Developers Stats::Scalar bytesWritten; 101310037SARM gem5 Developers Stats::Scalar bytesReadSys; 101410037SARM gem5 Developers Stats::Scalar bytesWrittenSys; 101510037SARM gem5 Developers Stats::Scalar servicedByWrQ; 101610037SARM gem5 Developers Stats::Scalar mergedWrBursts; 101710037SARM gem5 Developers Stats::Scalar neitherReadNorWrite; 101810037SARM gem5 Developers Stats::Vector perBankRdBursts; 101910037SARM gem5 Developers Stats::Vector perBankWrBursts; 102010037SARM gem5 Developers Stats::Scalar numRdRetry; 102110037SARM gem5 Developers Stats::Scalar numWrRetry; 102210037SARM gem5 Developers Stats::Scalar totGap; 102310037SARM gem5 Developers Stats::Vector readPktSize; 102410037SARM gem5 Developers Stats::Vector writePktSize; 102510037SARM gem5 Developers Stats::Vector rdQLenPdf; 102610037SARM gem5 Developers Stats::Vector wrQLenPdf; 102710037SARM gem5 Developers Stats::Histogram bytesPerActivate; 102810037SARM gem5 Developers Stats::Histogram rdPerTurnAround; 102910037SARM gem5 Developers Stats::Histogram wrPerTurnAround; 103010037SARM gem5 Developers 103110037SARM gem5 Developers // Latencies summed over all requests 103210037SARM gem5 Developers Stats::Scalar totQLat; 103310037SARM gem5 Developers Stats::Scalar totMemAccLat; 103410037SARM gem5 Developers Stats::Scalar totBusLat; 103510037SARM gem5 Developers 103610037SARM gem5 Developers // Average latencies per request 103710037SARM gem5 Developers Stats::Formula avgQLat; 103810037SARM gem5 Developers Stats::Formula avgBusLat; 103910037SARM gem5 Developers Stats::Formula avgMemAccLat; 104010037SARM gem5 Developers 104110037SARM gem5 Developers // Average bandwidth 104210037SARM gem5 Developers Stats::Formula avgRdBW; 104310037SARM gem5 Developers Stats::Formula avgWrBW; 104410037SARM gem5 Developers Stats::Formula avgRdBWSys; 104510037SARM gem5 Developers Stats::Formula avgWrBWSys; 104610037SARM gem5 Developers Stats::Formula peakBW; 104710037SARM gem5 Developers Stats::Formula busUtil; 104810037SARM gem5 Developers Stats::Formula busUtilRead; 104910037SARM gem5 Developers Stats::Formula busUtilWrite; 105010037SARM gem5 Developers 105110037SARM gem5 Developers // Average queue lengths 105210337SAndrew.Bardsley@arm.com Stats::Average avgRdQLen; 105310037SARM gem5 Developers Stats::Average avgWrQLen; 105410037SARM gem5 Developers 105510037SARM gem5 Developers // Row hit count and rate 105610037SARM gem5 Developers Stats::Scalar readRowHits; 105710037SARM gem5 Developers Stats::Scalar writeRowHits; 105810337SAndrew.Bardsley@arm.com Stats::Formula readRowHitRate; 105910037SARM gem5 Developers Stats::Formula writeRowHitRate; 106010337SAndrew.Bardsley@arm.com Stats::Formula avgGap; 106110037SARM gem5 Developers 106210337SAndrew.Bardsley@arm.com // DRAM Power Calculation 106310037SARM gem5 Developers Stats::Formula pageHitRate; 106410337SAndrew.Bardsley@arm.com 106510037SARM gem5 Developers // Holds the value of the rank of burst issued 106610337SAndrew.Bardsley@arm.com uint8_t activeRank; 106710037SARM gem5 Developers 106810337SAndrew.Bardsley@arm.com // timestamp offset 106910037SARM gem5 Developers uint64_t timeStampOffset; 107010337SAndrew.Bardsley@arm.com 107110037SARM gem5 Developers /** The time when stats were last reset used to calculate average power */ 107210337SAndrew.Bardsley@arm.com Tick lastStatsResetTick; 107310037SARM gem5 Developers 107410037SARM gem5 Developers /** 107510037SARM gem5 Developers * Upstream caches need this packet until true is returned, so 107610037SARM gem5 Developers * hold it for deletion until a subsequent call 107710037SARM gem5 Developers */ 107810037SARM gem5 Developers std::unique_ptr<Packet> pendingDelete; 107910037SARM gem5 Developers 108010037SARM gem5 Developers /** 108110037SARM gem5 Developers * This function increments the energy when called. If stats are 108210037SARM gem5 Developers * dumped periodically, note accumulated energy values will 108310037SARM gem5 Developers * appear in the stats (even if the stats are reset). This is a 108410037SARM gem5 Developers * result of the energy values coming from DRAMPower, and there 108510037SARM gem5 Developers * is currently no support for resetting the state. 108610037SARM gem5 Developers * 108710337SAndrew.Bardsley@arm.com * @param rank Currrent rank 108810037SARM gem5 Developers */ 108910037SARM gem5 Developers void updatePowerStats(Rank& rank_ref); 109010037SARM gem5 Developers 109110037SARM gem5 Developers /** 109210337SAndrew.Bardsley@arm.com * Function for sorting Command structures based on timeStamp 109310037SARM gem5 Developers * 109410337SAndrew.Bardsley@arm.com * @param a Memory Command 109510037SARM gem5 Developers * @param next Memory Command 109610337SAndrew.Bardsley@arm.com * @return true if timeStamp of Command 1 < timeStamp of Command 2 109710037SARM gem5 Developers */ 109810337SAndrew.Bardsley@arm.com static bool sortTime(const Command& cmd, const Command& cmd_next) { 109910037SARM gem5 Developers return cmd.timeStamp < cmd_next.timeStamp; 110010037SARM gem5 Developers }; 110110037SARM gem5 Developers 110210037SARM gem5 Developers public: 110310037SARM gem5 Developers 110410037SARM gem5 Developers void regStats() override; 110510037SARM gem5 Developers 110610037SARM gem5 Developers DRAMCtrl(const DRAMCtrlParams* p); 110710037SARM gem5 Developers 110810337SAndrew.Bardsley@arm.com DrainState drain() override; 110910037SARM gem5 Developers 111010037SARM gem5 Developers virtual BaseSlavePort& getSlavePort(const std::string& if_name, 111110037SARM gem5 Developers PortID idx = InvalidPortID) override; 111210037SARM gem5 Developers 111310037SARM gem5 Developers virtual void init() override; 111410037SARM gem5 Developers virtual void startup() override; 111510037SARM gem5 Developers virtual void drainResume() override; 111610037SARM gem5 Developers 111710337SAndrew.Bardsley@arm.com /** 111810037SARM gem5 Developers * Return true once refresh is complete for all ranks and there are no 111910037SARM gem5 Developers * additional commands enqueued. (only evaluated when draining) 112010037SARM gem5 Developers * This will ensure that all banks are closed, power state is IDLE, and 112110337SAndrew.Bardsley@arm.com * power stats have been updated 112210037SARM gem5 Developers * 112310037SARM gem5 Developers * @return true if all ranks have refreshed, with no commands enqueued 112410037SARM gem5 Developers * 112510037SARM gem5 Developers */ 112610037SARM gem5 Developers bool allRanksDrained() const; 112710037SARM gem5 Developers 112810037SARM gem5 Developers protected: 112910037SARM gem5 Developers 113010337SAndrew.Bardsley@arm.com Tick recvAtomic(PacketPtr pkt); 113110037SARM gem5 Developers void recvFunctional(PacketPtr pkt); 113210037SARM gem5 Developers bool recvTimingReq(PacketPtr pkt); 113310037SARM gem5 Developers 113410037SARM gem5 Developers}; 113510037SARM gem5 Developers 113610037SARM gem5 Developers#endif //__MEM_DRAM_CTRL_HH__ 113710037SARM gem5 Developers