traffic_gen.hh (9557:8666e81607a6) traffic_gen.hh (9666:74aca4cb081e)
1/*
2 * Copyright (c) 2012 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 24 unchanged lines hidden (view full) ---

33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Thomas Grass
38 * Andreas Hansson
39 * Sascha Bischoff
40 */
1/*
2 * Copyright (c) 2012 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 24 unchanged lines hidden (view full) ---

33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Thomas Grass
38 * Andreas Hansson
39 * Sascha Bischoff
40 */
41#ifndef __MEM_TRAFFIC_GEN_HH__
42#define __MEM_TRAFFIC_GEN_HH__
41#ifndef __CPU_TRAFFIC_GEN_TRAFFIC_GEN_HH__
42#define __CPU_TRAFFIC_GEN_TRAFFIC_GEN_HH__
43
44#include "base/hashmap.hh"
43
44#include "base/hashmap.hh"
45#include "cpu/testers/traffic_gen/generators.hh"
45#include "mem/mem_object.hh"
46#include "mem/qport.hh"
47#include "params/TrafficGen.hh"
46#include "mem/mem_object.hh"
47#include "mem/qport.hh"
48#include "params/TrafficGen.hh"
48#include "proto/protoio.hh"
49
50/**
51 * The traffic generator is a master module that generates stimuli for
52 * the memory system, based on a collection of simple behaviours that
53 * are either probabilistic or based on traces. It can be used stand
54 * alone for creating test cases for interconnect and memory
55 * controllers, or function as a black box replacement for system
56 * components that are not yet modelled in detail, e.g. a video engine

--- 97 unchanged lines hidden (view full) ---

154
155 /** Struct to represent a probabilistic transition during parsing. */
156 struct Transition {
157 uint32_t from;
158 uint32_t to;
159 double p;
160 };
161
49
50/**
51 * The traffic generator is a master module that generates stimuli for
52 * the memory system, based on a collection of simple behaviours that
53 * are either probabilistic or based on traces. It can be used stand
54 * alone for creating test cases for interconnect and memory
55 * controllers, or function as a black box replacement for system
56 * components that are not yet modelled in detail, e.g. a video engine

--- 97 unchanged lines hidden (view full) ---

154
155 /** Struct to represent a probabilistic transition during parsing. */
156 struct Transition {
157 uint32_t from;
158 uint32_t to;
159 double p;
160 };
161
162 /** Base class for all generator states */
163 class BaseGen
164 {
165
166 protected:
167
168 /** Port used to send requests */
169 QueuedMasterPort& port;
170
171 /** The MasterID used for generating requests */
172 const MasterID masterID;
173
174 /**
175 * Create a new request and associated packet and schedule
176 * it to be sent in the current tick.
177 *
178 * @param addr Physical address to use
179 * @param size Size of the request
180 * @param cmd Memory command to send
181 */
182 void send(Addr addr, unsigned size, const MemCmd& cmd);
183
184 public:
185
186 /** Time to spend in this state */
187 const Tick duration;
188
189 /**
190 * Create a base generator.
191 *
192 * @param _port port used to send requests
193 * @param master_id MasterID set on each request
194 * @param _duration duration of this state before transitioning
195 */
196 BaseGen(QueuedMasterPort& _port, MasterID master_id,
197 Tick _duration);
198
199 virtual ~BaseGen() { }
200
201 /**
202 * Get the name, useful for DPRINTFs.
203 *
204 * @return the port name
205 */
206 std::string name() const { return port.name(); }
207
208 /**
209 * Enter this generator state.
210 */
211 virtual void enter() = 0;
212
213 /**
214 * Execute this generator state.
215 */
216 virtual void execute() = 0;
217
218 /**
219 * Exit this generator state. By default do nothing.
220 */
221 virtual void exit() { };
222
223 /**
224 * Determine the next execute tick. MaxTick means that
225 * there will not be any further event in the current
226 * activation cycle of the state.
227 *
228 * @return next tick when the state should be executed
229 */
230 virtual Tick nextExecuteTick() = 0;
231
232 };
233
234 /**
235 * The idle generator does nothing.
236 */
237 class IdleGen : public BaseGen
238 {
239
240 public:
241
242 IdleGen(QueuedMasterPort& _port, MasterID master_id,
243 Tick _duration)
244 : BaseGen(_port, master_id, _duration)
245 { }
246
247 void enter() { }
248
249 void execute() { }
250
251 Tick nextExecuteTick() { return MaxTick; }
252 };
253
254 /**
255 * The linear generator generates sequential requests from a
256 * start to an end address, with a fixed block size. A
257 * fraction of the requests are reads, as determined by the
258 * read percent. There is an optional data limit for when to
259 * stop generating new requests.
260 */
261 class LinearGen : public BaseGen
262 {
263
264 public:
265
266 /**
267 * Create a linear address sequence generator. Set
268 * min_period == max_period for a fixed inter-transaction
269 * time.
270 *
271 * @param _port port used to send requests
272 * @param master_id MasterID set on each request
273 * @param _duration duration of this state before transitioning
274 * @param start_addr Start address
275 * @param end_addr End address
276 * @param _blocksize Size used for transactions injected
277 * @param min_period Lower limit of random inter-transaction time
278 * @param max_period Upper limit of random inter-transaction time
279 * @param read_percent Percent of transactions that are reads
280 * @param data_limit Upper limit on how much data to read/write
281 */
282 LinearGen(QueuedMasterPort& _port, MasterID master_id,
283 Tick _duration, Addr start_addr, Addr end_addr,
284 Addr _blocksize, Tick min_period, Tick max_period,
285 uint8_t read_percent, Addr data_limit)
286 : BaseGen(_port, master_id, _duration),
287 startAddr(start_addr), endAddr(end_addr),
288 blocksize(_blocksize), minPeriod(min_period),
289 maxPeriod(max_period), readPercent(read_percent),
290 dataLimit(data_limit)
291 { }
292
293 void enter();
294
295 void execute();
296
297 Tick nextExecuteTick();
298
299 private:
300
301 /** Start of address range */
302 const Addr startAddr;
303
304 /** End of address range */
305 const Addr endAddr;
306
307 /** Blocksize and address increment */
308 const Addr blocksize;
309
310 /** Request generation period */
311 const Tick minPeriod;
312 const Tick maxPeriod;
313
314 /**
315 * Percent of generated transactions that should be reads
316 */
317 const uint8_t readPercent;
318
319 /** Maximum amount of data to manipulate */
320 const Addr dataLimit;
321
322 /** Address of next request */
323 Addr nextAddr;
324
325 /**
326 * Counter to determine the amount of data
327 * manipulated. Used to determine if we should continue
328 * generating requests.
329 */
330 Addr dataManipulated;
331 };
332
333 /**
334 * The random generator is similar to the linear one, but does
335 * not generate sequential addresses. Instead it randomly
336 * picks an address in the range, aligned to the block size.
337 */
338 class RandomGen : public BaseGen
339 {
340
341 public:
342
343 /**
344 * Create a random address sequence generator. Set
345 * min_period == max_period for a fixed inter-transaction
346 * time.
347 *
348 * @param _port port used to send requests
349 * @param master_id MasterID set on each request
350 * @param _duration duration of this state before transitioning
351 * @param start_addr Start address
352 * @param end_addr End address
353 * @param _blocksize Size used for transactions injected
354 * @param min_period Lower limit of random inter-transaction time
355 * @param max_period Upper limit of random inter-transaction time
356 * @param read_percent Percent of transactions that are reads
357 * @param data_limit Upper limit on how much data to read/write
358 */
359 RandomGen(QueuedMasterPort& _port, MasterID master_id,
360 Tick _duration, Addr start_addr, Addr end_addr,
361 Addr _blocksize, Tick min_period, Tick max_period,
362 uint8_t read_percent, Addr data_limit)
363 : BaseGen(_port, master_id, _duration),
364 startAddr(start_addr), endAddr(end_addr),
365 blocksize(_blocksize), minPeriod(min_period),
366 maxPeriod(max_period), readPercent(read_percent),
367 dataLimit(data_limit)
368 { }
369
370 void enter();
371
372 void execute();
373
374 Tick nextExecuteTick();
375
376 private:
377
378 /** Start of address range */
379 const Addr startAddr;
380
381 /** End of address range */
382 const Addr endAddr;
383
384 /** Block size */
385 const Addr blocksize;
386
387 /** Request generation period */
388 const Tick minPeriod;
389 const Tick maxPeriod;
390
391 /**
392 * Percent of generated transactions that should be reads
393 */
394 const uint8_t readPercent;
395
396 /** Maximum amount of data to manipulate */
397 const Addr dataLimit;
398
399 /**
400 * Counter to determine the amount of data
401 * manipulated. Used to determine if we should continue
402 * generating requests.
403 */
404 Addr dataManipulated;
405 };
406
407 /**
408 * The trace replay generator reads a trace file and plays
409 * back the transactions. The trace is offset with respect to
410 * the time when the state was entered.
411 */
412 class TraceGen : public BaseGen
413 {
414
415 private:
416
417 /**
418 * This struct stores a line in the trace file.
419 */
420 struct TraceElement {
421
422 /** Specifies if the request is to be a read or a write */
423 MemCmd cmd;
424
425 /** The address for the request */
426 Addr addr;
427
428 /** The size of the access for the request */
429 Addr blocksize;
430
431 /** The time at which the request should be sent */
432 Tick tick;
433
434 /**
435 * Check validity of this element.
436 *
437 * @return if this element is valid
438 */
439 bool isValid() const {
440 return cmd != MemCmd::InvalidCmd;
441 }
442
443 /**
444 * Make this element invalid.
445 */
446 void clear() {
447 cmd = MemCmd::InvalidCmd;
448 }
449 };
450
451 /**
452 * The InputStream encapsulates a trace file and the
453 * internal buffers and populates TraceElements based on
454 * the input.
455 */
456 class InputStream
457 {
458
459 private:
460
461 /// Input file stream for the protobuf trace
462 ProtoInputStream trace;
463
464 public:
465
466 /**
467 * Create a trace input stream for a given file name.
468 *
469 * @param filename Path to the file to read from
470 */
471 InputStream(const std::string& filename);
472
473 /**
474 * Reset the stream such that it can be played once
475 * again.
476 */
477 void reset();
478
479 /**
480 * Attempt to read a trace element from the stream,
481 * and also notify the caller if the end of the file
482 * was reached.
483 *
484 * @param element Trace element to populate
485 * @return True if an element could be read successfully
486 */
487 bool read(TraceElement& element);
488 };
489
490 public:
491
492 /**
493 * Create a trace generator.
494 *
495 * @param _port port used to send requests
496 * @param master_id MasterID set on each request
497 * @param _duration duration of this state before transitioning
498 * @param trace_file File to read the transactions from
499 * @param addr_offset Positive offset to add to trace address
500 */
501 TraceGen(QueuedMasterPort& _port, MasterID master_id,
502 Tick _duration, const std::string& trace_file,
503 Addr addr_offset)
504 : BaseGen(_port, master_id, _duration),
505 trace(trace_file),
506 addrOffset(addr_offset),
507 traceComplete(false)
508 {
509 }
510
511 void enter();
512
513 void execute();
514
515 void exit();
516
517 /**
518 * Read a line of the trace file. Returns the raw tick
519 * when the next request should be generated. If the end
520 * of the file has been reached, it returns MaxTick to
521 * indicate that there will be no more requests.
522 */
523 Tick nextExecuteTick();
524
525 private:
526
527 /** Input stream used for reading the input trace file */
528 InputStream trace;
529
530 /** Store the current and next element in the trace */
531 TraceElement currElement;
532 TraceElement nextElement;
533
534 /**
535 * Stores the time when the state was entered. This is to add an
536 * offset to the times stored in the trace file.
537 */
538 Tick tickOffset;
539
540 /**
541 * Offset for memory requests. Used to shift the trace
542 * away from the CPU address space.
543 */
544 Addr addrOffset;
545
546 /**
547 * Set to true when the trace replay for one instance of
548 * state is complete.
549 */
550 bool traceComplete;
551 };
552
553 /** Pointer to owner of request handler */
554 TrafficGen& owner;
555
556 /** Pointer to request handler */
557 QueuedMasterPort& port;
558
559 /** State transition matrix */
560 std::vector<std::vector<double> > transitionMatrix;

--- 59 unchanged lines hidden (view full) ---

620 unsigned int drain(DrainManager *dm);
621
622 void serialize(std::ostream &os);
623
624 void unserialize(Checkpoint* cp, const std::string& section);
625
626};
627
162 /** Pointer to owner of request handler */
163 TrafficGen& owner;
164
165 /** Pointer to request handler */
166 QueuedMasterPort& port;
167
168 /** State transition matrix */
169 std::vector<std::vector<double> > transitionMatrix;

--- 59 unchanged lines hidden (view full) ---

229 unsigned int drain(DrainManager *dm);
230
231 void serialize(std::ostream &os);
232
233 void unserialize(Checkpoint* cp, const std::string& section);
234
235};
236
628#endif //__MEM_TRAFFIC_GEN_HH__
237#endif //__CPU_TRAFFIC_GEN_TRAFFIC_GEN_HH__