CommandAnalysis.cc revision 10428
110428Sandreas.hansson@arm.com/* 210428Sandreas.hansson@arm.com * Copyright (c) 2012-2014, TU Delft 310428Sandreas.hansson@arm.com * Copyright (c) 2012-2014, TU Eindhoven 410428Sandreas.hansson@arm.com * Copyright (c) 2012-2014, TU Kaiserslautern 510428Sandreas.hansson@arm.com * All rights reserved. 610428Sandreas.hansson@arm.com * 710428Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 810428Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 910428Sandreas.hansson@arm.com * met: 1010428Sandreas.hansson@arm.com * 1110428Sandreas.hansson@arm.com * 1. Redistributions of source code must retain the above copyright 1210428Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer. 1310428Sandreas.hansson@arm.com * 1410428Sandreas.hansson@arm.com * 2. Redistributions in binary form must reproduce the above copyright 1510428Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 1610428Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution. 1710428Sandreas.hansson@arm.com * 1810428Sandreas.hansson@arm.com * 3. Neither the name of the copyright holder nor the names of its 1910428Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 2010428Sandreas.hansson@arm.com * this software without specific prior written permission. 2110428Sandreas.hansson@arm.com * 2210428Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 2310428Sandreas.hansson@arm.com * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2410428Sandreas.hansson@arm.com * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 2510428Sandreas.hansson@arm.com * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2610428Sandreas.hansson@arm.com * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2710428Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 2810428Sandreas.hansson@arm.com * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2910428Sandreas.hansson@arm.com * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3010428Sandreas.hansson@arm.com * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3110428Sandreas.hansson@arm.com * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3210428Sandreas.hansson@arm.com * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3310428Sandreas.hansson@arm.com * 3410428Sandreas.hansson@arm.com * Authors: Karthik Chandrasekar, Matthias Jung, Omar Naji, Sven Goossens 3510428Sandreas.hansson@arm.com * 3610428Sandreas.hansson@arm.com */ 3710428Sandreas.hansson@arm.com 3810428Sandreas.hansson@arm.com#include <fstream> 3910428Sandreas.hansson@arm.com#include <algorithm> 4010428Sandreas.hansson@arm.com#include <sstream> 4110428Sandreas.hansson@arm.com 4210428Sandreas.hansson@arm.com#include "CommandAnalysis.h" 4310428Sandreas.hansson@arm.com#include "CmdScheduler.h" 4410428Sandreas.hansson@arm.com 4510428Sandreas.hansson@arm.comusing namespace Data; 4610428Sandreas.hansson@arm.comusing namespace std; 4710428Sandreas.hansson@arm.com 4810428Sandreas.hansson@arm.comCommandAnalysis::CommandAnalysis() 4910428Sandreas.hansson@arm.com{ 5010428Sandreas.hansson@arm.com} 5110428Sandreas.hansson@arm.com 5210428Sandreas.hansson@arm.comCommandAnalysis::CommandAnalysis(const int nbrofBanks) 5310428Sandreas.hansson@arm.com{ 5410428Sandreas.hansson@arm.com // Initializing all counters and variables 5510428Sandreas.hansson@arm.com 5610428Sandreas.hansson@arm.com numberofacts = 0; 5710428Sandreas.hansson@arm.com numberofpres = 0; 5810428Sandreas.hansson@arm.com numberofreads = 0; 5910428Sandreas.hansson@arm.com numberofwrites = 0; 6010428Sandreas.hansson@arm.com numberofrefs = 0; 6110428Sandreas.hansson@arm.com f_act_pdns = 0; 6210428Sandreas.hansson@arm.com s_act_pdns = 0; 6310428Sandreas.hansson@arm.com f_pre_pdns = 0; 6410428Sandreas.hansson@arm.com s_pre_pdns = 0; 6510428Sandreas.hansson@arm.com numberofsrefs = 0; 6610428Sandreas.hansson@arm.com 6710428Sandreas.hansson@arm.com pop = 0; 6810428Sandreas.hansson@arm.com init = 0; 6910428Sandreas.hansson@arm.com zero = 0; 7010428Sandreas.hansson@arm.com 7110428Sandreas.hansson@arm.com actcycles = 0; 7210428Sandreas.hansson@arm.com precycles = 0; 7310428Sandreas.hansson@arm.com f_act_pdcycles = 0; 7410428Sandreas.hansson@arm.com s_act_pdcycles = 0; 7510428Sandreas.hansson@arm.com f_pre_pdcycles = 0; 7610428Sandreas.hansson@arm.com s_pre_pdcycles = 0; 7710428Sandreas.hansson@arm.com pup_act_cycles = 0; 7810428Sandreas.hansson@arm.com pup_pre_cycles = 0; 7910428Sandreas.hansson@arm.com sref_cycles = 0; 8010428Sandreas.hansson@arm.com spup_cycles = 0; 8110428Sandreas.hansson@arm.com sref_ref_act_cycles = 0; 8210428Sandreas.hansson@arm.com sref_ref_pre_cycles = 0; 8310428Sandreas.hansson@arm.com spup_ref_act_cycles = 0; 8410428Sandreas.hansson@arm.com spup_ref_pre_cycles = 0; 8510428Sandreas.hansson@arm.com idlecycles_act = 0; 8610428Sandreas.hansson@arm.com idlecycles_pre = 0; 8710428Sandreas.hansson@arm.com 8810428Sandreas.hansson@arm.com latest_act_cycle = -1; 8910428Sandreas.hansson@arm.com latest_pre_cycle = -1; 9010428Sandreas.hansson@arm.com latest_read_cycle = -1; 9110428Sandreas.hansson@arm.com latest_write_cycle = -1; 9210428Sandreas.hansson@arm.com end_read_op = 0; 9310428Sandreas.hansson@arm.com end_write_op = 0; 9410428Sandreas.hansson@arm.com end_act_op = 0; 9510428Sandreas.hansson@arm.com 9610428Sandreas.hansson@arm.com first_act_cycle = 0; 9710428Sandreas.hansson@arm.com last_pre_cycle = 0; 9810428Sandreas.hansson@arm.com 9910428Sandreas.hansson@arm.com bankstate.resize(nbrofBanks, 0); 10010428Sandreas.hansson@arm.com last_states.resize(nbrofBanks); 10110428Sandreas.hansson@arm.com mem_state = 0; 10210428Sandreas.hansson@arm.com 10310428Sandreas.hansson@arm.com sref_cycle = 0; 10410428Sandreas.hansson@arm.com pdn_cycle = 0; 10510428Sandreas.hansson@arm.com 10610428Sandreas.hansson@arm.com cmd_list.clear(); 10710428Sandreas.hansson@arm.com full_cmd_list.resize(1, MemCommand::PRE); 10810428Sandreas.hansson@arm.com cached_cmd.clear(); 10910428Sandreas.hansson@arm.com activation_cycle.resize(nbrofBanks, 0); 11010428Sandreas.hansson@arm.com} 11110428Sandreas.hansson@arm.com 11210428Sandreas.hansson@arm.com// function to clear all arrays 11310428Sandreas.hansson@arm.comvoid CommandAnalysis::clear() 11410428Sandreas.hansson@arm.com{ 11510428Sandreas.hansson@arm.com cached_cmd.clear(); 11610428Sandreas.hansson@arm.com cmd_list.clear(); 11710428Sandreas.hansson@arm.com full_cmd_list.clear(); 11810428Sandreas.hansson@arm.com last_states.clear(); 11910428Sandreas.hansson@arm.com bankstate.clear(); 12010428Sandreas.hansson@arm.com} 12110428Sandreas.hansson@arm.com 12210428Sandreas.hansson@arm.com// Reads through the trace file, identifies the timestamp, command and bank 12310428Sandreas.hansson@arm.com// If the issued command includes an auto-precharge, adds an explicit 12410428Sandreas.hansson@arm.com// precharge to a cached command list and computes the precharge offset from the 12510428Sandreas.hansson@arm.com// issued command timestamp, when the auto-precharge would kick in 12610428Sandreas.hansson@arm.com 12710428Sandreas.hansson@arm.comvoid CommandAnalysis::getCommands(const Data::MemorySpecification& memSpec, 12810428Sandreas.hansson@arm.com const int nbrofBanks, std::vector<MemCommand>& list, bool lastupdate) 12910428Sandreas.hansson@arm.com{ 13010428Sandreas.hansson@arm.com for (vector<MemCommand>::const_iterator i = list.begin(); i != list.end(); ++i) { 13110428Sandreas.hansson@arm.com const MemCommand& cmd = *i; 13210428Sandreas.hansson@arm.com cmd_list.push_back(cmd); 13310428Sandreas.hansson@arm.com 13410428Sandreas.hansson@arm.com MemCommand::cmds cmdType = cmd.getType(); 13510428Sandreas.hansson@arm.com if (cmdType == MemCommand::ACT) { 13610428Sandreas.hansson@arm.com activation_cycle[cmd.getBank()] = cmd.getTimeInt64(); 13710428Sandreas.hansson@arm.com } else if (cmdType == MemCommand::RDA || cmdType == MemCommand::WRA) { 13810428Sandreas.hansson@arm.com // Remove auto-precharge flag from command 13910428Sandreas.hansson@arm.com cmd_list.back().setType(cmd.typeWithoutAutoPrechargeFlag()); 14010428Sandreas.hansson@arm.com 14110428Sandreas.hansson@arm.com // Add the auto precharge to the list of cached_cmds 14210428Sandreas.hansson@arm.com int64_t preTime = max(cmd.getTimeInt64() + cmd.getPrechargeOffset(memSpec, cmdType), 14310428Sandreas.hansson@arm.com activation_cycle[cmd.getBank()] + memSpec.memTimingSpec.RAS); 14410428Sandreas.hansson@arm.com cached_cmd.push_back(MemCommand(MemCommand::PRE, cmd.getBank(), static_cast<double>(preTime))); 14510428Sandreas.hansson@arm.com } 14610428Sandreas.hansson@arm.com } 14710428Sandreas.hansson@arm.com pop = 0; 14810428Sandreas.hansson@arm.com // Note: the extra pre-cmds at the end of the lists, and the cast to double 14910428Sandreas.hansson@arm.com // of the size vector is probably not desirable. 15010428Sandreas.hansson@arm.com cmd_list.push_back(MemCommand::PRE); 15110428Sandreas.hansson@arm.com cached_cmd.push_back(MemCommand::PRE); 15210428Sandreas.hansson@arm.com analyse_commands(nbrofBanks, memSpec, cmd_list.size()-1, 15310428Sandreas.hansson@arm.com cached_cmd.size()-1, lastupdate); 15410428Sandreas.hansson@arm.com cmd_list.clear(); 15510428Sandreas.hansson@arm.com cached_cmd.clear(); 15610428Sandreas.hansson@arm.com} // CommandAnalysis::getCommands 15710428Sandreas.hansson@arm.com 15810428Sandreas.hansson@arm.com// Checks the auto-precharge cached command list and inserts the explicit 15910428Sandreas.hansson@arm.com// precharges with the appropriate timestamp in the original command list 16010428Sandreas.hansson@arm.com// (by merging) based on their offset from the issuing command. Calls the 16110428Sandreas.hansson@arm.com// evaluate function to analyse this expanded list of commands. 16210428Sandreas.hansson@arm.com 16310428Sandreas.hansson@arm.comvoid CommandAnalysis::analyse_commands(const int nbrofBanks, 16410428Sandreas.hansson@arm.com Data::MemorySpecification memSpec, int64_t nCommands, int64_t nCached, bool lastupdate) 16510428Sandreas.hansson@arm.com{ 16610428Sandreas.hansson@arm.com full_cmd_list.resize(1, MemCommand::PRE); 16710428Sandreas.hansson@arm.com unsigned mCommands = 0; 16810428Sandreas.hansson@arm.com unsigned mCached = 0; 16910428Sandreas.hansson@arm.com for (unsigned i = 0; i < nCommands + nCached + 1; i++) { 17010428Sandreas.hansson@arm.com if (cached_cmd.size() > 1) { 17110428Sandreas.hansson@arm.com if ((cmd_list[mCommands].getTime() > 1) && (init == 0)) { 17210428Sandreas.hansson@arm.com full_cmd_list[i].setType(MemCommand::PREA); 17310428Sandreas.hansson@arm.com init = 1; 17410428Sandreas.hansson@arm.com pop = 1; 17510428Sandreas.hansson@arm.com } else { 17610428Sandreas.hansson@arm.com init = 1; 17710428Sandreas.hansson@arm.com if ((cached_cmd[mCached].getTime() > 0) && (cmd_list. 17810428Sandreas.hansson@arm.com at(mCommands).getTime() < cached_cmd[mCached]. 17910428Sandreas.hansson@arm.com getTime()) && ((cmd_list[mCommands].getTime() > 0) || 18010428Sandreas.hansson@arm.com ((cmd_list[mCommands].getTime() == 0) && (cmd_list[mCommands]. 18110428Sandreas.hansson@arm.com getType() != MemCommand::PRE)))) { 18210428Sandreas.hansson@arm.com full_cmd_list[i] = cmd_list[mCommands]; 18310428Sandreas.hansson@arm.com mCommands++; 18410428Sandreas.hansson@arm.com } else if ((cached_cmd[mCached].getTime() > 0) && (cmd_list[mCommands]. 18510428Sandreas.hansson@arm.com getTime() >= cached_cmd[mCached].getTime())) { 18610428Sandreas.hansson@arm.com full_cmd_list[i] = cached_cmd[mCached]; 18710428Sandreas.hansson@arm.com mCached++; 18810428Sandreas.hansson@arm.com } else if (cached_cmd[mCached].getTime() == 0) { 18910428Sandreas.hansson@arm.com if ((cmd_list[mCommands].getTime() > 0) || ((cmd_list[mCommands]. 19010428Sandreas.hansson@arm.com getTime() == 0) && (cmd_list[mCommands]. 19110428Sandreas.hansson@arm.com getType() != MemCommand::PRE))) { 19210428Sandreas.hansson@arm.com full_cmd_list[i] = cmd_list[mCommands]; 19310428Sandreas.hansson@arm.com mCommands++; 19410428Sandreas.hansson@arm.com } 19510428Sandreas.hansson@arm.com } else if (cmd_list[mCommands].getTime() == 0) { 19610428Sandreas.hansson@arm.com full_cmd_list[i] = cached_cmd[mCached]; 19710428Sandreas.hansson@arm.com mCached++; 19810428Sandreas.hansson@arm.com } 19910428Sandreas.hansson@arm.com } 20010428Sandreas.hansson@arm.com } else { 20110428Sandreas.hansson@arm.com if ((cmd_list[mCommands].getTime() > 1) && (init == 0)) { 20210428Sandreas.hansson@arm.com full_cmd_list[i].setType(MemCommand::PREA); 20310428Sandreas.hansson@arm.com init = 1; 20410428Sandreas.hansson@arm.com pop = 1; 20510428Sandreas.hansson@arm.com } else { 20610428Sandreas.hansson@arm.com init = 1; 20710428Sandreas.hansson@arm.com if ((cmd_list[mCommands].getTime() > 0) || ((cmd_list. 20810428Sandreas.hansson@arm.com at(mCommands).getTime() == 0) && (cmd_list[mCommands]. 20910428Sandreas.hansson@arm.com getType() != MemCommand::PRE))) { 21010428Sandreas.hansson@arm.com full_cmd_list[i] = cmd_list[mCommands]; 21110428Sandreas.hansson@arm.com mCommands++; 21210428Sandreas.hansson@arm.com } 21310428Sandreas.hansson@arm.com } 21410428Sandreas.hansson@arm.com } 21510428Sandreas.hansson@arm.com full_cmd_list.resize(full_cmd_list.size() + 1, MemCommand::PRE); 21610428Sandreas.hansson@arm.com } 21710428Sandreas.hansson@arm.com 21810428Sandreas.hansson@arm.com full_cmd_list.pop_back(); 21910428Sandreas.hansson@arm.com if (pop == 0) { 22010428Sandreas.hansson@arm.com full_cmd_list.pop_back(); 22110428Sandreas.hansson@arm.com } 22210428Sandreas.hansson@arm.com if (lastupdate) { 22310428Sandreas.hansson@arm.com full_cmd_list.resize(full_cmd_list.size() + 1, MemCommand::NOP); 22410428Sandreas.hansson@arm.com full_cmd_list[full_cmd_list.size() - 1].setTime(full_cmd_list 22510428Sandreas.hansson@arm.com [full_cmd_list.size() - 2].getTime() + timeToCompletion(memSpec, 22610428Sandreas.hansson@arm.com full_cmd_list[full_cmd_list.size() - 2].getType()) - 1); 22710428Sandreas.hansson@arm.com } 22810428Sandreas.hansson@arm.com 22910428Sandreas.hansson@arm.com evaluate(memSpec, full_cmd_list, nbrofBanks); 23010428Sandreas.hansson@arm.com} // CommandAnalysis::analyse_commands 23110428Sandreas.hansson@arm.com 23210428Sandreas.hansson@arm.com// To get the time of completion of the issued command 23310428Sandreas.hansson@arm.com// Derived based on JEDEC specifications 23410428Sandreas.hansson@arm.com 23510428Sandreas.hansson@arm.comint CommandAnalysis::timeToCompletion(const MemorySpecification& 23610428Sandreas.hansson@arm.com memSpec, MemCommand::cmds type) 23710428Sandreas.hansson@arm.com{ 23810428Sandreas.hansson@arm.com int offset = 0; 23910428Sandreas.hansson@arm.com const MemTimingSpec& memTimingSpec = memSpec.memTimingSpec; 24010428Sandreas.hansson@arm.com const MemArchitectureSpec& memArchSpec = memSpec.memArchSpec; 24110428Sandreas.hansson@arm.com 24210428Sandreas.hansson@arm.com if (type == MemCommand::RD) { 24310428Sandreas.hansson@arm.com offset = static_cast<int>(memTimingSpec.RL + 24410428Sandreas.hansson@arm.com memTimingSpec.DQSCK + 1 + (memArchSpec.burstLength / 24510428Sandreas.hansson@arm.com memArchSpec.dataRate)); 24610428Sandreas.hansson@arm.com } else if (type == MemCommand::WR) { 24710428Sandreas.hansson@arm.com offset = static_cast<int>(memTimingSpec.WL + 24810428Sandreas.hansson@arm.com (memArchSpec.burstLength / memArchSpec.dataRate) + 24910428Sandreas.hansson@arm.com memTimingSpec.WR); 25010428Sandreas.hansson@arm.com } else if (type == MemCommand::ACT) { 25110428Sandreas.hansson@arm.com offset = static_cast<int>(memTimingSpec.RCD); 25210428Sandreas.hansson@arm.com } else if ((type == MemCommand::PRE) || (type == MemCommand::PREA)) { 25310428Sandreas.hansson@arm.com offset = static_cast<int>(memTimingSpec.RP); 25410428Sandreas.hansson@arm.com } 25510428Sandreas.hansson@arm.com return offset; 25610428Sandreas.hansson@arm.com} // CommandAnalysis::timeToCompletion 25710428Sandreas.hansson@arm.com 25810428Sandreas.hansson@arm.com// Used to analyse a given list of commands and identify command timings 25910428Sandreas.hansson@arm.com// and memory state transitions 26010428Sandreas.hansson@arm.comvoid CommandAnalysis::evaluate(const MemorySpecification& memSpec, 26110428Sandreas.hansson@arm.com vector<MemCommand>& cmd_list, int nbrofBanks) 26210428Sandreas.hansson@arm.com{ 26310428Sandreas.hansson@arm.com // for each command identify timestamp, type and bank 26410428Sandreas.hansson@arm.com for (unsigned cmd_list_counter = 0; cmd_list_counter < cmd_list.size(); 26510428Sandreas.hansson@arm.com cmd_list_counter++) { 26610428Sandreas.hansson@arm.com // For command type 26710428Sandreas.hansson@arm.com int type = cmd_list[cmd_list_counter].getType(); 26810428Sandreas.hansson@arm.com // For command bank 26910428Sandreas.hansson@arm.com int bank = cmd_list[cmd_list_counter].getBank(); 27010428Sandreas.hansson@arm.com // Command Issue timestamp in clock cycles (cc) 27110428Sandreas.hansson@arm.com int64_t timestamp = cmd_list[cmd_list_counter].getTimeInt64(); 27210428Sandreas.hansson@arm.com 27310428Sandreas.hansson@arm.com if (type == MemCommand::ACT) { 27410428Sandreas.hansson@arm.com // If command is ACT - update number of acts, bank state of the 27510428Sandreas.hansson@arm.com // target bank, first and latest activation cycle and the memory 27610428Sandreas.hansson@arm.com // state. Update the number of precharged/idle-precharged cycles. 27710428Sandreas.hansson@arm.com numberofacts++; 27810428Sandreas.hansson@arm.com if (bankstate[bank] == 1) { 27910428Sandreas.hansson@arm.com printWarning("Bank is already active!", type, timestamp, bank); 28010428Sandreas.hansson@arm.com } 28110428Sandreas.hansson@arm.com bankstate[bank] = 1; 28210428Sandreas.hansson@arm.com if (mem_state == 0) { 28310428Sandreas.hansson@arm.com first_act_cycle = timestamp; 28410428Sandreas.hansson@arm.com precycles += max(zero, timestamp - last_pre_cycle); 28510428Sandreas.hansson@arm.com idle_pre_update(memSpec, timestamp, latest_pre_cycle); 28610428Sandreas.hansson@arm.com } 28710428Sandreas.hansson@arm.com latest_act_cycle = timestamp; 28810428Sandreas.hansson@arm.com mem_state++; 28910428Sandreas.hansson@arm.com } else if (type == MemCommand::RD) { 29010428Sandreas.hansson@arm.com // If command is RD - update number of reads and read cycle. Check 29110428Sandreas.hansson@arm.com // for active idle cycles (if any). 29210428Sandreas.hansson@arm.com if (bankstate[bank] == 0) { 29310428Sandreas.hansson@arm.com printWarning("Bank is not active!", type, timestamp, bank); 29410428Sandreas.hansson@arm.com } 29510428Sandreas.hansson@arm.com numberofreads++; 29610428Sandreas.hansson@arm.com idle_act_update(memSpec, latest_read_cycle, latest_write_cycle, 29710428Sandreas.hansson@arm.com latest_act_cycle, timestamp); 29810428Sandreas.hansson@arm.com latest_read_cycle = timestamp; 29910428Sandreas.hansson@arm.com } else if (type == MemCommand::WR) { 30010428Sandreas.hansson@arm.com // If command is WR - update number of writes and write cycle. Check 30110428Sandreas.hansson@arm.com // for active idle cycles (if any). 30210428Sandreas.hansson@arm.com if (bankstate[bank] == 0) { 30310428Sandreas.hansson@arm.com printWarning("Bank is not active!", type, timestamp, bank); 30410428Sandreas.hansson@arm.com } 30510428Sandreas.hansson@arm.com numberofwrites++; 30610428Sandreas.hansson@arm.com idle_act_update(memSpec, latest_read_cycle, latest_write_cycle, 30710428Sandreas.hansson@arm.com latest_act_cycle, timestamp); 30810428Sandreas.hansson@arm.com latest_write_cycle = timestamp; 30910428Sandreas.hansson@arm.com } else if (type == MemCommand::REF) { 31010428Sandreas.hansson@arm.com // If command is REF - update number of refreshes, set bank state of 31110428Sandreas.hansson@arm.com // all banks to ACT, set the last PRE cycles at RFC-RP cycles from 31210428Sandreas.hansson@arm.com // timestamp, set the number of active cycles to RFC-RP and check 31310428Sandreas.hansson@arm.com // for active and precharged cycles and idle active and idle 31410428Sandreas.hansson@arm.com // precharged cycles before refresh. Change memory state to 0. 31510428Sandreas.hansson@arm.com printWarningIfActive("One or more banks are active! REF requires all banks to be precharged.", type, timestamp, bank); 31610428Sandreas.hansson@arm.com numberofrefs++; 31710428Sandreas.hansson@arm.com idle_pre_update(memSpec, timestamp, latest_pre_cycle); 31810428Sandreas.hansson@arm.com first_act_cycle = timestamp; 31910428Sandreas.hansson@arm.com precycles += max(zero, timestamp - last_pre_cycle); 32010428Sandreas.hansson@arm.com last_pre_cycle = timestamp + memSpec.memTimingSpec.RFC - 32110428Sandreas.hansson@arm.com memSpec.memTimingSpec.RP; 32210428Sandreas.hansson@arm.com latest_pre_cycle = last_pre_cycle; 32310428Sandreas.hansson@arm.com actcycles += memSpec.memTimingSpec.RFC - memSpec.memTimingSpec.RP; 32410428Sandreas.hansson@arm.com mem_state = 0; 32510428Sandreas.hansson@arm.com for (int j = 0; j < nbrofBanks; j++) { 32610428Sandreas.hansson@arm.com bankstate[j] = 0; 32710428Sandreas.hansson@arm.com } 32810428Sandreas.hansson@arm.com } else if (type == MemCommand::PRE) { 32910428Sandreas.hansson@arm.com // If command is explicit PRE - update number of precharges, bank 33010428Sandreas.hansson@arm.com // state of the target bank and last and latest precharge cycle. 33110428Sandreas.hansson@arm.com // Calculate the number of active cycles if the memory was in the 33210428Sandreas.hansson@arm.com // active state before, but there is a state transition to PRE now. 33310428Sandreas.hansson@arm.com // If not, update the number of precharged cycles and idle cycles. 33410428Sandreas.hansson@arm.com // Update memory state if needed. 33510428Sandreas.hansson@arm.com if (bankstate[bank] == 1) { 33610428Sandreas.hansson@arm.com numberofpres++; 33710428Sandreas.hansson@arm.com } 33810428Sandreas.hansson@arm.com bankstate[bank] = 0; 33910428Sandreas.hansson@arm.com 34010428Sandreas.hansson@arm.com if (mem_state == 1) { 34110428Sandreas.hansson@arm.com actcycles += max(zero, timestamp - first_act_cycle); 34210428Sandreas.hansson@arm.com last_pre_cycle = timestamp; 34310428Sandreas.hansson@arm.com idle_act_update(memSpec, latest_read_cycle, latest_write_cycle, 34410428Sandreas.hansson@arm.com latest_act_cycle, timestamp); 34510428Sandreas.hansson@arm.com } else if (mem_state == 0) { 34610428Sandreas.hansson@arm.com precycles += max(zero, timestamp - last_pre_cycle); 34710428Sandreas.hansson@arm.com idle_pre_update(memSpec, timestamp, latest_pre_cycle); 34810428Sandreas.hansson@arm.com last_pre_cycle = timestamp; 34910428Sandreas.hansson@arm.com } 35010428Sandreas.hansson@arm.com latest_pre_cycle = timestamp; 35110428Sandreas.hansson@arm.com if (mem_state > 0) { 35210428Sandreas.hansson@arm.com mem_state--; 35310428Sandreas.hansson@arm.com } else { 35410428Sandreas.hansson@arm.com mem_state = 0; 35510428Sandreas.hansson@arm.com } 35610428Sandreas.hansson@arm.com } else if (type == MemCommand::PREA) { 35710428Sandreas.hansson@arm.com // If command is explicit PREA (precharge all banks) - update 35810428Sandreas.hansson@arm.com // number of precharges by the number of banks, update the bank 35910428Sandreas.hansson@arm.com // state of all banks to PRE and set the precharge cycle. 36010428Sandreas.hansson@arm.com // Calculate the number of active cycles if the memory was in the 36110428Sandreas.hansson@arm.com // active state before, but there is a state transition to PRE now. 36210428Sandreas.hansson@arm.com // If not, update the number of precharged cycles and idle cycles. 36310428Sandreas.hansson@arm.com if (timestamp == 0) { 36410428Sandreas.hansson@arm.com numberofpres += 0; 36510428Sandreas.hansson@arm.com } else { 36610428Sandreas.hansson@arm.com numberofpres += mem_state; 36710428Sandreas.hansson@arm.com } 36810428Sandreas.hansson@arm.com 36910428Sandreas.hansson@arm.com if (mem_state > 0) { 37010428Sandreas.hansson@arm.com actcycles += max(zero, timestamp - first_act_cycle); 37110428Sandreas.hansson@arm.com idle_act_update(memSpec, latest_read_cycle, latest_write_cycle, 37210428Sandreas.hansson@arm.com latest_act_cycle, timestamp); 37310428Sandreas.hansson@arm.com } else if (mem_state == 0) { 37410428Sandreas.hansson@arm.com precycles += max(zero, timestamp - last_pre_cycle); 37510428Sandreas.hansson@arm.com idle_pre_update(memSpec, timestamp, latest_pre_cycle); 37610428Sandreas.hansson@arm.com } 37710428Sandreas.hansson@arm.com 37810428Sandreas.hansson@arm.com latest_pre_cycle = timestamp; 37910428Sandreas.hansson@arm.com last_pre_cycle = timestamp; 38010428Sandreas.hansson@arm.com 38110428Sandreas.hansson@arm.com mem_state = 0; 38210428Sandreas.hansson@arm.com 38310428Sandreas.hansson@arm.com for (int j = 0; j < nbrofBanks; j++) { 38410428Sandreas.hansson@arm.com bankstate[j] = 0; 38510428Sandreas.hansson@arm.com } 38610428Sandreas.hansson@arm.com } else if (type == MemCommand::PDN_F_ACT) { 38710428Sandreas.hansson@arm.com // If command is fast-exit active power-down - update number of 38810428Sandreas.hansson@arm.com // power-downs, set the power-down cycle and the memory mode to 38910428Sandreas.hansson@arm.com // fast-exit active power-down. Save states of all the banks from 39010428Sandreas.hansson@arm.com // the cycle before entering active power-down, to be returned to 39110428Sandreas.hansson@arm.com // after powering-up. Update active and active idle cycles. 39210428Sandreas.hansson@arm.com printWarningIfNotActive("All banks are precharged! Incorrect use of Active Power-Down.", type, timestamp, bank); 39310428Sandreas.hansson@arm.com f_act_pdns++; 39410428Sandreas.hansson@arm.com for (int j = 0; j < nbrofBanks; j++) { 39510428Sandreas.hansson@arm.com last_states[j] = bankstate[j]; 39610428Sandreas.hansson@arm.com } 39710428Sandreas.hansson@arm.com pdn_cycle = timestamp; 39810428Sandreas.hansson@arm.com actcycles += max(zero, timestamp - first_act_cycle); 39910428Sandreas.hansson@arm.com idle_act_update(memSpec, latest_read_cycle, latest_write_cycle, 40010428Sandreas.hansson@arm.com latest_act_cycle, timestamp); 40110428Sandreas.hansson@arm.com mem_state = CommandAnalysis::MS_PDN_F_ACT; 40210428Sandreas.hansson@arm.com } else if (type == MemCommand::PDN_S_ACT) { 40310428Sandreas.hansson@arm.com // If command is slow-exit active power-down - update number of 40410428Sandreas.hansson@arm.com // power-downs, set the power-down cycle and the memory mode to 40510428Sandreas.hansson@arm.com // slow-exit active power-down. Save states of all the banks from 40610428Sandreas.hansson@arm.com // the cycle before entering active power-down, to be returned to 40710428Sandreas.hansson@arm.com // after powering-up. Update active and active idle cycles. 40810428Sandreas.hansson@arm.com printWarningIfNotActive("All banks are precharged! Incorrect use of Active Power-Down.", type, timestamp, bank); 40910428Sandreas.hansson@arm.com s_act_pdns++; 41010428Sandreas.hansson@arm.com for (int j = 0; j < nbrofBanks; j++) { 41110428Sandreas.hansson@arm.com last_states[j] = bankstate[j]; 41210428Sandreas.hansson@arm.com } 41310428Sandreas.hansson@arm.com pdn_cycle = timestamp; 41410428Sandreas.hansson@arm.com actcycles += max(zero, timestamp - first_act_cycle); 41510428Sandreas.hansson@arm.com idle_act_update(memSpec, latest_read_cycle, latest_write_cycle, 41610428Sandreas.hansson@arm.com latest_act_cycle, timestamp); 41710428Sandreas.hansson@arm.com mem_state = CommandAnalysis::MS_PDN_S_ACT; 41810428Sandreas.hansson@arm.com } else if (type == MemCommand::PDN_F_PRE) { 41910428Sandreas.hansson@arm.com // If command is fast-exit precharged power-down - update number of 42010428Sandreas.hansson@arm.com // power-downs, set the power-down cycle and the memory mode to 42110428Sandreas.hansson@arm.com // fast-exit precahrged power-down. Update precharged and precharged 42210428Sandreas.hansson@arm.com // idle cycles. 42310428Sandreas.hansson@arm.com printWarningIfActive("One or more banks are active! Incorrect use of Precharged Power-Down.", type, timestamp, bank); 42410428Sandreas.hansson@arm.com f_pre_pdns++; 42510428Sandreas.hansson@arm.com pdn_cycle = timestamp; 42610428Sandreas.hansson@arm.com precycles += max(zero, timestamp - last_pre_cycle); 42710428Sandreas.hansson@arm.com idle_pre_update(memSpec, timestamp, latest_pre_cycle); 42810428Sandreas.hansson@arm.com mem_state = CommandAnalysis::MS_PDN_F_PRE; 42910428Sandreas.hansson@arm.com } else if (type == MemCommand::PDN_S_PRE) { 43010428Sandreas.hansson@arm.com // If command is slow-exit precharged power-down - update number of 43110428Sandreas.hansson@arm.com // power-downs, set the power-down cycle and the memory mode to 43210428Sandreas.hansson@arm.com // slow-exit precahrged power-down. Update precharged and precharged 43310428Sandreas.hansson@arm.com // idle cycles. 43410428Sandreas.hansson@arm.com printWarningIfActive("One or more banks are active! Incorrect use of Precharged Power-Down.", type, timestamp, bank); 43510428Sandreas.hansson@arm.com s_pre_pdns++; 43610428Sandreas.hansson@arm.com pdn_cycle = timestamp; 43710428Sandreas.hansson@arm.com precycles += max(zero, timestamp - last_pre_cycle); 43810428Sandreas.hansson@arm.com idle_pre_update(memSpec, timestamp, latest_pre_cycle); 43910428Sandreas.hansson@arm.com mem_state = CommandAnalysis::MS_PDN_S_PRE; 44010428Sandreas.hansson@arm.com } else if (type == MemCommand::PUP_ACT) { 44110428Sandreas.hansson@arm.com // If command is power-up in the active mode - check the power-down 44210428Sandreas.hansson@arm.com // exit-mode employed (fast or slow), update the number of power-down 44310428Sandreas.hansson@arm.com // and power-up cycles and the latest and first act cycle. Also, reset 44410428Sandreas.hansson@arm.com // all the individual bank states to the respective saved states 44510428Sandreas.hansson@arm.com // before entering power-down. 44610428Sandreas.hansson@arm.com if (mem_state == CommandAnalysis::MS_PDN_F_ACT) { 44710428Sandreas.hansson@arm.com f_act_pdcycles += max(zero, timestamp - pdn_cycle); 44810428Sandreas.hansson@arm.com pup_act_cycles += memSpec.memTimingSpec.XP; 44910428Sandreas.hansson@arm.com latest_act_cycle = max(timestamp, timestamp + 45010428Sandreas.hansson@arm.com memSpec.memTimingSpec.XP - memSpec.memTimingSpec.RCD); 45110428Sandreas.hansson@arm.com } else if (mem_state == CommandAnalysis::MS_PDN_S_ACT) { 45210428Sandreas.hansson@arm.com s_act_pdcycles += max(zero, timestamp - pdn_cycle); 45310428Sandreas.hansson@arm.com if (memSpec.memArchSpec.dll == false) { 45410428Sandreas.hansson@arm.com pup_act_cycles += memSpec.memTimingSpec.XP; 45510428Sandreas.hansson@arm.com latest_act_cycle = max(timestamp, timestamp + 45610428Sandreas.hansson@arm.com memSpec.memTimingSpec.XP - memSpec.memTimingSpec.RCD); 45710428Sandreas.hansson@arm.com } else { 45810428Sandreas.hansson@arm.com pup_act_cycles += memSpec.memTimingSpec.XPDLL - 45910428Sandreas.hansson@arm.com memSpec.memTimingSpec.RCD; 46010428Sandreas.hansson@arm.com latest_act_cycle = max(timestamp, timestamp + 46110428Sandreas.hansson@arm.com memSpec.memTimingSpec.XPDLL - 46210428Sandreas.hansson@arm.com (2 * memSpec.memTimingSpec.RCD)); 46310428Sandreas.hansson@arm.com } 46410428Sandreas.hansson@arm.com } else if ((mem_state != CommandAnalysis::MS_PDN_S_ACT) || (mem_state != 46510428Sandreas.hansson@arm.com CommandAnalysis::MS_PDN_F_ACT)) { 46610428Sandreas.hansson@arm.com cerr << "Incorrect use of Active Power-Up!" << endl; 46710428Sandreas.hansson@arm.com } 46810428Sandreas.hansson@arm.com mem_state = 0; 46910428Sandreas.hansson@arm.com for (int j = 0; j < nbrofBanks; j++) { 47010428Sandreas.hansson@arm.com bankstate[j] = last_states[j]; 47110428Sandreas.hansson@arm.com mem_state += last_states[j]; 47210428Sandreas.hansson@arm.com } 47310428Sandreas.hansson@arm.com first_act_cycle = timestamp; 47410428Sandreas.hansson@arm.com } else if (type == MemCommand::PUP_PRE) { 47510428Sandreas.hansson@arm.com // If command is power-up in the precharged mode - check the power-down 47610428Sandreas.hansson@arm.com // exit-mode employed (fast or slow), update the number of power-down 47710428Sandreas.hansson@arm.com // and power-up cycles and the latest and last pre cycle. 47810428Sandreas.hansson@arm.com if (mem_state == CommandAnalysis::MS_PDN_F_PRE) { 47910428Sandreas.hansson@arm.com f_pre_pdcycles += max(zero, timestamp - pdn_cycle); 48010428Sandreas.hansson@arm.com pup_pre_cycles += memSpec.memTimingSpec.XP; 48110428Sandreas.hansson@arm.com latest_pre_cycle = max(timestamp, timestamp + 48210428Sandreas.hansson@arm.com memSpec.memTimingSpec.XP - memSpec.memTimingSpec.RP); 48310428Sandreas.hansson@arm.com } else if (mem_state == CommandAnalysis::MS_PDN_S_PRE) { 48410428Sandreas.hansson@arm.com s_pre_pdcycles += max(zero, timestamp - pdn_cycle); 48510428Sandreas.hansson@arm.com if (memSpec.memArchSpec.dll == false) { 48610428Sandreas.hansson@arm.com pup_pre_cycles += memSpec.memTimingSpec.XP; 48710428Sandreas.hansson@arm.com latest_pre_cycle = max(timestamp, timestamp + 48810428Sandreas.hansson@arm.com memSpec.memTimingSpec.XP - memSpec.memTimingSpec.RP); 48910428Sandreas.hansson@arm.com } else { 49010428Sandreas.hansson@arm.com pup_pre_cycles += memSpec.memTimingSpec.XPDLL - 49110428Sandreas.hansson@arm.com memSpec.memTimingSpec.RCD; 49210428Sandreas.hansson@arm.com latest_pre_cycle = max(timestamp, timestamp + 49310428Sandreas.hansson@arm.com memSpec.memTimingSpec.XPDLL - memSpec.memTimingSpec.RCD - 49410428Sandreas.hansson@arm.com memSpec.memTimingSpec.RP); 49510428Sandreas.hansson@arm.com } 49610428Sandreas.hansson@arm.com } else if ((mem_state != CommandAnalysis::MS_PDN_S_PRE) || (mem_state != 49710428Sandreas.hansson@arm.com CommandAnalysis::MS_PDN_F_PRE)) { 49810428Sandreas.hansson@arm.com cerr << "Incorrect use of Precharged Power-Up!" << endl; 49910428Sandreas.hansson@arm.com } 50010428Sandreas.hansson@arm.com mem_state = 0; 50110428Sandreas.hansson@arm.com last_pre_cycle = timestamp; 50210428Sandreas.hansson@arm.com } else if (type == MemCommand::SREN) { 50310428Sandreas.hansson@arm.com // If command is self-refresh - update number of self-refreshes, 50410428Sandreas.hansson@arm.com // set memory state to SREF, update precharge and idle precharge 50510428Sandreas.hansson@arm.com // cycles and set the self-refresh cycle. 50610428Sandreas.hansson@arm.com printWarningIfActive("One or more banks are active! SREF requires all banks to be precharged.", type, timestamp, bank); 50710428Sandreas.hansson@arm.com numberofsrefs++; 50810428Sandreas.hansson@arm.com sref_cycle = timestamp; 50910428Sandreas.hansson@arm.com precycles += max(zero, timestamp - last_pre_cycle); 51010428Sandreas.hansson@arm.com idle_pre_update(memSpec, timestamp, latest_pre_cycle); 51110428Sandreas.hansson@arm.com mem_state = CommandAnalysis::MS_SREF; 51210428Sandreas.hansson@arm.com } else if (type == MemCommand::SREX) { 51310428Sandreas.hansson@arm.com // If command is self-refresh exit - update the number of self-refresh 51410428Sandreas.hansson@arm.com // clock cycles, number of active and precharged auto-refresh clock 51510428Sandreas.hansson@arm.com // cycles during self-refresh and self-refresh exit based on the number 51610428Sandreas.hansson@arm.com // of cycles in the self-refresh mode and auto-refresh duration (RFC). 51710428Sandreas.hansson@arm.com // Set the last and latest precharge cycle accordingly and set the 51810428Sandreas.hansson@arm.com // memory state to 0. 51910428Sandreas.hansson@arm.com if (mem_state != CommandAnalysis::MS_SREF) { 52010428Sandreas.hansson@arm.com cerr << "Incorrect use of Self-Refresh Power-Up!" << endl; 52110428Sandreas.hansson@arm.com } 52210428Sandreas.hansson@arm.com if (max(zero, timestamp - sref_cycle) >= memSpec.memTimingSpec.RFC) { 52310428Sandreas.hansson@arm.com sref_cycles += max(zero, timestamp - sref_cycle 52410428Sandreas.hansson@arm.com - memSpec.memTimingSpec.RFC); 52510428Sandreas.hansson@arm.com sref_ref_act_cycles += memSpec.memTimingSpec.RFC - 52610428Sandreas.hansson@arm.com memSpec.memTimingSpec.RP; 52710428Sandreas.hansson@arm.com sref_ref_pre_cycles += memSpec.memTimingSpec.RP; 52810428Sandreas.hansson@arm.com last_pre_cycle = timestamp; 52910428Sandreas.hansson@arm.com if (memSpec.memArchSpec.dll == false) { 53010428Sandreas.hansson@arm.com spup_cycles += memSpec.memTimingSpec.XS; 53110428Sandreas.hansson@arm.com latest_pre_cycle = max(timestamp, timestamp + 53210428Sandreas.hansson@arm.com memSpec.memTimingSpec.XS - memSpec.memTimingSpec.RP); 53310428Sandreas.hansson@arm.com } else { 53410428Sandreas.hansson@arm.com spup_cycles += memSpec.memTimingSpec.XSDLL - 53510428Sandreas.hansson@arm.com memSpec.memTimingSpec.RCD; 53610428Sandreas.hansson@arm.com latest_pre_cycle = max(timestamp, timestamp + 53710428Sandreas.hansson@arm.com memSpec.memTimingSpec.XSDLL - memSpec.memTimingSpec.RCD 53810428Sandreas.hansson@arm.com - memSpec.memTimingSpec.RP); 53910428Sandreas.hansson@arm.com } 54010428Sandreas.hansson@arm.com } else { 54110428Sandreas.hansson@arm.com int64_t sref_diff = memSpec.memTimingSpec.RFC - memSpec.memTimingSpec.RP; 54210428Sandreas.hansson@arm.com int64_t sref_pre = max(zero, timestamp - sref_cycle - sref_diff); 54310428Sandreas.hansson@arm.com int64_t spup_pre = memSpec.memTimingSpec.RP - sref_pre; 54410428Sandreas.hansson@arm.com int64_t sref_act = max(zero, timestamp - sref_cycle); 54510428Sandreas.hansson@arm.com int64_t spup_act = memSpec.memTimingSpec.RFC - sref_act; 54610428Sandreas.hansson@arm.com 54710428Sandreas.hansson@arm.com if (max(zero, timestamp - sref_cycle) >= sref_diff) { 54810428Sandreas.hansson@arm.com sref_ref_act_cycles += sref_diff; 54910428Sandreas.hansson@arm.com sref_ref_pre_cycles += sref_pre; 55010428Sandreas.hansson@arm.com spup_ref_pre_cycles += spup_pre; 55110428Sandreas.hansson@arm.com last_pre_cycle = timestamp + spup_pre; 55210428Sandreas.hansson@arm.com if (memSpec.memArchSpec.dll == false) { 55310428Sandreas.hansson@arm.com spup_cycles += memSpec.memTimingSpec.XS - spup_pre; 55410428Sandreas.hansson@arm.com latest_pre_cycle = max(timestamp, timestamp + 55510428Sandreas.hansson@arm.com memSpec.memTimingSpec.XS - spup_pre - 55610428Sandreas.hansson@arm.com memSpec.memTimingSpec.RP); 55710428Sandreas.hansson@arm.com } else { 55810428Sandreas.hansson@arm.com spup_cycles += memSpec.memTimingSpec.XSDLL - 55910428Sandreas.hansson@arm.com memSpec.memTimingSpec.RCD - spup_pre; 56010428Sandreas.hansson@arm.com latest_pre_cycle = max(timestamp, timestamp + 56110428Sandreas.hansson@arm.com memSpec.memTimingSpec.XSDLL - memSpec.memTimingSpec.RCD - 56210428Sandreas.hansson@arm.com spup_pre - memSpec.memTimingSpec.RP); 56310428Sandreas.hansson@arm.com } 56410428Sandreas.hansson@arm.com } else { 56510428Sandreas.hansson@arm.com sref_ref_act_cycles += sref_act; 56610428Sandreas.hansson@arm.com spup_ref_act_cycles += spup_act; 56710428Sandreas.hansson@arm.com spup_ref_pre_cycles += memSpec.memTimingSpec.RP; 56810428Sandreas.hansson@arm.com last_pre_cycle = timestamp + spup_act + memSpec.memTimingSpec.RP; 56910428Sandreas.hansson@arm.com if (memSpec.memArchSpec.dll == false) { 57010428Sandreas.hansson@arm.com spup_cycles += memSpec.memTimingSpec.XS - spup_act - 57110428Sandreas.hansson@arm.com memSpec.memTimingSpec.RP; 57210428Sandreas.hansson@arm.com latest_pre_cycle = max(timestamp, timestamp + 57310428Sandreas.hansson@arm.com memSpec.memTimingSpec.XS - spup_act - 57410428Sandreas.hansson@arm.com (2 * memSpec.memTimingSpec.RP)); 57510428Sandreas.hansson@arm.com } else { 57610428Sandreas.hansson@arm.com spup_cycles += memSpec.memTimingSpec.XSDLL - 57710428Sandreas.hansson@arm.com memSpec.memTimingSpec.RCD - spup_act - 57810428Sandreas.hansson@arm.com memSpec.memTimingSpec.RP; 57910428Sandreas.hansson@arm.com latest_pre_cycle = max(timestamp, timestamp + 58010428Sandreas.hansson@arm.com memSpec.memTimingSpec.XSDLL - memSpec.memTimingSpec.RCD - 58110428Sandreas.hansson@arm.com spup_act - (2 * memSpec.memTimingSpec.RP)); 58210428Sandreas.hansson@arm.com } 58310428Sandreas.hansson@arm.com } 58410428Sandreas.hansson@arm.com } 58510428Sandreas.hansson@arm.com mem_state = 0; 58610428Sandreas.hansson@arm.com } else if ((type == MemCommand::END) || (type == MemCommand::NOP)) { 58710428Sandreas.hansson@arm.com // May be optionally used at the end of memory trace for better accuracy 58810428Sandreas.hansson@arm.com // Update all counters based on completion of operations. 58910428Sandreas.hansson@arm.com if ((mem_state > 0) && (mem_state < 9)) { 59010428Sandreas.hansson@arm.com actcycles += max(zero, timestamp - first_act_cycle); 59110428Sandreas.hansson@arm.com idle_act_update(memSpec, latest_read_cycle, latest_write_cycle, 59210428Sandreas.hansson@arm.com latest_act_cycle, timestamp); 59310428Sandreas.hansson@arm.com } else if (mem_state == 0) { 59410428Sandreas.hansson@arm.com precycles += max(zero, timestamp - last_pre_cycle); 59510428Sandreas.hansson@arm.com idle_pre_update(memSpec, timestamp, latest_pre_cycle); 59610428Sandreas.hansson@arm.com } else if (mem_state == CommandAnalysis::MS_PDN_F_ACT) { 59710428Sandreas.hansson@arm.com f_act_pdcycles += max(zero, timestamp - pdn_cycle); 59810428Sandreas.hansson@arm.com } else if (mem_state == CommandAnalysis::MS_PDN_S_ACT) { 59910428Sandreas.hansson@arm.com s_act_pdcycles += max(zero, timestamp - pdn_cycle); 60010428Sandreas.hansson@arm.com } else if (mem_state == CommandAnalysis::MS_PDN_F_PRE) { 60110428Sandreas.hansson@arm.com f_pre_pdcycles += max(zero, timestamp - pdn_cycle); 60210428Sandreas.hansson@arm.com } else if (mem_state == CommandAnalysis::MS_PDN_S_PRE) { 60310428Sandreas.hansson@arm.com s_pre_pdcycles += max(zero, timestamp - pdn_cycle); 60410428Sandreas.hansson@arm.com } else if (mem_state == CommandAnalysis::MS_SREF) { 60510428Sandreas.hansson@arm.com sref_cycles += max(zero, timestamp - sref_cycle); 60610428Sandreas.hansson@arm.com } 60710428Sandreas.hansson@arm.com } 60810428Sandreas.hansson@arm.com } 60910428Sandreas.hansson@arm.com} // CommandAnalysis::evaluate 61010428Sandreas.hansson@arm.com 61110428Sandreas.hansson@arm.com// To update idle period information whenever active cycles may be idle 61210428Sandreas.hansson@arm.comvoid CommandAnalysis::idle_act_update(const MemorySpecification& memSpec, 61310428Sandreas.hansson@arm.com int64_t latest_read_cycle, int64_t latest_write_cycle, 61410428Sandreas.hansson@arm.com int64_t latest_act_cycle, int64_t timestamp) 61510428Sandreas.hansson@arm.com{ 61610428Sandreas.hansson@arm.com if (latest_read_cycle >= 0) { 61710428Sandreas.hansson@arm.com end_read_op = latest_read_cycle + timeToCompletion(memSpec, 61810428Sandreas.hansson@arm.com MemCommand::RD) - 1; 61910428Sandreas.hansson@arm.com } 62010428Sandreas.hansson@arm.com 62110428Sandreas.hansson@arm.com if (latest_write_cycle >= 0) { 62210428Sandreas.hansson@arm.com end_write_op = latest_write_cycle + timeToCompletion(memSpec, 62310428Sandreas.hansson@arm.com MemCommand::WR) - 1; 62410428Sandreas.hansson@arm.com } 62510428Sandreas.hansson@arm.com 62610428Sandreas.hansson@arm.com if (latest_act_cycle >= 0) { 62710428Sandreas.hansson@arm.com end_act_op = latest_act_cycle + timeToCompletion(memSpec, 62810428Sandreas.hansson@arm.com MemCommand::ACT) - 1; 62910428Sandreas.hansson@arm.com } 63010428Sandreas.hansson@arm.com 63110428Sandreas.hansson@arm.com idlecycles_act += max(zero, timestamp - max(max(end_read_op, end_write_op), 63210428Sandreas.hansson@arm.com end_act_op)); 63310428Sandreas.hansson@arm.com} // CommandAnalysis::idle_act_update 63410428Sandreas.hansson@arm.com 63510428Sandreas.hansson@arm.com// To update idle period information whenever precharged cycles may be idle 63610428Sandreas.hansson@arm.comvoid CommandAnalysis::idle_pre_update(const MemorySpecification& memSpec, 63710428Sandreas.hansson@arm.com int64_t timestamp, int64_t latest_pre_cycle) 63810428Sandreas.hansson@arm.com{ 63910428Sandreas.hansson@arm.com if (latest_pre_cycle > 0) { 64010428Sandreas.hansson@arm.com idlecycles_pre += max(zero, timestamp - latest_pre_cycle - 64110428Sandreas.hansson@arm.com memSpec.memTimingSpec.RP); 64210428Sandreas.hansson@arm.com } else if (latest_pre_cycle == 0) { 64310428Sandreas.hansson@arm.com idlecycles_pre += max(zero, timestamp - latest_pre_cycle); 64410428Sandreas.hansson@arm.com } 64510428Sandreas.hansson@arm.com} 64610428Sandreas.hansson@arm.com 64710428Sandreas.hansson@arm.comvoid CommandAnalysis::printWarningIfActive(const string& warning, int type, int64_t timestamp, int bank) 64810428Sandreas.hansson@arm.com{ 64910428Sandreas.hansson@arm.com if (mem_state != 0) { 65010428Sandreas.hansson@arm.com printWarning(warning, type, timestamp, bank); 65110428Sandreas.hansson@arm.com } 65210428Sandreas.hansson@arm.com} 65310428Sandreas.hansson@arm.com 65410428Sandreas.hansson@arm.comvoid CommandAnalysis::printWarningIfNotActive(const string& warning, int type, int64_t timestamp, int bank) 65510428Sandreas.hansson@arm.com{ 65610428Sandreas.hansson@arm.com if (mem_state == 0) { 65710428Sandreas.hansson@arm.com printWarning(warning, type, timestamp, bank); 65810428Sandreas.hansson@arm.com } 65910428Sandreas.hansson@arm.com} 66010428Sandreas.hansson@arm.com 66110428Sandreas.hansson@arm.comvoid CommandAnalysis::printWarning(const string& warning, int type, int64_t timestamp, int bank) 66210428Sandreas.hansson@arm.com{ 66310428Sandreas.hansson@arm.com cerr << "WARNING: " << warning << endl; 66410428Sandreas.hansson@arm.com cerr << "Command: " << type << ", Timestamp: " << timestamp << 66510428Sandreas.hansson@arm.com ", Bank: " << bank << endl; 66610428Sandreas.hansson@arm.com} 667