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__ |