traffic_gen.hh revision 9342
19241Sandreas.hansson@arm.com/* 29241Sandreas.hansson@arm.com * Copyright (c) 2012 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#ifndef __MEM_TRAFFIC_GEN_HH__ 429241Sandreas.hansson@arm.com#define __MEM_TRAFFIC_GEN_HH__ 439241Sandreas.hansson@arm.com 449241Sandreas.hansson@arm.com#include <fstream> 459241Sandreas.hansson@arm.com 469241Sandreas.hansson@arm.com#include "base/hashmap.hh" 479241Sandreas.hansson@arm.com#include "mem/mem_object.hh" 489241Sandreas.hansson@arm.com#include "mem/qport.hh" 499241Sandreas.hansson@arm.com#include "params/TrafficGen.hh" 509241Sandreas.hansson@arm.com 519241Sandreas.hansson@arm.com/** 529241Sandreas.hansson@arm.com * The traffic generator is a master module that generates stimuli for 539241Sandreas.hansson@arm.com * the memory system, based on a collection of simple behaviours that 549241Sandreas.hansson@arm.com * are either probabilistic or based on traces. It can be used stand 559241Sandreas.hansson@arm.com * alone for creating test cases for interconnect and memory 569241Sandreas.hansson@arm.com * controllers, or function as a black box replacement for system 579241Sandreas.hansson@arm.com * components that are not yet modelled in detail, e.g. a video engine 589241Sandreas.hansson@arm.com * or baseband subsystem. 599241Sandreas.hansson@arm.com */ 609241Sandreas.hansson@arm.comclass TrafficGen : public MemObject 619241Sandreas.hansson@arm.com{ 629241Sandreas.hansson@arm.com 639241Sandreas.hansson@arm.com private: 649241Sandreas.hansson@arm.com 659241Sandreas.hansson@arm.com /** 669241Sandreas.hansson@arm.com * The system used to determine which mode we are currently operating 679241Sandreas.hansson@arm.com * in. 689241Sandreas.hansson@arm.com */ 699241Sandreas.hansson@arm.com System* system; 709241Sandreas.hansson@arm.com 719241Sandreas.hansson@arm.com /** 729241Sandreas.hansson@arm.com * MasterID used in generated requests. 739241Sandreas.hansson@arm.com */ 749241Sandreas.hansson@arm.com MasterID masterID; 759241Sandreas.hansson@arm.com 769241Sandreas.hansson@arm.com protected: 779241Sandreas.hansson@arm.com 789241Sandreas.hansson@arm.com /** 799241Sandreas.hansson@arm.com * The state graph is responsible for instantiating and keeping 809241Sandreas.hansson@arm.com * track of the various generator states and also perform the 819241Sandreas.hansson@arm.com * transitions and call the appropriate functions when entering, 829241Sandreas.hansson@arm.com * executing and exiting a state. 839241Sandreas.hansson@arm.com */ 849241Sandreas.hansson@arm.com class StateGraph 859241Sandreas.hansson@arm.com { 869241Sandreas.hansson@arm.com 879241Sandreas.hansson@arm.com public: 889241Sandreas.hansson@arm.com 899241Sandreas.hansson@arm.com /** 909241Sandreas.hansson@arm.com * Create a state graph from an input file. 919241Sandreas.hansson@arm.com * 929241Sandreas.hansson@arm.com * @param _owner used solely for the name 939241Sandreas.hansson@arm.com * @param _port port used to send requests 949241Sandreas.hansson@arm.com * @param file_name configuration description to read in 959241Sandreas.hansson@arm.com * @param master_id the unique id used for all requests 969241Sandreas.hansson@arm.com */ 979241Sandreas.hansson@arm.com StateGraph(TrafficGen& _owner, QueuedMasterPort& _port, 989241Sandreas.hansson@arm.com const std::string& file_name, MasterID master_id) 999241Sandreas.hansson@arm.com : nextTransitionTick(0), owner(_owner), port(_port) 1009241Sandreas.hansson@arm.com { 1019241Sandreas.hansson@arm.com parseConfig(file_name, master_id); 1029241Sandreas.hansson@arm.com } 1039241Sandreas.hansson@arm.com 1049241Sandreas.hansson@arm.com /** 1059241Sandreas.hansson@arm.com * Get the name, used for DPRINTFs. 1069241Sandreas.hansson@arm.com * 1079241Sandreas.hansson@arm.com * @return the owner's name 1089241Sandreas.hansson@arm.com */ 1099241Sandreas.hansson@arm.com std::string name() const { return owner.name(); } 1109241Sandreas.hansson@arm.com 1119241Sandreas.hansson@arm.com /** 1129241Sandreas.hansson@arm.com * Either perform a state transition or execute the current 1139241Sandreas.hansson@arm.com * state, depending on the current time. 1149241Sandreas.hansson@arm.com */ 1159241Sandreas.hansson@arm.com void update(); 1169241Sandreas.hansson@arm.com 1179241Sandreas.hansson@arm.com /** 1189241Sandreas.hansson@arm.com * Determine next state and perform the transition. 1199241Sandreas.hansson@arm.com */ 1209241Sandreas.hansson@arm.com void transition(); 1219241Sandreas.hansson@arm.com 1229241Sandreas.hansson@arm.com /** 1239241Sandreas.hansson@arm.com * Enter a new state. 1249241Sandreas.hansson@arm.com * 1259241Sandreas.hansson@arm.com * @param newState identifier of state to enter 1269241Sandreas.hansson@arm.com */ 1279241Sandreas.hansson@arm.com void enterState(uint32_t newState); 1289241Sandreas.hansson@arm.com 1299241Sandreas.hansson@arm.com /** 1309241Sandreas.hansson@arm.com * Get the tick of the next event, either an execution or a 1319241Sandreas.hansson@arm.com * transition. 1329241Sandreas.hansson@arm.com * 1339241Sandreas.hansson@arm.com * @return tick of the next state graph event 1349241Sandreas.hansson@arm.com */ 1359241Sandreas.hansson@arm.com Tick nextEventTick() 1369241Sandreas.hansson@arm.com { 1379241Sandreas.hansson@arm.com return std::min(states[currState]->nextExecuteTick(), 1389241Sandreas.hansson@arm.com nextTransitionTick); 1399241Sandreas.hansson@arm.com 1409241Sandreas.hansson@arm.com } 1419241Sandreas.hansson@arm.com 1429241Sandreas.hansson@arm.com /** Time of next transition */ 1439241Sandreas.hansson@arm.com Tick nextTransitionTick; 1449241Sandreas.hansson@arm.com 1459241Sandreas.hansson@arm.com private: 1469241Sandreas.hansson@arm.com 1479241Sandreas.hansson@arm.com /** 1489241Sandreas.hansson@arm.com * Parse the config file and build the state map and 1499241Sandreas.hansson@arm.com * transition matrix. 1509241Sandreas.hansson@arm.com * 1519241Sandreas.hansson@arm.com * @param file_name Config file name to parse 1529241Sandreas.hansson@arm.com * @param master_id MasterID to use for generated requests 1539241Sandreas.hansson@arm.com */ 1549241Sandreas.hansson@arm.com void parseConfig(const std::string& file_name, MasterID master_id); 1559241Sandreas.hansson@arm.com 1569241Sandreas.hansson@arm.com /** Struct to represent a probabilistic transition during parsing. */ 1579241Sandreas.hansson@arm.com struct Transition { 1589241Sandreas.hansson@arm.com uint32_t from; 1599241Sandreas.hansson@arm.com uint32_t to; 1609241Sandreas.hansson@arm.com double p; 1619241Sandreas.hansson@arm.com }; 1629241Sandreas.hansson@arm.com 1639241Sandreas.hansson@arm.com /** Base class for all generator states */ 1649241Sandreas.hansson@arm.com class BaseGen 1659241Sandreas.hansson@arm.com { 1669241Sandreas.hansson@arm.com 1679241Sandreas.hansson@arm.com protected: 1689241Sandreas.hansson@arm.com 1699241Sandreas.hansson@arm.com /** Port used to send requests */ 1709241Sandreas.hansson@arm.com QueuedMasterPort& port; 1719241Sandreas.hansson@arm.com 1729241Sandreas.hansson@arm.com /** The MasterID used for generating requests */ 1739241Sandreas.hansson@arm.com const MasterID masterID; 1749241Sandreas.hansson@arm.com 1759241Sandreas.hansson@arm.com public: 1769241Sandreas.hansson@arm.com 1779241Sandreas.hansson@arm.com /** Time to spend in this state */ 1789241Sandreas.hansson@arm.com const Tick duration; 1799241Sandreas.hansson@arm.com 1809241Sandreas.hansson@arm.com /** 1819241Sandreas.hansson@arm.com * Create a base generator. 1829241Sandreas.hansson@arm.com * 1839241Sandreas.hansson@arm.com * @param _port port used to send requests 1849241Sandreas.hansson@arm.com * @param master_id MasterID set on each request 1859241Sandreas.hansson@arm.com * @param _duration duration of this state before transitioning 1869241Sandreas.hansson@arm.com */ 1879241Sandreas.hansson@arm.com BaseGen(QueuedMasterPort& _port, MasterID master_id, 1889241Sandreas.hansson@arm.com Tick _duration); 1899241Sandreas.hansson@arm.com 1909241Sandreas.hansson@arm.com virtual ~BaseGen() { } 1919241Sandreas.hansson@arm.com 1929241Sandreas.hansson@arm.com /** 1939241Sandreas.hansson@arm.com * Get the name, useful for DPRINTFs. 1949241Sandreas.hansson@arm.com * 1959241Sandreas.hansson@arm.com * @return the port name 1969241Sandreas.hansson@arm.com */ 1979241Sandreas.hansson@arm.com std::string name() const { return port.name(); } 1989241Sandreas.hansson@arm.com 1999241Sandreas.hansson@arm.com /** 2009241Sandreas.hansson@arm.com * Enter this generator state. 2019241Sandreas.hansson@arm.com */ 2029241Sandreas.hansson@arm.com virtual void enter() = 0; 2039241Sandreas.hansson@arm.com 2049241Sandreas.hansson@arm.com /** 2059241Sandreas.hansson@arm.com * Execute this generator state. 2069241Sandreas.hansson@arm.com */ 2079241Sandreas.hansson@arm.com virtual void execute() = 0; 2089241Sandreas.hansson@arm.com 2099241Sandreas.hansson@arm.com /** 2109241Sandreas.hansson@arm.com * Exit this generator state. By default do nothing. 2119241Sandreas.hansson@arm.com */ 2129241Sandreas.hansson@arm.com virtual void exit() { }; 2139241Sandreas.hansson@arm.com 2149241Sandreas.hansson@arm.com /** 2159241Sandreas.hansson@arm.com * Determine the next execute tick. MaxTick means that 2169241Sandreas.hansson@arm.com * there will not be any further event in the current 2179241Sandreas.hansson@arm.com * activation cycle of the state. 2189241Sandreas.hansson@arm.com * 2199241Sandreas.hansson@arm.com * @return next tick when the state should be executed 2209241Sandreas.hansson@arm.com */ 2219241Sandreas.hansson@arm.com virtual Tick nextExecuteTick() = 0; 2229241Sandreas.hansson@arm.com 2239241Sandreas.hansson@arm.com }; 2249241Sandreas.hansson@arm.com 2259241Sandreas.hansson@arm.com /** 2269241Sandreas.hansson@arm.com * The idle generator does nothing. 2279241Sandreas.hansson@arm.com */ 2289241Sandreas.hansson@arm.com class IdleGen : public BaseGen 2299241Sandreas.hansson@arm.com { 2309241Sandreas.hansson@arm.com 2319241Sandreas.hansson@arm.com public: 2329241Sandreas.hansson@arm.com 2339241Sandreas.hansson@arm.com IdleGen(QueuedMasterPort& _port, MasterID master_id, 2349241Sandreas.hansson@arm.com Tick _duration) 2359241Sandreas.hansson@arm.com : BaseGen(_port, master_id, _duration) 2369241Sandreas.hansson@arm.com { } 2379241Sandreas.hansson@arm.com 2389241Sandreas.hansson@arm.com void enter() { } 2399241Sandreas.hansson@arm.com 2409241Sandreas.hansson@arm.com void execute() { } 2419241Sandreas.hansson@arm.com 2429241Sandreas.hansson@arm.com Tick nextExecuteTick() { return MaxTick; } 2439241Sandreas.hansson@arm.com }; 2449241Sandreas.hansson@arm.com 2459241Sandreas.hansson@arm.com /** 2469241Sandreas.hansson@arm.com * The linear generator generates sequential requests from a 2479241Sandreas.hansson@arm.com * start to an end address, with a fixed block size. A 2489241Sandreas.hansson@arm.com * fraction of the requests are reads, as determined by the 2499241Sandreas.hansson@arm.com * read percent. There is an optional data limit for when to 2509241Sandreas.hansson@arm.com * stop generating new requests. 2519241Sandreas.hansson@arm.com */ 2529241Sandreas.hansson@arm.com class LinearGen : public BaseGen 2539241Sandreas.hansson@arm.com { 2549241Sandreas.hansson@arm.com 2559241Sandreas.hansson@arm.com public: 2569241Sandreas.hansson@arm.com 2579241Sandreas.hansson@arm.com /** 2589241Sandreas.hansson@arm.com * Create a linear address sequence generator. Set 2599241Sandreas.hansson@arm.com * min_period == max_period for a fixed inter-transaction 2609241Sandreas.hansson@arm.com * time. 2619241Sandreas.hansson@arm.com * 2629241Sandreas.hansson@arm.com * @param _port port used to send requests 2639241Sandreas.hansson@arm.com * @param master_id MasterID set on each request 2649241Sandreas.hansson@arm.com * @param _duration duration of this state before transitioning 2659241Sandreas.hansson@arm.com * @param start_addr Start address 2669241Sandreas.hansson@arm.com * @param end_addr End address 2679241Sandreas.hansson@arm.com * @param _blocksize Size used for transactions injected 2689241Sandreas.hansson@arm.com * @param min_period Lower limit of random inter-transaction time 2699241Sandreas.hansson@arm.com * @param max_period Upper limit of random inter-transaction time 2709241Sandreas.hansson@arm.com * @param read_percent Percent of transactions that are reads 2719241Sandreas.hansson@arm.com * @param data_limit Upper limit on how much data to read/write 2729241Sandreas.hansson@arm.com */ 2739241Sandreas.hansson@arm.com LinearGen(QueuedMasterPort& _port, MasterID master_id, 2749241Sandreas.hansson@arm.com Tick _duration, Addr start_addr, Addr end_addr, 2759241Sandreas.hansson@arm.com Addr _blocksize, Tick min_period, Tick max_period, 2769241Sandreas.hansson@arm.com uint8_t read_percent, Addr data_limit) 2779241Sandreas.hansson@arm.com : BaseGen(_port, master_id, _duration), 2789241Sandreas.hansson@arm.com startAddr(start_addr), endAddr(end_addr), 2799241Sandreas.hansson@arm.com blocksize(_blocksize), minPeriod(min_period), 2809241Sandreas.hansson@arm.com maxPeriod(max_period), readPercent(read_percent), 2819241Sandreas.hansson@arm.com dataLimit(data_limit) 2829241Sandreas.hansson@arm.com { } 2839241Sandreas.hansson@arm.com 2849241Sandreas.hansson@arm.com void enter(); 2859241Sandreas.hansson@arm.com 2869241Sandreas.hansson@arm.com void execute(); 2879241Sandreas.hansson@arm.com 2889241Sandreas.hansson@arm.com Tick nextExecuteTick(); 2899241Sandreas.hansson@arm.com 2909241Sandreas.hansson@arm.com private: 2919241Sandreas.hansson@arm.com 2929241Sandreas.hansson@arm.com /** Start of address range */ 2939241Sandreas.hansson@arm.com const Addr startAddr; 2949241Sandreas.hansson@arm.com 2959241Sandreas.hansson@arm.com /** End of address range */ 2969241Sandreas.hansson@arm.com const Addr endAddr; 2979241Sandreas.hansson@arm.com 2989241Sandreas.hansson@arm.com /** Blocksize and address increment */ 2999241Sandreas.hansson@arm.com const Addr blocksize; 3009241Sandreas.hansson@arm.com 3019241Sandreas.hansson@arm.com /** Request generation period */ 3029241Sandreas.hansson@arm.com const Tick minPeriod; 3039241Sandreas.hansson@arm.com const Tick maxPeriod; 3049241Sandreas.hansson@arm.com 3059241Sandreas.hansson@arm.com /** 3069241Sandreas.hansson@arm.com * Percent of generated transactions that should be reads 3079241Sandreas.hansson@arm.com */ 3089241Sandreas.hansson@arm.com const uint8_t readPercent; 3099241Sandreas.hansson@arm.com 3109241Sandreas.hansson@arm.com /** Maximum amount of data to manipulate */ 3119241Sandreas.hansson@arm.com const Addr dataLimit; 3129241Sandreas.hansson@arm.com 3139241Sandreas.hansson@arm.com /** Address of next request */ 3149241Sandreas.hansson@arm.com Addr nextAddr; 3159241Sandreas.hansson@arm.com 3169241Sandreas.hansson@arm.com /** 3179241Sandreas.hansson@arm.com * Counter to determine the amount of data 3189241Sandreas.hansson@arm.com * manipulated. Used to determine if we should continue 3199241Sandreas.hansson@arm.com * generating requests. 3209241Sandreas.hansson@arm.com */ 3219241Sandreas.hansson@arm.com Addr dataManipulated; 3229241Sandreas.hansson@arm.com }; 3239241Sandreas.hansson@arm.com 3249241Sandreas.hansson@arm.com /** 3259241Sandreas.hansson@arm.com * The random generator is similar to the linear one, but does 3269241Sandreas.hansson@arm.com * not generate sequential addresses. Instead it randomly 3279241Sandreas.hansson@arm.com * picks an address in the range, aligned to the block size. 3289241Sandreas.hansson@arm.com */ 3299241Sandreas.hansson@arm.com class RandomGen : public BaseGen 3309241Sandreas.hansson@arm.com { 3319241Sandreas.hansson@arm.com 3329241Sandreas.hansson@arm.com public: 3339241Sandreas.hansson@arm.com 3349241Sandreas.hansson@arm.com /** 3359241Sandreas.hansson@arm.com * Create a random address sequence generator. Set 3369241Sandreas.hansson@arm.com * min_period == max_period for a fixed inter-transaction 3379241Sandreas.hansson@arm.com * time. 3389241Sandreas.hansson@arm.com * 3399241Sandreas.hansson@arm.com * @param _port port used to send requests 3409241Sandreas.hansson@arm.com * @param master_id MasterID set on each request 3419241Sandreas.hansson@arm.com * @param _duration duration of this state before transitioning 3429241Sandreas.hansson@arm.com * @param start_addr Start address 3439241Sandreas.hansson@arm.com * @param end_addr End address 3449241Sandreas.hansson@arm.com * @param _blocksize Size used for transactions injected 3459241Sandreas.hansson@arm.com * @param min_period Lower limit of random inter-transaction time 3469241Sandreas.hansson@arm.com * @param max_period Upper limit of random inter-transaction time 3479241Sandreas.hansson@arm.com * @param read_percent Percent of transactions that are reads 3489241Sandreas.hansson@arm.com * @param data_limit Upper limit on how much data to read/write 3499241Sandreas.hansson@arm.com */ 3509241Sandreas.hansson@arm.com RandomGen(QueuedMasterPort& _port, MasterID master_id, 3519241Sandreas.hansson@arm.com Tick _duration, Addr start_addr, Addr end_addr, 3529241Sandreas.hansson@arm.com Addr _blocksize, Tick min_period, Tick max_period, 3539241Sandreas.hansson@arm.com uint8_t read_percent, Addr data_limit) 3549241Sandreas.hansson@arm.com : BaseGen(_port, master_id, _duration), 3559241Sandreas.hansson@arm.com startAddr(start_addr), endAddr(end_addr), 3569241Sandreas.hansson@arm.com blocksize(_blocksize), minPeriod(min_period), 3579241Sandreas.hansson@arm.com maxPeriod(max_period), readPercent(read_percent), 3589241Sandreas.hansson@arm.com dataLimit(data_limit) 3599241Sandreas.hansson@arm.com { } 3609241Sandreas.hansson@arm.com 3619241Sandreas.hansson@arm.com void enter(); 3629241Sandreas.hansson@arm.com 3639241Sandreas.hansson@arm.com void execute(); 3649241Sandreas.hansson@arm.com 3659241Sandreas.hansson@arm.com Tick nextExecuteTick(); 3669241Sandreas.hansson@arm.com 3679241Sandreas.hansson@arm.com private: 3689241Sandreas.hansson@arm.com 3699241Sandreas.hansson@arm.com /** Start of address range */ 3709241Sandreas.hansson@arm.com const Addr startAddr; 3719241Sandreas.hansson@arm.com 3729241Sandreas.hansson@arm.com /** End of address range */ 3739241Sandreas.hansson@arm.com const Addr endAddr; 3749241Sandreas.hansson@arm.com 3759241Sandreas.hansson@arm.com /** Block size */ 3769241Sandreas.hansson@arm.com const Addr blocksize; 3779241Sandreas.hansson@arm.com 3789241Sandreas.hansson@arm.com /** Request generation period */ 3799241Sandreas.hansson@arm.com const Tick minPeriod; 3809241Sandreas.hansson@arm.com const Tick maxPeriod; 3819241Sandreas.hansson@arm.com 3829241Sandreas.hansson@arm.com /** 3839241Sandreas.hansson@arm.com * Percent of generated transactions that should be reads 3849241Sandreas.hansson@arm.com */ 3859241Sandreas.hansson@arm.com const uint8_t readPercent; 3869241Sandreas.hansson@arm.com 3879241Sandreas.hansson@arm.com /** Maximum amount of data to manipulate */ 3889241Sandreas.hansson@arm.com const Addr dataLimit; 3899241Sandreas.hansson@arm.com 3909241Sandreas.hansson@arm.com /** 3919241Sandreas.hansson@arm.com * Counter to determine the amount of data 3929241Sandreas.hansson@arm.com * manipulated. Used to determine if we should continue 3939241Sandreas.hansson@arm.com * generating requests. 3949241Sandreas.hansson@arm.com */ 3959241Sandreas.hansson@arm.com Addr dataManipulated; 3969241Sandreas.hansson@arm.com }; 3979241Sandreas.hansson@arm.com 3989241Sandreas.hansson@arm.com /** 3999241Sandreas.hansson@arm.com * The trace replay generator reads a trace file and plays 4009241Sandreas.hansson@arm.com * back the transactions. The trace is offset with respect to 4019241Sandreas.hansson@arm.com * the time when the state was entered. 4029241Sandreas.hansson@arm.com */ 4039241Sandreas.hansson@arm.com class TraceGen : public BaseGen 4049241Sandreas.hansson@arm.com { 4059241Sandreas.hansson@arm.com 4069241Sandreas.hansson@arm.com private: 4079241Sandreas.hansson@arm.com 4089241Sandreas.hansson@arm.com /** 4099241Sandreas.hansson@arm.com * This struct stores a line in the trace file. 4109241Sandreas.hansson@arm.com */ 4119241Sandreas.hansson@arm.com struct TraceElement { 4129241Sandreas.hansson@arm.com 4139241Sandreas.hansson@arm.com /** Specifies if the request is to be a read or a write */ 4149241Sandreas.hansson@arm.com MemCmd cmd; 4159241Sandreas.hansson@arm.com 4169241Sandreas.hansson@arm.com /** The address for the request */ 4179241Sandreas.hansson@arm.com Addr addr; 4189241Sandreas.hansson@arm.com 4199241Sandreas.hansson@arm.com /** The size of the access for the request */ 4209241Sandreas.hansson@arm.com Addr blocksize; 4219241Sandreas.hansson@arm.com 4229241Sandreas.hansson@arm.com /** The time at which the request should be sent */ 4239241Sandreas.hansson@arm.com Tick tick; 4249241Sandreas.hansson@arm.com 4259241Sandreas.hansson@arm.com /** 4269241Sandreas.hansson@arm.com * Check validity of this element. 4279241Sandreas.hansson@arm.com * 4289241Sandreas.hansson@arm.com * @return if this element is valid 4299241Sandreas.hansson@arm.com */ 4309241Sandreas.hansson@arm.com bool isValid() const { 4319241Sandreas.hansson@arm.com return cmd != MemCmd::InvalidCmd; 4329241Sandreas.hansson@arm.com } 4339241Sandreas.hansson@arm.com 4349241Sandreas.hansson@arm.com /** 4359241Sandreas.hansson@arm.com * Make this element invalid. 4369241Sandreas.hansson@arm.com */ 4379241Sandreas.hansson@arm.com void clear() { 4389241Sandreas.hansson@arm.com cmd = MemCmd::InvalidCmd; 4399241Sandreas.hansson@arm.com } 4409241Sandreas.hansson@arm.com }; 4419241Sandreas.hansson@arm.com 4429241Sandreas.hansson@arm.com public: 4439241Sandreas.hansson@arm.com 4449241Sandreas.hansson@arm.com /** 4459241Sandreas.hansson@arm.com * Create a trace generator. 4469241Sandreas.hansson@arm.com * 4479241Sandreas.hansson@arm.com * @param _port port used to send requests 4489241Sandreas.hansson@arm.com * @param master_id MasterID set on each request 4499241Sandreas.hansson@arm.com * @param _duration duration of this state before transitioning 4509241Sandreas.hansson@arm.com * @param trace_file File to read the transactions from 4519241Sandreas.hansson@arm.com * @param addr_offset Positive offset to add to trace address 4529241Sandreas.hansson@arm.com */ 4539241Sandreas.hansson@arm.com TraceGen(QueuedMasterPort& _port, MasterID master_id, 4549241Sandreas.hansson@arm.com Tick _duration, const std::string& trace_file, 4559241Sandreas.hansson@arm.com Addr addr_offset) 4569241Sandreas.hansson@arm.com : BaseGen(_port, master_id, _duration), 4579241Sandreas.hansson@arm.com traceFile(trace_file), 4589241Sandreas.hansson@arm.com addrOffset(addr_offset), 4599241Sandreas.hansson@arm.com traceComplete(false) 4609241Sandreas.hansson@arm.com { 4619241Sandreas.hansson@arm.com /** 4629241Sandreas.hansson@arm.com * Create a 4MB read buffer for the input trace 4639241Sandreas.hansson@arm.com * file. This is to reduce the number of disk accesses 4649241Sandreas.hansson@arm.com * and thereby speed up the execution of the code. 4659241Sandreas.hansson@arm.com */ 4669241Sandreas.hansson@arm.com readBuffer = new char[4 * 1024 * 1024]; 4679241Sandreas.hansson@arm.com trace.rdbuf()->pubsetbuf(readBuffer, 4 * 1024 * 1024); 4689241Sandreas.hansson@arm.com trace.open(traceFile.c_str(), std::ifstream::in); 4699241Sandreas.hansson@arm.com 4709241Sandreas.hansson@arm.com if (!trace.is_open()) { 4719241Sandreas.hansson@arm.com fatal("Traffic generator %s trace file could not be" 4729241Sandreas.hansson@arm.com " opened: %s\n", name(), traceFile); 4739241Sandreas.hansson@arm.com } 4749241Sandreas.hansson@arm.com } 4759241Sandreas.hansson@arm.com 4769241Sandreas.hansson@arm.com ~TraceGen() { 4779241Sandreas.hansson@arm.com // free the memory used by the readBuffer 4789241Sandreas.hansson@arm.com delete[] readBuffer; 4799241Sandreas.hansson@arm.com } 4809241Sandreas.hansson@arm.com 4819241Sandreas.hansson@arm.com void enter(); 4829241Sandreas.hansson@arm.com 4839241Sandreas.hansson@arm.com void execute(); 4849241Sandreas.hansson@arm.com 4859241Sandreas.hansson@arm.com void exit(); 4869241Sandreas.hansson@arm.com 4879241Sandreas.hansson@arm.com /** 4889241Sandreas.hansson@arm.com * Read a line of the trace file. Returns the raw tick 4899241Sandreas.hansson@arm.com * when the next request should be generated. If the end 4909241Sandreas.hansson@arm.com * of the file has been reached, it returns MaxTick to 4919241Sandreas.hansson@arm.com * indicate that there will be no more requests. 4929241Sandreas.hansson@arm.com */ 4939241Sandreas.hansson@arm.com Tick nextExecuteTick(); 4949241Sandreas.hansson@arm.com 4959241Sandreas.hansson@arm.com private: 4969241Sandreas.hansson@arm.com 4979241Sandreas.hansson@arm.com /** Path to the trace file */ 4989241Sandreas.hansson@arm.com std::string traceFile; 4999241Sandreas.hansson@arm.com 5009241Sandreas.hansson@arm.com /** Input stream used for reading the input trace file */ 5019241Sandreas.hansson@arm.com std::ifstream trace; 5029241Sandreas.hansson@arm.com 5039241Sandreas.hansson@arm.com /** Larger buffer used for reading from the stream */ 5049241Sandreas.hansson@arm.com char* readBuffer; 5059241Sandreas.hansson@arm.com 5069241Sandreas.hansson@arm.com /** Store the current and next element in the trace */ 5079241Sandreas.hansson@arm.com TraceElement currElement; 5089241Sandreas.hansson@arm.com TraceElement nextElement; 5099241Sandreas.hansson@arm.com 5109241Sandreas.hansson@arm.com /** 5119241Sandreas.hansson@arm.com * Stores the time when the state was entered. This is to add an 5129241Sandreas.hansson@arm.com * offset to the times stored in the trace file. 5139241Sandreas.hansson@arm.com */ 5149241Sandreas.hansson@arm.com Tick tickOffset; 5159241Sandreas.hansson@arm.com 5169241Sandreas.hansson@arm.com /** 5179241Sandreas.hansson@arm.com * Offset for memory requests. Used to shift the trace 5189241Sandreas.hansson@arm.com * away from the CPU address space. 5199241Sandreas.hansson@arm.com */ 5209241Sandreas.hansson@arm.com Addr addrOffset; 5219241Sandreas.hansson@arm.com 5229241Sandreas.hansson@arm.com /** 5239241Sandreas.hansson@arm.com * Set to true when the trace replay for one instance of 5249241Sandreas.hansson@arm.com * state is complete. 5259241Sandreas.hansson@arm.com */ 5269241Sandreas.hansson@arm.com bool traceComplete; 5279241Sandreas.hansson@arm.com 5289241Sandreas.hansson@arm.com /** 5299241Sandreas.hansson@arm.com * Used to store the Tick when the next generate should 5309241Sandreas.hansson@arm.com * occur. It is to remove a transaction as soon as we 5319241Sandreas.hansson@arm.com * enter the state. 5329241Sandreas.hansson@arm.com */ 5339241Sandreas.hansson@arm.com Tick oldEmitTime; 5349241Sandreas.hansson@arm.com }; 5359241Sandreas.hansson@arm.com 5369241Sandreas.hansson@arm.com /** Pointer to owner of request handler */ 5379241Sandreas.hansson@arm.com TrafficGen& owner; 5389241Sandreas.hansson@arm.com 5399241Sandreas.hansson@arm.com /** Pointer to request handler */ 5409241Sandreas.hansson@arm.com QueuedMasterPort& port; 5419241Sandreas.hansson@arm.com 5429241Sandreas.hansson@arm.com /** State transition matrix */ 5439241Sandreas.hansson@arm.com std::vector<std::vector<double> > transitionMatrix; 5449241Sandreas.hansson@arm.com 5459241Sandreas.hansson@arm.com public: 5469241Sandreas.hansson@arm.com 5479241Sandreas.hansson@arm.com /** Index of the current state */ 5489241Sandreas.hansson@arm.com uint32_t currState; 5499241Sandreas.hansson@arm.com 5509241Sandreas.hansson@arm.com /** Map of states */ 5519241Sandreas.hansson@arm.com m5::hash_map<uint32_t, BaseGen*> states; 5529241Sandreas.hansson@arm.com }; 5539241Sandreas.hansson@arm.com 5549241Sandreas.hansson@arm.com 5559241Sandreas.hansson@arm.com /** Queued handler */ 5569241Sandreas.hansson@arm.com class TrafficGenPort : public QueuedMasterPort 5579241Sandreas.hansson@arm.com { 5589241Sandreas.hansson@arm.com public: 5599241Sandreas.hansson@arm.com 5609241Sandreas.hansson@arm.com TrafficGenPort(const std::string& name, TrafficGen& _owner) 5619241Sandreas.hansson@arm.com : QueuedMasterPort(name, &_owner, queue), queue(_owner, *this), 5629241Sandreas.hansson@arm.com owner(_owner) 5639241Sandreas.hansson@arm.com { } 5649241Sandreas.hansson@arm.com 5659241Sandreas.hansson@arm.com protected: 5669241Sandreas.hansson@arm.com 5679241Sandreas.hansson@arm.com bool recvTimingResp(PacketPtr pkt); 5689241Sandreas.hansson@arm.com 5699241Sandreas.hansson@arm.com private: 5709241Sandreas.hansson@arm.com 5719241Sandreas.hansson@arm.com MasterPacketQueue queue; 5729241Sandreas.hansson@arm.com 5739241Sandreas.hansson@arm.com // Owner of the port 5749241Sandreas.hansson@arm.com TrafficGen& owner; 5759241Sandreas.hansson@arm.com 5769241Sandreas.hansson@arm.com }; 5779241Sandreas.hansson@arm.com 5789241Sandreas.hansson@arm.com TrafficGenPort port; 5799241Sandreas.hansson@arm.com 5809241Sandreas.hansson@arm.com /** Request generator state graph */ 5819241Sandreas.hansson@arm.com StateGraph stateGraph; 5829241Sandreas.hansson@arm.com 5839241Sandreas.hansson@arm.com /** 5849241Sandreas.hansson@arm.com * Schedules event for next update and executes an update on the 5859241Sandreas.hansson@arm.com * state graph. 5869241Sandreas.hansson@arm.com */ 5879241Sandreas.hansson@arm.com void updateStateGraph(); 5889241Sandreas.hansson@arm.com 5899241Sandreas.hansson@arm.com /** Event for updating the state graph */ 5909241Sandreas.hansson@arm.com EventWrapper<TrafficGen, 5919241Sandreas.hansson@arm.com &TrafficGen::updateStateGraph> updateStateGraphEvent; 5929241Sandreas.hansson@arm.com 5939241Sandreas.hansson@arm.com 5949241Sandreas.hansson@arm.com public: 5959241Sandreas.hansson@arm.com 5969241Sandreas.hansson@arm.com TrafficGen(const TrafficGenParams* p); 5979241Sandreas.hansson@arm.com 5989241Sandreas.hansson@arm.com ~TrafficGen() {} 5999241Sandreas.hansson@arm.com 6009294Sandreas.hansson@arm.com virtual BaseMasterPort& getMasterPort(const std::string &if_name, 6019294Sandreas.hansson@arm.com PortID idx = InvalidPortID); 6029241Sandreas.hansson@arm.com 6039241Sandreas.hansson@arm.com void init(); 6049241Sandreas.hansson@arm.com 6059241Sandreas.hansson@arm.com void initState(); 6069241Sandreas.hansson@arm.com 6079342SAndreas.Sandberg@arm.com unsigned int drain(DrainManager *dm); 6089241Sandreas.hansson@arm.com 6099241Sandreas.hansson@arm.com void serialize(std::ostream &os); 6109241Sandreas.hansson@arm.com 6119241Sandreas.hansson@arm.com void unserialize(Checkpoint* cp, const std::string& section); 6129241Sandreas.hansson@arm.com 6139241Sandreas.hansson@arm.com}; 6149241Sandreas.hansson@arm.com 6159241Sandreas.hansson@arm.com#endif //__MEM_TRAFFIC_GEN_HH__ 616