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