traffic_gen.hh revision 9294:8fb03b13de02
110037SARM gem5 Developers/* 210844Sandreas.sandberg@arm.com * Copyright (c) 2012 ARM Limited 310037SARM gem5 Developers * All rights reserved 410037SARM gem5 Developers * 510037SARM gem5 Developers * The license below extends only to copyright in the software and shall 610037SARM gem5 Developers * not be construed as granting a license to any other intellectual 710037SARM gem5 Developers * property including but not limited to intellectual property relating 810037SARM gem5 Developers * to a hardware implementation of the functionality of the software 910037SARM gem5 Developers * licensed hereunder. You may use the software subject to the license 1010037SARM gem5 Developers * terms below provided that you ensure that this notice is replicated 1110037SARM gem5 Developers * unmodified and in its entirety in all distributions of the software, 1210037SARM gem5 Developers * modified or unmodified, in source code or in binary form. 1310037SARM gem5 Developers * 1410037SARM gem5 Developers * Redistribution and use in source and binary forms, with or without 1510037SARM gem5 Developers * modification, are permitted provided that the following conditions are 1610037SARM gem5 Developers * met: redistributions of source code must retain the above copyright 1710037SARM gem5 Developers * notice, this list of conditions and the following disclaimer; 1810037SARM gem5 Developers * redistributions in binary form must reproduce the above copyright 1910037SARM gem5 Developers * notice, this list of conditions and the following disclaimer in the 2010037SARM gem5 Developers * documentation and/or other materials provided with the distribution; 2110037SARM gem5 Developers * neither the name of the copyright holders nor the names of its 2210037SARM gem5 Developers * contributors may be used to endorse or promote products derived from 2310037SARM gem5 Developers * this software without specific prior written permission. 2410037SARM gem5 Developers * 2510037SARM gem5 Developers * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610037SARM gem5 Developers * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710037SARM gem5 Developers * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810037SARM gem5 Developers * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910037SARM gem5 Developers * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010037SARM gem5 Developers * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110037SARM gem5 Developers * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210037SARM gem5 Developers * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310037SARM gem5 Developers * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410037SARM gem5 Developers * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510037SARM gem5 Developers * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610037SARM gem5 Developers * 3710037SARM gem5 Developers * Authors: Thomas Grass 3810844Sandreas.sandberg@arm.com * Andreas Hansson 3910037SARM gem5 Developers * Sascha Bischoff 4010037SARM gem5 Developers */ 4110844Sandreas.sandberg@arm.com#ifndef __MEM_TRAFFIC_GEN_HH__ 4210844Sandreas.sandberg@arm.com#define __MEM_TRAFFIC_GEN_HH__ 4310037SARM gem5 Developers 4410037SARM gem5 Developers#include <fstream> 4510037SARM gem5 Developers 4610847Sandreas.sandberg@arm.com#include "base/hashmap.hh" 4710844Sandreas.sandberg@arm.com#include "mem/mem_object.hh" 4810847Sandreas.sandberg@arm.com#include "mem/qport.hh" 4910844Sandreas.sandberg@arm.com#include "params/TrafficGen.hh" 5010844Sandreas.sandberg@arm.com 5110844Sandreas.sandberg@arm.com/** 5210844Sandreas.sandberg@arm.com * The traffic generator is a master module that generates stimuli for 5310844Sandreas.sandberg@arm.com * the memory system, based on a collection of simple behaviours that 5410844Sandreas.sandberg@arm.com * are either probabilistic or based on traces. It can be used stand 5510037SARM gem5 Developers * alone for creating test cases for interconnect and memory 5610037SARM gem5 Developers * controllers, or function as a black box replacement for system 5710844Sandreas.sandberg@arm.com * components that are not yet modelled in detail, e.g. a video engine 5810037SARM gem5 Developers * or baseband subsystem. 5910037SARM gem5 Developers */ 6010037SARM gem5 Developersclass TrafficGen : public MemObject 6110037SARM gem5 Developers{ 6210037SARM gem5 Developers 6310037SARM gem5 Developers private: 6410037SARM gem5 Developers 6510037SARM gem5 Developers /** 6610037SARM gem5 Developers * The system used to determine which mode we are currently operating 6710037SARM gem5 Developers * in. 6810037SARM gem5 Developers */ 6910905Sandreas.sandberg@arm.com System* system; 7010037SARM gem5 Developers 7110844Sandreas.sandberg@arm.com /** 7210037SARM gem5 Developers * MasterID used in generated requests. 7310037SARM gem5 Developers */ 7410037SARM gem5 Developers MasterID masterID; 7510037SARM gem5 Developers 7610037SARM gem5 Developers protected: 7710037SARM gem5 Developers 7810905Sandreas.sandberg@arm.com /** 7910037SARM gem5 Developers * The state graph is responsible for instantiating and keeping 8010844Sandreas.sandberg@arm.com * track of the various generator states and also perform the 8110844Sandreas.sandberg@arm.com * transitions and call the appropriate functions when entering, 8210844Sandreas.sandberg@arm.com * executing and exiting a state. 8310844Sandreas.sandberg@arm.com */ 8410037SARM gem5 Developers class StateGraph 8510037SARM gem5 Developers { 8610037SARM gem5 Developers 8710037SARM gem5 Developers public: 8810037SARM gem5 Developers 8910844Sandreas.sandberg@arm.com /** 9010844Sandreas.sandberg@arm.com * Create a state graph from an input file. 9110844Sandreas.sandberg@arm.com * 9210844Sandreas.sandberg@arm.com * @param _owner used solely for the name 9310844Sandreas.sandberg@arm.com * @param _port port used to send requests 9410844Sandreas.sandberg@arm.com * @param file_name configuration description to read in 9510844Sandreas.sandberg@arm.com * @param master_id the unique id used for all requests 9610844Sandreas.sandberg@arm.com */ 9710845Sandreas.sandberg@arm.com StateGraph(TrafficGen& _owner, QueuedMasterPort& _port, 9810844Sandreas.sandberg@arm.com const std::string& file_name, MasterID master_id) 9910844Sandreas.sandberg@arm.com : nextTransitionTick(0), owner(_owner), port(_port) 10010844Sandreas.sandberg@arm.com { 10110844Sandreas.sandberg@arm.com parseConfig(file_name, master_id); 10210037SARM gem5 Developers } 10310844Sandreas.sandberg@arm.com 10410037SARM gem5 Developers /** 10510037SARM gem5 Developers * Get the name, used for DPRINTFs. 10610037SARM gem5 Developers * 10710037SARM gem5 Developers * @return the owner's name 10810037SARM gem5 Developers */ 10910037SARM gem5 Developers std::string name() const { return owner.name(); } 11010844Sandreas.sandberg@arm.com 11110037SARM gem5 Developers /** 11210844Sandreas.sandberg@arm.com * Either perform a state transition or execute the current 11310844Sandreas.sandberg@arm.com * state, depending on the current time. 11410037SARM gem5 Developers */ 11510037SARM gem5 Developers void update(); 11610037SARM gem5 Developers 11710037SARM gem5 Developers /** 11810844Sandreas.sandberg@arm.com * Determine next state and perform the transition. 11910037SARM gem5 Developers */ 12010037SARM gem5 Developers void transition(); 12110844Sandreas.sandberg@arm.com 12210844Sandreas.sandberg@arm.com /** 12310037SARM gem5 Developers * Enter a new state. 12410037SARM gem5 Developers * 12510844Sandreas.sandberg@arm.com * @param newState identifier of state to enter 12610037SARM gem5 Developers */ 12710844Sandreas.sandberg@arm.com void enterState(uint32_t newState); 12810844Sandreas.sandberg@arm.com 12910037SARM gem5 Developers /** 13010037SARM gem5 Developers * Get the tick of the next event, either an execution or a 13110037SARM gem5 Developers * transition. 13210037SARM gem5 Developers * 13310844Sandreas.sandberg@arm.com * @return tick of the next state graph event 13410037SARM gem5 Developers */ 13510844Sandreas.sandberg@arm.com Tick nextEventTick() 13610844Sandreas.sandberg@arm.com { 13710037SARM gem5 Developers return std::min(states[currState]->nextExecuteTick(), 13810037SARM gem5 Developers nextTransitionTick); 13910037SARM gem5 Developers 14010844Sandreas.sandberg@arm.com } 14110844Sandreas.sandberg@arm.com 14210844Sandreas.sandberg@arm.com /** Time of next transition */ 14310844Sandreas.sandberg@arm.com Tick nextTransitionTick; 14410844Sandreas.sandberg@arm.com 14510844Sandreas.sandberg@arm.com private: 14610844Sandreas.sandberg@arm.com 14710037SARM gem5 Developers /** 14810037SARM gem5 Developers * Parse the config file and build the state map and 14910037SARM gem5 Developers * transition matrix. 15010037SARM gem5 Developers * 15110037SARM gem5 Developers * @param file_name Config file name to parse 15210844Sandreas.sandberg@arm.com * @param master_id MasterID to use for generated requests 15310037SARM gem5 Developers */ 15410037SARM gem5 Developers void parseConfig(const std::string& file_name, MasterID master_id); 15510037SARM gem5 Developers 15610844Sandreas.sandberg@arm.com /** Struct to represent a probabilistic transition during parsing. */ 15710037SARM gem5 Developers struct Transition { 15810037SARM gem5 Developers uint32_t from; 15910037SARM gem5 Developers uint32_t to; 16010037SARM gem5 Developers double p; 16110037SARM gem5 Developers }; 16210037SARM gem5 Developers 16310845Sandreas.sandberg@arm.com /** Base class for all generator states */ 16410845Sandreas.sandberg@arm.com class BaseGen 16510845Sandreas.sandberg@arm.com { 16610845Sandreas.sandberg@arm.com 16710845Sandreas.sandberg@arm.com protected: 16810845Sandreas.sandberg@arm.com 16910845Sandreas.sandberg@arm.com /** Port used to send requests */ 17010844Sandreas.sandberg@arm.com QueuedMasterPort& port; 17110844Sandreas.sandberg@arm.com 17210844Sandreas.sandberg@arm.com /** The MasterID used for generating requests */ 17310845Sandreas.sandberg@arm.com const MasterID masterID; 17410844Sandreas.sandberg@arm.com 17510844Sandreas.sandberg@arm.com public: 17610037SARM gem5 Developers 17710905Sandreas.sandberg@arm.com /** Time to spend in this state */ 17810037SARM gem5 Developers const Tick duration; 17910905Sandreas.sandberg@arm.com 18010037SARM gem5 Developers /** 18110845Sandreas.sandberg@arm.com * Create a base generator. 18210844Sandreas.sandberg@arm.com * 18310844Sandreas.sandberg@arm.com * @param _port port used to send requests 18410037SARM gem5 Developers * @param master_id MasterID set on each request 18510037SARM gem5 Developers * @param _duration duration of this state before transitioning 18610844Sandreas.sandberg@arm.com */ 18710037SARM gem5 Developers BaseGen(QueuedMasterPort& _port, MasterID master_id, 18810037SARM gem5 Developers Tick _duration); 18910037SARM gem5 Developers 19010037SARM gem5 Developers virtual ~BaseGen() { } 19110037SARM gem5 Developers 19210905Sandreas.sandberg@arm.com /** 19310037SARM gem5 Developers * Get the name, useful for DPRINTFs. 19410905Sandreas.sandberg@arm.com * 19510845Sandreas.sandberg@arm.com * @return the port name 19610845Sandreas.sandberg@arm.com */ 19710845Sandreas.sandberg@arm.com std::string name() const { return port.name(); } 19810845Sandreas.sandberg@arm.com 19910845Sandreas.sandberg@arm.com /** 20010037SARM gem5 Developers * Enter this generator state. 20110037SARM gem5 Developers */ 20210037SARM gem5 Developers virtual void enter() = 0; 20310844Sandreas.sandberg@arm.com 20410037SARM gem5 Developers /** 20510844Sandreas.sandberg@arm.com * Execute this generator state. 20610037SARM gem5 Developers */ 20710037SARM gem5 Developers virtual void execute() = 0; 20810037SARM gem5 Developers 20910844Sandreas.sandberg@arm.com /** 21010844Sandreas.sandberg@arm.com * Exit this generator state. By default do nothing. 21110037SARM gem5 Developers */ 21210844Sandreas.sandberg@arm.com virtual void exit() { }; 21310844Sandreas.sandberg@arm.com 21410844Sandreas.sandberg@arm.com /** 21510844Sandreas.sandberg@arm.com * Determine the next execute tick. MaxTick means that 21610844Sandreas.sandberg@arm.com * there will not be any further event in the current 21710844Sandreas.sandberg@arm.com * activation cycle of the state. 21810037SARM gem5 Developers * 21910844Sandreas.sandberg@arm.com * @return next tick when the state should be executed 22010844Sandreas.sandberg@arm.com */ 22110844Sandreas.sandberg@arm.com virtual Tick nextExecuteTick() = 0; 22210844Sandreas.sandberg@arm.com 22310844Sandreas.sandberg@arm.com }; 22410844Sandreas.sandberg@arm.com 22510844Sandreas.sandberg@arm.com /** 22610844Sandreas.sandberg@arm.com * The idle generator does nothing. 22710844Sandreas.sandberg@arm.com */ 22810844Sandreas.sandberg@arm.com class IdleGen : public BaseGen 22910844Sandreas.sandberg@arm.com { 23010844Sandreas.sandberg@arm.com 23110844Sandreas.sandberg@arm.com public: 23210844Sandreas.sandberg@arm.com 23310844Sandreas.sandberg@arm.com IdleGen(QueuedMasterPort& _port, MasterID master_id, 23410845Sandreas.sandberg@arm.com Tick _duration) 23510845Sandreas.sandberg@arm.com : BaseGen(_port, master_id, _duration) 23610844Sandreas.sandberg@arm.com { } 23710844Sandreas.sandberg@arm.com 23810037SARM gem5 Developers void enter() { } 23910037SARM gem5 Developers 24010037SARM gem5 Developers void execute() { } 24110905Sandreas.sandberg@arm.com 24210037SARM gem5 Developers Tick nextExecuteTick() { return MaxTick; } 24310905Sandreas.sandberg@arm.com }; 24410844Sandreas.sandberg@arm.com 24510905Sandreas.sandberg@arm.com /** 24610844Sandreas.sandberg@arm.com * The linear generator generates sequential requests from a 24710844Sandreas.sandberg@arm.com * start to an end address, with a fixed block size. A 24810905Sandreas.sandberg@arm.com * fraction of the requests are reads, as determined by the 24910844Sandreas.sandberg@arm.com * read percent. There is an optional data limit for when to 25010905Sandreas.sandberg@arm.com * stop generating new requests. 25110905Sandreas.sandberg@arm.com */ 25210905Sandreas.sandberg@arm.com class LinearGen : public BaseGen 25310905Sandreas.sandberg@arm.com { 25410037SARM gem5 Developers 25510037SARM gem5 Developers public: 25610037SARM gem5 Developers 25710037SARM gem5 Developers /** 25810905Sandreas.sandberg@arm.com * Create a linear address sequence generator. Set 25910037SARM gem5 Developers * min_period == max_period for a fixed inter-transaction 26010905Sandreas.sandberg@arm.com * time. 26110844Sandreas.sandberg@arm.com * 26210844Sandreas.sandberg@arm.com * @param _port port used to send requests 26310844Sandreas.sandberg@arm.com * @param master_id MasterID set on each request 26410844Sandreas.sandberg@arm.com * @param _duration duration of this state before transitioning 26510844Sandreas.sandberg@arm.com * @param start_addr Start address 26610844Sandreas.sandberg@arm.com * @param end_addr End address 26710844Sandreas.sandberg@arm.com * @param _blocksize Size used for transactions injected 26810844Sandreas.sandberg@arm.com * @param min_period Lower limit of random inter-transaction time 26910844Sandreas.sandberg@arm.com * @param max_period Upper limit of random inter-transaction time 27010844Sandreas.sandberg@arm.com * @param read_percent Percent of transactions that are reads 27110844Sandreas.sandberg@arm.com * @param data_limit Upper limit on how much data to read/write 27210844Sandreas.sandberg@arm.com */ 27310844Sandreas.sandberg@arm.com LinearGen(QueuedMasterPort& _port, MasterID master_id, 27410844Sandreas.sandberg@arm.com Tick _duration, Addr start_addr, Addr end_addr, 27510844Sandreas.sandberg@arm.com Addr _blocksize, Tick min_period, Tick max_period, 27610844Sandreas.sandberg@arm.com uint8_t read_percent, Addr data_limit) 27710905Sandreas.sandberg@arm.com : BaseGen(_port, master_id, _duration), 27810905Sandreas.sandberg@arm.com startAddr(start_addr), endAddr(end_addr), 27910037SARM gem5 Developers blocksize(_blocksize), minPeriod(min_period), 28010037SARM gem5 Developers maxPeriod(max_period), readPercent(read_percent), 28110037SARM gem5 Developers dataLimit(data_limit) 28210844Sandreas.sandberg@arm.com { } 28310844Sandreas.sandberg@arm.com 28410844Sandreas.sandberg@arm.com void enter(); 28510844Sandreas.sandberg@arm.com 28610844Sandreas.sandberg@arm.com void execute(); 28710844Sandreas.sandberg@arm.com 28810844Sandreas.sandberg@arm.com Tick nextExecuteTick(); 28910844Sandreas.sandberg@arm.com 29010844Sandreas.sandberg@arm.com private: 29110844Sandreas.sandberg@arm.com 29210844Sandreas.sandberg@arm.com /** Start of address range */ 29310844Sandreas.sandberg@arm.com const Addr startAddr; 29410844Sandreas.sandberg@arm.com 29510844Sandreas.sandberg@arm.com /** End of address range */ 29610844Sandreas.sandberg@arm.com const Addr endAddr; 29710844Sandreas.sandberg@arm.com 29810844Sandreas.sandberg@arm.com /** Blocksize and address increment */ 29910844Sandreas.sandberg@arm.com const Addr blocksize; 30010844Sandreas.sandberg@arm.com 30110845Sandreas.sandberg@arm.com /** Request generation period */ 30210844Sandreas.sandberg@arm.com const Tick minPeriod; 30310844Sandreas.sandberg@arm.com const Tick maxPeriod; 30410844Sandreas.sandberg@arm.com 30510844Sandreas.sandberg@arm.com /** 30610844Sandreas.sandberg@arm.com * Percent of generated transactions that should be reads 30710844Sandreas.sandberg@arm.com */ 30810844Sandreas.sandberg@arm.com const uint8_t readPercent; 30910844Sandreas.sandberg@arm.com 31010844Sandreas.sandberg@arm.com /** Maximum amount of data to manipulate */ 31110844Sandreas.sandberg@arm.com const Addr dataLimit; 31210844Sandreas.sandberg@arm.com 31310844Sandreas.sandberg@arm.com /** Address of next request */ 31410844Sandreas.sandberg@arm.com Addr nextAddr; 31510844Sandreas.sandberg@arm.com 31610844Sandreas.sandberg@arm.com /** 31710844Sandreas.sandberg@arm.com * Counter to determine the amount of data 31810844Sandreas.sandberg@arm.com * manipulated. Used to determine if we should continue 31910844Sandreas.sandberg@arm.com * generating requests. 32010844Sandreas.sandberg@arm.com */ 32110844Sandreas.sandberg@arm.com Addr dataManipulated; 32210844Sandreas.sandberg@arm.com }; 32310844Sandreas.sandberg@arm.com 32410844Sandreas.sandberg@arm.com /** 32510844Sandreas.sandberg@arm.com * The random generator is similar to the linear one, but does 32610844Sandreas.sandberg@arm.com * not generate sequential addresses. Instead it randomly 32710844Sandreas.sandberg@arm.com * picks an address in the range, aligned to the block size. 32810844Sandreas.sandberg@arm.com */ 32910844Sandreas.sandberg@arm.com class RandomGen : public BaseGen 33010844Sandreas.sandberg@arm.com { 33110844Sandreas.sandberg@arm.com 33210844Sandreas.sandberg@arm.com public: 33310844Sandreas.sandberg@arm.com 33410844Sandreas.sandberg@arm.com /** 33510844Sandreas.sandberg@arm.com * Create a random address sequence generator. Set 33610844Sandreas.sandberg@arm.com * min_period == max_period for a fixed inter-transaction 33710844Sandreas.sandberg@arm.com * time. 33810844Sandreas.sandberg@arm.com * 33910844Sandreas.sandberg@arm.com * @param _port port used to send requests 34010844Sandreas.sandberg@arm.com * @param master_id MasterID set on each request 34110844Sandreas.sandberg@arm.com * @param _duration duration of this state before transitioning 34210844Sandreas.sandberg@arm.com * @param start_addr Start address 34310844Sandreas.sandberg@arm.com * @param end_addr End address 34410844Sandreas.sandberg@arm.com * @param _blocksize Size used for transactions injected 34510844Sandreas.sandberg@arm.com * @param min_period Lower limit of random inter-transaction time 34610844Sandreas.sandberg@arm.com * @param max_period Upper limit of random inter-transaction time 34710844Sandreas.sandberg@arm.com * @param read_percent Percent of transactions that are reads 34810844Sandreas.sandberg@arm.com * @param data_limit Upper limit on how much data to read/write 34910844Sandreas.sandberg@arm.com */ 35010844Sandreas.sandberg@arm.com RandomGen(QueuedMasterPort& _port, MasterID master_id, 35110844Sandreas.sandberg@arm.com Tick _duration, Addr start_addr, Addr end_addr, 35210844Sandreas.sandberg@arm.com Addr _blocksize, Tick min_period, Tick max_period, 35310845Sandreas.sandberg@arm.com uint8_t read_percent, Addr data_limit) 35410845Sandreas.sandberg@arm.com : BaseGen(_port, master_id, _duration), 35510845Sandreas.sandberg@arm.com startAddr(start_addr), endAddr(end_addr), 35610844Sandreas.sandberg@arm.com blocksize(_blocksize), minPeriod(min_period), 35710844Sandreas.sandberg@arm.com maxPeriod(max_period), readPercent(read_percent), 35810845Sandreas.sandberg@arm.com dataLimit(data_limit) 35910845Sandreas.sandberg@arm.com { } 36010845Sandreas.sandberg@arm.com 36110844Sandreas.sandberg@arm.com void enter(); 36210844Sandreas.sandberg@arm.com 36310845Sandreas.sandberg@arm.com void execute(); 36410845Sandreas.sandberg@arm.com 36510845Sandreas.sandberg@arm.com Tick nextExecuteTick(); 36610844Sandreas.sandberg@arm.com 36710844Sandreas.sandberg@arm.com private: 36810845Sandreas.sandberg@arm.com 36910845Sandreas.sandberg@arm.com /** Start of address range */ 37010844Sandreas.sandberg@arm.com const Addr startAddr; 37110844Sandreas.sandberg@arm.com 37210844Sandreas.sandberg@arm.com /** End of address range */ 37310844Sandreas.sandberg@arm.com const Addr endAddr; 37410844Sandreas.sandberg@arm.com 37510844Sandreas.sandberg@arm.com /** Block size */ 37610844Sandreas.sandberg@arm.com const Addr blocksize; 37710844Sandreas.sandberg@arm.com 37810844Sandreas.sandberg@arm.com /** Request generation period */ 37910844Sandreas.sandberg@arm.com const Tick minPeriod; 38010844Sandreas.sandberg@arm.com const Tick maxPeriod; 38110844Sandreas.sandberg@arm.com 38210844Sandreas.sandberg@arm.com /** 38310844Sandreas.sandberg@arm.com * Percent of generated transactions that should be reads 38410844Sandreas.sandberg@arm.com */ 38510844Sandreas.sandberg@arm.com const uint8_t readPercent; 38610844Sandreas.sandberg@arm.com 38710844Sandreas.sandberg@arm.com /** Maximum amount of data to manipulate */ 38810844Sandreas.sandberg@arm.com const Addr dataLimit; 38910844Sandreas.sandberg@arm.com 39010844Sandreas.sandberg@arm.com /** 39110844Sandreas.sandberg@arm.com * Counter to determine the amount of data 39210844Sandreas.sandberg@arm.com * manipulated. Used to determine if we should continue 39310844Sandreas.sandberg@arm.com * generating requests. 39410844Sandreas.sandberg@arm.com */ 39510844Sandreas.sandberg@arm.com Addr dataManipulated; 39610844Sandreas.sandberg@arm.com }; 39710844Sandreas.sandberg@arm.com 39810844Sandreas.sandberg@arm.com /** 39910844Sandreas.sandberg@arm.com * The trace replay generator reads a trace file and plays 40010844Sandreas.sandberg@arm.com * back the transactions. The trace is offset with respect to 40110844Sandreas.sandberg@arm.com * the time when the state was entered. 40210844Sandreas.sandberg@arm.com */ 40310844Sandreas.sandberg@arm.com class TraceGen : public BaseGen 40410844Sandreas.sandberg@arm.com { 40510844Sandreas.sandberg@arm.com 40610844Sandreas.sandberg@arm.com private: 40710844Sandreas.sandberg@arm.com 40810844Sandreas.sandberg@arm.com /** 40910844Sandreas.sandberg@arm.com * This struct stores a line in the trace file. 41010844Sandreas.sandberg@arm.com */ 41110844Sandreas.sandberg@arm.com struct TraceElement { 41210844Sandreas.sandberg@arm.com 41310844Sandreas.sandberg@arm.com /** Specifies if the request is to be a read or a write */ 41410844Sandreas.sandberg@arm.com MemCmd cmd; 41510844Sandreas.sandberg@arm.com 41610844Sandreas.sandberg@arm.com /** The address for the request */ 41710844Sandreas.sandberg@arm.com Addr addr; 41810844Sandreas.sandberg@arm.com 41910844Sandreas.sandberg@arm.com /** The size of the access for the request */ 42010844Sandreas.sandberg@arm.com Addr blocksize; 42110844Sandreas.sandberg@arm.com 42210844Sandreas.sandberg@arm.com /** The time at which the request should be sent */ 42310844Sandreas.sandberg@arm.com Tick tick; 42410844Sandreas.sandberg@arm.com 42510844Sandreas.sandberg@arm.com /** 42610844Sandreas.sandberg@arm.com * Check validity of this element. 42710844Sandreas.sandberg@arm.com * 42810844Sandreas.sandberg@arm.com * @return if this element is valid 42910844Sandreas.sandberg@arm.com */ 43010844Sandreas.sandberg@arm.com bool isValid() const { 43110844Sandreas.sandberg@arm.com return cmd != MemCmd::InvalidCmd; 43210844Sandreas.sandberg@arm.com } 43310844Sandreas.sandberg@arm.com 43410845Sandreas.sandberg@arm.com /** 43510844Sandreas.sandberg@arm.com * Make this element invalid. 43610844Sandreas.sandberg@arm.com */ 43710844Sandreas.sandberg@arm.com void clear() { 43810845Sandreas.sandberg@arm.com cmd = MemCmd::InvalidCmd; 43910845Sandreas.sandberg@arm.com } 44010844Sandreas.sandberg@arm.com }; 44110844Sandreas.sandberg@arm.com 44210845Sandreas.sandberg@arm.com public: 44310845Sandreas.sandberg@arm.com 44410844Sandreas.sandberg@arm.com /** 44510844Sandreas.sandberg@arm.com * Create a trace generator. 44610845Sandreas.sandberg@arm.com * 44710845Sandreas.sandberg@arm.com * @param _port port used to send requests 44810844Sandreas.sandberg@arm.com * @param master_id MasterID set on each request 44910844Sandreas.sandberg@arm.com * @param _duration duration of this state before transitioning 45010845Sandreas.sandberg@arm.com * @param trace_file File to read the transactions from 45110844Sandreas.sandberg@arm.com * @param addr_offset Positive offset to add to trace address 45210844Sandreas.sandberg@arm.com */ 45310844Sandreas.sandberg@arm.com TraceGen(QueuedMasterPort& _port, MasterID master_id, 45410844Sandreas.sandberg@arm.com Tick _duration, const std::string& trace_file, 45510844Sandreas.sandberg@arm.com Addr addr_offset) 45610844Sandreas.sandberg@arm.com : BaseGen(_port, master_id, _duration), 45710844Sandreas.sandberg@arm.com traceFile(trace_file), 45810844Sandreas.sandberg@arm.com addrOffset(addr_offset), 45910844Sandreas.sandberg@arm.com traceComplete(false) 46010844Sandreas.sandberg@arm.com { 46110844Sandreas.sandberg@arm.com /** 46210844Sandreas.sandberg@arm.com * Create a 4MB read buffer for the input trace 46310844Sandreas.sandberg@arm.com * file. This is to reduce the number of disk accesses 46410844Sandreas.sandberg@arm.com * and thereby speed up the execution of the code. 46510844Sandreas.sandberg@arm.com */ 46610844Sandreas.sandberg@arm.com readBuffer = new char[4 * 1024 * 1024]; 46710844Sandreas.sandberg@arm.com trace.rdbuf()->pubsetbuf(readBuffer, 4 * 1024 * 1024); 46810844Sandreas.sandberg@arm.com trace.open(traceFile.c_str(), std::ifstream::in); 46910844Sandreas.sandberg@arm.com 47010844Sandreas.sandberg@arm.com if (!trace.is_open()) { 47110844Sandreas.sandberg@arm.com fatal("Traffic generator %s trace file could not be" 47210844Sandreas.sandberg@arm.com " opened: %s\n", name(), traceFile); 47310844Sandreas.sandberg@arm.com } 47410844Sandreas.sandberg@arm.com } 47510844Sandreas.sandberg@arm.com 47610844Sandreas.sandberg@arm.com ~TraceGen() { 47710844Sandreas.sandberg@arm.com // free the memory used by the readBuffer 47810844Sandreas.sandberg@arm.com delete[] readBuffer; 47910844Sandreas.sandberg@arm.com } 48010847Sandreas.sandberg@arm.com 48110847Sandreas.sandberg@arm.com void enter(); 48210847Sandreas.sandberg@arm.com 48310847Sandreas.sandberg@arm.com void execute(); 48410847Sandreas.sandberg@arm.com 48510847Sandreas.sandberg@arm.com void exit(); 48610847Sandreas.sandberg@arm.com 48710847Sandreas.sandberg@arm.com /** 48810847Sandreas.sandberg@arm.com * Read a line of the trace file. Returns the raw tick 48910847Sandreas.sandberg@arm.com * when the next request should be generated. If the end 49010847Sandreas.sandberg@arm.com * of the file has been reached, it returns MaxTick to 49110847Sandreas.sandberg@arm.com * indicate that there will be no more requests. 49210847Sandreas.sandberg@arm.com */ 49310847Sandreas.sandberg@arm.com Tick nextExecuteTick(); 49410847Sandreas.sandberg@arm.com 49510847Sandreas.sandberg@arm.com private: 49610847Sandreas.sandberg@arm.com 49710905Sandreas.sandberg@arm.com /** Path to the trace file */ 49810847Sandreas.sandberg@arm.com std::string traceFile; 49910905Sandreas.sandberg@arm.com 50010847Sandreas.sandberg@arm.com /** Input stream used for reading the input trace file */ 50110905Sandreas.sandberg@arm.com std::ifstream trace; 50210847Sandreas.sandberg@arm.com 50310905Sandreas.sandberg@arm.com /** Larger buffer used for reading from the stream */ 50410905Sandreas.sandberg@arm.com char* readBuffer; 50510847Sandreas.sandberg@arm.com 50610847Sandreas.sandberg@arm.com /** Store the current and next element in the trace */ 50710847Sandreas.sandberg@arm.com TraceElement currElement; 50810905Sandreas.sandberg@arm.com TraceElement nextElement; 50910847Sandreas.sandberg@arm.com 51010905Sandreas.sandberg@arm.com /** 51110847Sandreas.sandberg@arm.com * Stores the time when the state was entered. This is to add an 51210847Sandreas.sandberg@arm.com * offset to the times stored in the trace file. 51310847Sandreas.sandberg@arm.com */ 51410847Sandreas.sandberg@arm.com Tick tickOffset; 51510847Sandreas.sandberg@arm.com 51610847Sandreas.sandberg@arm.com /** 51710847Sandreas.sandberg@arm.com * Offset for memory requests. Used to shift the trace 51810847Sandreas.sandberg@arm.com * away from the CPU address space. 51910905Sandreas.sandberg@arm.com */ 52010905Sandreas.sandberg@arm.com Addr addrOffset; 52110847Sandreas.sandberg@arm.com 52210847Sandreas.sandberg@arm.com /** 52310847Sandreas.sandberg@arm.com * Set to true when the trace replay for one instance of 52410847Sandreas.sandberg@arm.com * state is complete. 52510847Sandreas.sandberg@arm.com */ 52610847Sandreas.sandberg@arm.com bool traceComplete; 52710847Sandreas.sandberg@arm.com 52810847Sandreas.sandberg@arm.com /** 52910847Sandreas.sandberg@arm.com * Used to store the Tick when the next generate should 53010847Sandreas.sandberg@arm.com * occur. It is to remove a transaction as soon as we 53110847Sandreas.sandberg@arm.com * enter the state. 53210847Sandreas.sandberg@arm.com */ 53310847Sandreas.sandberg@arm.com Tick oldEmitTime; 53410847Sandreas.sandberg@arm.com }; 53510847Sandreas.sandberg@arm.com 53610847Sandreas.sandberg@arm.com /** Pointer to owner of request handler */ 53710847Sandreas.sandberg@arm.com TrafficGen& owner; 53810847Sandreas.sandberg@arm.com 53910847Sandreas.sandberg@arm.com /** Pointer to request handler */ 54010847Sandreas.sandberg@arm.com QueuedMasterPort& port; 54110847Sandreas.sandberg@arm.com 54210847Sandreas.sandberg@arm.com /** State transition matrix */ 54310847Sandreas.sandberg@arm.com std::vector<std::vector<double> > transitionMatrix; 54410847Sandreas.sandberg@arm.com 54510847Sandreas.sandberg@arm.com public: 54610847Sandreas.sandberg@arm.com 54710847Sandreas.sandberg@arm.com /** Index of the current state */ 54810847Sandreas.sandberg@arm.com uint32_t currState; 54910847Sandreas.sandberg@arm.com 55010847Sandreas.sandberg@arm.com /** Map of states */ 55110847Sandreas.sandberg@arm.com m5::hash_map<uint32_t, BaseGen*> states; 55210847Sandreas.sandberg@arm.com }; 55310847Sandreas.sandberg@arm.com 55410847Sandreas.sandberg@arm.com 55510847Sandreas.sandberg@arm.com /** Queued handler */ 55610847Sandreas.sandberg@arm.com class TrafficGenPort : public QueuedMasterPort 55710847Sandreas.sandberg@arm.com { 55810847Sandreas.sandberg@arm.com public: 55910847Sandreas.sandberg@arm.com 56010847Sandreas.sandberg@arm.com TrafficGenPort(const std::string& name, TrafficGen& _owner) 56110847Sandreas.sandberg@arm.com : QueuedMasterPort(name, &_owner, queue), queue(_owner, *this), 56210847Sandreas.sandberg@arm.com owner(_owner) 56310847Sandreas.sandberg@arm.com { } 56410847Sandreas.sandberg@arm.com 56510847Sandreas.sandberg@arm.com protected: 56610847Sandreas.sandberg@arm.com 56710847Sandreas.sandberg@arm.com bool recvTimingResp(PacketPtr pkt); 56810847Sandreas.sandberg@arm.com 56910847Sandreas.sandberg@arm.com private: 57010847Sandreas.sandberg@arm.com 57110847Sandreas.sandberg@arm.com MasterPacketQueue queue; 57210847Sandreas.sandberg@arm.com 57310847Sandreas.sandberg@arm.com // Owner of the port 57410847Sandreas.sandberg@arm.com TrafficGen& owner; 57510847Sandreas.sandberg@arm.com 57610847Sandreas.sandberg@arm.com }; 57710847Sandreas.sandberg@arm.com 57810847Sandreas.sandberg@arm.com TrafficGenPort port; 57910847Sandreas.sandberg@arm.com 58010847Sandreas.sandberg@arm.com /** Request generator state graph */ 58110847Sandreas.sandberg@arm.com StateGraph stateGraph; 58210847Sandreas.sandberg@arm.com 58310847Sandreas.sandberg@arm.com /** 58410847Sandreas.sandberg@arm.com * Schedules event for next update and executes an update on the 58510847Sandreas.sandberg@arm.com * state graph. 58610847Sandreas.sandberg@arm.com */ 58710847Sandreas.sandberg@arm.com void updateStateGraph(); 58810847Sandreas.sandberg@arm.com 58910847Sandreas.sandberg@arm.com /** Event for updating the state graph */ 59010847Sandreas.sandberg@arm.com EventWrapper<TrafficGen, 59110847Sandreas.sandberg@arm.com &TrafficGen::updateStateGraph> updateStateGraphEvent; 59210847Sandreas.sandberg@arm.com 59310847Sandreas.sandberg@arm.com 59410847Sandreas.sandberg@arm.com public: 59510847Sandreas.sandberg@arm.com 59610847Sandreas.sandberg@arm.com TrafficGen(const TrafficGenParams* p); 59710847Sandreas.sandberg@arm.com 59810847Sandreas.sandberg@arm.com ~TrafficGen() {} 59910847Sandreas.sandberg@arm.com 60010847Sandreas.sandberg@arm.com virtual BaseMasterPort& getMasterPort(const std::string &if_name, 60110847Sandreas.sandberg@arm.com PortID idx = InvalidPortID); 60210847Sandreas.sandberg@arm.com 60310847Sandreas.sandberg@arm.com void init(); 60410847Sandreas.sandberg@arm.com 60510847Sandreas.sandberg@arm.com void initState(); 60610847Sandreas.sandberg@arm.com 60710847Sandreas.sandberg@arm.com unsigned int drain(Event *drain_event); 60810847Sandreas.sandberg@arm.com 60910847Sandreas.sandberg@arm.com void serialize(std::ostream &os); 61010847Sandreas.sandberg@arm.com 61110847Sandreas.sandberg@arm.com void unserialize(Checkpoint* cp, const std::string& section); 61210847Sandreas.sandberg@arm.com 61310847Sandreas.sandberg@arm.com}; 61410847Sandreas.sandberg@arm.com 61510847Sandreas.sandberg@arm.com#endif //__MEM_TRAFFIC_GEN_HH__ 61610847Sandreas.sandberg@arm.com