19241Sandreas.hansson@arm.com/* 212810Sandreas.sandberg@arm.com * Copyright (c) 2012-2013, 2016-2018 ARM Limited 39241Sandreas.hansson@arm.com * All rights reserved 49241Sandreas.hansson@arm.com * 59241Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 69241Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 79241Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 89241Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 99241Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 109241Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 119241Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 129241Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 139241Sandreas.hansson@arm.com * 149241Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 159241Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 169241Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 179241Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 189241Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 199241Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 209241Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 219241Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 229241Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 239241Sandreas.hansson@arm.com * this software without specific prior written permission. 249241Sandreas.hansson@arm.com * 259241Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 269241Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 279241Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 289241Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 299241Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 309241Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 319241Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 329241Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 339241Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 349241Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 359241Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 369241Sandreas.hansson@arm.com * 379241Sandreas.hansson@arm.com * Authors: Thomas Grass 389241Sandreas.hansson@arm.com * Andreas Hansson 399241Sandreas.hansson@arm.com * Sascha Bischoff 409241Sandreas.hansson@arm.com */ 4111540Sandreas.sandberg@arm.com#include "cpu/testers/traffic_gen/traffic_gen.hh" 4211540Sandreas.sandberg@arm.com 4311540Sandreas.sandberg@arm.com#include <libgen.h> 4411540Sandreas.sandberg@arm.com#include <unistd.h> 459241Sandreas.hansson@arm.com 4612811Sandreas.sandberg@arm.com#include <fstream> 479241Sandreas.hansson@arm.com#include <sstream> 489241Sandreas.hansson@arm.com 4910138Sneha.agarwal@arm.com#include "base/intmath.hh" 509241Sandreas.hansson@arm.com#include "base/random.hh" 519241Sandreas.hansson@arm.com#include "debug/TrafficGen.hh" 5212810Sandreas.sandberg@arm.com#include "params/TrafficGen.hh" 539241Sandreas.hansson@arm.com#include "sim/stats.hh" 549241Sandreas.hansson@arm.com#include "sim/system.hh" 559241Sandreas.hansson@arm.com 569241Sandreas.hansson@arm.comusing namespace std; 579241Sandreas.hansson@arm.com 589241Sandreas.hansson@arm.comTrafficGen::TrafficGen(const TrafficGenParams* p) 5912810Sandreas.sandberg@arm.com : BaseTrafficGen(p), 609718Sandreas.hansson@arm.com configFile(p->config_file), 6112810Sandreas.sandberg@arm.com currState(0) 629241Sandreas.hansson@arm.com{ 639241Sandreas.hansson@arm.com} 649241Sandreas.hansson@arm.com 659241Sandreas.hansson@arm.comTrafficGen* 669241Sandreas.hansson@arm.comTrafficGenParams::create() 679241Sandreas.hansson@arm.com{ 689241Sandreas.hansson@arm.com return new TrafficGen(this); 699241Sandreas.hansson@arm.com} 709241Sandreas.hansson@arm.com 7112810Sandreas.sandberg@arm.comvoid 7212810Sandreas.sandberg@arm.comTrafficGen::init() 739241Sandreas.hansson@arm.com{ 7412810Sandreas.sandberg@arm.com BaseTrafficGen::init(); 7512810Sandreas.sandberg@arm.com 7612810Sandreas.sandberg@arm.com parseConfig(); 779241Sandreas.hansson@arm.com} 789241Sandreas.hansson@arm.com 799241Sandreas.hansson@arm.comvoid 8012810Sandreas.sandberg@arm.comTrafficGen::initState() 819241Sandreas.hansson@arm.com{ 8212810Sandreas.sandberg@arm.com BaseTrafficGen::initState(); 839241Sandreas.hansson@arm.com 8412810Sandreas.sandberg@arm.com // when not restoring from a checkpoint, make sure we kick things off 859524SAndreas.Sandberg@ARM.com if (system->isTimingMode()) { 869241Sandreas.hansson@arm.com DPRINTF(TrafficGen, "Timing mode, activating request generator\n"); 8712810Sandreas.sandberg@arm.com start(); 889241Sandreas.hansson@arm.com } else { 899241Sandreas.hansson@arm.com DPRINTF(TrafficGen, 909241Sandreas.hansson@arm.com "Traffic generator is only active in timing mode\n"); 919241Sandreas.hansson@arm.com } 929241Sandreas.hansson@arm.com} 939241Sandreas.hansson@arm.com 949241Sandreas.hansson@arm.comvoid 9510905Sandreas.sandberg@arm.comTrafficGen::serialize(CheckpointOut &cp) const 969241Sandreas.hansson@arm.com{ 9712810Sandreas.sandberg@arm.com SERIALIZE_SCALAR(currState); 989241Sandreas.hansson@arm.com 9912810Sandreas.sandberg@arm.com BaseTrafficGen::serialize(cp); 1009241Sandreas.hansson@arm.com} 1019241Sandreas.hansson@arm.com 1029241Sandreas.hansson@arm.comvoid 10310905Sandreas.sandberg@arm.comTrafficGen::unserialize(CheckpointIn &cp) 1049241Sandreas.hansson@arm.com{ 1059719Sandreas.hansson@arm.com // @todo In the case of a stateful generator state such as the 1069719Sandreas.hansson@arm.com // trace player we would also have to restore the position in the 1079720Sandreas.hansson@arm.com // trace playback and the tick offset 1089719Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(currState); 1099241Sandreas.hansson@arm.com 11012810Sandreas.sandberg@arm.com BaseTrafficGen::unserialize(cp); 1119241Sandreas.hansson@arm.com} 1129241Sandreas.hansson@arm.com 11311540Sandreas.sandberg@arm.comstd::string 11411540Sandreas.sandberg@arm.comTrafficGen::resolveFile(const std::string &name) 11511540Sandreas.sandberg@arm.com{ 11611540Sandreas.sandberg@arm.com // Do nothing for empty and absolute file names 11711540Sandreas.sandberg@arm.com if (name.empty() || name[0] == '/') 11811540Sandreas.sandberg@arm.com return name; 11911540Sandreas.sandberg@arm.com 12011540Sandreas.sandberg@arm.com char *config_path = strdup(configFile.c_str()); 12111540Sandreas.sandberg@arm.com char *config_dir = dirname(config_path); 12211540Sandreas.sandberg@arm.com const std::string config_rel = csprintf("%s/%s", config_dir, name); 12311540Sandreas.sandberg@arm.com free(config_path); 12411540Sandreas.sandberg@arm.com 12511540Sandreas.sandberg@arm.com // Check the path relative to the config file first 12611540Sandreas.sandberg@arm.com if (access(config_rel.c_str(), R_OK) == 0) 12711540Sandreas.sandberg@arm.com return config_rel; 12811540Sandreas.sandberg@arm.com 12911540Sandreas.sandberg@arm.com // Fall back to the old behavior and search relative to the 13011540Sandreas.sandberg@arm.com // current working directory. 13111540Sandreas.sandberg@arm.com return name; 13211540Sandreas.sandberg@arm.com} 13311540Sandreas.sandberg@arm.com 1349241Sandreas.hansson@arm.comvoid 1359718Sandreas.hansson@arm.comTrafficGen::parseConfig() 1369241Sandreas.hansson@arm.com{ 1379241Sandreas.hansson@arm.com // keep track of the transitions parsed to create the matrix when 1389241Sandreas.hansson@arm.com // done 1399241Sandreas.hansson@arm.com vector<Transition> transitions; 1409241Sandreas.hansson@arm.com 1419241Sandreas.hansson@arm.com // open input file 1429241Sandreas.hansson@arm.com ifstream infile; 1439718Sandreas.hansson@arm.com infile.open(configFile.c_str(), ifstream::in); 1449241Sandreas.hansson@arm.com if (!infile.is_open()) { 1459241Sandreas.hansson@arm.com fatal("Traffic generator %s config file not found at %s\n", 1469718Sandreas.hansson@arm.com name(), configFile); 1479241Sandreas.hansson@arm.com } 1489241Sandreas.hansson@arm.com 14910128Sstan.czerniawski@arm.com bool init_state_set = false; 15010128Sstan.czerniawski@arm.com 1519241Sandreas.hansson@arm.com // read line by line and determine the action based on the first 1529241Sandreas.hansson@arm.com // keyword 1539241Sandreas.hansson@arm.com string keyword; 1549241Sandreas.hansson@arm.com string line; 1559241Sandreas.hansson@arm.com 1569241Sandreas.hansson@arm.com while (getline(infile, line).good()) { 1579241Sandreas.hansson@arm.com // see if this line is a comment line, and if so skip it 1589241Sandreas.hansson@arm.com if (line.find('#') != 1) { 1599241Sandreas.hansson@arm.com // create an input stream for the tokenization 1609241Sandreas.hansson@arm.com istringstream is(line); 1619241Sandreas.hansson@arm.com 1629241Sandreas.hansson@arm.com // determine the keyword 1639241Sandreas.hansson@arm.com is >> keyword; 1649241Sandreas.hansson@arm.com 1659241Sandreas.hansson@arm.com if (keyword == "STATE") { 1669241Sandreas.hansson@arm.com // parse the behaviour of this state 1679241Sandreas.hansson@arm.com uint32_t id; 1689241Sandreas.hansson@arm.com Tick duration; 1699241Sandreas.hansson@arm.com string mode; 1709241Sandreas.hansson@arm.com 1719241Sandreas.hansson@arm.com is >> id >> duration >> mode; 1729241Sandreas.hansson@arm.com 1739241Sandreas.hansson@arm.com if (mode == "TRACE") { 1749241Sandreas.hansson@arm.com string traceFile; 1759241Sandreas.hansson@arm.com Addr addrOffset; 1769241Sandreas.hansson@arm.com 1779241Sandreas.hansson@arm.com is >> traceFile >> addrOffset; 17811540Sandreas.sandberg@arm.com traceFile = resolveFile(traceFile); 1799241Sandreas.hansson@arm.com 18012811Sandreas.sandberg@arm.com states[id] = createTrace(duration, traceFile, addrOffset); 1819241Sandreas.hansson@arm.com DPRINTF(TrafficGen, "State: %d TraceGen\n", id); 1829241Sandreas.hansson@arm.com } else if (mode == "IDLE") { 18312811Sandreas.sandberg@arm.com states[id] = createIdle(duration); 1849241Sandreas.hansson@arm.com DPRINTF(TrafficGen, "State: %d IdleGen\n", id); 18512397SRiken.Gohil@arm.com } else if (mode == "EXIT") { 18612811Sandreas.sandberg@arm.com states[id] = createExit(duration); 18712397SRiken.Gohil@arm.com DPRINTF(TrafficGen, "State: %d ExitGen\n", id); 18810138Sneha.agarwal@arm.com } else if (mode == "LINEAR" || mode == "RANDOM" || 18910392Swendy.elsasser@arm.com mode == "DRAM" || mode == "DRAM_ROTATE") { 1909241Sandreas.hansson@arm.com uint32_t read_percent; 1919241Sandreas.hansson@arm.com Addr start_addr; 1929241Sandreas.hansson@arm.com Addr end_addr; 1939241Sandreas.hansson@arm.com Addr blocksize; 1949241Sandreas.hansson@arm.com Tick min_period; 1959241Sandreas.hansson@arm.com Tick max_period; 1969241Sandreas.hansson@arm.com Addr data_limit; 1979241Sandreas.hansson@arm.com 1989241Sandreas.hansson@arm.com is >> read_percent >> start_addr >> end_addr >> 1999241Sandreas.hansson@arm.com blocksize >> min_period >> max_period >> data_limit; 2009241Sandreas.hansson@arm.com 2019241Sandreas.hansson@arm.com DPRINTF(TrafficGen, "%s, addr %x to %x, size %d," 2029241Sandreas.hansson@arm.com " period %d to %d, %d%% reads\n", 2039241Sandreas.hansson@arm.com mode, start_addr, end_addr, blocksize, min_period, 2049241Sandreas.hansson@arm.com max_period, read_percent); 2059241Sandreas.hansson@arm.com 2069718Sandreas.hansson@arm.com 2079241Sandreas.hansson@arm.com if (mode == "LINEAR") { 20812811Sandreas.sandberg@arm.com states[id] = createLinear(duration, start_addr, 20912811Sandreas.sandberg@arm.com end_addr, blocksize, 21012811Sandreas.sandberg@arm.com min_period, max_period, 21112811Sandreas.sandberg@arm.com read_percent, data_limit); 2129241Sandreas.hansson@arm.com DPRINTF(TrafficGen, "State: %d LinearGen\n", id); 2139241Sandreas.hansson@arm.com } else if (mode == "RANDOM") { 21412811Sandreas.sandberg@arm.com states[id] = createRandom(duration, start_addr, 21512811Sandreas.sandberg@arm.com end_addr, blocksize, 21612811Sandreas.sandberg@arm.com min_period, max_period, 21712811Sandreas.sandberg@arm.com read_percent, data_limit); 2189241Sandreas.hansson@arm.com DPRINTF(TrafficGen, "State: %d RandomGen\n", id); 21910392Swendy.elsasser@arm.com } else if (mode == "DRAM" || mode == "DRAM_ROTATE") { 22010138Sneha.agarwal@arm.com // stride size (bytes) of the request for achieving 22110138Sneha.agarwal@arm.com // required hit length 22210138Sneha.agarwal@arm.com unsigned int stride_size; 22310138Sneha.agarwal@arm.com unsigned int page_size; 22410138Sneha.agarwal@arm.com unsigned int nbr_of_banks_DRAM; 22510138Sneha.agarwal@arm.com unsigned int nbr_of_banks_util; 22610138Sneha.agarwal@arm.com unsigned int addr_mapping; 22710392Swendy.elsasser@arm.com unsigned int nbr_of_ranks; 22810138Sneha.agarwal@arm.com 22910138Sneha.agarwal@arm.com is >> stride_size >> page_size >> nbr_of_banks_DRAM >> 23010392Swendy.elsasser@arm.com nbr_of_banks_util >> addr_mapping >> 23110392Swendy.elsasser@arm.com nbr_of_ranks; 23210138Sneha.agarwal@arm.com 23310138Sneha.agarwal@arm.com if (stride_size > page_size) 23410138Sneha.agarwal@arm.com warn("DRAM generator stride size (%d) is greater " 23510138Sneha.agarwal@arm.com "than page size (%d) of the memory\n", 23610138Sneha.agarwal@arm.com blocksize, page_size); 23710138Sneha.agarwal@arm.com 23810138Sneha.agarwal@arm.com // count the number of sequential packets to 23910138Sneha.agarwal@arm.com // generate 24010138Sneha.agarwal@arm.com unsigned int num_seq_pkts = 1; 24110138Sneha.agarwal@arm.com 24210138Sneha.agarwal@arm.com if (stride_size > blocksize) { 24310138Sneha.agarwal@arm.com num_seq_pkts = divCeil(stride_size, blocksize); 24410138Sneha.agarwal@arm.com DPRINTF(TrafficGen, "stride size: %d " 24510138Sneha.agarwal@arm.com "block size: %d, num_seq_pkts: %d\n", 24610138Sneha.agarwal@arm.com stride_size, blocksize, num_seq_pkts); 24710138Sneha.agarwal@arm.com } 24810138Sneha.agarwal@arm.com 24910392Swendy.elsasser@arm.com if (mode == "DRAM") { 25012811Sandreas.sandberg@arm.com states[id] = createDram(duration, start_addr, 25112811Sandreas.sandberg@arm.com end_addr, blocksize, 25212811Sandreas.sandberg@arm.com min_period, max_period, 25312811Sandreas.sandberg@arm.com read_percent, data_limit, 25412811Sandreas.sandberg@arm.com num_seq_pkts, page_size, 25512811Sandreas.sandberg@arm.com nbr_of_banks_DRAM, 25612811Sandreas.sandberg@arm.com nbr_of_banks_util, 25712811Sandreas.sandberg@arm.com addr_mapping, 25812811Sandreas.sandberg@arm.com nbr_of_ranks); 25910392Swendy.elsasser@arm.com DPRINTF(TrafficGen, "State: %d DramGen\n", id); 26010392Swendy.elsasser@arm.com } else { 26110392Swendy.elsasser@arm.com // Will rotate to the next rank after rotating 26210392Swendy.elsasser@arm.com // through all banks, for each command type. 26310392Swendy.elsasser@arm.com // In the 50% read case, series will be issued 26410392Swendy.elsasser@arm.com // for both RD & WR before the rank in incremented 26510392Swendy.elsasser@arm.com unsigned int max_seq_count_per_rank = 26610392Swendy.elsasser@arm.com (read_percent == 50) ? nbr_of_banks_util * 2 26710392Swendy.elsasser@arm.com : nbr_of_banks_util; 26810392Swendy.elsasser@arm.com 26912811Sandreas.sandberg@arm.com states[id] = createDramRot(duration, start_addr, 27012811Sandreas.sandberg@arm.com end_addr, blocksize, 27112811Sandreas.sandberg@arm.com min_period, max_period, 27212811Sandreas.sandberg@arm.com read_percent, 27312811Sandreas.sandberg@arm.com data_limit, 27412811Sandreas.sandberg@arm.com num_seq_pkts, page_size, 27512811Sandreas.sandberg@arm.com nbr_of_banks_DRAM, 27612811Sandreas.sandberg@arm.com nbr_of_banks_util, 27712811Sandreas.sandberg@arm.com addr_mapping, 27812811Sandreas.sandberg@arm.com nbr_of_ranks, 27912811Sandreas.sandberg@arm.com max_seq_count_per_rank); 28010392Swendy.elsasser@arm.com DPRINTF(TrafficGen, "State: %d DramRotGen\n", id); 28110392Swendy.elsasser@arm.com } 2829241Sandreas.hansson@arm.com } 2839241Sandreas.hansson@arm.com } else { 2849241Sandreas.hansson@arm.com fatal("%s: Unknown traffic generator mode: %s", 2859241Sandreas.hansson@arm.com name(), mode); 2869241Sandreas.hansson@arm.com } 2879241Sandreas.hansson@arm.com } else if (keyword == "TRANSITION") { 2889241Sandreas.hansson@arm.com Transition transition; 2899241Sandreas.hansson@arm.com 2909241Sandreas.hansson@arm.com is >> transition.from >> transition.to >> transition.p; 2919241Sandreas.hansson@arm.com 2929241Sandreas.hansson@arm.com transitions.push_back(transition); 2939241Sandreas.hansson@arm.com 2949241Sandreas.hansson@arm.com DPRINTF(TrafficGen, "Transition: %d -> %d\n", transition.from, 2959241Sandreas.hansson@arm.com transition.to); 2969241Sandreas.hansson@arm.com } else if (keyword == "INIT") { 2979241Sandreas.hansson@arm.com // set the initial state as the active state 2989241Sandreas.hansson@arm.com is >> currState; 2999241Sandreas.hansson@arm.com 30010128Sstan.czerniawski@arm.com init_state_set = true; 30110128Sstan.czerniawski@arm.com 3029241Sandreas.hansson@arm.com DPRINTF(TrafficGen, "Initial state: %d\n", currState); 3039241Sandreas.hansson@arm.com } 3049241Sandreas.hansson@arm.com } 3059241Sandreas.hansson@arm.com } 3069241Sandreas.hansson@arm.com 30710128Sstan.czerniawski@arm.com if (!init_state_set) 30810128Sstan.czerniawski@arm.com fatal("%s: initial state not specified (add 'INIT <id>' line " 30910128Sstan.czerniawski@arm.com "to the config file)\n", name()); 31010128Sstan.czerniawski@arm.com 3119241Sandreas.hansson@arm.com // resize and populate state transition matrix 3129721Ssascha.bischoff@arm.com transitionMatrix.resize(states.size()); 3139721Ssascha.bischoff@arm.com for (size_t i = 0; i < states.size(); i++) { 3149721Ssascha.bischoff@arm.com transitionMatrix[i].resize(states.size()); 3159241Sandreas.hansson@arm.com } 3169241Sandreas.hansson@arm.com 3179241Sandreas.hansson@arm.com for (vector<Transition>::iterator t = transitions.begin(); 3189241Sandreas.hansson@arm.com t != transitions.end(); ++t) { 3199241Sandreas.hansson@arm.com transitionMatrix[t->from][t->to] = t->p; 3209241Sandreas.hansson@arm.com } 3219241Sandreas.hansson@arm.com 3229241Sandreas.hansson@arm.com // ensure the egress edges do not have a probability larger than 3239241Sandreas.hansson@arm.com // one 3249721Ssascha.bischoff@arm.com for (size_t i = 0; i < states.size(); i++) { 3259241Sandreas.hansson@arm.com double sum = 0; 3269721Ssascha.bischoff@arm.com for (size_t j = 0; j < states.size(); j++) { 3279241Sandreas.hansson@arm.com sum += transitionMatrix[i][j]; 3289241Sandreas.hansson@arm.com } 3299241Sandreas.hansson@arm.com 3309241Sandreas.hansson@arm.com // avoid comparing floating point numbers 3319241Sandreas.hansson@arm.com if (abs(sum - 1.0) > 0.001) 3329241Sandreas.hansson@arm.com fatal("%s has transition probability != 1 for state %d\n", 3339241Sandreas.hansson@arm.com name(), i); 3349241Sandreas.hansson@arm.com } 3359241Sandreas.hansson@arm.com 3369241Sandreas.hansson@arm.com // close input file 3379241Sandreas.hansson@arm.com infile.close(); 3389241Sandreas.hansson@arm.com} 3399241Sandreas.hansson@arm.com 34012810Sandreas.sandberg@arm.comsize_t 34112810Sandreas.sandberg@arm.comTrafficGen::nextState() 3429241Sandreas.hansson@arm.com{ 34310348Sandreas.hansson@arm.com double p = random_mt.random<double>(); 3449241Sandreas.hansson@arm.com assert(currState < transitionMatrix.size()); 3459584Sandreas@sandberg.pp.se double cumulative = 0.0; 3469584Sandreas@sandberg.pp.se size_t i = 0; 3479584Sandreas@sandberg.pp.se do { 3489241Sandreas.hansson@arm.com cumulative += transitionMatrix[currState][i]; 3499241Sandreas.hansson@arm.com ++i; 3509584Sandreas@sandberg.pp.se } while (cumulative < p && i < transitionMatrix[currState].size()); 3519584Sandreas@sandberg.pp.se 35212810Sandreas.sandberg@arm.com return i - 1; 3539241Sandreas.hansson@arm.com} 3549241Sandreas.hansson@arm.com 35512810Sandreas.sandberg@arm.comstd::shared_ptr<BaseGen> 35612810Sandreas.sandberg@arm.comTrafficGen::nextGenerator() 3579241Sandreas.hansson@arm.com{ 35812810Sandreas.sandberg@arm.com // Return the initial state if there isn't an active generator, 35912810Sandreas.sandberg@arm.com // otherwise perform a state transition. 36012810Sandreas.sandberg@arm.com if (activeGenerator) 36112810Sandreas.sandberg@arm.com currState = nextState(); 3629241Sandreas.hansson@arm.com 36312810Sandreas.sandberg@arm.com DPRINTF(TrafficGen, "Transition to state %d\n", currState); 36412810Sandreas.sandberg@arm.com return states[currState]; 3659241Sandreas.hansson@arm.com} 366