CmdScheduler.cc revision 11555
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 * 3411555Sjungma@eit.uni-kl.de * Authors: Karthik Chandrasekar, Yonghui Li, Sven Goossens 3510428Sandreas.hansson@arm.com * 3610428Sandreas.hansson@arm.com */ 3710428Sandreas.hansson@arm.com#include "CmdScheduler.h" 3810428Sandreas.hansson@arm.com 3910428Sandreas.hansson@arm.com#include <cassert> 4010428Sandreas.hansson@arm.com#include <cmath> // For log2 4110428Sandreas.hansson@arm.com 4210428Sandreas.hansson@arm.com#include <algorithm> // For max 4310428Sandreas.hansson@arm.com 4410428Sandreas.hansson@arm.com 4511555Sjungma@eit.uni-kl.de#define MILLION 1000000 4611555Sjungma@eit.uni-kl.de 4711555Sjungma@eit.uni-kl.de 4810428Sandreas.hansson@arm.comusing namespace std; 4910428Sandreas.hansson@arm.comusing namespace Data; 5010428Sandreas.hansson@arm.com 5110428Sandreas.hansson@arm.com// Read the traces and get the transaction. Each transaction is executed by 5210428Sandreas.hansson@arm.com// scheduling a number of commands to the memory. Hence, the transactions are 5310428Sandreas.hansson@arm.com// translated into a sequence of commands which will be used for power analysis. 5411555Sjungma@eit.uni-kl.devoid cmdScheduler::transTranslation(const MemorySpecification& memSpec, 5510428Sandreas.hansson@arm.com ifstream& trans_trace, int grouping, int interleaving, int burst, int powerdown) 5610428Sandreas.hansson@arm.com{ 5710428Sandreas.hansson@arm.com commands.open("commands.trace", ifstream::out); 5811555Sjungma@eit.uni-kl.de const MemArchitectureSpec& memArchSpec = memSpec.memArchSpec; 5910428Sandreas.hansson@arm.com nBanks = memArchSpec.nbrOfBanks; 6010428Sandreas.hansson@arm.com nColumns = memArchSpec.nbrOfColumns; 6110428Sandreas.hansson@arm.com burstLength = memArchSpec.burstLength; 6210428Sandreas.hansson@arm.com nbrOfBankGroups = memArchSpec.nbrOfBankGroups; 6310428Sandreas.hansson@arm.com 6410428Sandreas.hansson@arm.com BGI = grouping; 6510428Sandreas.hansson@arm.com BI = interleaving; 6610428Sandreas.hansson@arm.com BC = burst; 6710428Sandreas.hansson@arm.com power_down = powerdown; 6810428Sandreas.hansson@arm.com 6910428Sandreas.hansson@arm.com schedulingInitialization(memSpec); 7010428Sandreas.hansson@arm.com getTrans(trans_trace, memSpec); 7110428Sandreas.hansson@arm.com 7210428Sandreas.hansson@arm.com trans_trace.close(); 7310428Sandreas.hansson@arm.com commands.close(); 7410428Sandreas.hansson@arm.com ACT.erase(ACT.begin(), ACT.end()); 7510428Sandreas.hansson@arm.com PRE.erase(PRE.begin(), PRE.end()); 7610428Sandreas.hansson@arm.com RDWR.erase(RDWR.begin(), RDWR.end()); 7710428Sandreas.hansson@arm.com cmdScheduling.erase(cmdScheduling.begin(), cmdScheduling.end()); 7810428Sandreas.hansson@arm.com cmdList.erase(cmdList.begin(), cmdList.end()); 7910428Sandreas.hansson@arm.com transTrace.erase(transTrace.begin(), transTrace.end()); 8010428Sandreas.hansson@arm.com} // cmdScheduler::transTranslation 8110428Sandreas.hansson@arm.com 8210428Sandreas.hansson@arm.com// initialize the variables and vectors for starting command scheduling. 8311555Sjungma@eit.uni-kl.devoid cmdScheduler::schedulingInitialization(const MemorySpecification& memSpec) 8410428Sandreas.hansson@arm.com{ 8511555Sjungma@eit.uni-kl.de const MemTimingSpec& memTimingSpec = memSpec.memTimingSpec; 8610428Sandreas.hansson@arm.com 8711555Sjungma@eit.uni-kl.de const size_t numBanks = static_cast<size_t>(memSpec.memArchSpec.nbrOfBanks); 8811555Sjungma@eit.uni-kl.de ACT.resize(2 * numBanks); 8911555Sjungma@eit.uni-kl.de RDWR.resize(2 * numBanks); 9011555Sjungma@eit.uni-kl.de PRE.resize(numBanks); 9110428Sandreas.hansson@arm.com bankaccess = memSpec.memArchSpec.nbrOfBanks; 9210428Sandreas.hansson@arm.com if (!ACT.empty()) { 9310428Sandreas.hansson@arm.com ACT.erase(ACT.begin(), ACT.end()); 9410428Sandreas.hansson@arm.com } 9510428Sandreas.hansson@arm.com if (!PRE.empty()) { 9610428Sandreas.hansson@arm.com PRE.erase(PRE.begin(), PRE.end()); 9710428Sandreas.hansson@arm.com } 9810428Sandreas.hansson@arm.com if (!RDWR.empty()) { 9910428Sandreas.hansson@arm.com RDWR.erase(RDWR.begin(), RDWR.end()); 10010428Sandreas.hansson@arm.com } 10110428Sandreas.hansson@arm.com 10210428Sandreas.hansson@arm.com ///////////////initialization////////////// 10311555Sjungma@eit.uni-kl.de for (int64_t i = 0; i < memSpec.memArchSpec.nbrOfBanks; i++) { 10410428Sandreas.hansson@arm.com cmd.Type = PRECHARGE; 10511555Sjungma@eit.uni-kl.de cmd.bank = static_cast<unsigned>(i); 10610428Sandreas.hansson@arm.com cmd.name = "PRE"; 10711555Sjungma@eit.uni-kl.de if (memSpec.id == "WIDEIO_SDR") { 10811555Sjungma@eit.uni-kl.de cmd.time = 1 - memSpec.memTimingSpec.TAW; 10911555Sjungma@eit.uni-kl.de } else { 11011555Sjungma@eit.uni-kl.de cmd.time = 1 - memSpec.memTimingSpec.FAW; 11111555Sjungma@eit.uni-kl.de } 11210428Sandreas.hansson@arm.com 11310428Sandreas.hansson@arm.com PRE.push_back(cmd); 11410428Sandreas.hansson@arm.com 11510428Sandreas.hansson@arm.com cmd.Type = ACTIVATE; 11610428Sandreas.hansson@arm.com cmd.name = "ACT"; 11710428Sandreas.hansson@arm.com ACT.push_back(cmd); 11810428Sandreas.hansson@arm.com 11910428Sandreas.hansson@arm.com cmd.Type = WRITE; 12010428Sandreas.hansson@arm.com cmd.name = "WRITE"; 12110428Sandreas.hansson@arm.com cmd.time = -1; 12211555Sjungma@eit.uni-kl.de RDWR[static_cast<size_t>(i)].push_back(cmd); 12310428Sandreas.hansson@arm.com } 12410428Sandreas.hansson@arm.com tREF = memTimingSpec.REFI; 12510428Sandreas.hansson@arm.com transFinish.time = 0; 12610428Sandreas.hansson@arm.com transFinish.bank = 0; 12710428Sandreas.hansson@arm.com 12810428Sandreas.hansson@arm.com PreRDWR.bank = -1; 12910428Sandreas.hansson@arm.com PreRDWR.Type = READ; 13010428Sandreas.hansson@arm.com PreRDWR.name = "RD"; 13110428Sandreas.hansson@arm.com PreRDWR.time = -1; 13210428Sandreas.hansson@arm.com startTime = 0; 13310428Sandreas.hansson@arm.com} // cmdScheduler::schedulingInitialization 13410428Sandreas.hansson@arm.com 13510428Sandreas.hansson@arm.com// transactions are generated according to the information read from the traces. 13610428Sandreas.hansson@arm.com// Then the command scheduling function is triggered to generate commands and 13710428Sandreas.hansson@arm.com// schedule them to the memory according to the timing constraints. 13811555Sjungma@eit.uni-kl.devoid cmdScheduler::getTrans(std::ifstream& trans_trace, const MemorySpecification& memSpec) 13910428Sandreas.hansson@arm.com{ 14010428Sandreas.hansson@arm.com std::string line; 14110428Sandreas.hansson@arm.com 14210428Sandreas.hansson@arm.com transTime = 0; 14311555Sjungma@eit.uni-kl.de uint64_t newtranstime; 14411555Sjungma@eit.uni-kl.de uint64_t transAddr; 14511555Sjungma@eit.uni-kl.de int64_t transType = 1; 14610428Sandreas.hansson@arm.com trans TransItem; 14710428Sandreas.hansson@arm.com 14810428Sandreas.hansson@arm.com if (!transTrace.empty()) { 14910428Sandreas.hansson@arm.com transTrace.erase(transTrace.begin(), transTrace.end()); 15010428Sandreas.hansson@arm.com } 15110428Sandreas.hansson@arm.com 15210428Sandreas.hansson@arm.com while (getline(trans_trace, line)) { 15310428Sandreas.hansson@arm.com istringstream linestream(line); 15410428Sandreas.hansson@arm.com string item; 15511555Sjungma@eit.uni-kl.de uint64_t itemnum = 0; 15610428Sandreas.hansson@arm.com while (getline(linestream, item, ',')) { 15710428Sandreas.hansson@arm.com if (itemnum == 0) { 15810428Sandreas.hansson@arm.com stringstream timestamp(item); 15910428Sandreas.hansson@arm.com timestamp >> newtranstime; 16011555Sjungma@eit.uni-kl.de transTime = transTime + static_cast<int64_t>(newtranstime); 16110428Sandreas.hansson@arm.com } else if (itemnum == 1) { 16210428Sandreas.hansson@arm.com if (item == "write" || item == "WRITE") { 16310428Sandreas.hansson@arm.com transType = WRITE; 16410428Sandreas.hansson@arm.com } else { 16510428Sandreas.hansson@arm.com transType = READ; 16610428Sandreas.hansson@arm.com } 16710428Sandreas.hansson@arm.com } else if (itemnum == 2) { 16810428Sandreas.hansson@arm.com stringstream timestamp(item); 16910428Sandreas.hansson@arm.com timestamp >> std::hex >> transAddr; 17010428Sandreas.hansson@arm.com } 17110428Sandreas.hansson@arm.com itemnum++; 17210428Sandreas.hansson@arm.com } 17310428Sandreas.hansson@arm.com // generate a transaction 17410428Sandreas.hansson@arm.com TransItem.timeStamp = transTime; 17510428Sandreas.hansson@arm.com TransItem.logicalAddress = transAddr; 17610428Sandreas.hansson@arm.com TransItem.type = transType; 17710428Sandreas.hansson@arm.com 17810428Sandreas.hansson@arm.com transTrace.push_back(TransItem); 17910428Sandreas.hansson@arm.com 18010428Sandreas.hansson@arm.com if (transTrace.size() == MILLION) { 18110428Sandreas.hansson@arm.com // The scheduling is implemented for every MILLION transactions. 18210428Sandreas.hansson@arm.com // It is used to reduce the used memory during the running of this tool. 18310428Sandreas.hansson@arm.com analyticalScheduling(memSpec); 18410428Sandreas.hansson@arm.com transTrace.erase(transTrace.begin(), transTrace.end()); 18510428Sandreas.hansson@arm.com } 18610428Sandreas.hansson@arm.com } 18710428Sandreas.hansson@arm.com 18810428Sandreas.hansson@arm.com if ((transTrace.size() < MILLION) && (!transTrace.empty())) { 18910428Sandreas.hansson@arm.com analyticalScheduling(memSpec); 19010428Sandreas.hansson@arm.com transTrace.erase(transTrace.begin(), transTrace.end()); 19110428Sandreas.hansson@arm.com } 19210428Sandreas.hansson@arm.com} // cmdScheduler::getTrans 19310428Sandreas.hansson@arm.com 19410428Sandreas.hansson@arm.com// Transactions are executed individually and the command scheduling is 19510428Sandreas.hansson@arm.com// independent between transactions. The commands for a new transaction cannot 19610428Sandreas.hansson@arm.com// be scheduled until all the commands for the current one are scheduled. 19710428Sandreas.hansson@arm.com// After the scheduling, a sequence of commands are obtained and they are written 19810428Sandreas.hansson@arm.com// into commands.txt which will be used for power analysis. 19911555Sjungma@eit.uni-kl.devoid cmdScheduler::analyticalScheduling(const MemorySpecification& memSpec) 20010428Sandreas.hansson@arm.com{ 20111555Sjungma@eit.uni-kl.de int64_t transType = -1; 20211555Sjungma@eit.uni-kl.de int64_t timer = 0; 20311555Sjungma@eit.uni-kl.de uint64_t bankGroupPointer = 0; 20411555Sjungma@eit.uni-kl.de uint64_t bankGroupAddr = 0; 20510428Sandreas.hansson@arm.com bool collisionFound; 20610428Sandreas.hansson@arm.com physicalAddr PhysicalAddress; 20710428Sandreas.hansson@arm.com bool bankGroupSwitch = false; 20811555Sjungma@eit.uni-kl.de std::vector<uint64_t> bankPointer(static_cast<size_t>(nbrOfBankGroups), 0); 20911555Sjungma@eit.uni-kl.de std::vector<int64_t> bankAccessNum(static_cast<size_t>(nBanks), -1); 21011555Sjungma@eit.uni-kl.de std::vector<bool> ACTSchedule(static_cast<size_t>(nBanks), false); 21111555Sjungma@eit.uni-kl.de uint64_t bankAddr = 0; 21211555Sjungma@eit.uni-kl.de int64_t endTime = 0; 21311555Sjungma@eit.uni-kl.de int64_t tComing_REF = 0; 21410428Sandreas.hansson@arm.com 21510428Sandreas.hansson@arm.com Inselfrefresh = 0; 21610428Sandreas.hansson@arm.com 21711555Sjungma@eit.uni-kl.de const MemTimingSpec& memTimingSpec = memSpec.memTimingSpec; 21810428Sandreas.hansson@arm.com 21911555Sjungma@eit.uni-kl.de for (uint64_t t = 0; t < transTrace.size(); t++) { 22010428Sandreas.hansson@arm.com cmdScheduling.erase(cmdScheduling.begin(), cmdScheduling.end()); 22110428Sandreas.hansson@arm.com 22211555Sjungma@eit.uni-kl.de for (auto a : ACTSchedule) { 22311555Sjungma@eit.uni-kl.de a = false; 22411555Sjungma@eit.uni-kl.de } 22511555Sjungma@eit.uni-kl.de 22611555Sjungma@eit.uni-kl.de for (auto& b : bankAccessNum) { 22711555Sjungma@eit.uni-kl.de b = -1; 22810428Sandreas.hansson@arm.com } 22910428Sandreas.hansson@arm.com 23010428Sandreas.hansson@arm.com timingsGet = false; 23110428Sandreas.hansson@arm.com timer = transTrace[t].timeStamp; 23210428Sandreas.hansson@arm.com 23310428Sandreas.hansson@arm.com PhysicalAddress = memoryMap(transTrace[t], memSpec); 23410428Sandreas.hansson@arm.com 23511555Sjungma@eit.uni-kl.de for (auto& b : bankPointer) { 23611555Sjungma@eit.uni-kl.de b = PhysicalAddress.bankAddr; // the bank pointer per group. 23710428Sandreas.hansson@arm.com } 23810428Sandreas.hansson@arm.com bankGroupPointer = PhysicalAddress.bankGroupAddr; 23910428Sandreas.hansson@arm.com 24011555Sjungma@eit.uni-kl.de endTime = max(transFinish.time, PRE[static_cast<size_t>(transFinish.bank)].time + 24111555Sjungma@eit.uni-kl.de static_cast<int>(memTimingSpec.RP)); 24210428Sandreas.hansson@arm.com 24310428Sandreas.hansson@arm.com // Before starting the scheduling for the next transaction, it has to 24410428Sandreas.hansson@arm.com // check whether it is necessary for implementing power down. 24510428Sandreas.hansson@arm.com if (power_down == SELF_REFRESH) 24610428Sandreas.hansson@arm.com pdScheduling(endTime, timer, memSpec); 24710428Sandreas.hansson@arm.com else if (power_down == POWER_DOWN) 24810428Sandreas.hansson@arm.com pdScheduling(endTime, min(timer, tREF), memSpec); 24910428Sandreas.hansson@arm.com 25010428Sandreas.hansson@arm.com tComing_REF = tREF; 25110428Sandreas.hansson@arm.com 25210428Sandreas.hansson@arm.com ///////////////Scheduling Refresh//////////////////////// 25310428Sandreas.hansson@arm.com if (((transFinish.time >= tREF) || (timer >= tREF))) { 25411555Sjungma@eit.uni-kl.de for (int64_t i = 0; i <= ((timer - tComing_REF) > 0 ? (timer - tComing_REF) / 25510428Sandreas.hansson@arm.com memTimingSpec.REFI : 0); i++) { 25610428Sandreas.hansson@arm.com cmd.bank = 0; 25710428Sandreas.hansson@arm.com cmd.name = "REF"; 25811555Sjungma@eit.uni-kl.de cmd.time = max(max(max(transFinish.time, PRE[static_cast<size_t>(transFinish.bank)].time + memTimingSpec.RP), tREF), startTime); 25911555Sjungma@eit.uni-kl.de if ((power_down == SELF_REFRESH && !Inselfrefresh) || power_down != SELF_REFRESH) { 26010428Sandreas.hansson@arm.com cmdScheduling.push_back(cmd); 26110428Sandreas.hansson@arm.com startTime = cmd.time + memTimingSpec.RFC; 26210428Sandreas.hansson@arm.com } 26310428Sandreas.hansson@arm.com tREF = tREF + memTimingSpec.REFI; 26410428Sandreas.hansson@arm.com // during the refreshing, power down should be taken into account. 26510428Sandreas.hansson@arm.com if (!Inselfrefresh) 26610428Sandreas.hansson@arm.com pdScheduling(endTime, min(timer, tREF), memSpec); 26710428Sandreas.hansson@arm.com } 26810428Sandreas.hansson@arm.com } 26910428Sandreas.hansson@arm.com ///////////////Execution Transactions/////////////////// 27011555Sjungma@eit.uni-kl.de uint64_t Bs = PhysicalAddress.bankAddr; 27110428Sandreas.hansson@arm.com transType = transTrace[t].type; 27210428Sandreas.hansson@arm.com 27310428Sandreas.hansson@arm.com tRWTP = getRWTP(transType, memSpec); 27410428Sandreas.hansson@arm.com 27510428Sandreas.hansson@arm.com for (int i = 0; i < BI; i++) { 27610428Sandreas.hansson@arm.com for (int k = 0; k < BC; k++) { 27710428Sandreas.hansson@arm.com if (memSpec.memoryType == MemoryType::DDR4) { 27810428Sandreas.hansson@arm.com bankGroupPointer = PhysicalAddress.bankGroupAddr; 27910428Sandreas.hansson@arm.com } 28010428Sandreas.hansson@arm.com 28110428Sandreas.hansson@arm.com for (int j = 0; j < BGI; j++) { 28210428Sandreas.hansson@arm.com bankGroupSwitch = false; 28310428Sandreas.hansson@arm.com if (memSpec.memoryType == MemoryType::DDR4) { 28410428Sandreas.hansson@arm.com if (bankGroupPointer != bankGroupAddr) { 28510428Sandreas.hansson@arm.com bankGroupSwitch = true; 28610428Sandreas.hansson@arm.com } 28710428Sandreas.hansson@arm.com // update to the current bank group address. 28811555Sjungma@eit.uni-kl.de bankGroupAddr = PhysicalAddress.bankGroupAddr + static_cast<uint64_t>(j); 28911555Sjungma@eit.uni-kl.de bankAddr = bankGroupAddr * static_cast<uint64_t>(nBanks) / nbrOfBankGroups + bankPointer[bankGroupAddr]; 29010428Sandreas.hansson@arm.com } else { 29110428Sandreas.hansson@arm.com bankAddr = Bs + i; 29210428Sandreas.hansson@arm.com } 29310428Sandreas.hansson@arm.com 29410428Sandreas.hansson@arm.com if (!timingsGet) { 29510428Sandreas.hansson@arm.com getTimingConstraints(bankGroupSwitch, memSpec, 29610428Sandreas.hansson@arm.com PreRDWR.Type, transType); 29710428Sandreas.hansson@arm.com } 29810428Sandreas.hansson@arm.com 29910428Sandreas.hansson@arm.com ////////////////ACT Scheduling/////////////////// 30010428Sandreas.hansson@arm.com if (!ACTSchedule[bankAddr]) { 30110428Sandreas.hansson@arm.com cmd.bank = bankAddr; 30210428Sandreas.hansson@arm.com cmd.PhysicalAddr.bankAddr = cmd.bank; 30310428Sandreas.hansson@arm.com cmd.PhysicalAddr.rowAddr = PhysicalAddress.rowAddr; 30410428Sandreas.hansson@arm.com cmd.Type = ACTIVATE; 30510428Sandreas.hansson@arm.com cmd.name = "ACT"; 30610428Sandreas.hansson@arm.com Inselfrefresh = 0; 30710428Sandreas.hansson@arm.com cmd.time = max(max(ACT[bankaccess - 1].time + tRRD_init, 30810428Sandreas.hansson@arm.com PRE[cmd.bank].time + static_cast<int>(memTimingSpec.RP)), 30910428Sandreas.hansson@arm.com ACT[bankaccess - 4].time + 31010428Sandreas.hansson@arm.com static_cast<int>(memTimingSpec.FAW)); 31110428Sandreas.hansson@arm.com 31210428Sandreas.hansson@arm.com if (memSpec.memoryType == MemoryType::WIDEIO_SDR) { 31310428Sandreas.hansson@arm.com cmd.time = max(max(ACT[bankaccess - 1].time + tRRD_init, 31410428Sandreas.hansson@arm.com PRE[cmd.bank].time + static_cast<int>(memTimingSpec.RP)), 31510428Sandreas.hansson@arm.com ACT[bankaccess - 2].time + 31610428Sandreas.hansson@arm.com static_cast<int>(memTimingSpec.TAW)); 31710428Sandreas.hansson@arm.com } 31810428Sandreas.hansson@arm.com 31911555Sjungma@eit.uni-kl.de if (i == 0 && j == 0) { 32010428Sandreas.hansson@arm.com cmd.time = max(cmd.time, PreRDWR.time + 1); 32110428Sandreas.hansson@arm.com cmd.time = max(cmd.time, timer); 32210428Sandreas.hansson@arm.com cmd.time = max(startTime, cmd.time); 32310428Sandreas.hansson@arm.com } 32410428Sandreas.hansson@arm.com 32510428Sandreas.hansson@arm.com //////////collision detection//////////////////// 32610428Sandreas.hansson@arm.com for (int n = 1; n <= i * BGI + j; n++) { 32710428Sandreas.hansson@arm.com collisionFound = false; 32810428Sandreas.hansson@arm.com for (unsigned m = 0; m < RDWR[bankaccess - n].size(); m++) { 32910428Sandreas.hansson@arm.com if (RDWR[bankaccess - n][m].time == cmd.time) { 33010428Sandreas.hansson@arm.com cmd.time += 1; // ACT is shifted 33110428Sandreas.hansson@arm.com collisionFound = true; 33210428Sandreas.hansson@arm.com break; 33310428Sandreas.hansson@arm.com } 33410428Sandreas.hansson@arm.com } 33510428Sandreas.hansson@arm.com if (collisionFound) { 33610428Sandreas.hansson@arm.com break; 33710428Sandreas.hansson@arm.com } 33810428Sandreas.hansson@arm.com } 33910428Sandreas.hansson@arm.com 34010428Sandreas.hansson@arm.com ACT.push_back(cmd); 34110428Sandreas.hansson@arm.com cmdScheduling.push_back(cmd); 34210428Sandreas.hansson@arm.com 34310428Sandreas.hansson@arm.com ACTSchedule[bankAddr] = true; 34410428Sandreas.hansson@arm.com bankAccessNum[bankAddr] = bankaccess; 34510428Sandreas.hansson@arm.com bankaccess++; 34610428Sandreas.hansson@arm.com } 34710428Sandreas.hansson@arm.com 34810428Sandreas.hansson@arm.com /////RDWR Scheduling////// 34910428Sandreas.hansson@arm.com cmd.bank = bankAddr; 35010428Sandreas.hansson@arm.com cmd.PhysicalAddr.bankAddr = cmd.bank; 35110428Sandreas.hansson@arm.com cmd.PhysicalAddr.rowAddr = PhysicalAddress.rowAddr; 35210428Sandreas.hansson@arm.com cmd.PhysicalAddr.colAddr = PhysicalAddress.colAddr + k * burstLength; 35310428Sandreas.hansson@arm.com cmd.Type = transType; 35410428Sandreas.hansson@arm.com switch (transType) { 35510428Sandreas.hansson@arm.com case READ: 35610428Sandreas.hansson@arm.com cmd.name = "RD"; 35710428Sandreas.hansson@arm.com break; 35810428Sandreas.hansson@arm.com 35910428Sandreas.hansson@arm.com case WRITE: 36010428Sandreas.hansson@arm.com cmd.name = "WR"; 36110428Sandreas.hansson@arm.com break; 36210428Sandreas.hansson@arm.com } 36310428Sandreas.hansson@arm.com for (int ACTBank = static_cast<int>(ACT.size() - 1); 36410428Sandreas.hansson@arm.com ACTBank >= 0; ACTBank--) { 36511555Sjungma@eit.uni-kl.de if (ACT[ACTBank].bank == static_cast<int64_t>(bankAddr)) { 36610428Sandreas.hansson@arm.com cmd.time = max(PreRDWR.time + tSwitch_init, ACT.back().time 36710428Sandreas.hansson@arm.com + static_cast<int>(memTimingSpec.RCD)); 36810428Sandreas.hansson@arm.com break; 36910428Sandreas.hansson@arm.com } 37010428Sandreas.hansson@arm.com } 37110428Sandreas.hansson@arm.com 37210428Sandreas.hansson@arm.com if ((i == BI - 1) && (k == BC - 1) && (j == BGI - 1)) { 37310428Sandreas.hansson@arm.com transFinish.time = cmd.time + 1; 37410428Sandreas.hansson@arm.com transFinish.bank = bankAddr; 37510428Sandreas.hansson@arm.com } 37610428Sandreas.hansson@arm.com if (k == BC - 1) { 37710428Sandreas.hansson@arm.com switch (transType) { 37810428Sandreas.hansson@arm.com case READ: 37910428Sandreas.hansson@arm.com cmd.name = "RDA"; 38010428Sandreas.hansson@arm.com break; 38110428Sandreas.hansson@arm.com 38210428Sandreas.hansson@arm.com case WRITE: 38310428Sandreas.hansson@arm.com cmd.name = "WRA"; 38410428Sandreas.hansson@arm.com break; 38510428Sandreas.hansson@arm.com } 38610428Sandreas.hansson@arm.com } 38710428Sandreas.hansson@arm.com PreRDWR = cmd; 38810428Sandreas.hansson@arm.com 38910428Sandreas.hansson@arm.com RDWR[bankAccessNum[bankAddr]].push_back(cmd); 39010428Sandreas.hansson@arm.com cmdScheduling.push_back(cmd); 39110428Sandreas.hansson@arm.com 39210428Sandreas.hansson@arm.com ////////////////PRE Scheduling//////////////////// 39310428Sandreas.hansson@arm.com if (k == BC - 1) { 39410428Sandreas.hansson@arm.com PRE[bankAddr].bank = bankAddr; 39510428Sandreas.hansson@arm.com PRE[bankAddr].Type = PRECHARGE; 39610428Sandreas.hansson@arm.com PRE[bankAddr].name = "PRE"; 39710428Sandreas.hansson@arm.com for (int ACTBank = static_cast<int>(ACT.size() - 1); 39810428Sandreas.hansson@arm.com ACTBank >= 0; ACTBank--) { 39911555Sjungma@eit.uni-kl.de if (ACT[ACTBank].bank == static_cast<int64_t>(bankAddr)) { 40010428Sandreas.hansson@arm.com PRE[bankAddr].time = max(ACT.back().time + 40110428Sandreas.hansson@arm.com static_cast<int>(memTimingSpec.RAS), 40210428Sandreas.hansson@arm.com PreRDWR.time + tRWTP); 40310428Sandreas.hansson@arm.com break; 40410428Sandreas.hansson@arm.com } 40510428Sandreas.hansson@arm.com } 40610428Sandreas.hansson@arm.com bankPointer[bankGroupAddr] = bankPointer[bankGroupAddr] + 1; 40710428Sandreas.hansson@arm.com } 40810428Sandreas.hansson@arm.com 40910428Sandreas.hansson@arm.com bankGroupPointer++; 41010428Sandreas.hansson@arm.com } 41110428Sandreas.hansson@arm.com } 41210428Sandreas.hansson@arm.com } 41310428Sandreas.hansson@arm.com 41410428Sandreas.hansson@arm.com // make sure the scheduled commands are stored with an ascending scheduling time 41510428Sandreas.hansson@arm.com sort(cmdScheduling.begin(), cmdScheduling.end(), 41610428Sandreas.hansson@arm.com commandItem::commandItemSorter()); 41710428Sandreas.hansson@arm.com 41810428Sandreas.hansson@arm.com // write the scheduled commands into commands.txt. 41910428Sandreas.hansson@arm.com for (unsigned i = 0; i < cmdScheduling.size(); i++) { 42010428Sandreas.hansson@arm.com cmdList.push_back(cmdScheduling[i]); 42110428Sandreas.hansson@arm.com } 42210428Sandreas.hansson@arm.com 42310428Sandreas.hansson@arm.com /////////////Update Vector Length///////////////// 42410428Sandreas.hansson@arm.com // the vector length is reduced so that less memory is used for running 42510428Sandreas.hansson@arm.com // this tool. 42611555Sjungma@eit.uni-kl.de if (ACT.size() >= static_cast<size_t>(memSpec.memArchSpec.nbrOfBanks)) { 42710428Sandreas.hansson@arm.com for (int m = 0; m < BI * BGI; m++) { 42810428Sandreas.hansson@arm.com ACT.erase(ACT.begin()); 42910428Sandreas.hansson@arm.com RDWR[0].erase(RDWR[0].begin(), RDWR[0].end()); 43010428Sandreas.hansson@arm.com for (int h = 0; h < bankaccess - 1 - m; h++) { 43110428Sandreas.hansson@arm.com RDWR[h].insert(RDWR[h].begin(), RDWR[h + 1].begin(), RDWR[h + 1].end()); 43210428Sandreas.hansson@arm.com RDWR[h + 1].resize(0); 43310428Sandreas.hansson@arm.com } 43410428Sandreas.hansson@arm.com } 43510428Sandreas.hansson@arm.com bankaccess = bankaccess - (BI * BGI); 43610428Sandreas.hansson@arm.com } 43710428Sandreas.hansson@arm.com } 43810428Sandreas.hansson@arm.com 43910428Sandreas.hansson@arm.com for (unsigned j = 0; j < cmdList.size(); j++) { 44010428Sandreas.hansson@arm.com commands.precision(0); 44110428Sandreas.hansson@arm.com commands << fixed << cmdList[j].time << "," << cmdList[j].name << "," << 44210428Sandreas.hansson@arm.com cmdList[j].bank << endl; 44310428Sandreas.hansson@arm.com } 44410428Sandreas.hansson@arm.com cmdList.erase(cmdList.begin(), cmdList.end()); 44510428Sandreas.hansson@arm.com} // cmdScheduler::analyticalScheduling 44610428Sandreas.hansson@arm.com 44710428Sandreas.hansson@arm.com// to add the power down/up during the command scheduling for transactions. 44810428Sandreas.hansson@arm.com// It is called when the command scheduling for a transaction is finished, and it 44910428Sandreas.hansson@arm.com// is also called if there is a refresh. 45011555Sjungma@eit.uni-kl.devoid cmdScheduler::pdScheduling(int64_t endTime, int64_t timer, 45111555Sjungma@eit.uni-kl.de const MemorySpecification& memSpec) 45210428Sandreas.hansson@arm.com{ 45311555Sjungma@eit.uni-kl.de int64_t ZERO = 0; 45411555Sjungma@eit.uni-kl.de const MemTimingSpec& memTimingSpec = memSpec.memTimingSpec; 45510428Sandreas.hansson@arm.com 45610428Sandreas.hansson@arm.com endTime = max(endTime, startTime); 45711555Sjungma@eit.uni-kl.de int64_t pdTime = max(ZERO, timer - endTime); 45810428Sandreas.hansson@arm.com 45910428Sandreas.hansson@arm.com if ((timer > (endTime + memTimingSpec.CKE)) && (power_down == POWER_DOWN)) { 46010428Sandreas.hansson@arm.com cmd.bank = 0; 46110428Sandreas.hansson@arm.com cmd.name = "PDN_S_PRE"; 46210428Sandreas.hansson@arm.com cmd.time = endTime; 46310428Sandreas.hansson@arm.com cmdScheduling.push_back(cmd); 46410428Sandreas.hansson@arm.com cmd.name = "PUP_PRE"; 46510428Sandreas.hansson@arm.com 46610428Sandreas.hansson@arm.com if (pdTime > memTimingSpec.REFI) 46710428Sandreas.hansson@arm.com cmd.time = cmd.time + memTimingSpec.REFI; 46810428Sandreas.hansson@arm.com else 46910428Sandreas.hansson@arm.com cmd.time = cmd.time + pdTime; 47010428Sandreas.hansson@arm.com 47110428Sandreas.hansson@arm.com if (memSpec.memoryType.isLPDDRFamily()) 47210428Sandreas.hansson@arm.com startTime = cmd.time + memTimingSpec.XP; 47310428Sandreas.hansson@arm.com else 47410428Sandreas.hansson@arm.com startTime = cmd.time + memTimingSpec.XPDLL - memTimingSpec.RCD; 47510428Sandreas.hansson@arm.com 47610428Sandreas.hansson@arm.com cmdScheduling.push_back(cmd); 47710428Sandreas.hansson@arm.com } else if ((timer > (endTime + memTimingSpec.CKESR)) && (power_down == SELF_REFRESH)) { 47810428Sandreas.hansson@arm.com cmd.bank = 0; 47910428Sandreas.hansson@arm.com cmd.name = "SREN"; 48010428Sandreas.hansson@arm.com cmd.time = endTime; 48110428Sandreas.hansson@arm.com cmdScheduling.push_back(cmd); 48210428Sandreas.hansson@arm.com Inselfrefresh = 1; 48310428Sandreas.hansson@arm.com cmd.name = "SREX"; 48410428Sandreas.hansson@arm.com cmd.time = cmd.time + pdTime; 48510428Sandreas.hansson@arm.com 48610428Sandreas.hansson@arm.com if (memSpec.memoryType.isLPDDRFamily()) 48710428Sandreas.hansson@arm.com startTime = cmd.time + memTimingSpec.XS; 48810428Sandreas.hansson@arm.com else 48910428Sandreas.hansson@arm.com startTime = cmd.time + memTimingSpec.XSDLL - memTimingSpec.RCD; 49010428Sandreas.hansson@arm.com 49110428Sandreas.hansson@arm.com cmdScheduling.push_back(cmd); 49210428Sandreas.hansson@arm.com } 49310428Sandreas.hansson@arm.com} // cmdScheduler::pdScheduling 49410428Sandreas.hansson@arm.com 49510428Sandreas.hansson@arm.com// get the time when a precharge occurs after a read/write command is scheduled. 49610428Sandreas.hansson@arm.com// In addition, it copes with different kind of memories. 49711555Sjungma@eit.uni-kl.deint64_t cmdScheduler::getRWTP(int64_t transType, const MemorySpecification& memSpec) 49810428Sandreas.hansson@arm.com{ 49911555Sjungma@eit.uni-kl.de int64_t tRWTP_init = 0; 50011555Sjungma@eit.uni-kl.de const MemTimingSpec& memTimingSpec = memSpec.memTimingSpec; 50111555Sjungma@eit.uni-kl.de const MemArchitectureSpec& memArchSpec = memSpec.memArchSpec; 50210428Sandreas.hansson@arm.com 50310428Sandreas.hansson@arm.com if (transType == READ) { 50410428Sandreas.hansson@arm.com switch (memSpec.memoryType) { 50510428Sandreas.hansson@arm.com case MemoryType::LPDDR: 50610428Sandreas.hansson@arm.com case MemoryType::WIDEIO_SDR: 50710428Sandreas.hansson@arm.com tRWTP_init = memArchSpec.burstLength / memArchSpec.dataRate; 50810428Sandreas.hansson@arm.com break; 50910428Sandreas.hansson@arm.com 51010428Sandreas.hansson@arm.com case MemoryType::LPDDR2: 51110428Sandreas.hansson@arm.com case MemoryType::LPDDR3: 51210428Sandreas.hansson@arm.com tRWTP_init = memArchSpec.burstLength / memArchSpec.dataRate + 51311555Sjungma@eit.uni-kl.de max(int64_t(0), memTimingSpec.RTP - 2); 51410428Sandreas.hansson@arm.com break; 51510428Sandreas.hansson@arm.com 51610428Sandreas.hansson@arm.com case MemoryType::DDR2: 51710428Sandreas.hansson@arm.com tRWTP_init = memTimingSpec.AL + memArchSpec.burstLength / 51810428Sandreas.hansson@arm.com memArchSpec.dataRate + 51911555Sjungma@eit.uni-kl.de max(memTimingSpec.RTP, int64_t(2)) - 2; 52010428Sandreas.hansson@arm.com break; 52110428Sandreas.hansson@arm.com 52210428Sandreas.hansson@arm.com case MemoryType::DDR3: 52310428Sandreas.hansson@arm.com case MemoryType::DDR4: 52410428Sandreas.hansson@arm.com tRWTP_init = memTimingSpec.RTP; 52510428Sandreas.hansson@arm.com break; 52610428Sandreas.hansson@arm.com default: 52710428Sandreas.hansson@arm.com assert("Unknown memory type" && false); 52810428Sandreas.hansson@arm.com } // switch 52910428Sandreas.hansson@arm.com } else if (transType == WRITE) { 53010428Sandreas.hansson@arm.com if (memSpec.memoryType == MemoryType::WIDEIO_SDR) { 53110428Sandreas.hansson@arm.com tRWTP_init = memTimingSpec.WL + memArchSpec.burstLength / 53211555Sjungma@eit.uni-kl.de memArchSpec.dataRate - 1 + memTimingSpec.WR; 53310428Sandreas.hansson@arm.com } else { 53410428Sandreas.hansson@arm.com tRWTP_init = memTimingSpec.WL + memArchSpec.burstLength / 53511555Sjungma@eit.uni-kl.de memArchSpec.dataRate + memTimingSpec.WR; 53610428Sandreas.hansson@arm.com } 53710428Sandreas.hansson@arm.com if ((memSpec.memoryType == MemoryType::LPDDR2) || 53810428Sandreas.hansson@arm.com (memSpec.memoryType == MemoryType::LPDDR3)) { 53910428Sandreas.hansson@arm.com tRWTP_init = tRWTP_init + 1; 54010428Sandreas.hansson@arm.com } 54110428Sandreas.hansson@arm.com } 54210428Sandreas.hansson@arm.com 54310428Sandreas.hansson@arm.com return tRWTP_init; 54410428Sandreas.hansson@arm.com} // cmdScheduler::getRWTP 54510428Sandreas.hansson@arm.com 54610428Sandreas.hansson@arm.com// get the timings for command scheduling according to different memories. 54710428Sandreas.hansson@arm.com// In particular, tSwitch_init is generally used to provide the timings for 54810428Sandreas.hansson@arm.com// scheduling a read/write command after a read/write command which have been 54910428Sandreas.hansson@arm.com// scheduled to any possible banks within any possible bank groups (DDR4). 55011555Sjungma@eit.uni-kl.devoid cmdScheduler::getTimingConstraints(bool BGSwitch, const MemorySpecification& memSpec, 55111555Sjungma@eit.uni-kl.de int64_t PreType, int64_t CurrentType) 55210428Sandreas.hansson@arm.com{ 55311555Sjungma@eit.uni-kl.de const MemTimingSpec& memTimingSpec = memSpec.memTimingSpec; 55411555Sjungma@eit.uni-kl.de const MemArchitectureSpec& memArchSpec = memSpec.memArchSpec; 55510428Sandreas.hansson@arm.com 55610428Sandreas.hansson@arm.com if (memSpec.memoryType != MemoryType::DDR4) { 55710428Sandreas.hansson@arm.com tRRD_init = memTimingSpec.RRD; 55810428Sandreas.hansson@arm.com if (PreType == CurrentType) { 55910428Sandreas.hansson@arm.com tSwitch_init = memTimingSpec.CCD; 56010428Sandreas.hansson@arm.com timingsGet = true; 56110428Sandreas.hansson@arm.com } 56210428Sandreas.hansson@arm.com 56310428Sandreas.hansson@arm.com if ((PreType == WRITE) && (CurrentType == READ)) { 56410428Sandreas.hansson@arm.com if (memSpec.memoryType == MemoryType::WIDEIO_SDR) { 56510428Sandreas.hansson@arm.com tSwitch_init = memTimingSpec.WL + memArchSpec.burstLength / 56610428Sandreas.hansson@arm.com memArchSpec.dataRate - 1 + memTimingSpec.WTR; 56710428Sandreas.hansson@arm.com } else { 56810428Sandreas.hansson@arm.com tSwitch_init = memTimingSpec.WL + memArchSpec.burstLength / 56910428Sandreas.hansson@arm.com memArchSpec.dataRate + memTimingSpec.WTR; 57010428Sandreas.hansson@arm.com } 57110428Sandreas.hansson@arm.com 57210428Sandreas.hansson@arm.com if ((memSpec.memoryType == MemoryType::LPDDR2) || 57310428Sandreas.hansson@arm.com (memSpec.memoryType == MemoryType::LPDDR3)) { 57410428Sandreas.hansson@arm.com tSwitch_init = tSwitch_init + 1; 57510428Sandreas.hansson@arm.com } 57610428Sandreas.hansson@arm.com } 57710428Sandreas.hansson@arm.com } 57810428Sandreas.hansson@arm.com 57910428Sandreas.hansson@arm.com if (memSpec.memoryType == MemoryType::DDR4) { 58010428Sandreas.hansson@arm.com if (BGSwitch) { 58110428Sandreas.hansson@arm.com tCCD_init = memTimingSpec.CCD_S; 58210428Sandreas.hansson@arm.com tRRD_init = memTimingSpec.RRD_S; 58310428Sandreas.hansson@arm.com tWTR_init = memTimingSpec.WTR_S; 58410428Sandreas.hansson@arm.com } else { 58510428Sandreas.hansson@arm.com tCCD_init = memTimingSpec.CCD_L; 58610428Sandreas.hansson@arm.com tRRD_init = memTimingSpec.RRD_L; 58710428Sandreas.hansson@arm.com tWTR_init = memTimingSpec.WTR_L; 58810428Sandreas.hansson@arm.com } 58910428Sandreas.hansson@arm.com 59010428Sandreas.hansson@arm.com if (PreType == CurrentType) { 59110428Sandreas.hansson@arm.com tSwitch_init = tCCD_init; 59210428Sandreas.hansson@arm.com timingsGet = true; 59311555Sjungma@eit.uni-kl.de } else if (PreType == WRITE && CurrentType == READ) { 59410428Sandreas.hansson@arm.com tSwitch_init = memTimingSpec.WL + memArchSpec.burstLength / 59510428Sandreas.hansson@arm.com memArchSpec.dataRate + tWTR_init; 59610428Sandreas.hansson@arm.com } 59710428Sandreas.hansson@arm.com } 59810428Sandreas.hansson@arm.com 59910428Sandreas.hansson@arm.com if ((PreType == READ) && (CurrentType == WRITE)) { 60010428Sandreas.hansson@arm.com tSwitch_init = memTimingSpec.RL + memArchSpec.burstLength / 60110428Sandreas.hansson@arm.com memArchSpec.dataRate + 2 - memTimingSpec.WL; 60210428Sandreas.hansson@arm.com } 60310428Sandreas.hansson@arm.com} // cmdScheduler::getTimingConstraints 60410428Sandreas.hansson@arm.com 60510428Sandreas.hansson@arm.com// The logical address of each transaction is translated into a physical address 60610428Sandreas.hansson@arm.com// which consists of bank group (for DDR4), bank, row and column addresses. 60710428Sandreas.hansson@arm.comcmdScheduler::physicalAddr cmdScheduler::memoryMap(trans Trans, 60811555Sjungma@eit.uni-kl.de const MemorySpecification& memSpec) 60910428Sandreas.hansson@arm.com{ 61011555Sjungma@eit.uni-kl.de int64_t DecLogic; 61110428Sandreas.hansson@arm.com physicalAddr PhysicalAddr; 61210428Sandreas.hansson@arm.com 61310428Sandreas.hansson@arm.com DecLogic = Trans.logicalAddress; 61410428Sandreas.hansson@arm.com 61510428Sandreas.hansson@arm.com // row-bank-column-BI-BC-BGI-BL 61611555Sjungma@eit.uni-kl.de if (BGI > 1 && memSpec.memoryType == MemoryType::DDR4) { 61711555Sjungma@eit.uni-kl.de uint64_t colBits = uintLog2(nColumns); 61811555Sjungma@eit.uni-kl.de uint64_t bankShift = colBits + ((BI > 1) ? uintLog2(BI) : 0) + ((BGI > 1) ? uintLog2(BGI) : 0); 61911555Sjungma@eit.uni-kl.de uint64_t bankMask = (nBanks / (BI * nbrOfBankGroups) - 1) << bankShift; 62011555Sjungma@eit.uni-kl.de uint64_t bankAddr = (DecLogic & bankMask) >> (colBits + ((BGI > 1) ? uintLog2(BGI) : 0)); 62110428Sandreas.hansson@arm.com PhysicalAddr.bankAddr = bankAddr; 62210428Sandreas.hansson@arm.com 62311555Sjungma@eit.uni-kl.de uint64_t bankGroupShift = uintLog2(burstLength); 62411555Sjungma@eit.uni-kl.de uint64_t bankGroupMask = (nbrOfBankGroups / BGI - 1) << bankGroupShift; 62511555Sjungma@eit.uni-kl.de uint64_t bankGroupAddr = (DecLogic & bankGroupMask) >> bankGroupShift; 62610428Sandreas.hansson@arm.com PhysicalAddr.bankGroupAddr = bankGroupAddr; 62710428Sandreas.hansson@arm.com 62811555Sjungma@eit.uni-kl.de uint64_t colShift = uintLog2(BC * burstLength) + 62911555Sjungma@eit.uni-kl.de ((BI > 1) ? uintLog2(BI) : 0) + ((BGI > 1) ? uintLog2(BGI) : 0); 63011555Sjungma@eit.uni-kl.de uint64_t colMask = (nColumns / (BC * burstLength) - 1) << colShift; 63111555Sjungma@eit.uni-kl.de uint64_t colAddr = (DecLogic & colMask) >> (colShift - uintLog2(static_cast<uint64_t>(BC) * burstLength)); 63210428Sandreas.hansson@arm.com PhysicalAddr.colAddr = colAddr; 63310428Sandreas.hansson@arm.com } else { 63411555Sjungma@eit.uni-kl.de uint64_t colBits = uintLog2(nColumns); 63511555Sjungma@eit.uni-kl.de uint64_t bankShift = colBits + ((BI > 1) ? uintLog2(BI) : 0); 63611555Sjungma@eit.uni-kl.de uint64_t bankMask = (nBanks / BI - 1) << bankShift; 63711555Sjungma@eit.uni-kl.de uint64_t bankAddr = (DecLogic & bankMask) >> colBits; 63810428Sandreas.hansson@arm.com PhysicalAddr.bankAddr = bankAddr; 63910428Sandreas.hansson@arm.com 64011555Sjungma@eit.uni-kl.de uint64_t colShift = (uintLog2(BC * burstLength) + ((BI > 1) ? uintLog2(BI) : 0)); 64111555Sjungma@eit.uni-kl.de uint64_t colMask = (nColumns / (BC * burstLength) - 1) << colShift; 64211555Sjungma@eit.uni-kl.de uint64_t colAddr = (DecLogic & colMask) >> (colShift - uintLog2(BC * burstLength)); 64310428Sandreas.hansson@arm.com PhysicalAddr.colAddr = colAddr; 64410428Sandreas.hansson@arm.com 64510428Sandreas.hansson@arm.com PhysicalAddr.bankGroupAddr = 0; 64610428Sandreas.hansson@arm.com } 64710428Sandreas.hansson@arm.com 64811555Sjungma@eit.uni-kl.de uint64_t rowShift = uintLog2(nColumns * nBanks); 64911555Sjungma@eit.uni-kl.de uint64_t rowMask = (memSpec.memArchSpec.nbrOfRows - 1) << rowShift; 65011555Sjungma@eit.uni-kl.de uint64_t rowAddr = (DecLogic & rowMask) >> rowShift; 65110428Sandreas.hansson@arm.com PhysicalAddr.rowAddr = rowAddr; 65210428Sandreas.hansson@arm.com 65310428Sandreas.hansson@arm.com return PhysicalAddr; 65410428Sandreas.hansson@arm.com} // cmdScheduler::memoryMap 65511555Sjungma@eit.uni-kl.de 65611555Sjungma@eit.uni-kl.deuint64_t cmdScheduler::uintLog2(uint64_t in) 65711555Sjungma@eit.uni-kl.de{ 65811555Sjungma@eit.uni-kl.de return static_cast<uint64_t>(log2(in)); 65911555Sjungma@eit.uni-kl.de}