traffic_gen.cc revision 10138
19241Sandreas.hansson@arm.com/* 29717Sandreas.hansson@arm.com * Copyright (c) 2012-2013 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 */ 419241Sandreas.hansson@arm.com 429241Sandreas.hansson@arm.com#include <sstream> 439241Sandreas.hansson@arm.com 4410138Sneha.agarwal@arm.com#include "base/intmath.hh" 459241Sandreas.hansson@arm.com#include "base/random.hh" 469241Sandreas.hansson@arm.com#include "cpu/testers/traffic_gen/traffic_gen.hh" 479241Sandreas.hansson@arm.com#include "debug/Checkpoint.hh" 489241Sandreas.hansson@arm.com#include "debug/TrafficGen.hh" 499241Sandreas.hansson@arm.com#include "sim/stats.hh" 509241Sandreas.hansson@arm.com#include "sim/system.hh" 519241Sandreas.hansson@arm.com 529241Sandreas.hansson@arm.comusing namespace std; 539241Sandreas.hansson@arm.com 549241Sandreas.hansson@arm.comTrafficGen::TrafficGen(const TrafficGenParams* p) 559241Sandreas.hansson@arm.com : MemObject(p), 569241Sandreas.hansson@arm.com system(p->system), 579241Sandreas.hansson@arm.com masterID(system->getMasterId(name())), 589718Sandreas.hansson@arm.com configFile(p->config_file), 599720Sandreas.hansson@arm.com elasticReq(p->elastic_req), 609717Sandreas.hansson@arm.com nextTransitionTick(0), 619719Sandreas.hansson@arm.com nextPacketTick(0), 629241Sandreas.hansson@arm.com port(name() + ".port", *this), 639719Sandreas.hansson@arm.com retryPkt(NULL), 649719Sandreas.hansson@arm.com retryPktTick(0), 659719Sandreas.hansson@arm.com updateEvent(this), 669719Sandreas.hansson@arm.com drainManager(NULL) 679241Sandreas.hansson@arm.com{ 689241Sandreas.hansson@arm.com} 699241Sandreas.hansson@arm.com 709241Sandreas.hansson@arm.comTrafficGen* 719241Sandreas.hansson@arm.comTrafficGenParams::create() 729241Sandreas.hansson@arm.com{ 739241Sandreas.hansson@arm.com return new TrafficGen(this); 749241Sandreas.hansson@arm.com} 759241Sandreas.hansson@arm.com 769294Sandreas.hansson@arm.comBaseMasterPort& 779294Sandreas.hansson@arm.comTrafficGen::getMasterPort(const string& if_name, PortID idx) 789241Sandreas.hansson@arm.com{ 799241Sandreas.hansson@arm.com if (if_name == "port") { 809241Sandreas.hansson@arm.com return port; 819241Sandreas.hansson@arm.com } else { 829241Sandreas.hansson@arm.com return MemObject::getMasterPort(if_name, idx); 839241Sandreas.hansson@arm.com } 849241Sandreas.hansson@arm.com} 859241Sandreas.hansson@arm.com 869241Sandreas.hansson@arm.comvoid 879241Sandreas.hansson@arm.comTrafficGen::init() 889241Sandreas.hansson@arm.com{ 899241Sandreas.hansson@arm.com if (!port.isConnected()) 909241Sandreas.hansson@arm.com fatal("The port of %s is not connected!\n", name()); 919241Sandreas.hansson@arm.com 929241Sandreas.hansson@arm.com // if the system is in timing mode active the request generator 939524SAndreas.Sandberg@ARM.com if (system->isTimingMode()) { 949241Sandreas.hansson@arm.com DPRINTF(TrafficGen, "Timing mode, activating request generator\n"); 959241Sandreas.hansson@arm.com 969718Sandreas.hansson@arm.com parseConfig(); 979718Sandreas.hansson@arm.com 989241Sandreas.hansson@arm.com // enter initial state 999717Sandreas.hansson@arm.com enterState(currState); 1009241Sandreas.hansson@arm.com } else { 1019241Sandreas.hansson@arm.com DPRINTF(TrafficGen, 1029241Sandreas.hansson@arm.com "Traffic generator is only active in timing mode\n"); 1039241Sandreas.hansson@arm.com } 1049241Sandreas.hansson@arm.com} 1059241Sandreas.hansson@arm.com 1069241Sandreas.hansson@arm.comvoid 1079241Sandreas.hansson@arm.comTrafficGen::initState() 1089241Sandreas.hansson@arm.com{ 1099241Sandreas.hansson@arm.com // when not restoring from a checkpoint, make sure we kick things off 1109524SAndreas.Sandberg@ARM.com if (system->isTimingMode()) { 1119719Sandreas.hansson@arm.com // call nextPacketTick on the state to advance it 1129720Sandreas.hansson@arm.com nextPacketTick = states[currState]->nextPacketTick(elasticReq, 0); 1139719Sandreas.hansson@arm.com schedule(updateEvent, std::min(nextPacketTick, nextTransitionTick)); 1149241Sandreas.hansson@arm.com } else { 1159241Sandreas.hansson@arm.com DPRINTF(TrafficGen, 1169241Sandreas.hansson@arm.com "Traffic generator is only active in timing mode\n"); 1179241Sandreas.hansson@arm.com } 1189241Sandreas.hansson@arm.com} 1199241Sandreas.hansson@arm.com 1209241Sandreas.hansson@arm.comunsigned int 1219342SAndreas.Sandberg@arm.comTrafficGen::drain(DrainManager *dm) 1229241Sandreas.hansson@arm.com{ 12310051Srioshering@gmail.com if (!updateEvent.scheduled()) { 12410051Srioshering@gmail.com // no event has been scheduled yet (e.g. switched from atomic mode) 12510051Srioshering@gmail.com return 0; 12610051Srioshering@gmail.com } 12710051Srioshering@gmail.com 1289719Sandreas.hansson@arm.com if (retryPkt == NULL) { 1299719Sandreas.hansson@arm.com // shut things down 1309719Sandreas.hansson@arm.com nextPacketTick = MaxTick; 1319719Sandreas.hansson@arm.com nextTransitionTick = MaxTick; 1329719Sandreas.hansson@arm.com deschedule(updateEvent); 1339719Sandreas.hansson@arm.com return 0; 1349719Sandreas.hansson@arm.com } else { 1359719Sandreas.hansson@arm.com drainManager = dm; 1369719Sandreas.hansson@arm.com return 1; 1379719Sandreas.hansson@arm.com } 1389241Sandreas.hansson@arm.com} 1399241Sandreas.hansson@arm.com 1409241Sandreas.hansson@arm.comvoid 1419241Sandreas.hansson@arm.comTrafficGen::serialize(ostream &os) 1429241Sandreas.hansson@arm.com{ 1439241Sandreas.hansson@arm.com DPRINTF(Checkpoint, "Serializing TrafficGen\n"); 1449241Sandreas.hansson@arm.com 1459241Sandreas.hansson@arm.com // save ticks of the graph event if it is scheduled 1469719Sandreas.hansson@arm.com Tick nextEvent = updateEvent.scheduled() ? updateEvent.when() : 0; 1479241Sandreas.hansson@arm.com 1489719Sandreas.hansson@arm.com DPRINTF(TrafficGen, "Saving nextEvent=%llu\n", nextEvent); 1499241Sandreas.hansson@arm.com 1509717Sandreas.hansson@arm.com SERIALIZE_SCALAR(nextEvent); 1519241Sandreas.hansson@arm.com 1529241Sandreas.hansson@arm.com SERIALIZE_SCALAR(nextTransitionTick); 1539241Sandreas.hansson@arm.com 1549719Sandreas.hansson@arm.com SERIALIZE_SCALAR(nextPacketTick); 1559719Sandreas.hansson@arm.com 1569719Sandreas.hansson@arm.com SERIALIZE_SCALAR(currState); 1579241Sandreas.hansson@arm.com} 1589241Sandreas.hansson@arm.com 1599241Sandreas.hansson@arm.comvoid 1609241Sandreas.hansson@arm.comTrafficGen::unserialize(Checkpoint* cp, const string& section) 1619241Sandreas.hansson@arm.com{ 1629241Sandreas.hansson@arm.com // restore scheduled events 1639717Sandreas.hansson@arm.com Tick nextEvent; 1649717Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(nextEvent); 1659717Sandreas.hansson@arm.com if (nextEvent != 0) { 1669717Sandreas.hansson@arm.com schedule(updateEvent, nextEvent); 1679241Sandreas.hansson@arm.com } 1689241Sandreas.hansson@arm.com 1699241Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(nextTransitionTick); 1709719Sandreas.hansson@arm.com 1719719Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(nextPacketTick); 1729719Sandreas.hansson@arm.com 1739719Sandreas.hansson@arm.com // @todo In the case of a stateful generator state such as the 1749719Sandreas.hansson@arm.com // trace player we would also have to restore the position in the 1759720Sandreas.hansson@arm.com // trace playback and the tick offset 1769719Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(currState); 1779241Sandreas.hansson@arm.com} 1789241Sandreas.hansson@arm.com 1799241Sandreas.hansson@arm.comvoid 1809717Sandreas.hansson@arm.comTrafficGen::update() 1819241Sandreas.hansson@arm.com{ 1829717Sandreas.hansson@arm.com // if we have reached the time for the next state transition, then 1839717Sandreas.hansson@arm.com // perform the transition 1849717Sandreas.hansson@arm.com if (curTick() >= nextTransitionTick) { 1859717Sandreas.hansson@arm.com transition(); 1869717Sandreas.hansson@arm.com } else { 1879719Sandreas.hansson@arm.com assert(curTick() >= nextPacketTick); 1889719Sandreas.hansson@arm.com // get the next packet and try to send it 1899718Sandreas.hansson@arm.com PacketPtr pkt = states[currState]->getNextPacket(); 1909719Sandreas.hansson@arm.com numPackets++; 1919719Sandreas.hansson@arm.com if (!port.sendTimingReq(pkt)) { 1929719Sandreas.hansson@arm.com retryPkt = pkt; 1939719Sandreas.hansson@arm.com retryPktTick = curTick(); 1949719Sandreas.hansson@arm.com } 1959719Sandreas.hansson@arm.com } 1969719Sandreas.hansson@arm.com 1979719Sandreas.hansson@arm.com // if we are waiting for a retry, do not schedule any further 1989719Sandreas.hansson@arm.com // events, in the case of a transition or a successful send, go 1999719Sandreas.hansson@arm.com // ahead and determine when the next update should take place 2009719Sandreas.hansson@arm.com if (retryPkt == NULL) { 2019719Sandreas.hansson@arm.com // schedule next update event based on either the next execute 2029719Sandreas.hansson@arm.com // tick or the next transition, which ever comes first 2039720Sandreas.hansson@arm.com nextPacketTick = states[currState]->nextPacketTick(elasticReq, 0); 2049719Sandreas.hansson@arm.com Tick nextEventTick = std::min(nextPacketTick, nextTransitionTick); 2059719Sandreas.hansson@arm.com DPRINTF(TrafficGen, "Next event scheduled at %lld\n", nextEventTick); 2069719Sandreas.hansson@arm.com schedule(updateEvent, nextEventTick); 2079717Sandreas.hansson@arm.com } 2089241Sandreas.hansson@arm.com} 2099241Sandreas.hansson@arm.com 2109241Sandreas.hansson@arm.comvoid 2119718Sandreas.hansson@arm.comTrafficGen::parseConfig() 2129241Sandreas.hansson@arm.com{ 2139241Sandreas.hansson@arm.com // keep track of the transitions parsed to create the matrix when 2149241Sandreas.hansson@arm.com // done 2159241Sandreas.hansson@arm.com vector<Transition> transitions; 2169241Sandreas.hansson@arm.com 2179241Sandreas.hansson@arm.com // open input file 2189241Sandreas.hansson@arm.com ifstream infile; 2199718Sandreas.hansson@arm.com infile.open(configFile.c_str(), ifstream::in); 2209241Sandreas.hansson@arm.com if (!infile.is_open()) { 2219241Sandreas.hansson@arm.com fatal("Traffic generator %s config file not found at %s\n", 2229718Sandreas.hansson@arm.com name(), configFile); 2239241Sandreas.hansson@arm.com } 2249241Sandreas.hansson@arm.com 22510128Sstan.czerniawski@arm.com bool init_state_set = false; 22610128Sstan.czerniawski@arm.com 2279241Sandreas.hansson@arm.com // read line by line and determine the action based on the first 2289241Sandreas.hansson@arm.com // keyword 2299241Sandreas.hansson@arm.com string keyword; 2309241Sandreas.hansson@arm.com string line; 2319241Sandreas.hansson@arm.com 2329241Sandreas.hansson@arm.com while (getline(infile, line).good()) { 2339241Sandreas.hansson@arm.com // see if this line is a comment line, and if so skip it 2349241Sandreas.hansson@arm.com if (line.find('#') != 1) { 2359241Sandreas.hansson@arm.com // create an input stream for the tokenization 2369241Sandreas.hansson@arm.com istringstream is(line); 2379241Sandreas.hansson@arm.com 2389241Sandreas.hansson@arm.com // determine the keyword 2399241Sandreas.hansson@arm.com is >> keyword; 2409241Sandreas.hansson@arm.com 2419241Sandreas.hansson@arm.com if (keyword == "STATE") { 2429241Sandreas.hansson@arm.com // parse the behaviour of this state 2439241Sandreas.hansson@arm.com uint32_t id; 2449241Sandreas.hansson@arm.com Tick duration; 2459241Sandreas.hansson@arm.com string mode; 2469241Sandreas.hansson@arm.com 2479241Sandreas.hansson@arm.com is >> id >> duration >> mode; 2489241Sandreas.hansson@arm.com 2499241Sandreas.hansson@arm.com if (mode == "TRACE") { 2509241Sandreas.hansson@arm.com string traceFile; 2519241Sandreas.hansson@arm.com Addr addrOffset; 2529241Sandreas.hansson@arm.com 2539241Sandreas.hansson@arm.com is >> traceFile >> addrOffset; 2549241Sandreas.hansson@arm.com 2559718Sandreas.hansson@arm.com states[id] = new TraceGen(name(), masterID, duration, 2569241Sandreas.hansson@arm.com traceFile, addrOffset); 2579241Sandreas.hansson@arm.com DPRINTF(TrafficGen, "State: %d TraceGen\n", id); 2589241Sandreas.hansson@arm.com } else if (mode == "IDLE") { 2599718Sandreas.hansson@arm.com states[id] = new IdleGen(name(), masterID, duration); 2609241Sandreas.hansson@arm.com DPRINTF(TrafficGen, "State: %d IdleGen\n", id); 26110138Sneha.agarwal@arm.com } else if (mode == "LINEAR" || mode == "RANDOM" || 26210138Sneha.agarwal@arm.com mode == "DRAM") { 2639241Sandreas.hansson@arm.com uint32_t read_percent; 2649241Sandreas.hansson@arm.com Addr start_addr; 2659241Sandreas.hansson@arm.com Addr end_addr; 2669241Sandreas.hansson@arm.com Addr blocksize; 2679241Sandreas.hansson@arm.com Tick min_period; 2689241Sandreas.hansson@arm.com Tick max_period; 2699241Sandreas.hansson@arm.com Addr data_limit; 2709241Sandreas.hansson@arm.com 2719241Sandreas.hansson@arm.com is >> read_percent >> start_addr >> end_addr >> 2729241Sandreas.hansson@arm.com blocksize >> min_period >> max_period >> data_limit; 2739241Sandreas.hansson@arm.com 2749241Sandreas.hansson@arm.com DPRINTF(TrafficGen, "%s, addr %x to %x, size %d," 2759241Sandreas.hansson@arm.com " period %d to %d, %d%% reads\n", 2769241Sandreas.hansson@arm.com mode, start_addr, end_addr, blocksize, min_period, 2779241Sandreas.hansson@arm.com max_period, read_percent); 2789241Sandreas.hansson@arm.com 2799718Sandreas.hansson@arm.com 2809814Sandreas.hansson@arm.com if (blocksize > system->cacheLineSize()) 2819718Sandreas.hansson@arm.com fatal("TrafficGen %s block size (%d) is larger than " 28210138Sneha.agarwal@arm.com "cache line size (%d)\n", name(), 2839814Sandreas.hansson@arm.com blocksize, system->cacheLineSize()); 2849718Sandreas.hansson@arm.com 2859241Sandreas.hansson@arm.com if (read_percent > 100) 2869718Sandreas.hansson@arm.com fatal("%s cannot have more than 100% reads", name()); 2879241Sandreas.hansson@arm.com 2889722Ssascha.bischoff@arm.com if (min_period > max_period) 2899722Ssascha.bischoff@arm.com fatal("%s cannot have min_period > max_period", name()); 2909722Ssascha.bischoff@arm.com 2919241Sandreas.hansson@arm.com if (mode == "LINEAR") { 2929718Sandreas.hansson@arm.com states[id] = new LinearGen(name(), masterID, 2939241Sandreas.hansson@arm.com duration, start_addr, 2949241Sandreas.hansson@arm.com end_addr, blocksize, 2959241Sandreas.hansson@arm.com min_period, max_period, 2969241Sandreas.hansson@arm.com read_percent, data_limit); 2979241Sandreas.hansson@arm.com DPRINTF(TrafficGen, "State: %d LinearGen\n", id); 2989241Sandreas.hansson@arm.com } else if (mode == "RANDOM") { 2999718Sandreas.hansson@arm.com states[id] = new RandomGen(name(), masterID, 3009241Sandreas.hansson@arm.com duration, start_addr, 3019241Sandreas.hansson@arm.com end_addr, blocksize, 3029241Sandreas.hansson@arm.com min_period, max_period, 3039241Sandreas.hansson@arm.com read_percent, data_limit); 3049241Sandreas.hansson@arm.com DPRINTF(TrafficGen, "State: %d RandomGen\n", id); 30510138Sneha.agarwal@arm.com } else if (mode == "DRAM") { 30610138Sneha.agarwal@arm.com // stride size (bytes) of the request for achieving 30710138Sneha.agarwal@arm.com // required hit length 30810138Sneha.agarwal@arm.com unsigned int stride_size; 30910138Sneha.agarwal@arm.com unsigned int page_size; 31010138Sneha.agarwal@arm.com unsigned int nbr_of_banks_DRAM; 31110138Sneha.agarwal@arm.com unsigned int nbr_of_banks_util; 31210138Sneha.agarwal@arm.com unsigned int addr_mapping; 31310138Sneha.agarwal@arm.com 31410138Sneha.agarwal@arm.com is >> stride_size >> page_size >> nbr_of_banks_DRAM >> 31510138Sneha.agarwal@arm.com nbr_of_banks_util >> addr_mapping; 31610138Sneha.agarwal@arm.com 31710138Sneha.agarwal@arm.com if (stride_size > page_size) 31810138Sneha.agarwal@arm.com warn("DRAM generator stride size (%d) is greater " 31910138Sneha.agarwal@arm.com "than page size (%d) of the memory\n", 32010138Sneha.agarwal@arm.com blocksize, page_size); 32110138Sneha.agarwal@arm.com 32210138Sneha.agarwal@arm.com if (nbr_of_banks_util > nbr_of_banks_DRAM) 32310138Sneha.agarwal@arm.com fatal("Attempting to use more banks (%) than " 32410138Sneha.agarwal@arm.com "what is available (%)\n", 32510138Sneha.agarwal@arm.com nbr_of_banks_util, nbr_of_banks_DRAM); 32610138Sneha.agarwal@arm.com 32710138Sneha.agarwal@arm.com if (nbr_of_banks_util > nbr_of_banks_DRAM) 32810138Sneha.agarwal@arm.com fatal("Attempting to use more banks (%) than " 32910138Sneha.agarwal@arm.com "what is available (%)\n", 33010138Sneha.agarwal@arm.com nbr_of_banks_util, nbr_of_banks_DRAM); 33110138Sneha.agarwal@arm.com 33210138Sneha.agarwal@arm.com // count the number of sequential packets to 33310138Sneha.agarwal@arm.com // generate 33410138Sneha.agarwal@arm.com unsigned int num_seq_pkts = 1; 33510138Sneha.agarwal@arm.com 33610138Sneha.agarwal@arm.com if (stride_size > blocksize) { 33710138Sneha.agarwal@arm.com num_seq_pkts = divCeil(stride_size, blocksize); 33810138Sneha.agarwal@arm.com DPRINTF(TrafficGen, "stride size: %d " 33910138Sneha.agarwal@arm.com "block size: %d, num_seq_pkts: %d\n", 34010138Sneha.agarwal@arm.com stride_size, blocksize, num_seq_pkts); 34110138Sneha.agarwal@arm.com } 34210138Sneha.agarwal@arm.com 34310138Sneha.agarwal@arm.com states[id] = new DramGen(name(), masterID, 34410138Sneha.agarwal@arm.com duration, start_addr, 34510138Sneha.agarwal@arm.com end_addr, blocksize, 34610138Sneha.agarwal@arm.com min_period, max_period, 34710138Sneha.agarwal@arm.com read_percent, data_limit, 34810138Sneha.agarwal@arm.com num_seq_pkts, page_size, 34910138Sneha.agarwal@arm.com nbr_of_banks_DRAM, 35010138Sneha.agarwal@arm.com nbr_of_banks_util, 35110138Sneha.agarwal@arm.com addr_mapping); 35210138Sneha.agarwal@arm.com DPRINTF(TrafficGen, "State: %d DramGen\n", id); 3539241Sandreas.hansson@arm.com } 3549241Sandreas.hansson@arm.com } else { 3559241Sandreas.hansson@arm.com fatal("%s: Unknown traffic generator mode: %s", 3569241Sandreas.hansson@arm.com name(), mode); 3579241Sandreas.hansson@arm.com } 3589241Sandreas.hansson@arm.com } else if (keyword == "TRANSITION") { 3599241Sandreas.hansson@arm.com Transition transition; 3609241Sandreas.hansson@arm.com 3619241Sandreas.hansson@arm.com is >> transition.from >> transition.to >> transition.p; 3629241Sandreas.hansson@arm.com 3639241Sandreas.hansson@arm.com transitions.push_back(transition); 3649241Sandreas.hansson@arm.com 3659241Sandreas.hansson@arm.com DPRINTF(TrafficGen, "Transition: %d -> %d\n", transition.from, 3669241Sandreas.hansson@arm.com transition.to); 3679241Sandreas.hansson@arm.com } else if (keyword == "INIT") { 3689241Sandreas.hansson@arm.com // set the initial state as the active state 3699241Sandreas.hansson@arm.com is >> currState; 3709241Sandreas.hansson@arm.com 37110128Sstan.czerniawski@arm.com init_state_set = true; 37210128Sstan.czerniawski@arm.com 3739241Sandreas.hansson@arm.com DPRINTF(TrafficGen, "Initial state: %d\n", currState); 3749241Sandreas.hansson@arm.com } 3759241Sandreas.hansson@arm.com } 3769241Sandreas.hansson@arm.com } 3779241Sandreas.hansson@arm.com 37810128Sstan.czerniawski@arm.com if (!init_state_set) 37910128Sstan.czerniawski@arm.com fatal("%s: initial state not specified (add 'INIT <id>' line " 38010128Sstan.czerniawski@arm.com "to the config file)\n", name()); 38110128Sstan.czerniawski@arm.com 3829241Sandreas.hansson@arm.com // resize and populate state transition matrix 3839721Ssascha.bischoff@arm.com transitionMatrix.resize(states.size()); 3849721Ssascha.bischoff@arm.com for (size_t i = 0; i < states.size(); i++) { 3859721Ssascha.bischoff@arm.com transitionMatrix[i].resize(states.size()); 3869241Sandreas.hansson@arm.com } 3879241Sandreas.hansson@arm.com 3889241Sandreas.hansson@arm.com for (vector<Transition>::iterator t = transitions.begin(); 3899241Sandreas.hansson@arm.com t != transitions.end(); ++t) { 3909241Sandreas.hansson@arm.com transitionMatrix[t->from][t->to] = t->p; 3919241Sandreas.hansson@arm.com } 3929241Sandreas.hansson@arm.com 3939241Sandreas.hansson@arm.com // ensure the egress edges do not have a probability larger than 3949241Sandreas.hansson@arm.com // one 3959721Ssascha.bischoff@arm.com for (size_t i = 0; i < states.size(); i++) { 3969241Sandreas.hansson@arm.com double sum = 0; 3979721Ssascha.bischoff@arm.com for (size_t j = 0; j < states.size(); j++) { 3989241Sandreas.hansson@arm.com sum += transitionMatrix[i][j]; 3999241Sandreas.hansson@arm.com } 4009241Sandreas.hansson@arm.com 4019241Sandreas.hansson@arm.com // avoid comparing floating point numbers 4029241Sandreas.hansson@arm.com if (abs(sum - 1.0) > 0.001) 4039241Sandreas.hansson@arm.com fatal("%s has transition probability != 1 for state %d\n", 4049241Sandreas.hansson@arm.com name(), i); 4059241Sandreas.hansson@arm.com } 4069241Sandreas.hansson@arm.com 4079241Sandreas.hansson@arm.com // close input file 4089241Sandreas.hansson@arm.com infile.close(); 4099241Sandreas.hansson@arm.com} 4109241Sandreas.hansson@arm.com 4119241Sandreas.hansson@arm.comvoid 4129717Sandreas.hansson@arm.comTrafficGen::transition() 4139241Sandreas.hansson@arm.com{ 4149241Sandreas.hansson@arm.com // exit the current state 4159241Sandreas.hansson@arm.com states[currState]->exit(); 4169241Sandreas.hansson@arm.com 4179241Sandreas.hansson@arm.com // determine next state 4189241Sandreas.hansson@arm.com double p = random_mt.gen_real1(); 4199241Sandreas.hansson@arm.com assert(currState < transitionMatrix.size()); 4209584Sandreas@sandberg.pp.se double cumulative = 0.0; 4219584Sandreas@sandberg.pp.se size_t i = 0; 4229584Sandreas@sandberg.pp.se do { 4239241Sandreas.hansson@arm.com cumulative += transitionMatrix[currState][i]; 4249241Sandreas.hansson@arm.com ++i; 4259584Sandreas@sandberg.pp.se } while (cumulative < p && i < transitionMatrix[currState].size()); 4269584Sandreas@sandberg.pp.se 4279584Sandreas@sandberg.pp.se enterState(i - 1); 4289241Sandreas.hansson@arm.com} 4299241Sandreas.hansson@arm.com 4309241Sandreas.hansson@arm.comvoid 4319717Sandreas.hansson@arm.comTrafficGen::enterState(uint32_t newState) 4329241Sandreas.hansson@arm.com{ 4339241Sandreas.hansson@arm.com DPRINTF(TrafficGen, "Transition to state %d\n", newState); 4349241Sandreas.hansson@arm.com 4359241Sandreas.hansson@arm.com currState = newState; 4369719Sandreas.hansson@arm.com // we could have been delayed and not transitioned on the exact 4379719Sandreas.hansson@arm.com // tick when we were supposed to (due to back pressure when 4389719Sandreas.hansson@arm.com // sending a packet) 4399719Sandreas.hansson@arm.com nextTransitionTick = curTick() + states[currState]->duration; 4409241Sandreas.hansson@arm.com states[currState]->enter(); 4419241Sandreas.hansson@arm.com} 4429241Sandreas.hansson@arm.com 4439719Sandreas.hansson@arm.comvoid 4449719Sandreas.hansson@arm.comTrafficGen::recvRetry() 4459719Sandreas.hansson@arm.com{ 4469719Sandreas.hansson@arm.com assert(retryPkt != NULL); 4479719Sandreas.hansson@arm.com 4489719Sandreas.hansson@arm.com DPRINTF(TrafficGen, "Received retry\n"); 4499719Sandreas.hansson@arm.com numRetries++; 4509719Sandreas.hansson@arm.com // attempt to send the packet, and if we are successful start up 4519719Sandreas.hansson@arm.com // the machinery again 4529719Sandreas.hansson@arm.com if (port.sendTimingReq(retryPkt)) { 4539719Sandreas.hansson@arm.com retryPkt = NULL; 4549719Sandreas.hansson@arm.com // remember how much delay was incurred due to back-pressure 4559720Sandreas.hansson@arm.com // when sending the request, we also use this to derive 4569720Sandreas.hansson@arm.com // the tick for the next packet 4579719Sandreas.hansson@arm.com Tick delay = curTick() - retryPktTick; 4589719Sandreas.hansson@arm.com retryPktTick = 0; 4599719Sandreas.hansson@arm.com retryTicks += delay; 4609719Sandreas.hansson@arm.com 4619719Sandreas.hansson@arm.com if (drainManager == NULL) { 4629719Sandreas.hansson@arm.com // packet is sent, so find out when the next one is due 4639720Sandreas.hansson@arm.com nextPacketTick = states[currState]->nextPacketTick(elasticReq, 4649720Sandreas.hansson@arm.com delay); 4659719Sandreas.hansson@arm.com Tick nextEventTick = std::min(nextPacketTick, nextTransitionTick); 4669719Sandreas.hansson@arm.com schedule(updateEvent, std::max(curTick(), nextEventTick)); 4679719Sandreas.hansson@arm.com } else { 4689719Sandreas.hansson@arm.com // shut things down 4699719Sandreas.hansson@arm.com nextPacketTick = MaxTick; 4709719Sandreas.hansson@arm.com nextTransitionTick = MaxTick; 4719719Sandreas.hansson@arm.com drainManager->signalDrainDone(); 4729719Sandreas.hansson@arm.com // Clear the drain event once we're done with it. 4739719Sandreas.hansson@arm.com drainManager = NULL; 4749719Sandreas.hansson@arm.com } 4759719Sandreas.hansson@arm.com } 4769719Sandreas.hansson@arm.com} 4779719Sandreas.hansson@arm.com 4789719Sandreas.hansson@arm.comvoid 4799719Sandreas.hansson@arm.comTrafficGen::regStats() 4809719Sandreas.hansson@arm.com{ 4819719Sandreas.hansson@arm.com // Initialise all the stats 4829719Sandreas.hansson@arm.com using namespace Stats; 4839719Sandreas.hansson@arm.com 4849719Sandreas.hansson@arm.com numPackets 4859719Sandreas.hansson@arm.com .name(name() + ".numPackets") 4869719Sandreas.hansson@arm.com .desc("Number of packets generated"); 4879719Sandreas.hansson@arm.com 4889719Sandreas.hansson@arm.com numRetries 4899719Sandreas.hansson@arm.com .name(name() + ".numRetries") 4909719Sandreas.hansson@arm.com .desc("Number of retries"); 4919719Sandreas.hansson@arm.com 4929719Sandreas.hansson@arm.com retryTicks 4939719Sandreas.hansson@arm.com .name(name() + ".retryTicks") 4949719Sandreas.hansson@arm.com .desc("Time spent waiting due to back-pressure (ticks)"); 4959719Sandreas.hansson@arm.com} 4969719Sandreas.hansson@arm.com 4979241Sandreas.hansson@arm.combool 4989241Sandreas.hansson@arm.comTrafficGen::TrafficGenPort::recvTimingResp(PacketPtr pkt) 4999241Sandreas.hansson@arm.com{ 5009241Sandreas.hansson@arm.com delete pkt->req; 5019241Sandreas.hansson@arm.com delete pkt; 5029241Sandreas.hansson@arm.com 5039241Sandreas.hansson@arm.com return true; 5049241Sandreas.hansson@arm.com} 505