CmdHandlers.cc revision 12266
112266Sradhika.jagtap@arm.com/* 212266Sradhika.jagtap@arm.com * Copyright (c) 2012-2014, TU Delft 312266Sradhika.jagtap@arm.com * Copyright (c) 2012-2014, TU Eindhoven 412266Sradhika.jagtap@arm.com * Copyright (c) 2012-2014, TU Kaiserslautern 512266Sradhika.jagtap@arm.com * All rights reserved. 612266Sradhika.jagtap@arm.com * 712266Sradhika.jagtap@arm.com * Redistribution and use in source and binary forms, with or without 812266Sradhika.jagtap@arm.com * modification, are permitted provided that the following conditions are 912266Sradhika.jagtap@arm.com * met: 1012266Sradhika.jagtap@arm.com * 1112266Sradhika.jagtap@arm.com * 1. Redistributions of source code must retain the above copyright 1212266Sradhika.jagtap@arm.com * notice, this list of conditions and the following disclaimer. 1312266Sradhika.jagtap@arm.com * 1412266Sradhika.jagtap@arm.com * 2. Redistributions in binary form must reproduce the above copyright 1512266Sradhika.jagtap@arm.com * notice, this list of conditions and the following disclaimer in the 1612266Sradhika.jagtap@arm.com * documentation and/or other materials provided with the distribution. 1712266Sradhika.jagtap@arm.com * 1812266Sradhika.jagtap@arm.com * 3. Neither the name of the copyright holder nor the names of its 1912266Sradhika.jagtap@arm.com * contributors may be used to endorse or promote products derived from 2012266Sradhika.jagtap@arm.com * this software without specific prior written permission. 2112266Sradhika.jagtap@arm.com * 2212266Sradhika.jagtap@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 2312266Sradhika.jagtap@arm.com * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2412266Sradhika.jagtap@arm.com * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 2512266Sradhika.jagtap@arm.com * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2612266Sradhika.jagtap@arm.com * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2712266Sradhika.jagtap@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 2812266Sradhika.jagtap@arm.com * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2912266Sradhika.jagtap@arm.com * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3012266Sradhika.jagtap@arm.com * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3112266Sradhika.jagtap@arm.com * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3212266Sradhika.jagtap@arm.com * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3312266Sradhika.jagtap@arm.com * 3412266Sradhika.jagtap@arm.com */ 3512266Sradhika.jagtap@arm.com 3612266Sradhika.jagtap@arm.com#include "CommandAnalysis.h" 3712266Sradhika.jagtap@arm.com 3812266Sradhika.jagtap@arm.comusing std::cerr; 3912266Sradhika.jagtap@arm.comusing std::endl; 4012266Sradhika.jagtap@arm.comusing std::max; 4112266Sradhika.jagtap@arm.com 4212266Sradhika.jagtap@arm.comusing namespace Data; 4312266Sradhika.jagtap@arm.com 4412266Sradhika.jagtap@arm.com 4512266Sradhika.jagtap@arm.comint64_t zero_guard(int64_t cycles_in, const char* warning) 4612266Sradhika.jagtap@arm.com{ 4712266Sradhika.jagtap@arm.com // Calculate max(0, cycles_in) 4812266Sradhika.jagtap@arm.com int64_t zero = 0; 4912266Sradhika.jagtap@arm.com if (warning != nullptr && cycles_in < 0) { 5012266Sradhika.jagtap@arm.com // This line is commented out for now, we will attempt to remove the situations where 5112266Sradhika.jagtap@arm.com // these warnings trigger later. 5212266Sradhika.jagtap@arm.com // cerr << "WARNING: " << warning << endl; 5312266Sradhika.jagtap@arm.com } 5412266Sradhika.jagtap@arm.com return max(zero, cycles_in); 5512266Sradhika.jagtap@arm.com} 5612266Sradhika.jagtap@arm.com 5712266Sradhika.jagtap@arm.comvoid CommandAnalysis::handleAct(unsigned bank, int64_t timestamp) 5812266Sradhika.jagtap@arm.com{ 5912266Sradhika.jagtap@arm.com printWarningIfPoweredDown("Command issued while in power-down mode.", MemCommand::ACT, timestamp, bank); 6012266Sradhika.jagtap@arm.com // If command is ACT - update number of acts, bank state of the 6112266Sradhika.jagtap@arm.com // target bank, first and latest activation cycle and the memory 6212266Sradhika.jagtap@arm.com // state. Update the number of precharged/idle-precharged cycles. 6312266Sradhika.jagtap@arm.com // If the bank is already active ignore the command and generate a 6412266Sradhika.jagtap@arm.com // warning. 6512266Sradhika.jagtap@arm.com if (isPrecharged(bank)) { 6612266Sradhika.jagtap@arm.com numberofactsBanks[bank]++; 6712266Sradhika.jagtap@arm.com 6812266Sradhika.jagtap@arm.com if (nActiveBanks() == 0) { 6912266Sradhika.jagtap@arm.com // Here a memory state transition to ACT is happening. Save the 7012266Sradhika.jagtap@arm.com // number of cycles in precharge state (increment the counter). 7112266Sradhika.jagtap@arm.com first_act_cycle = timestamp; 7212266Sradhika.jagtap@arm.com precycles += zero_guard(timestamp - last_pre_cycle, "1 last_pre_cycle is in the future."); 7312266Sradhika.jagtap@arm.com idle_pre_update(timestamp, latest_pre_cycle); 7412266Sradhika.jagtap@arm.com } 7512266Sradhika.jagtap@arm.com 7612266Sradhika.jagtap@arm.com bank_state[bank] = BANK_ACTIVE; 7712266Sradhika.jagtap@arm.com latest_act_cycle = timestamp; 7812266Sradhika.jagtap@arm.com } else { 7912266Sradhika.jagtap@arm.com printWarning("Bank is already active!", MemCommand::ACT, timestamp, bank); 8012266Sradhika.jagtap@arm.com } 8112266Sradhika.jagtap@arm.com} 8212266Sradhika.jagtap@arm.com 8312266Sradhika.jagtap@arm.comvoid CommandAnalysis::handleRd(unsigned bank, int64_t timestamp) 8412266Sradhika.jagtap@arm.com{ 8512266Sradhika.jagtap@arm.com printWarningIfPoweredDown("Command issued while in power-down mode.", MemCommand::RD, timestamp, bank); 8612266Sradhika.jagtap@arm.com // If command is RD - update number of reads and read cycle. Check 8712266Sradhika.jagtap@arm.com // for active idle cycles (if any). 8812266Sradhika.jagtap@arm.com if (isPrecharged(bank)) { 8912266Sradhika.jagtap@arm.com printWarning("Bank is not active!", MemCommand::RD, timestamp, bank); 9012266Sradhika.jagtap@arm.com } 9112266Sradhika.jagtap@arm.com numberofreadsBanks[bank]++; 9212266Sradhika.jagtap@arm.com idle_act_update(latest_read_cycle, latest_write_cycle, latest_act_cycle, timestamp); 9312266Sradhika.jagtap@arm.com latest_read_cycle = timestamp; 9412266Sradhika.jagtap@arm.com} 9512266Sradhika.jagtap@arm.com 9612266Sradhika.jagtap@arm.comvoid CommandAnalysis::handleWr(unsigned bank, int64_t timestamp) 9712266Sradhika.jagtap@arm.com{ 9812266Sradhika.jagtap@arm.com printWarningIfPoweredDown("Command issued while in power-down mode.", MemCommand::WR, timestamp, bank); 9912266Sradhika.jagtap@arm.com // If command is WR - update number of writes and write cycle. Check 10012266Sradhika.jagtap@arm.com // for active idle cycles (if any). 10112266Sradhika.jagtap@arm.com if (isPrecharged(bank)) { 10212266Sradhika.jagtap@arm.com printWarning("Bank is not active!", MemCommand::WR, timestamp, bank); 10312266Sradhika.jagtap@arm.com } 10412266Sradhika.jagtap@arm.com numberofwritesBanks[bank]++; 10512266Sradhika.jagtap@arm.com idle_act_update(latest_read_cycle, latest_write_cycle, latest_act_cycle, timestamp); 10612266Sradhika.jagtap@arm.com latest_write_cycle = timestamp; 10712266Sradhika.jagtap@arm.com} 10812266Sradhika.jagtap@arm.com 10912266Sradhika.jagtap@arm.comvoid CommandAnalysis::handleRef(unsigned bank, int64_t timestamp) 11012266Sradhika.jagtap@arm.com{ 11112266Sradhika.jagtap@arm.com printWarningIfPoweredDown("Command issued while in power-down mode.", MemCommand::REF, timestamp, bank); 11212266Sradhika.jagtap@arm.com // If command is REF - update number of refreshes, set bank state of 11312266Sradhika.jagtap@arm.com // all banks to ACT, set the last PRE cycles at RFC-RP cycles from 11412266Sradhika.jagtap@arm.com // timestamp, set the number of active cycles to RFC-RP and check 11512266Sradhika.jagtap@arm.com // for active and precharged cycles and idle active and idle 11612266Sradhika.jagtap@arm.com // precharged cycles before refresh. Change memory state to 0. 11712266Sradhika.jagtap@arm.com printWarningIfActive("One or more banks are active! REF requires all banks to be precharged.", MemCommand::REF, timestamp, bank); 11812266Sradhika.jagtap@arm.com numberofrefs++; 11912266Sradhika.jagtap@arm.com idle_pre_update(timestamp, latest_pre_cycle); 12012266Sradhika.jagtap@arm.com first_act_cycle = timestamp; 12112266Sradhika.jagtap@arm.com std::fill(first_act_cycle_banks.begin(), first_act_cycle_banks.end(), timestamp); 12212266Sradhika.jagtap@arm.com precycles += zero_guard(timestamp - last_pre_cycle, "2 last_pre_cycle is in the future."); 12312266Sradhika.jagtap@arm.com last_pre_cycle = timestamp + memSpec.memTimingSpec.RFC - memSpec.memTimingSpec.RP; 12412266Sradhika.jagtap@arm.com latest_pre_cycle = last_pre_cycle; 12512266Sradhika.jagtap@arm.com actcycles += memSpec.memTimingSpec.RFC - memSpec.memTimingSpec.RP; 12612266Sradhika.jagtap@arm.com for (auto &e : actcyclesBanks) { 12712266Sradhika.jagtap@arm.com e += memSpec.memTimingSpec.RFC - memSpec.memTimingSpec.RP; 12812266Sradhika.jagtap@arm.com } 12912266Sradhika.jagtap@arm.com for (auto& bs : bank_state) { 13012266Sradhika.jagtap@arm.com bs = BANK_PRECHARGED; 13112266Sradhika.jagtap@arm.com } 13212266Sradhika.jagtap@arm.com} 13312266Sradhika.jagtap@arm.com 13412266Sradhika.jagtap@arm.comvoid CommandAnalysis::handleRefB(unsigned bank, int64_t timestamp) 13512266Sradhika.jagtap@arm.com{ 13612266Sradhika.jagtap@arm.com // A REFB command requires a previous PRE command. 13712266Sradhika.jagtap@arm.com if (isPrecharged(bank)) { 13812266Sradhika.jagtap@arm.com // This previous PRE command handler is also responsible for keeping the 13912266Sradhika.jagtap@arm.com // memory state updated. 14012266Sradhika.jagtap@arm.com // Here we consider that the memory state is not changed in order to keep 14112266Sradhika.jagtap@arm.com // things simple, since the transition from PRE to ACT state takes time. 14212266Sradhika.jagtap@arm.com numberofrefbBanks[bank]++; 14312266Sradhika.jagtap@arm.com // Length of the refresh: here we have an approximation, we consider tRP 14412266Sradhika.jagtap@arm.com // also as act cycles because the bank will be precharged (stable) after 14512266Sradhika.jagtap@arm.com // tRP. 14612266Sradhika.jagtap@arm.com actcyclesBanks[bank] += memSpec.memTimingSpec.RAS + memSpec.memTimingSpec.RP; 14712266Sradhika.jagtap@arm.com } else { 14812266Sradhika.jagtap@arm.com printWarning("Bank must be precharged for REFB!", MemCommand::REFB, timestamp, bank); 14912266Sradhika.jagtap@arm.com } 15012266Sradhika.jagtap@arm.com} 15112266Sradhika.jagtap@arm.com 15212266Sradhika.jagtap@arm.comvoid CommandAnalysis::handlePre(unsigned bank, int64_t timestamp) 15312266Sradhika.jagtap@arm.com{ 15412266Sradhika.jagtap@arm.com printWarningIfPoweredDown("Command issued while in power-down mode.", MemCommand::PRE, timestamp, bank); 15512266Sradhika.jagtap@arm.com // If command is explicit PRE - update number of precharges, bank 15612266Sradhika.jagtap@arm.com // state of the target bank and last and latest precharge cycle. 15712266Sradhika.jagtap@arm.com // Calculate the number of active cycles if the memory was in the 15812266Sradhika.jagtap@arm.com // active state before, but there is a state transition to PRE now 15912266Sradhika.jagtap@arm.com // (i.e., this is the last active bank). 16012266Sradhika.jagtap@arm.com // If the bank is already precharged ignore the command and generate a 16112266Sradhika.jagtap@arm.com // warning. 16212266Sradhika.jagtap@arm.com 16312266Sradhika.jagtap@arm.com // Precharge only if the target bank is active 16412266Sradhika.jagtap@arm.com if (bank_state[bank] == BANK_ACTIVE) { 16512266Sradhika.jagtap@arm.com numberofpresBanks[bank]++; 16612266Sradhika.jagtap@arm.com actcyclesBanks[bank] += zero_guard(timestamp - first_act_cycle_banks[bank], "first_act_cycle is in the future (bank)."); 16712266Sradhika.jagtap@arm.com // Since we got here, at least one bank is active 16812266Sradhika.jagtap@arm.com assert(nActiveBanks() != 0); 16912266Sradhika.jagtap@arm.com 17012266Sradhika.jagtap@arm.com if (nActiveBanks() == 1) { 17112266Sradhika.jagtap@arm.com // This is the last active bank. Therefore, here a memory state 17212266Sradhika.jagtap@arm.com // transition to PRE is happening. Let's increment the active cycle 17312266Sradhika.jagtap@arm.com // counter. 17412266Sradhika.jagtap@arm.com actcycles += zero_guard(timestamp - first_act_cycle, "first_act_cycle is in the future."); 17512266Sradhika.jagtap@arm.com last_pre_cycle = timestamp; 17612266Sradhika.jagtap@arm.com idle_act_update(latest_read_cycle, latest_write_cycle, latest_act_cycle, timestamp); 17712266Sradhika.jagtap@arm.com } 17812266Sradhika.jagtap@arm.com 17912266Sradhika.jagtap@arm.com bank_state[bank] = BANK_PRECHARGED; 18012266Sradhika.jagtap@arm.com latest_pre_cycle = timestamp; 18112266Sradhika.jagtap@arm.com } else { 18212266Sradhika.jagtap@arm.com printWarning("Bank is already precharged!", MemCommand::PRE, timestamp, bank); 18312266Sradhika.jagtap@arm.com } 18412266Sradhika.jagtap@arm.com} 18512266Sradhika.jagtap@arm.com 18612266Sradhika.jagtap@arm.comvoid CommandAnalysis::handlePreA(unsigned bank, int64_t timestamp) 18712266Sradhika.jagtap@arm.com{ 18812266Sradhika.jagtap@arm.com printWarningIfPoweredDown("Command issued while in power-down mode.", MemCommand::PREA, timestamp, bank); 18912266Sradhika.jagtap@arm.com // If command is explicit PREA (precharge all banks) - update 19012266Sradhika.jagtap@arm.com // number of precharges by the number of active banks, update the bank 19112266Sradhika.jagtap@arm.com // state of all banks to PRE and set the precharge cycle (the cycle in 19212266Sradhika.jagtap@arm.com // which the memory state changes from ACT to PRE, aka last_pre_cycle). 19312266Sradhika.jagtap@arm.com // Calculate the number of active cycles if the memory was in the 19412266Sradhika.jagtap@arm.com // active state before, but there is a state transition to PRE now. 19512266Sradhika.jagtap@arm.com 19612266Sradhika.jagtap@arm.com if (nActiveBanks() > 0) { 19712266Sradhika.jagtap@arm.com // Active banks are being precharged 19812266Sradhika.jagtap@arm.com // At least one bank was active, therefore the current memory state is 19912266Sradhika.jagtap@arm.com // ACT. Since all banks are being precharged a memory state transition 20012266Sradhika.jagtap@arm.com // to PRE is happening. Add to the counter the amount of cycles the 20112266Sradhika.jagtap@arm.com // memory remained in the ACT state. 20212266Sradhika.jagtap@arm.com 20312266Sradhika.jagtap@arm.com actcycles += zero_guard(timestamp - first_act_cycle, "first_act_cycle is in the future."); 20412266Sradhika.jagtap@arm.com last_pre_cycle = timestamp; 20512266Sradhika.jagtap@arm.com 20612266Sradhika.jagtap@arm.com for (unsigned b = 0; b < num_banks; b++) { 20712266Sradhika.jagtap@arm.com if (bank_state[b] == BANK_ACTIVE) { 20812266Sradhika.jagtap@arm.com // Active banks are being precharged 20912266Sradhika.jagtap@arm.com numberofpresBanks[b] += 1; 21012266Sradhika.jagtap@arm.com actcyclesBanks[b] += zero_guard(timestamp - first_act_cycle_banks[b], "first_act_cycle is in the future (bank)."); 21112266Sradhika.jagtap@arm.com } 21212266Sradhika.jagtap@arm.com } 21312266Sradhika.jagtap@arm.com 21412266Sradhika.jagtap@arm.com idle_act_update(latest_read_cycle, latest_write_cycle, latest_act_cycle, timestamp); 21512266Sradhika.jagtap@arm.com 21612266Sradhika.jagtap@arm.com latest_pre_cycle = timestamp; 21712266Sradhika.jagtap@arm.com // Reset the state for all banks to precharged. 21812266Sradhika.jagtap@arm.com for (auto& bs : bank_state) { 21912266Sradhika.jagtap@arm.com bs = BANK_PRECHARGED; 22012266Sradhika.jagtap@arm.com } 22112266Sradhika.jagtap@arm.com } else { 22212266Sradhika.jagtap@arm.com printWarning("All banks are already precharged!", MemCommand::PREA, timestamp, bank); 22312266Sradhika.jagtap@arm.com } 22412266Sradhika.jagtap@arm.com} 22512266Sradhika.jagtap@arm.com 22612266Sradhika.jagtap@arm.comvoid CommandAnalysis::handlePdnFAct(unsigned bank, int64_t timestamp) 22712266Sradhika.jagtap@arm.com{ 22812266Sradhika.jagtap@arm.com // If command is fast-exit active power-down - update number of 22912266Sradhika.jagtap@arm.com // power-downs, set the power-down cycle and the memory mode to 23012266Sradhika.jagtap@arm.com // fast-exit active power-down. Save states of all the banks from 23112266Sradhika.jagtap@arm.com // the cycle before entering active power-down, to be returned to 23212266Sradhika.jagtap@arm.com // after powering-up. Update active and active idle cycles. 23312266Sradhika.jagtap@arm.com printWarningIfNotActive("All banks are precharged! Incorrect use of Active Power-Down.", MemCommand::PDN_F_ACT, timestamp, bank); 23412266Sradhika.jagtap@arm.com f_act_pdns++; 23512266Sradhika.jagtap@arm.com last_bank_state = bank_state; 23612266Sradhika.jagtap@arm.com pdn_cycle = timestamp; 23712266Sradhika.jagtap@arm.com actcycles += zero_guard(timestamp - first_act_cycle, "first_act_cycle is in the future."); 23812266Sradhika.jagtap@arm.com for (unsigned b = 0; b < num_banks; b++) { 23912266Sradhika.jagtap@arm.com if (bank_state[b] == BANK_ACTIVE) { 24012266Sradhika.jagtap@arm.com actcyclesBanks[b] += zero_guard(timestamp - first_act_cycle_banks[b], "first_act_cycle is in the future (bank)."); 24112266Sradhika.jagtap@arm.com } 24212266Sradhika.jagtap@arm.com } 24312266Sradhika.jagtap@arm.com idle_act_update(latest_read_cycle, latest_write_cycle, latest_act_cycle, timestamp); 24412266Sradhika.jagtap@arm.com mem_state = CommandAnalysis::MS_PDN_F_ACT; 24512266Sradhika.jagtap@arm.com} 24612266Sradhika.jagtap@arm.com 24712266Sradhika.jagtap@arm.comvoid CommandAnalysis::handlePdnSAct(unsigned bank, int64_t timestamp) 24812266Sradhika.jagtap@arm.com{ 24912266Sradhika.jagtap@arm.com // If command is slow-exit active power-down - update number of 25012266Sradhika.jagtap@arm.com // power-downs, set the power-down cycle and the memory mode to 25112266Sradhika.jagtap@arm.com // slow-exit active power-down. Save states of all the banks from 25212266Sradhika.jagtap@arm.com // the cycle before entering active power-down, to be returned to 25312266Sradhika.jagtap@arm.com // after powering-up. Update active and active idle cycles. 25412266Sradhika.jagtap@arm.com printWarningIfNotActive("All banks are precharged! Incorrect use of Active Power-Down.", MemCommand::PDN_S_ACT, timestamp, bank); 25512266Sradhika.jagtap@arm.com s_act_pdns++; 25612266Sradhika.jagtap@arm.com last_bank_state = bank_state; 25712266Sradhika.jagtap@arm.com pdn_cycle = timestamp; 25812266Sradhika.jagtap@arm.com actcycles += zero_guard(timestamp - first_act_cycle, "first_act_cycle is in the future."); 25912266Sradhika.jagtap@arm.com for (unsigned b = 0; b < num_banks; b++) { 26012266Sradhika.jagtap@arm.com if (bank_state[b] == BANK_ACTIVE) { 26112266Sradhika.jagtap@arm.com actcyclesBanks[b] += zero_guard(timestamp - first_act_cycle_banks[b], "first_act_cycle is in the future (bank)."); 26212266Sradhika.jagtap@arm.com } 26312266Sradhika.jagtap@arm.com } 26412266Sradhika.jagtap@arm.com idle_act_update(latest_read_cycle, latest_write_cycle, latest_act_cycle, timestamp); 26512266Sradhika.jagtap@arm.com mem_state = CommandAnalysis::MS_PDN_S_ACT; 26612266Sradhika.jagtap@arm.com} 26712266Sradhika.jagtap@arm.com 26812266Sradhika.jagtap@arm.comvoid CommandAnalysis::handlePdnFPre(unsigned bank, int64_t timestamp) 26912266Sradhika.jagtap@arm.com{ 27012266Sradhika.jagtap@arm.com // If command is fast-exit precharged power-down - update number of 27112266Sradhika.jagtap@arm.com // power-downs, set the power-down cycle and the memory mode to 27212266Sradhika.jagtap@arm.com // fast-exit precahrged power-down. Update precharged and precharged 27312266Sradhika.jagtap@arm.com // idle cycles. 27412266Sradhika.jagtap@arm.com printWarningIfActive("One or more banks are active! Incorrect use of Precharged Power-Down.", MemCommand::PDN_F_PRE, timestamp, bank); 27512266Sradhika.jagtap@arm.com f_pre_pdns++; 27612266Sradhika.jagtap@arm.com pdn_cycle = timestamp; 27712266Sradhika.jagtap@arm.com precycles += zero_guard(timestamp - last_pre_cycle, "3 last_pre_cycle is in the future."); 27812266Sradhika.jagtap@arm.com idle_pre_update(timestamp, latest_pre_cycle); 27912266Sradhika.jagtap@arm.com mem_state = CommandAnalysis::MS_PDN_F_PRE; 28012266Sradhika.jagtap@arm.com} 28112266Sradhika.jagtap@arm.com 28212266Sradhika.jagtap@arm.comvoid CommandAnalysis::handlePdnSPre(unsigned bank, int64_t timestamp) 28312266Sradhika.jagtap@arm.com{ 28412266Sradhika.jagtap@arm.com // If command is slow-exit precharged power-down - update number of 28512266Sradhika.jagtap@arm.com // power-downs, set the power-down cycle and the memory mode to 28612266Sradhika.jagtap@arm.com // slow-exit precahrged power-down. Update precharged and precharged 28712266Sradhika.jagtap@arm.com // idle cycles. 28812266Sradhika.jagtap@arm.com printWarningIfActive("One or more banks are active! Incorrect use of Precharged Power-Down.", MemCommand::PDN_S_PRE, timestamp, bank); 28912266Sradhika.jagtap@arm.com s_pre_pdns++; 29012266Sradhika.jagtap@arm.com pdn_cycle = timestamp; 29112266Sradhika.jagtap@arm.com precycles += zero_guard(timestamp - last_pre_cycle, "4 last_pre_cycle is in the future."); 29212266Sradhika.jagtap@arm.com idle_pre_update(timestamp, latest_pre_cycle); 29312266Sradhika.jagtap@arm.com mem_state = CommandAnalysis::MS_PDN_S_PRE; 29412266Sradhika.jagtap@arm.com} 29512266Sradhika.jagtap@arm.com 29612266Sradhika.jagtap@arm.comvoid CommandAnalysis::handlePupAct(int64_t timestamp) 29712266Sradhika.jagtap@arm.com{ 29812266Sradhika.jagtap@arm.com // If command is power-up in the active mode - check the power-down 29912266Sradhika.jagtap@arm.com // exit-mode employed (fast or slow), update the number of power-down 30012266Sradhika.jagtap@arm.com // and power-up cycles and the latest and first act cycle. Also, reset 30112266Sradhika.jagtap@arm.com // all the individual bank states to the respective saved states 30212266Sradhika.jagtap@arm.com // before entering power-down. 30312266Sradhika.jagtap@arm.com const MemTimingSpec& t = memSpec.memTimingSpec; 30412266Sradhika.jagtap@arm.com 30512266Sradhika.jagtap@arm.com if (mem_state == CommandAnalysis::MS_PDN_F_ACT) { 30612266Sradhika.jagtap@arm.com f_act_pdcycles += zero_guard(timestamp - pdn_cycle, "pdn_cycle is in the future."); 30712266Sradhika.jagtap@arm.com pup_act_cycles += t.XP; 30812266Sradhika.jagtap@arm.com latest_act_cycle = timestamp; 30912266Sradhika.jagtap@arm.com } else if (mem_state == CommandAnalysis::MS_PDN_S_ACT) { 31012266Sradhika.jagtap@arm.com s_act_pdcycles += zero_guard(timestamp - pdn_cycle, "pdn_cycle is in the future."); 31112266Sradhika.jagtap@arm.com if (memSpec.memArchSpec.dll == false) { 31212266Sradhika.jagtap@arm.com pup_act_cycles += t.XP; 31312266Sradhika.jagtap@arm.com latest_act_cycle = timestamp; 31412266Sradhika.jagtap@arm.com } else { 31512266Sradhika.jagtap@arm.com pup_act_cycles += t.XPDLL - t.RCD; 31612266Sradhika.jagtap@arm.com latest_act_cycle = timestamp + zero_guard(t.XPDLL - (2 * t.RCD), "t.XPDLL - (2 * t.RCD) < 0"); 31712266Sradhika.jagtap@arm.com } 31812266Sradhika.jagtap@arm.com } else { 31912266Sradhika.jagtap@arm.com cerr << "Incorrect use of Active Power-Up!" << endl; 32012266Sradhika.jagtap@arm.com } 32112266Sradhika.jagtap@arm.com mem_state = MS_NOT_IN_PD; 32212266Sradhika.jagtap@arm.com bank_state = last_bank_state; 32312266Sradhika.jagtap@arm.com first_act_cycle = timestamp; 32412266Sradhika.jagtap@arm.com std::fill(first_act_cycle_banks.begin(), first_act_cycle_banks.end(), timestamp); 32512266Sradhika.jagtap@arm.com} 32612266Sradhika.jagtap@arm.com 32712266Sradhika.jagtap@arm.comvoid CommandAnalysis::handlePupPre(int64_t timestamp) 32812266Sradhika.jagtap@arm.com{ 32912266Sradhika.jagtap@arm.com // If command is power-up in the precharged mode - check the power-down 33012266Sradhika.jagtap@arm.com // exit-mode employed (fast or slow), update the number of power-down 33112266Sradhika.jagtap@arm.com // and power-up cycles and the latest and last pre cycle. 33212266Sradhika.jagtap@arm.com const MemTimingSpec& t = memSpec.memTimingSpec; 33312266Sradhika.jagtap@arm.com if (mem_state == CommandAnalysis::MS_PDN_F_PRE) { 33412266Sradhika.jagtap@arm.com f_pre_pdcycles += zero_guard(timestamp - pdn_cycle, "pdn_cycle is in the future."); 33512266Sradhika.jagtap@arm.com pup_pre_cycles += t.XP; 33612266Sradhika.jagtap@arm.com latest_pre_cycle = timestamp; 33712266Sradhika.jagtap@arm.com } else if (mem_state == CommandAnalysis::MS_PDN_S_PRE) { 33812266Sradhika.jagtap@arm.com s_pre_pdcycles += zero_guard(timestamp - pdn_cycle, "pdn_cycle is in the future."); 33912266Sradhika.jagtap@arm.com if (memSpec.memArchSpec.dll == false) { 34012266Sradhika.jagtap@arm.com pup_pre_cycles += t.XP; 34112266Sradhika.jagtap@arm.com latest_pre_cycle = timestamp; 34212266Sradhika.jagtap@arm.com } else { 34312266Sradhika.jagtap@arm.com pup_pre_cycles += t.XPDLL - t.RCD; 34412266Sradhika.jagtap@arm.com latest_pre_cycle = timestamp + zero_guard(t.XPDLL - t.RCD - t.RP, "t.XPDLL - t.RCD - t.RP"); 34512266Sradhika.jagtap@arm.com } 34612266Sradhika.jagtap@arm.com } else { 34712266Sradhika.jagtap@arm.com cerr << "Incorrect use of Precharged Power-Up!" << endl; 34812266Sradhika.jagtap@arm.com } 34912266Sradhika.jagtap@arm.com mem_state = MS_NOT_IN_PD; 35012266Sradhika.jagtap@arm.com last_pre_cycle = timestamp; 35112266Sradhika.jagtap@arm.com} 35212266Sradhika.jagtap@arm.com 35312266Sradhika.jagtap@arm.comvoid CommandAnalysis::handleSREn(unsigned bank, int64_t timestamp) 35412266Sradhika.jagtap@arm.com{ 35512266Sradhika.jagtap@arm.com // If command is self-refresh - update number of self-refreshes, 35612266Sradhika.jagtap@arm.com // set memory state to SREF, update precharge and idle precharge 35712266Sradhika.jagtap@arm.com // cycles and set the self-refresh cycle. 35812266Sradhika.jagtap@arm.com printWarningIfActive("One or more banks are active! SREF requires all banks to be precharged.", MemCommand::SREN, timestamp, bank); 35912266Sradhika.jagtap@arm.com numberofsrefs++; 36012266Sradhika.jagtap@arm.com sref_cycle = timestamp; 36112266Sradhika.jagtap@arm.com sref_cycle_window = timestamp; 36212266Sradhika.jagtap@arm.com sref_ref_pre_cycles_window = 0; 36312266Sradhika.jagtap@arm.com sref_ref_act_cycles_window = 0; 36412266Sradhika.jagtap@arm.com precycles += zero_guard(timestamp - last_pre_cycle, "5 last_pre_cycle is in the future."); 36512266Sradhika.jagtap@arm.com idle_pre_update(timestamp, latest_pre_cycle); 36612266Sradhika.jagtap@arm.com mem_state = CommandAnalysis::MS_SREF; 36712266Sradhika.jagtap@arm.com} 36812266Sradhika.jagtap@arm.com 36912266Sradhika.jagtap@arm.comvoid CommandAnalysis::handleSREx(unsigned bank, int64_t timestamp) 37012266Sradhika.jagtap@arm.com{ 37112266Sradhika.jagtap@arm.com // If command is self-refresh exit - update the number of self-refresh 37212266Sradhika.jagtap@arm.com // clock cycles, number of active and precharged auto-refresh clock 37312266Sradhika.jagtap@arm.com // cycles during self-refresh and self-refresh exit based on the number 37412266Sradhika.jagtap@arm.com // of cycles in the self-refresh mode and auto-refresh duration (RFC). 37512266Sradhika.jagtap@arm.com // Set the last and latest precharge cycle accordingly and set the 37612266Sradhika.jagtap@arm.com // memory state to 0. 37712266Sradhika.jagtap@arm.com const MemTimingSpec& t = memSpec.memTimingSpec; 37812266Sradhika.jagtap@arm.com if (mem_state != CommandAnalysis::MS_SREF) { 37912266Sradhika.jagtap@arm.com cerr << "Incorrect use of Self-Refresh Power-Up!" << endl; 38012266Sradhika.jagtap@arm.com } 38112266Sradhika.jagtap@arm.com // The total duration of self-refresh is given by the difference between 38212266Sradhika.jagtap@arm.com // the current clock cycle and the clock cycle of entering self-refresh. 38312266Sradhika.jagtap@arm.com int64_t sref_duration = timestamp - sref_cycle; 38412266Sradhika.jagtap@arm.com 38512266Sradhika.jagtap@arm.com // Negative or zero duration should never happen. 38612266Sradhika.jagtap@arm.com if (sref_duration <= 0) { 38712266Sradhika.jagtap@arm.com printWarning("Invalid Self-Refresh duration!", MemCommand::SREX, timestamp, bank); 38812266Sradhika.jagtap@arm.com sref_duration = 0; 38912266Sradhika.jagtap@arm.com } 39012266Sradhika.jagtap@arm.com 39112266Sradhika.jagtap@arm.com // The minimum time that the DRAM must remain in Self-Refresh is CKESR. 39212266Sradhika.jagtap@arm.com if (sref_duration < t.CKESR) { 39312266Sradhika.jagtap@arm.com printWarning("Self-Refresh duration < CKESR!", MemCommand::SREX, timestamp, bank); 39412266Sradhika.jagtap@arm.com } 39512266Sradhika.jagtap@arm.com 39612266Sradhika.jagtap@arm.com if (sref_duration >= t.RFC) { 39712266Sradhika.jagtap@arm.com /* 39812266Sradhika.jagtap@arm.com * Self-refresh Exit Context 1 (tSREF >= tRFC): 39912266Sradhika.jagtap@arm.com * The memory remained in self-refresh for a certain number of clock 40012266Sradhika.jagtap@arm.com * cycles greater than a refresh cycle time (RFC). Consequently, the 40112266Sradhika.jagtap@arm.com * initial auto-refresh accomplished. 40212266Sradhika.jagtap@arm.com * 40312266Sradhika.jagtap@arm.com * 40412266Sradhika.jagtap@arm.com * SREN # SREX 40512266Sradhika.jagtap@arm.com * | # ^ 40612266Sradhika.jagtap@arm.com * | # | 40712266Sradhika.jagtap@arm.com * |<------------------------- tSREF ----------...----->| 40812266Sradhika.jagtap@arm.com * | # | 40912266Sradhika.jagtap@arm.com * | Initial Auto-Refresh # | 41012266Sradhika.jagtap@arm.com * v # | 41112266Sradhika.jagtap@arm.com * ------------------------------------#-------...-----------------> t 41212266Sradhika.jagtap@arm.com * # 41312266Sradhika.jagtap@arm.com * <------------- tRFC --------------># 41412266Sradhika.jagtap@arm.com * <---- (tRFC - tRP) ----><-- tRP --># 41512266Sradhika.jagtap@arm.com * | | 41612266Sradhika.jagtap@arm.com * v v 41712266Sradhika.jagtap@arm.com * sref_ref_act_cycles sref_ref_pre_cycles 41812266Sradhika.jagtap@arm.com * 41912266Sradhika.jagtap@arm.com * 42012266Sradhika.jagtap@arm.com * Summary: 42112266Sradhika.jagtap@arm.com * sref_cycles += tSREF – tRFC 42212266Sradhika.jagtap@arm.com * sref_ref_act_cycles += tRFC - tRP 42312266Sradhika.jagtap@arm.com * sref_ref_pre_cycles += tRP 42412266Sradhika.jagtap@arm.com * spup_ref_act_cycles += 0 42512266Sradhika.jagtap@arm.com * spup_ref_pre_cycles += 0 42612266Sradhika.jagtap@arm.com * 42712266Sradhika.jagtap@arm.com */ 42812266Sradhika.jagtap@arm.com 42912266Sradhika.jagtap@arm.com // The initial auto-refresh consumes (IDD5 − IDD3N) over one refresh 43012266Sradhika.jagtap@arm.com // period (RFC) from the start of the self-refresh. 43112266Sradhika.jagtap@arm.com sref_ref_act_cycles += t.RFC - 43212266Sradhika.jagtap@arm.com t.RP - sref_ref_act_cycles_window; 43312266Sradhika.jagtap@arm.com sref_ref_pre_cycles += t.RP - sref_ref_pre_cycles_window; 43412266Sradhika.jagtap@arm.com last_pre_cycle = timestamp; 43512266Sradhika.jagtap@arm.com 43612266Sradhika.jagtap@arm.com // The IDD6 current is consumed for the time period spent in the 43712266Sradhika.jagtap@arm.com // self-refresh mode, which excludes the time spent in finishing the 43812266Sradhika.jagtap@arm.com // initial auto-refresh. 43912266Sradhika.jagtap@arm.com if (sref_cycle_window > sref_cycle + t.RFC) { 44012266Sradhika.jagtap@arm.com sref_cycles += zero_guard(timestamp - sref_cycle_window, "sref_cycle_window is in the future."); 44112266Sradhika.jagtap@arm.com } else { 44212266Sradhika.jagtap@arm.com sref_cycles += zero_guard(timestamp - sref_cycle - t.RFC, "sref_cycle - t.RFC < 0"); 44312266Sradhika.jagtap@arm.com } 44412266Sradhika.jagtap@arm.com 44512266Sradhika.jagtap@arm.com // IDD2N current is consumed when exiting the self-refresh state. 44612266Sradhika.jagtap@arm.com if (memSpec.memArchSpec.dll == false) { 44712266Sradhika.jagtap@arm.com spup_cycles += t.XS; 44812266Sradhika.jagtap@arm.com latest_pre_cycle = timestamp + zero_guard(t.XS - t.RP, "t.XS - t.RP < 0"); 44912266Sradhika.jagtap@arm.com } else { 45012266Sradhika.jagtap@arm.com spup_cycles += t.XSDLL - t.RCD; 45112266Sradhika.jagtap@arm.com latest_pre_cycle = timestamp + zero_guard(t.XSDLL - t.RCD - t.RP, "t.XSDLL - t.RCD - t.RP < 0"); 45212266Sradhika.jagtap@arm.com } 45312266Sradhika.jagtap@arm.com 45412266Sradhika.jagtap@arm.com } else { 45512266Sradhika.jagtap@arm.com // Self-refresh Exit Context 2 (tSREF < tRFC): 45612266Sradhika.jagtap@arm.com // Exit self-refresh before the completion of the initial 45712266Sradhika.jagtap@arm.com // auto-refresh. 45812266Sradhika.jagtap@arm.com 45912266Sradhika.jagtap@arm.com // Number of active cycles needed by an auto-refresh. 46012266Sradhika.jagtap@arm.com int64_t ref_act_cycles = t.RFC - t.RP; 46112266Sradhika.jagtap@arm.com 46212266Sradhika.jagtap@arm.com if (sref_duration >= ref_act_cycles) { 46312266Sradhika.jagtap@arm.com /* 46412266Sradhika.jagtap@arm.com * Self-refresh Exit Context 2A (tSREF < tRFC && tSREF >= tRFC - tRP): 46512266Sradhika.jagtap@arm.com * The duration of self-refresh is equal or greater than the number 46612266Sradhika.jagtap@arm.com * of active cycles needed by the initial auto-refresh. 46712266Sradhika.jagtap@arm.com * 46812266Sradhika.jagtap@arm.com * 46912266Sradhika.jagtap@arm.com * SREN SREX 47012266Sradhika.jagtap@arm.com * | ^ # 47112266Sradhika.jagtap@arm.com * | | # 47212266Sradhika.jagtap@arm.com * |<------------------ tSREF --------------------->| # 47312266Sradhika.jagtap@arm.com * | | # 47412266Sradhika.jagtap@arm.com * | Initial Auto-Refresh # 47512266Sradhika.jagtap@arm.com * v | # 47612266Sradhika.jagtap@arm.com * -----------------------------------------------------------#--> t 47712266Sradhika.jagtap@arm.com * # 47812266Sradhika.jagtap@arm.com * <------------------------ tRFC --------------------------># 47912266Sradhika.jagtap@arm.com * <------------- (tRFC - tRP)--------------><----- tRP ----># 48012266Sradhika.jagtap@arm.com * | <-----><-------> 48112266Sradhika.jagtap@arm.com * v | | 48212266Sradhika.jagtap@arm.com * sref_ref_act_cycles v v 48312266Sradhika.jagtap@arm.com * sref_ref_pre_cycles spup_ref_pre_cycles 48412266Sradhika.jagtap@arm.com * 48512266Sradhika.jagtap@arm.com * 48612266Sradhika.jagtap@arm.com * Summary: 48712266Sradhika.jagtap@arm.com * sref_cycles += 0 48812266Sradhika.jagtap@arm.com * sref_ref_act_cycles += tRFC - tRP 48912266Sradhika.jagtap@arm.com * sref_ref_pre_cycles += tSREF – (tRFC – tRP) 49012266Sradhika.jagtap@arm.com * spup_ref_act_cycles += 0 49112266Sradhika.jagtap@arm.com * spup_ref_pre_cycles += tRP – sref_ref_pre_cycles 49212266Sradhika.jagtap@arm.com * 49312266Sradhika.jagtap@arm.com */ 49412266Sradhika.jagtap@arm.com 49512266Sradhika.jagtap@arm.com // Number of precharged cycles (zero <= pre_cycles < RP) 49612266Sradhika.jagtap@arm.com int64_t pre_cycles = sref_duration - ref_act_cycles - sref_ref_pre_cycles_window; 49712266Sradhika.jagtap@arm.com 49812266Sradhika.jagtap@arm.com sref_ref_act_cycles += ref_act_cycles - sref_ref_act_cycles_window; 49912266Sradhika.jagtap@arm.com sref_ref_pre_cycles += pre_cycles; 50012266Sradhika.jagtap@arm.com 50112266Sradhika.jagtap@arm.com // Number of precharged cycles during the self-refresh power-up. It 50212266Sradhika.jagtap@arm.com // is at maximum tRP (if pre_cycles is zero). 50312266Sradhika.jagtap@arm.com int64_t spup_pre = t.RP - pre_cycles; 50412266Sradhika.jagtap@arm.com 50512266Sradhika.jagtap@arm.com spup_ref_pre_cycles += spup_pre; 50612266Sradhika.jagtap@arm.com 50712266Sradhika.jagtap@arm.com last_pre_cycle = timestamp + spup_pre; 50812266Sradhika.jagtap@arm.com 50912266Sradhika.jagtap@arm.com if (memSpec.memArchSpec.dll == false) { 51012266Sradhika.jagtap@arm.com spup_cycles += t.XS - spup_pre; 51112266Sradhika.jagtap@arm.com latest_pre_cycle = timestamp + zero_guard(t.XS - spup_pre - t.RP, "t.XS - spup_pre - t.RP < 0"); 51212266Sradhika.jagtap@arm.com } else { 51312266Sradhika.jagtap@arm.com spup_cycles += t.XSDLL - t.RCD - spup_pre; 51412266Sradhika.jagtap@arm.com latest_pre_cycle = timestamp + zero_guard(t.XSDLL - t.RCD - spup_pre - t.RP, "t.XSDLL - t.RCD - spup_pre - t.RP"); 51512266Sradhika.jagtap@arm.com } 51612266Sradhika.jagtap@arm.com } else { 51712266Sradhika.jagtap@arm.com /* 51812266Sradhika.jagtap@arm.com * Self-refresh Exit Context 2B (tSREF < tRFC - tRP): 51912266Sradhika.jagtap@arm.com * self-refresh duration is shorter than the number of active cycles 52012266Sradhika.jagtap@arm.com * needed by the initial auto-refresh. 52112266Sradhika.jagtap@arm.com * 52212266Sradhika.jagtap@arm.com * 52312266Sradhika.jagtap@arm.com * SREN SREX 52412266Sradhika.jagtap@arm.com * | ^ # 52512266Sradhika.jagtap@arm.com * | | # 52612266Sradhika.jagtap@arm.com * |<-------------- tSREF ----------->| # 52712266Sradhika.jagtap@arm.com * | | # 52812266Sradhika.jagtap@arm.com * | Initial Auto-Refresh # 52912266Sradhika.jagtap@arm.com * v | # 53012266Sradhika.jagtap@arm.com * ------------------------------------------------------------#--> t 53112266Sradhika.jagtap@arm.com * # 53212266Sradhika.jagtap@arm.com * <------------------------ tRFC ---------------------------># 53312266Sradhika.jagtap@arm.com * <-------------- (tRFC - tRP)-------------><------ tRP ----># 53412266Sradhika.jagtap@arm.com * <--------------------------------><------><---------------> 53512266Sradhika.jagtap@arm.com * | | | 53612266Sradhika.jagtap@arm.com * v v v 53712266Sradhika.jagtap@arm.com * sref_ref_act_cycles spup_ref_act_cycles spup_ref_pre_cycles 53812266Sradhika.jagtap@arm.com * 53912266Sradhika.jagtap@arm.com * 54012266Sradhika.jagtap@arm.com * Summary: 54112266Sradhika.jagtap@arm.com * sref_cycles += 0 54212266Sradhika.jagtap@arm.com * sref_ref_act_cycles += tSREF 54312266Sradhika.jagtap@arm.com * sref_ref_pre_cycles += 0 54412266Sradhika.jagtap@arm.com * spup_ref_act_cycles += (tRFC – tRP) - tSREF 54512266Sradhika.jagtap@arm.com * spup_ref_pre_cycles += tRP 54612266Sradhika.jagtap@arm.com * 54712266Sradhika.jagtap@arm.com */ 54812266Sradhika.jagtap@arm.com 54912266Sradhika.jagtap@arm.com sref_ref_act_cycles += sref_duration - sref_ref_act_cycles_window; 55012266Sradhika.jagtap@arm.com 55112266Sradhika.jagtap@arm.com int64_t spup_act = (t.RFC - t.RP) - sref_duration; 55212266Sradhika.jagtap@arm.com 55312266Sradhika.jagtap@arm.com spup_ref_act_cycles += spup_act; 55412266Sradhika.jagtap@arm.com spup_ref_pre_cycles += t.RP; 55512266Sradhika.jagtap@arm.com 55612266Sradhika.jagtap@arm.com last_pre_cycle = timestamp + spup_act + t.RP; 55712266Sradhika.jagtap@arm.com if (memSpec.memArchSpec.dll == false) { 55812266Sradhika.jagtap@arm.com spup_cycles += t.XS - spup_act - t.RP; 55912266Sradhika.jagtap@arm.com latest_pre_cycle = timestamp + zero_guard(t.XS - spup_act - (2 * t.RP), "t.XS - spup_act - (2 * t.RP) < 0"); 56012266Sradhika.jagtap@arm.com } else { 56112266Sradhika.jagtap@arm.com spup_cycles += t.XSDLL - t.RCD - spup_act - t.RP; 56212266Sradhika.jagtap@arm.com latest_pre_cycle = timestamp + zero_guard(t.XSDLL - t.RCD - spup_act - (2 * t.RP), "t.XSDLL - t.RCD - spup_act - (2 * t.RP) < 0"); 56312266Sradhika.jagtap@arm.com } 56412266Sradhika.jagtap@arm.com } 56512266Sradhika.jagtap@arm.com } 56612266Sradhika.jagtap@arm.com mem_state = MS_NOT_IN_PD; 56712266Sradhika.jagtap@arm.com} 56812266Sradhika.jagtap@arm.com 56912266Sradhika.jagtap@arm.com 57012266Sradhika.jagtap@arm.comvoid CommandAnalysis::handleNopEnd(int64_t timestamp) 57112266Sradhika.jagtap@arm.com{ 57212266Sradhika.jagtap@arm.com // May be optionally used at the end of memory trace for better accuracy 57312266Sradhika.jagtap@arm.com // Update all counters based on completion of operations. 57412266Sradhika.jagtap@arm.com const MemTimingSpec& t = memSpec.memTimingSpec; 57512266Sradhika.jagtap@arm.com for (unsigned b = 0; b < num_banks; b++) { 57612266Sradhika.jagtap@arm.com if (bank_state[b] == BANK_ACTIVE) { 57712266Sradhika.jagtap@arm.com actcyclesBanks[b] += zero_guard(timestamp - first_act_cycle_banks[b], "first_act_cycle is in the future (bank)"); 57812266Sradhika.jagtap@arm.com } 57912266Sradhika.jagtap@arm.com } 58012266Sradhika.jagtap@arm.com 58112266Sradhika.jagtap@arm.com if (nActiveBanks() > 0 && mem_state == MS_NOT_IN_PD) { 58212266Sradhika.jagtap@arm.com actcycles += zero_guard(timestamp - first_act_cycle, "first_act_cycle is in the future"); 58312266Sradhika.jagtap@arm.com idle_act_update(latest_read_cycle, latest_write_cycle, 58412266Sradhika.jagtap@arm.com latest_act_cycle, timestamp); 58512266Sradhika.jagtap@arm.com } else if (nActiveBanks() == 0 && mem_state == MS_NOT_IN_PD) { 58612266Sradhika.jagtap@arm.com precycles += zero_guard(timestamp - last_pre_cycle, "6 last_pre_cycle is in the future"); 58712266Sradhika.jagtap@arm.com idle_pre_update(timestamp, latest_pre_cycle); 58812266Sradhika.jagtap@arm.com } else if (mem_state == CommandAnalysis::MS_PDN_F_ACT) { 58912266Sradhika.jagtap@arm.com f_act_pdcycles += zero_guard(timestamp - pdn_cycle, "pdn_cycle is in the future"); 59012266Sradhika.jagtap@arm.com } else if (mem_state == CommandAnalysis::MS_PDN_S_ACT) { 59112266Sradhika.jagtap@arm.com s_act_pdcycles += zero_guard(timestamp - pdn_cycle, "pdn_cycle is in the future"); 59212266Sradhika.jagtap@arm.com } else if (mem_state == CommandAnalysis::MS_PDN_F_PRE) { 59312266Sradhika.jagtap@arm.com f_pre_pdcycles += zero_guard(timestamp - pdn_cycle, "pdn_cycle is in the future"); 59412266Sradhika.jagtap@arm.com } else if (mem_state == CommandAnalysis::MS_PDN_S_PRE) { 59512266Sradhika.jagtap@arm.com s_pre_pdcycles += zero_guard(timestamp - pdn_cycle, "pdn_cycle is in the future"); 59612266Sradhika.jagtap@arm.com } else if (mem_state == CommandAnalysis::MS_SREF) { 59712266Sradhika.jagtap@arm.com auto rfc_minus_rp = (t.RFC - t.RP); 59812266Sradhika.jagtap@arm.com 59912266Sradhika.jagtap@arm.com if (timestamp > sref_cycle + t.RFC) { 60012266Sradhika.jagtap@arm.com if (sref_cycle_window <= sref_cycle + rfc_minus_rp) { 60112266Sradhika.jagtap@arm.com sref_ref_act_cycles += rfc_minus_rp - sref_ref_act_cycles_window; 60212266Sradhika.jagtap@arm.com sref_ref_act_cycles_window = rfc_minus_rp; 60312266Sradhika.jagtap@arm.com sref_cycle_window = sref_cycle + rfc_minus_rp; 60412266Sradhika.jagtap@arm.com } 60512266Sradhika.jagtap@arm.com if (sref_cycle_window <= sref_cycle + t.RFC) { 60612266Sradhika.jagtap@arm.com sref_ref_pre_cycles += t.RP - sref_ref_pre_cycles_window; 60712266Sradhika.jagtap@arm.com sref_ref_pre_cycles_window = t.RP; 60812266Sradhika.jagtap@arm.com sref_cycle_window = sref_cycle + t.RFC; 60912266Sradhika.jagtap@arm.com } 61012266Sradhika.jagtap@arm.com sref_cycles += zero_guard(timestamp - sref_cycle_window, "sref_cycle_window is in the future"); 61112266Sradhika.jagtap@arm.com } else if (timestamp > sref_cycle + rfc_minus_rp) { 61212266Sradhika.jagtap@arm.com 61312266Sradhika.jagtap@arm.com if (sref_cycle_window <= sref_cycle + rfc_minus_rp) { 61412266Sradhika.jagtap@arm.com sref_ref_act_cycles += rfc_minus_rp - sref_ref_act_cycles_window; 61512266Sradhika.jagtap@arm.com sref_ref_act_cycles_window = rfc_minus_rp; 61612266Sradhika.jagtap@arm.com sref_cycle_window = sref_cycle + rfc_minus_rp; 61712266Sradhika.jagtap@arm.com } 61812266Sradhika.jagtap@arm.com sref_ref_pre_cycles_window += timestamp - sref_cycle_window; 61912266Sradhika.jagtap@arm.com sref_ref_pre_cycles += timestamp - sref_cycle_window; 62012266Sradhika.jagtap@arm.com } else { 62112266Sradhika.jagtap@arm.com sref_ref_act_cycles_window += timestamp - sref_cycle_window; 62212266Sradhika.jagtap@arm.com sref_ref_act_cycles += timestamp - sref_cycle_window; 62312266Sradhika.jagtap@arm.com } 62412266Sradhika.jagtap@arm.com } 62512266Sradhika.jagtap@arm.com} 626