42a43
> * Omar Naji
53a55
> #include <string>
140,142d141
< /** List to keep track of activate ticks */
< std::vector<std::deque<Tick>> actTicks;
<
160d158
< uint8_t rank;
172c170
< openRow(NO_ROW), rank(0), bank(0), bankgr(0),
---
> openRow(NO_ROW), bank(0), bankgr(0),
177a176
>
178a178,378
> * Rank class includes a vector of banks. Refresh and Power state
> * machines are defined per rank. Events required to change the
> * state of the refresh and power state machine are scheduled per
> * rank. This class allows the implementation of rank-wise refresh
> * and rank-wise power-down.
> */
> class Rank : public EventManager
> {
>
> private:
>
> /**
> * The power state captures the different operational states of
> * the DRAM and interacts with the bus read/write state machine,
> * and the refresh state machine. In the idle state all banks are
> * precharged. From there we either go to an auto refresh (as
> * determined by the refresh state machine), or to a precharge
> * power down mode. From idle the memory can also go to the active
> * state (with one or more banks active), and in turn from there
> * to active power down. At the moment we do not capture the deep
> * power down and self-refresh state.
> */
> enum PowerState {
> PWR_IDLE = 0,
> PWR_REF,
> PWR_PRE_PDN,
> PWR_ACT,
> PWR_ACT_PDN
> };
>
> /**
> * The refresh state is used to control the progress of the
> * refresh scheduling. When normal operation is in progress the
> * refresh state is idle. From there, it progresses to the refresh
> * drain state once tREFI has passed. The refresh drain state
> * captures the DRAM row active state, as it will stay there until
> * all ongoing accesses complete. Thereafter all banks are
> * precharged, and lastly, the DRAM is refreshed.
> */
> enum RefreshState {
> REF_IDLE = 0,
> REF_DRAIN,
> REF_PRE,
> REF_RUN
> };
>
> /**
> * A reference to the parent DRAMCtrl instance
> */
> DRAMCtrl& memory;
>
> /**
> * Since we are taking decisions out of order, we need to keep
> * track of what power transition is happening at what time, such
> * that we can go back in time and change history. For example, if
> * we precharge all banks and schedule going to the idle state, we
> * might at a later point decide to activate a bank before the
> * transition to idle would have taken place.
> */
> PowerState pwrStateTrans;
>
> /**
> * Current power state.
> */
> PowerState pwrState;
>
> /**
> * Track when we transitioned to the current power state
> */
> Tick pwrStateTick;
>
> /**
> * current refresh state
> */
> RefreshState refreshState;
>
> /**
> * Keep track of when a refresh is due.
> */
> Tick refreshDueAt;
>
> /*
> * Command energies
> */
> Stats::Scalar actEnergy;
> Stats::Scalar preEnergy;
> Stats::Scalar readEnergy;
> Stats::Scalar writeEnergy;
> Stats::Scalar refreshEnergy;
>
> /*
> * Active Background Energy
> */
> Stats::Scalar actBackEnergy;
>
> /*
> * Precharge Background Energy
> */
> Stats::Scalar preBackEnergy;
>
> Stats::Scalar totalEnergy;
> Stats::Scalar averagePower;
>
> /**
> * Track time spent in each power state.
> */
> Stats::Vector pwrStateTime;
>
> /**
> * Function to update Power Stats
> */
> void updatePowerStats();
>
> /**
> * Schedule a power state transition in the future, and
> * potentially override an already scheduled transition.
> *
> * @param pwr_state Power state to transition to
> * @param tick Tick when transition should take place
> */
> void schedulePowerEvent(PowerState pwr_state, Tick tick);
>
> public:
>
> /**
> * Current Rank index
> */
> uint8_t rank;
>
> /**
> * One DRAMPower instance per rank
> */
> DRAMPower power;
>
> /**
> * Vector of Banks. Each rank is made of several devices which in
> * term are made from several banks.
> */
> std::vector<Bank> banks;
>
> /**
> * To track number of banks which are currently active for
> * this rank.
> */
> unsigned int numBanksActive;
>
> /** List to keep track of activate ticks */
> std::deque<Tick> actTicks;
>
> Rank(DRAMCtrl& _memory, const DRAMCtrlParams* _p);
>
> const std::string name() const
> {
> return csprintf("%s_%d", memory.name(), rank);
> }
>
> /**
> * Kick off accounting for power and refresh states and
> * schedule initial refresh.
> *
> * @param ref_tick Tick for first refresh
> */
> void startup(Tick ref_tick);
>
> /**
> * Check if the current rank is available for scheduling.
> *
> * @param Return true if the rank is idle from a refresh point of view
> */
> bool isAvailable() const { return refreshState == REF_IDLE; }
>
> /**
> * Let the rank check if it was waiting for requests to drain
> * to allow it to transition states.
> */
> void checkDrainDone();
>
> /*
> * Function to register Stats
> */
> void regStats();
>
> void processActivateEvent();
> EventWrapper<Rank, &Rank::processActivateEvent>
> activateEvent;
>
> void processPrechargeEvent();
> EventWrapper<Rank, &Rank::processPrechargeEvent>
> prechargeEvent;
>
> void processRefreshEvent();
> EventWrapper<Rank, &Rank::processRefreshEvent>
> refreshEvent;
>
> void processPowerEvent();
> EventWrapper<Rank, &Rank::processPowerEvent>
> powerEvent;
>
> };
>
> /**
196c396
< { }
---
> { }
249a450
> Rank& rankRef;
253c454
< unsigned int _size, Bank& bank_ref)
---
> unsigned int _size, Bank& bank_ref, Rank& rank_ref)
257c458
< bankRef(bank_ref)
---
> bankRef(bank_ref), rankRef(rank_ref)
274,285d474
< void processActivateEvent();
< EventWrapper<DRAMCtrl, &DRAMCtrl::processActivateEvent> activateEvent;
<
< void processPrechargeEvent();
< EventWrapper<DRAMCtrl, &DRAMCtrl::processPrechargeEvent> prechargeEvent;
<
< void processRefreshEvent();
< EventWrapper<DRAMCtrl, &DRAMCtrl::processRefreshEvent> refreshEvent;
<
< void processPowerEvent();
< EventWrapper<DRAMCtrl,&DRAMCtrl::processPowerEvent> powerEvent;
<
377a567,568
> * @return true if a packet is scheduled to a rank which is available else
> * false
379c570
< void chooseNext(std::deque<DRAMPacket*>& queue, bool switched_cmd_type);
---
> bool chooseNext(std::deque<DRAMPacket*>& queue, bool switched_cmd_type);
388a580,581
> * @return true if a packet is scheduled to a rank which is available else
> * false
390c583
< void reorderQueue(std::deque<DRAMPacket*>& queue, bool switched_cmd_type);
---
> bool reorderQueue(std::deque<DRAMPacket*>& queue, bool switched_cmd_type);
410c603,604
< * @param bank Reference to the bank
---
> * @param rank_ref Reference to the rank
> * @param bank_ref Reference to the bank
414c608,609
< void activateBank(Bank& bank, Tick act_tick, uint32_t row);
---
> void activateBank(Rank& rank_ref, Bank& bank_ref, Tick act_tick,
> uint32_t row);
420a616
> * @param rank_ref The rank to precharge
425c621,622
< void prechargeBank(Bank& bank_ref, Tick pre_at, bool trace = true);
---
> void prechargeBank(Rank& rank_ref, Bank& bank_ref,
> Tick pre_at, bool trace = true);
455,456c652
< * Multi-dimensional vector of banks, first dimension is ranks,
< * second is bank
---
> * Vector of ranks
458c654
< std::vector<std::vector<Bank> > banks;
---
> std::vector<Rank*> ranks;
545,610d740
< /**
< * Keep track of when a refresh is due.
< */
< Tick refreshDueAt;
<
< /**
< * The refresh state is used to control the progress of the
< * refresh scheduling. When normal operation is in progress the
< * refresh state is idle. From there, it progresses to the refresh
< * drain state once tREFI has passed. The refresh drain state
< * captures the DRAM row active state, as it will stay there until
< * all ongoing accesses complete. Thereafter all banks are
< * precharged, and lastly, the DRAM is refreshed.
< */
< enum RefreshState {
< REF_IDLE = 0,
< REF_DRAIN,
< REF_PRE,
< REF_RUN
< };
<
< RefreshState refreshState;
<
< /**
< * The power state captures the different operational states of
< * the DRAM and interacts with the bus read/write state machine,
< * and the refresh state machine. In the idle state all banks are
< * precharged. From there we either go to an auto refresh (as
< * determined by the refresh state machine), or to a precharge
< * power down mode. From idle the memory can also go to the active
< * state (with one or more banks active), and in turn from there
< * to active power down. At the moment we do not capture the deep
< * power down and self-refresh state.
< */
< enum PowerState {
< PWR_IDLE = 0,
< PWR_REF,
< PWR_PRE_PDN,
< PWR_ACT,
< PWR_ACT_PDN
< };
<
< /**
< * Since we are taking decisions out of order, we need to keep
< * track of what power transition is happening at what time, such
< * that we can go back in time and change history. For example, if
< * we precharge all banks and schedule going to the idle state, we
< * might at a later point decide to activate a bank before the
< * transition to idle would have taken place.
< */
< PowerState pwrStateTrans;
<
< /**
< * Current power state.
< */
< PowerState pwrState;
<
< /**
< * Schedule a power state transition in the future, and
< * potentially override an already scheduled transition.
< *
< * @param pwr_state Power state to transition to
< * @param tick Tick when transition should take place
< */
< void schedulePowerEvent(PowerState pwr_state, Tick tick);
<
680d809
< Stats::Vector pwrStateTime;
682,701d810
< //Command energies
< Stats::Vector actEnergy;
< Stats::Vector preEnergy;
< Stats::Vector readEnergy;
< Stats::Vector writeEnergy;
< Stats::Vector refreshEnergy;
< //Active Background Energy
< Stats::Vector actBackEnergy;
< //Precharge Background Energy
< Stats::Vector preBackEnergy;
< Stats::Vector totalEnergy;
< //Power Consumed
< Stats::Vector averagePower;
<
< // Track when we transitioned to the current power state
< Tick pwrStateTick;
<
< // To track number of banks which are currently active
< unsigned int numBanksActive;
<
714,716d822
< // One DRAMPower instance per rank
< std::vector<DRAMPower> rankPower;
<
718,726c824,832
< * This function increments the energy when called. If stats are
< * dumped periodically, note accumulated energy values will
< * appear in the stats (even if the stats are reset). This is a
< * result of the energy values coming from DRAMPower, and there
< * is currently no support for resetting the state.
< *
< * @param rank Currrent rank
< */
< void updatePowerStats(uint8_t rank);
---
> * This function increments the energy when called. If stats are
> * dumped periodically, note accumulated energy values will
> * appear in the stats (even if the stats are reset). This is a
> * result of the energy values coming from DRAMPower, and there
> * is currently no support for resetting the state.
> *
> * @param rank Currrent rank
> */
> void updatePowerStats(Rank& rank_ref);