50 #include "debug/Checkpoint.hh"
51 #include "debug/TrafficGen.hh"
61 configFile(p->config_file),
62 elasticReq(p->elastic_req),
63 progressCheck(p->progress_check),
64 noProgressEvent(this),
65 nextTransitionTick(0),
68 port(
name() +
".port", *this),
77 TrafficGenParams::create()
85 if (if_name ==
"port") {
96 fatal(
"The port of %s is not connected!\n",
name());
108 "Traffic generator is only active in timing mode\n");
122 "Traffic generator is only active in timing mode\n");
148 DPRINTF(Checkpoint,
"Serializing TrafficGen\n");
170 if (nextEvent != 0) {
212 if (numSuppressed % 10000)
213 warn(
"%s suppressed %d packets with non-memory addresses\n",
214 name(), numSuppressed);
239 if (name.empty() || name[0] ==
'/')
242 char *config_path = strdup(
configFile.c_str());
243 char *config_dir = dirname(config_path);
244 const std::string config_rel =
csprintf(
"%s/%s", config_dir, name);
248 if (access(config_rel.c_str(), R_OK) == 0)
265 infile.open(
configFile.c_str(), ifstream::in);
266 if (!infile.is_open()) {
267 fatal(
"Traffic generator %s config file not found at %s\n",
271 bool init_state_set =
false;
278 while (getline(infile, line).good()) {
280 if (line.find(
'#') != 1) {
282 istringstream
is(line);
287 if (keyword ==
"STATE") {
293 is >>
id >> duration >>
mode;
295 if (mode ==
"TRACE") {
299 is >> traceFile >> addrOffset;
303 traceFile, addrOffset);
305 }
else if (mode ==
"IDLE") {
308 }
else if (mode ==
"LINEAR" || mode ==
"RANDOM" ||
309 mode ==
"DRAM" || mode ==
"DRAM_ROTATE") {
310 uint32_t read_percent;
318 is >> read_percent >> start_addr >> end_addr >>
319 blocksize >> min_period >> max_period >> data_limit;
322 " period %d to %d, %d%% reads\n",
323 mode, start_addr, end_addr, blocksize, min_period,
324 max_period, read_percent);
328 fatal(
"TrafficGen %s block size (%d) is larger than "
329 "cache line size (%d)\n",
name(),
332 if (read_percent > 100)
333 fatal(
"%s cannot have more than 100% reads",
name());
335 if (min_period > max_period)
336 fatal(
"%s cannot have min_period > max_period",
name());
338 if (mode ==
"LINEAR") {
340 duration, start_addr,
342 min_period, max_period,
343 read_percent, data_limit);
345 }
else if (mode ==
"RANDOM") {
347 duration, start_addr,
349 min_period, max_period,
350 read_percent, data_limit);
352 }
else if (mode ==
"DRAM" || mode ==
"DRAM_ROTATE") {
355 unsigned int stride_size;
356 unsigned int page_size;
357 unsigned int nbr_of_banks_DRAM;
358 unsigned int nbr_of_banks_util;
359 unsigned int addr_mapping;
360 unsigned int nbr_of_ranks;
362 is >> stride_size >> page_size >> nbr_of_banks_DRAM >>
363 nbr_of_banks_util >> addr_mapping >>
366 if (stride_size > page_size)
367 warn(
"DRAM generator stride size (%d) is greater "
368 "than page size (%d) of the memory\n",
369 blocksize, page_size);
371 if (nbr_of_banks_util > nbr_of_banks_DRAM)
372 fatal(
"Attempting to use more banks (%d) than "
373 "what is available (%d)\n",
374 nbr_of_banks_util, nbr_of_banks_DRAM);
378 unsigned int num_seq_pkts = 1;
380 if (stride_size > blocksize) {
381 num_seq_pkts =
divCeil(stride_size, blocksize);
383 "block size: %d, num_seq_pkts: %d\n",
384 stride_size, blocksize, num_seq_pkts);
387 if (mode ==
"DRAM") {
389 duration, start_addr,
391 min_period, max_period,
392 read_percent, data_limit,
393 num_seq_pkts, page_size,
404 unsigned int max_seq_count_per_rank =
405 (read_percent == 50) ? nbr_of_banks_util * 2
409 duration, start_addr,
411 min_period, max_period,
412 read_percent, data_limit,
413 num_seq_pkts, page_size,
418 max_seq_count_per_rank);
423 fatal(
"%s: Unknown traffic generator mode: %s",
426 }
else if (keyword ==
"TRANSITION") {
429 is >> transition.
from >> transition.
to >> transition.
p;
431 transitions.push_back(transition);
435 }
else if (keyword ==
"INIT") {
439 init_state_set =
true;
447 fatal(
"%s: initial state not specified (add 'INIT <id>' line "
448 "to the config file)\n",
name());
452 for (
size_t i = 0;
i <
states.size();
i++) {
457 t != transitions.end(); ++
t) {
463 for (
size_t i = 0;
i <
states.size();
i++) {
465 for (
size_t j = 0;
j <
states.size();
j++) {
470 if (abs(sum - 1.0) > 0.001)
471 fatal(
"%s has transition probability != 1 for state %d\n",
488 double cumulative = 0.0;
547 fatal(
"TrafficGen %s spent %llu ticks without making progress",
557 using namespace Stats;
561 .
desc(
"Number of packets generated");
565 .
desc(
"Number of retries");
569 .
desc(
"Time spent waiting due to back-pressure (ticks)");
EventWrapper< TrafficGen,&TrafficGen::update > updateEvent
Event for scheduling updates.
void recvReqRetry()
Receive a retry from the neighbouring port and attempt to resend the waiting packet.
TrafficGenPort port
The instance of master port used by the traffic generator.
bool isMemAddr(Addr addr) const
Check if a physical address is within a range of a memory that is part of the global address map...
PacketPtr retryPkt
Packet waiting to be sent.
const std::string & name()
DrainState
Object drain/handover states.
void noProgress()
Method to inform the user we have made no progress.
void enterState(uint32_t newState)
Enter a new state.
Tick nextPacketTick
Time of the next packet.
TrafficGen(const TrafficGenParams *p)
Struct to represent a probabilistic transition during parsing.
The linear generator generates sequential requests from a start to an end address, with a fixed block size.
Stats::Scalar retryTicks
Count the time incurred from back-pressure.
bool scheduled() const
Determine if the current event is scheduled.
uint32_t currState
Index of the current state.
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the slave port by calling its corresponding receive function...
Stats::Scalar numPackets
Count the number of generated packets.
const std::string configFile
The config file to parse.
std::vector< std::vector< double > > transitionMatrix
State transition matrix.
unsigned int cacheLineSize() const
Get the cache line size of the system.
void deschedule(Event &event)
std::enable_if< std::is_integral< T >::value, T >::type random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
void parseConfig()
Parse the config file and build the state map and transition matrix.
DrainState drain() override
Notify an object that it needs to drain its state.
#define UNSERIALIZE_SCALAR(scalar)
The idle generator does nothing.
The trace replay generator reads a trace file and plays back the transactions.
Tick curTick()
The current simulated tick.
std::string csprintf(const char *format, const Args &...args)
void regStats() override
Register statistics.
Tick when() const
Get the time that the event is scheduled.
The traffic generator is a master module that generates stimuli for the memory system, based on a collection of simple generator behaviours that are either probabilistic or based on traces.
uint64_t Tick
Tick count type.
BaseMasterPort & getMasterPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a master port with a given name and index.
System * system
The system used to determine which mode we are currently operating in.
DRAM specific generator is for issuing request with variable page hit length and bank utilization...
const RequestPtr req
A pointer to the original request.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
const bool elasticReq
Determine whether to add elasticity in the request injection, thus responding to backpressure by slow...
void serialize(CheckpointOut &cp) const override
Serialize an object.
void update()
Schedules event for next update and executes an update on the state graph, either performing a state ...
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Draining buffers pending serialization/handover.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Stats::Scalar numRetries
Count the number of retries.
Tick retryPktTick
Tick when the stalled packet was meant to be sent.
#define SERIALIZE_SCALAR(scalar)
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
void reschedule(Event &event, Tick when, bool always=false)
virtual const std::string name() const
std::string resolveFile(const std::string &name)
Resolve a file path in the configuration file.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
std::ostream CheckpointOut
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
The MemObject class extends the ClockedObject with accessor functions to get its master and slave por...
A BaseMasterPort is a protocol-agnostic master port, responsible only for the structural connection t...
The random generator is similar to the linear one, but does not generate sequential addresses...
void signalDrainDone() const
Signal that an object is drained.
Tick nextTransitionTick
Time of next transition.
T divCeil(const T &a, const U &b)
MasterID masterID
MasterID used in generated requests.
void schedule(Event &event, Tick when)
DrainState drainState() const
Return the current drain state of an object.
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
EventWrapper< TrafficGen,&TrafficGen::noProgress > noProgressEvent
Event to keep track of our progress, or lack thereof.
void regStats() override
Register statistics for this object.
virtual BaseMasterPort & getMasterPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a master port with a given name and index.
bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the slave port.
void transition()
Determine next state and perform the transition.
const Tick progressCheck
Time to tolerate waiting for retries (not making progress), until we declare things broken...
bool isTimingMode() const
Is the system in timing mode?
std::unordered_map< uint32_t, BaseGen * > states
Map of generator states.