41,42c41,42
< #ifndef __MEM_TRAFFIC_GEN_HH__
< #define __MEM_TRAFFIC_GEN_HH__
---
> #ifndef __CPU_TRAFFIC_GEN_TRAFFIC_GEN_HH__
> #define __CPU_TRAFFIC_GEN_TRAFFIC_GEN_HH__
44a45
> #include "cpu/testers/traffic_gen/generators.hh"
48d48
< #include "proto/protoio.hh"
162,552d161
< /** Base class for all generator states */
< class BaseGen
< {
<
< protected:
<
< /** Port used to send requests */
< QueuedMasterPort& port;
<
< /** The MasterID used for generating requests */
< const MasterID masterID;
<
< /**
< * Create a new request and associated packet and schedule
< * it to be sent in the current tick.
< *
< * @param addr Physical address to use
< * @param size Size of the request
< * @param cmd Memory command to send
< */
< void send(Addr addr, unsigned size, const MemCmd& cmd);
<
< public:
<
< /** Time to spend in this state */
< const Tick duration;
<
< /**
< * Create a base generator.
< *
< * @param _port port used to send requests
< * @param master_id MasterID set on each request
< * @param _duration duration of this state before transitioning
< */
< BaseGen(QueuedMasterPort& _port, MasterID master_id,
< Tick _duration);
<
< virtual ~BaseGen() { }
<
< /**
< * Get the name, useful for DPRINTFs.
< *
< * @return the port name
< */
< std::string name() const { return port.name(); }
<
< /**
< * Enter this generator state.
< */
< virtual void enter() = 0;
<
< /**
< * Execute this generator state.
< */
< virtual void execute() = 0;
<
< /**
< * Exit this generator state. By default do nothing.
< */
< virtual void exit() { };
<
< /**
< * Determine the next execute tick. MaxTick means that
< * there will not be any further event in the current
< * activation cycle of the state.
< *
< * @return next tick when the state should be executed
< */
< virtual Tick nextExecuteTick() = 0;
<
< };
<
< /**
< * The idle generator does nothing.
< */
< class IdleGen : public BaseGen
< {
<
< public:
<
< IdleGen(QueuedMasterPort& _port, MasterID master_id,
< Tick _duration)
< : BaseGen(_port, master_id, _duration)
< { }
<
< void enter() { }
<
< void execute() { }
<
< Tick nextExecuteTick() { return MaxTick; }
< };
<
< /**
< * The linear generator generates sequential requests from a
< * start to an end address, with a fixed block size. A
< * fraction of the requests are reads, as determined by the
< * read percent. There is an optional data limit for when to
< * stop generating new requests.
< */
< class LinearGen : public BaseGen
< {
<
< public:
<
< /**
< * Create a linear address sequence generator. Set
< * min_period == max_period for a fixed inter-transaction
< * time.
< *
< * @param _port port used to send requests
< * @param master_id MasterID set on each request
< * @param _duration duration of this state before transitioning
< * @param start_addr Start address
< * @param end_addr End address
< * @param _blocksize Size used for transactions injected
< * @param min_period Lower limit of random inter-transaction time
< * @param max_period Upper limit of random inter-transaction time
< * @param read_percent Percent of transactions that are reads
< * @param data_limit Upper limit on how much data to read/write
< */
< LinearGen(QueuedMasterPort& _port, MasterID master_id,
< Tick _duration, Addr start_addr, Addr end_addr,
< Addr _blocksize, Tick min_period, Tick max_period,
< uint8_t read_percent, Addr data_limit)
< : BaseGen(_port, master_id, _duration),
< startAddr(start_addr), endAddr(end_addr),
< blocksize(_blocksize), minPeriod(min_period),
< maxPeriod(max_period), readPercent(read_percent),
< dataLimit(data_limit)
< { }
<
< void enter();
<
< void execute();
<
< Tick nextExecuteTick();
<
< private:
<
< /** Start of address range */
< const Addr startAddr;
<
< /** End of address range */
< const Addr endAddr;
<
< /** Blocksize and address increment */
< const Addr blocksize;
<
< /** Request generation period */
< const Tick minPeriod;
< const Tick maxPeriod;
<
< /**
< * Percent of generated transactions that should be reads
< */
< const uint8_t readPercent;
<
< /** Maximum amount of data to manipulate */
< const Addr dataLimit;
<
< /** Address of next request */
< Addr nextAddr;
<
< /**
< * Counter to determine the amount of data
< * manipulated. Used to determine if we should continue
< * generating requests.
< */
< Addr dataManipulated;
< };
<
< /**
< * The random generator is similar to the linear one, but does
< * not generate sequential addresses. Instead it randomly
< * picks an address in the range, aligned to the block size.
< */
< class RandomGen : public BaseGen
< {
<
< public:
<
< /**
< * Create a random address sequence generator. Set
< * min_period == max_period for a fixed inter-transaction
< * time.
< *
< * @param _port port used to send requests
< * @param master_id MasterID set on each request
< * @param _duration duration of this state before transitioning
< * @param start_addr Start address
< * @param end_addr End address
< * @param _blocksize Size used for transactions injected
< * @param min_period Lower limit of random inter-transaction time
< * @param max_period Upper limit of random inter-transaction time
< * @param read_percent Percent of transactions that are reads
< * @param data_limit Upper limit on how much data to read/write
< */
< RandomGen(QueuedMasterPort& _port, MasterID master_id,
< Tick _duration, Addr start_addr, Addr end_addr,
< Addr _blocksize, Tick min_period, Tick max_period,
< uint8_t read_percent, Addr data_limit)
< : BaseGen(_port, master_id, _duration),
< startAddr(start_addr), endAddr(end_addr),
< blocksize(_blocksize), minPeriod(min_period),
< maxPeriod(max_period), readPercent(read_percent),
< dataLimit(data_limit)
< { }
<
< void enter();
<
< void execute();
<
< Tick nextExecuteTick();
<
< private:
<
< /** Start of address range */
< const Addr startAddr;
<
< /** End of address range */
< const Addr endAddr;
<
< /** Block size */
< const Addr blocksize;
<
< /** Request generation period */
< const Tick minPeriod;
< const Tick maxPeriod;
<
< /**
< * Percent of generated transactions that should be reads
< */
< const uint8_t readPercent;
<
< /** Maximum amount of data to manipulate */
< const Addr dataLimit;
<
< /**
< * Counter to determine the amount of data
< * manipulated. Used to determine if we should continue
< * generating requests.
< */
< Addr dataManipulated;
< };
<
< /**
< * The trace replay generator reads a trace file and plays
< * back the transactions. The trace is offset with respect to
< * the time when the state was entered.
< */
< class TraceGen : public BaseGen
< {
<
< private:
<
< /**
< * This struct stores a line in the trace file.
< */
< struct TraceElement {
<
< /** Specifies if the request is to be a read or a write */
< MemCmd cmd;
<
< /** The address for the request */
< Addr addr;
<
< /** The size of the access for the request */
< Addr blocksize;
<
< /** The time at which the request should be sent */
< Tick tick;
<
< /**
< * Check validity of this element.
< *
< * @return if this element is valid
< */
< bool isValid() const {
< return cmd != MemCmd::InvalidCmd;
< }
<
< /**
< * Make this element invalid.
< */
< void clear() {
< cmd = MemCmd::InvalidCmd;
< }
< };
<
< /**
< * The InputStream encapsulates a trace file and the
< * internal buffers and populates TraceElements based on
< * the input.
< */
< class InputStream
< {
<
< private:
<
< /// Input file stream for the protobuf trace
< ProtoInputStream trace;
<
< public:
<
< /**
< * Create a trace input stream for a given file name.
< *
< * @param filename Path to the file to read from
< */
< InputStream(const std::string& filename);
<
< /**
< * Reset the stream such that it can be played once
< * again.
< */
< void reset();
<
< /**
< * Attempt to read a trace element from the stream,
< * and also notify the caller if the end of the file
< * was reached.
< *
< * @param element Trace element to populate
< * @return True if an element could be read successfully
< */
< bool read(TraceElement& element);
< };
<
< public:
<
< /**
< * Create a trace generator.
< *
< * @param _port port used to send requests
< * @param master_id MasterID set on each request
< * @param _duration duration of this state before transitioning
< * @param trace_file File to read the transactions from
< * @param addr_offset Positive offset to add to trace address
< */
< TraceGen(QueuedMasterPort& _port, MasterID master_id,
< Tick _duration, const std::string& trace_file,
< Addr addr_offset)
< : BaseGen(_port, master_id, _duration),
< trace(trace_file),
< addrOffset(addr_offset),
< traceComplete(false)
< {
< }
<
< void enter();
<
< void execute();
<
< void exit();
<
< /**
< * Read a line of the trace file. Returns the raw tick
< * when the next request should be generated. If the end
< * of the file has been reached, it returns MaxTick to
< * indicate that there will be no more requests.
< */
< Tick nextExecuteTick();
<
< private:
<
< /** Input stream used for reading the input trace file */
< InputStream trace;
<
< /** Store the current and next element in the trace */
< TraceElement currElement;
< TraceElement nextElement;
<
< /**
< * Stores the time when the state was entered. This is to add an
< * offset to the times stored in the trace file.
< */
< Tick tickOffset;
<
< /**
< * Offset for memory requests. Used to shift the trace
< * away from the CPU address space.
< */
< Addr addrOffset;
<
< /**
< * Set to true when the trace replay for one instance of
< * state is complete.
< */
< bool traceComplete;
< };
<
628c237
< #endif //__MEM_TRAFFIC_GEN_HH__
---
> #endif //__CPU_TRAFFIC_GEN_TRAFFIC_GEN_HH__