/*
- * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2012-2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
: MemObject(p),
system(p->system),
masterID(system->getMasterId(name())),
+ nextTransitionTick(0),
port(name() + ".port", *this),
- stateGraph(*this, port, p->config_file, masterID),
- updateStateGraphEvent(this)
+ updateEvent(this)
{
+ parseConfig(p->config_file, masterID);
}
TrafficGen*
DPRINTF(TrafficGen, "Timing mode, activating request generator\n");
// enter initial state
- stateGraph.enterState(stateGraph.currState);
+ enterState(currState);
} else {
DPRINTF(TrafficGen,
"Traffic generator is only active in timing mode\n");
{
// when not restoring from a checkpoint, make sure we kick things off
if (system->isTimingMode()) {
- Tick nextStateGraphEvent = stateGraph.nextEventTick();
- schedule(updateStateGraphEvent, nextStateGraphEvent);
+ schedule(updateEvent, nextEventTick());
} else {
DPRINTF(TrafficGen,
"Traffic generator is only active in timing mode\n");
DPRINTF(Checkpoint, "Serializing TrafficGen\n");
// save ticks of the graph event if it is scheduled
- Tick nextStateGraphEvent = updateStateGraphEvent.scheduled() ?
- updateStateGraphEvent.when() : 0;
+ Tick nextEvent = updateEvent.scheduled() ?
+ updateEvent.when() : 0;
- DPRINTF(TrafficGen, "Saving nextStateGraphEvent=%llu\n",
- nextStateGraphEvent);
+ DPRINTF(TrafficGen, "Saving nextEvent=%llu\n",
+ nextEvent);
- SERIALIZE_SCALAR(nextStateGraphEvent);
+ SERIALIZE_SCALAR(nextEvent);
- Tick nextTransitionTick = stateGraph.nextTransitionTick;
SERIALIZE_SCALAR(nextTransitionTick);
// @todo: also serialise the current state, figure out the best
TrafficGen::unserialize(Checkpoint* cp, const string& section)
{
// restore scheduled events
- Tick nextStateGraphEvent;
- UNSERIALIZE_SCALAR(nextStateGraphEvent);
- if (nextStateGraphEvent != 0) {
- schedule(updateStateGraphEvent, nextStateGraphEvent);
+ Tick nextEvent;
+ UNSERIALIZE_SCALAR(nextEvent);
+ if (nextEvent != 0) {
+ schedule(updateEvent, nextEvent);
}
- Tick nextTransitionTick;
UNSERIALIZE_SCALAR(nextTransitionTick);
- stateGraph.nextTransitionTick = nextTransitionTick;
}
void
-TrafficGen::updateStateGraph()
+TrafficGen::update()
{
// schedule next update event based on either the next execute
// tick or the next transition, which ever comes first
- Tick nextStateGraphEvent = stateGraph.nextEventTick();
+ Tick nextEvent = nextEventTick();
DPRINTF(TrafficGen, "Updating state graph, next event at %lld\n",
- nextStateGraphEvent);
- schedule(updateStateGraphEvent, nextStateGraphEvent);
+ nextEvent);
+ schedule(updateEvent, nextEvent);
// perform the update associated with the current update event
- stateGraph.update();
+
+ // if we have reached the time for the next state transition, then
+ // perform the transition
+ if (curTick() >= nextTransitionTick) {
+ transition();
+ } else {
+ // we are still in the current state and should execute it
+ states[currState]->execute();
+ }
}
void
-TrafficGen::StateGraph::parseConfig(const string& file_name,
- MasterID master_id)
+TrafficGen::parseConfig(const string& file_name, MasterID master_id)
{
// keep track of the transitions parsed to create the matrix when
// done
infile.open(file_name.c_str(), ifstream::in);
if (!infile.is_open()) {
fatal("Traffic generator %s config file not found at %s\n",
- owner.name(), file_name);
+ name(), file_name);
}
// read line by line and determine the action based on the first
}
void
-TrafficGen::StateGraph::update()
-{
- // if we have reached the time for the next state transition, then
- // perform the transition
- if (curTick() >= nextTransitionTick) {
- transition();
- } else {
- // we are still in the current state and should execute it
- states[currState]->execute();
- }
-}
-
-void
-TrafficGen::StateGraph::transition()
+TrafficGen::transition()
{
// exit the current state
states[currState]->exit();
}
void
-TrafficGen::StateGraph::enterState(uint32_t newState)
+TrafficGen::enterState(uint32_t newState)
{
DPRINTF(TrafficGen, "Transition to state %d\n", newState);
/*
- * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2012-2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
/**
* The traffic generator is a master module that generates stimuli for
- * the memory system, based on a collection of simple behaviours that
- * are either probabilistic or based on traces. It can be used stand
- * alone for creating test cases for interconnect and memory
- * controllers, or function as a black box replacement for system
- * components that are not yet modelled in detail, e.g. a video engine
- * or baseband subsystem.
+ * the memory system, based on a collection of simple generator
+ * behaviours that are either probabilistic or based on traces. It can
+ * be used stand alone for creating test cases for interconnect and
+ * memory controllers, or function as a black box replacement for
+ * system components that are not yet modelled in detail, e.g. a video
+ * engine or baseband subsystem.
*/
class TrafficGen : public MemObject
{
private:
/**
- * The system used to determine which mode we are currently operating
- * in.
+ * Determine next state and perform the transition.
*/
- System* system;
+ void transition();
/**
- * MasterID used in generated requests.
+ * Enter a new state.
+ *
+ * @param newState identifier of state to enter
*/
- MasterID masterID;
-
- protected:
+ void enterState(uint32_t newState);
/**
- * The state graph is responsible for instantiating and keeping
- * track of the various generator states and also perform the
- * transitions and call the appropriate functions when entering,
- * executing and exiting a state.
+ * Get the tick of the next event, either an execution or a
+ * transition.
+ *
+ * @return tick of the next update event
*/
- class StateGraph
+ Tick nextEventTick()
{
+ return std::min(states[currState]->nextExecuteTick(),
+ nextTransitionTick);
+ }
- public:
-
- /**
- * Create a state graph from an input file.
- *
- * @param _owner used solely for the name
- * @param _port port used to send requests
- * @param file_name configuration description to read in
- * @param master_id the unique id used for all requests
- */
- StateGraph(TrafficGen& _owner, QueuedMasterPort& _port,
- const std::string& file_name, MasterID master_id)
- : nextTransitionTick(0), owner(_owner), port(_port)
- {
- parseConfig(file_name, master_id);
- }
-
- /**
- * Get the name, used for DPRINTFs.
- *
- * @return the owner's name
- */
- std::string name() const { return owner.name(); }
-
- /**
- * Either perform a state transition or execute the current
- * state, depending on the current time.
- */
- void update();
-
- /**
- * Determine next state and perform the transition.
- */
- void transition();
-
- /**
- * Enter a new state.
- *
- * @param newState identifier of state to enter
- */
- void enterState(uint32_t newState);
-
- /**
- * Get the tick of the next event, either an execution or a
- * transition.
- *
- * @return tick of the next state graph event
- */
- Tick nextEventTick()
- {
- return std::min(states[currState]->nextExecuteTick(),
- nextTransitionTick);
-
- }
-
- /** Time of next transition */
- Tick nextTransitionTick;
-
- private:
-
- /**
- * Parse the config file and build the state map and
- * transition matrix.
- *
- * @param file_name Config file name to parse
- * @param master_id MasterID to use for generated requests
- */
- void parseConfig(const std::string& file_name, MasterID master_id);
+ /**
+ * Parse the config file and build the state map and
+ * transition matrix.
+ *
+ * @param file_name Config file name to parse
+ * @param master_id MasterID to use for generated requests
+ */
+ void parseConfig(const std::string& file_name, MasterID master_id);
- /** Struct to represent a probabilistic transition during parsing. */
- struct Transition {
- uint32_t from;
- uint32_t to;
- double p;
- };
+ /**
+ * Schedules event for next update and executes an update on the
+ * state graph, either performing a state transition or executing
+ * the current state, depending on the current time.
+ */
+ void update();
- /** Pointer to owner of request handler */
- TrafficGen& owner;
+ /** Struct to represent a probabilistic transition during parsing. */
+ struct Transition {
+ uint32_t from;
+ uint32_t to;
+ double p;
+ };
- /** Pointer to request handler */
- QueuedMasterPort& port;
+ /**
+ * The system used to determine which mode we are currently operating
+ * in.
+ */
+ System* system;
- /** State transition matrix */
- std::vector<std::vector<double> > transitionMatrix;
+ /**
+ * MasterID used in generated requests.
+ */
+ MasterID masterID;
- public:
+ /** Time of next transition */
+ Tick nextTransitionTick;
- /** Index of the current state */
- uint32_t currState;
+ /** State transition matrix */
+ std::vector<std::vector<double> > transitionMatrix;
- /** Map of states */
- m5::hash_map<uint32_t, BaseGen*> states;
- };
+ /** Index of the current state */
+ uint32_t currState;
+ /** Map of generator states */
+ m5::hash_map<uint32_t, BaseGen*> states;
- /** Queued handler */
+ /** Queued master port */
class TrafficGenPort : public QueuedMasterPort
{
public:
};
+ /** The instance of master port used by the traffic generator. */
TrafficGenPort port;
- /** Request generator state graph */
- StateGraph stateGraph;
-
- /**
- * Schedules event for next update and executes an update on the
- * state graph.
- */
- void updateStateGraph();
-
- /** Event for updating the state graph */
- EventWrapper<TrafficGen,
- &TrafficGen::updateStateGraph> updateStateGraphEvent;
+ /** Event for scheduling updates */
+ EventWrapper<TrafficGen, &TrafficGen::update> updateEvent;
public: