cpu-tester: Refactoring traffic generators into separate files.

Change-Id: I2372a0a88e276dcb0c06c3d0a789e010cfba8013
Reviewed-by: Matteo Andreozzi <matteo.andreozzi@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/5722
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
diff --git a/src/cpu/testers/traffic_gen/SConscript b/src/cpu/testers/traffic_gen/SConscript
index 00a3a84..d73819b 100644
--- a/src/cpu/testers/traffic_gen/SConscript
+++ b/src/cpu/testers/traffic_gen/SConscript
@@ -1,6 +1,6 @@
 # -*- mode:python -*-
 
-# Copyright (c) 2012 ARM Limited
+# Copyright (c) 2012, 2017 ARM Limited
 # All rights reserved.
 #
 # The license below extends only to copyright in the software and shall
@@ -44,7 +44,13 @@
 if env['HAVE_PROTOBUF']:
     SimObject('TrafficGen.py')
 
-    Source('generators.cc')
+    Source('base_gen.cc')
+    Source('dram_gen.cc')
+    Source('dram_rot_gen.cc')
+    Source('idle_gen.cc')
+    Source('linear_gen.cc')
+    Source('random_gen.cc')
+    Source('trace_gen.cc')
     Source('traffic_gen.cc')
 
     DebugFlag('TrafficGen')
diff --git a/src/cpu/testers/traffic_gen/base_gen.cc b/src/cpu/testers/traffic_gen/base_gen.cc
new file mode 100644
index 0000000..cd568f1
--- /dev/null
+++ b/src/cpu/testers/traffic_gen/base_gen.cc
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012-2013, 2016-2017 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed here under.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Thomas Grass
+ *          Andreas Hansson
+ *          Sascha Bischoff
+ *          Neha Agarwal
+ */
+
+#include "cpu/testers/traffic_gen/base_gen.hh"
+
+#include <algorithm>
+
+#include "base/random.hh"
+#include "base/trace.hh"
+#include "debug/TrafficGen.hh"
+#include "proto/packet.pb.h"
+
+BaseGen::BaseGen(const std::string& _name, MasterID master_id, Tick _duration)
+    : _name(_name), masterID(master_id), duration(_duration)
+{
+}
+
+PacketPtr
+BaseGen::getPacket(Addr addr, unsigned size, const MemCmd& cmd,
+                   Request::FlagsType flags)
+{
+    // Create new request
+    Request *req = new Request(addr, size, flags, masterID);
+    // Dummy PC to have PC-based prefetchers latch on; get entropy into higher
+    // bits
+    req->setPC(((Addr)masterID) << 2);
+
+    // Embed it in a packet
+    PacketPtr pkt = new Packet(req, cmd);
+
+    uint8_t* pkt_data = new uint8_t[req->getSize()];
+    pkt->dataDynamic(pkt_data);
+
+    if (cmd.isWrite()) {
+        std::fill_n(pkt_data, req->getSize(), (uint8_t)masterID);
+    }
+
+    return pkt;
+}
diff --git a/src/cpu/testers/traffic_gen/base_gen.hh b/src/cpu/testers/traffic_gen/base_gen.hh
new file mode 100644
index 0000000..26aa62d
--- /dev/null
+++ b/src/cpu/testers/traffic_gen/base_gen.hh
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2012-2013, 2017 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed here under.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Thomas Grass
+ *          Andreas Hansson
+ *          Sascha Bischoff
+ *          Neha Agarwal
+ */
+
+/**
+ * @file
+ * Declaration of the base generator class for all generators.
+ */
+
+#ifndef __CPU_TRAFFIC_GEN_BASE_GEN_HH__
+#define __CPU_TRAFFIC_GEN_BASE_GEN_HH__
+
+#include "base/bitfield.hh"
+#include "base/intmath.hh"
+#include "mem/packet.hh"
+#include "proto/protoio.hh"
+
+/**
+ * Base class for all generators, with the shared functionality and
+ * virtual functions for entering, executing and leaving the
+ * generator.
+ */
+class BaseGen
+{
+
+  protected:
+
+    /** Name to use for status and debug printing */
+    const std::string _name;
+
+    /** The MasterID used for generating requests */
+    const MasterID masterID;
+
+    /**
+     * Generate a new request and associated packet
+     *
+     * @param addr Physical address to use
+     * @param size Size of the request
+     * @param cmd Memory command to send
+     * @param flags Optional request flags
+     */
+    PacketPtr getPacket(Addr addr, unsigned size, const MemCmd& cmd,
+                        Request::FlagsType flags = 0);
+
+  public:
+
+    /** Time to spend in this state */
+    const Tick duration;
+
+    /**
+     * Create a base generator.
+     *
+     * @param _name Name to use for status and debug
+     * @param master_id MasterID set on each request
+     * @param _duration duration of this state before transitioning
+     */
+    BaseGen(const std::string& _name, MasterID master_id, Tick _duration);
+
+    virtual ~BaseGen() { }
+
+    /**
+     * Get the name, useful for DPRINTFs.
+     *
+     * @return the given name
+     */
+    std::string name() const { return _name; }
+
+    /**
+     * Enter this generator state.
+     */
+    virtual void enter() = 0;
+
+    /**
+     * Get the next generated packet.
+     *
+     * @return A packet to be sent at the current tick
+     */
+    virtual PacketPtr getNextPacket() = 0;
+
+    /**
+     * Exit this generator state. By default do nothing.
+     */
+    virtual void exit() { };
+
+    /**
+     * Determine the tick when the next packet is available. MaxTick
+     * means that there will not be any further packets in the current
+     * activation cycle of the generator.
+     *
+     * @param elastic should the injection respond to flow control or not
+     * @param delay time the previous packet spent waiting
+     * @return next tick when a packet is available
+     */
+    virtual Tick nextPacketTick(bool elastic, Tick delay) const = 0;
+
+};
+
+#endif
diff --git a/src/cpu/testers/traffic_gen/dram_gen.cc b/src/cpu/testers/traffic_gen/dram_gen.cc
new file mode 100644
index 0000000..bfa0ea9
--- /dev/null
+++ b/src/cpu/testers/traffic_gen/dram_gen.cc
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2012-2013, 2016-2017 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed here under.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Thomas Grass
+ *          Andreas Hansson
+ *          Sascha Bischoff
+ *          Neha Agarwal
+ */
+
+#include "cpu/testers/traffic_gen/dram_gen.hh"
+
+#include <algorithm>
+
+#include "base/random.hh"
+#include "base/trace.hh"
+#include "debug/TrafficGen.hh"
+#include "proto/packet.pb.h"
+
+PacketPtr
+DramGen::getNextPacket()
+{
+    // if this is the first of the packets in series to be generated,
+    // start counting again
+    if (countNumSeqPkts == 0) {
+        countNumSeqPkts = numSeqPkts;
+
+        // choose if we generate a read or a write here
+        isRead = readPercent != 0 &&
+            (readPercent == 100 || random_mt.random(0, 100) < readPercent);
+
+        assert((readPercent == 0 && !isRead) ||
+               (readPercent == 100 && isRead) ||
+               readPercent != 100);
+
+        // pick a random bank
+        unsigned int new_bank =
+            random_mt.random<unsigned int>(0, nbrOfBanksUtil - 1);
+
+        // pick a random rank
+        unsigned int new_rank =
+            random_mt.random<unsigned int>(0, nbrOfRanks - 1);
+
+        // Generate the start address of the command series
+        // routine will update addr variable with bank, rank, and col
+        // bits updated for random traffic mode
+        genStartAddr(new_bank, new_rank);
+
+    } else {
+        // increment the column by one
+        if (addrMapping == 1)
+            // addrMapping=1: RoRaBaCoCh/RoRaBaChCo
+            // Simply increment addr by blocksize to increment
+            // the column by one
+            addr += blocksize;
+
+        else if (addrMapping == 0) {
+            // addrMapping=0: RoCoRaBaCh
+            // Explicity increment the column bits
+            unsigned int new_col = ((addr / blocksize /
+                                       nbrOfBanksDRAM / nbrOfRanks) %
+                                   (pageSize / blocksize)) + 1;
+            replaceBits(addr, blockBits + bankBits + rankBits + pageBits - 1,
+                        blockBits + bankBits + rankBits, new_col);
+        }
+    }
+
+    DPRINTF(TrafficGen, "DramGen::getNextPacket: %c to addr %x, "
+            "size %d, countNumSeqPkts: %d, numSeqPkts: %d\n",
+            isRead ? 'r' : 'w', addr, blocksize, countNumSeqPkts, numSeqPkts);
+
+    // create a new request packet
+    PacketPtr pkt = getPacket(addr, blocksize,
+                              isRead ? MemCmd::ReadReq : MemCmd::WriteReq);
+
+    // add the amount of data manipulated to the total
+    dataManipulated += blocksize;
+
+    // subtract the number of packets remained to be generated
+    --countNumSeqPkts;
+
+    // return the generated packet
+    return pkt;
+}
+
+void
+DramGen::genStartAddr(unsigned int new_bank, unsigned int new_rank)
+{
+    // start by picking a random address in the range
+    addr = random_mt.random<Addr>(startAddr, endAddr - 1);
+
+    // round down to start address of a block, i.e. a DRAM burst
+    addr -= addr % blocksize;
+
+    // insert the bank bits at the right spot, and align the
+    // address to achieve the required hit length, this involves
+    // finding the appropriate start address such that all
+    // sequential packets target successive columns in the same
+    // page
+
+    // for example, if we have a stride size of 192B, which means
+    // for LPDDR3 where burstsize = 32B we have numSeqPkts = 6,
+    // the address generated previously can be such that these
+    // 192B cross the page boundary, hence it needs to be aligned
+    // so that they all belong to the same page for page hit
+    unsigned int columns_per_page = pageSize / blocksize;
+
+    // pick a random column, but ensure that there is room for
+    // numSeqPkts sequential columns in the same page
+    unsigned int new_col =
+        random_mt.random<unsigned int>(0, columns_per_page - numSeqPkts);
+
+    if (addrMapping == 1) {
+        // addrMapping=1: RoRaBaCoCh/RoRaBaChCo
+        // Block bits, then page bits, then bank bits, then rank bits
+        replaceBits(addr, blockBits + pageBits + bankBits - 1,
+                    blockBits + pageBits, new_bank);
+        replaceBits(addr, blockBits + pageBits - 1, blockBits, new_col);
+        if (rankBits != 0) {
+            replaceBits(addr, blockBits + pageBits + bankBits +rankBits - 1,
+                        blockBits + pageBits + bankBits, new_rank);
+        }
+    } else if (addrMapping == 0) {
+        // addrMapping=0: RoCoRaBaCh
+        // Block bits, then bank bits, then rank bits, then page bits
+        replaceBits(addr, blockBits + bankBits - 1, blockBits, new_bank);
+        replaceBits(addr, blockBits + bankBits + rankBits + pageBits - 1,
+                    blockBits + bankBits + rankBits, new_col);
+        if (rankBits != 0) {
+            replaceBits(addr, blockBits + bankBits + rankBits - 1,
+                        blockBits + bankBits, new_rank);
+        }
+    }
+}
diff --git a/src/cpu/testers/traffic_gen/dram_gen.hh b/src/cpu/testers/traffic_gen/dram_gen.hh
new file mode 100644
index 0000000..d18a14b
--- /dev/null
+++ b/src/cpu/testers/traffic_gen/dram_gen.hh
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2012-2013, 2017 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed here under.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Thomas Grass
+ *          Andreas Hansson
+ *          Sascha Bischoff
+ *          Neha Agarwal
+ */
+
+/**
+ * @file
+ * Declaration of the DRAM generator for issuing variable page
+ * hit length requests and bank utilisation.
+ */
+
+#ifndef __CPU_TRAFFIC_GEN_DRAM_GEN_HH__
+#define __CPU_TRAFFIC_GEN_DRAM_GEN_HH__
+
+#include "base/bitfield.hh"
+#include "base/intmath.hh"
+#include "mem/packet.hh"
+#include "proto/protoio.hh"
+#include "random_gen.hh"
+
+/**
+ * DRAM specific generator is for issuing request with variable page
+ * hit length and bank utilization. Currently assumes a single
+ * channel configuration.
+ */
+class DramGen : public RandomGen
+{
+
+  public:
+
+    /**
+     * Create a DRAM address sequence generator.
+     *
+     * @param _name Name to use for status and debug
+     * @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
+     * @param num_seq_pkts Number of packets per stride, each of _blocksize
+     * @param page_size Page size (bytes) used in the DRAM
+     * @param nbr_of_banks_DRAM Total number of banks in DRAM
+     * @param nbr_of_banks_util Number of banks to utilized,
+     *                          for N banks, we will use banks: 0->(N-1)
+     * @param addr_mapping Address mapping to be used,
+     *                     0: RoCoRaBaCh, 1: RoRaBaCoCh/RoRaBaChCo
+     *                     assumes single channel system
+     */
+    DramGen(const std::string& _name, 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,
+            unsigned int num_seq_pkts, unsigned int page_size,
+            unsigned int nbr_of_banks_DRAM, unsigned int nbr_of_banks_util,
+            unsigned int addr_mapping,
+            unsigned int nbr_of_ranks)
+        : RandomGen(_name, master_id, _duration, start_addr, end_addr,
+          _blocksize, min_period, max_period, read_percent, data_limit),
+          numSeqPkts(num_seq_pkts), countNumSeqPkts(0), addr(0),
+          isRead(true), pageSize(page_size),
+          pageBits(floorLog2(page_size / _blocksize)),
+          bankBits(floorLog2(nbr_of_banks_DRAM)),
+          blockBits(floorLog2(_blocksize)),
+          nbrOfBanksDRAM(nbr_of_banks_DRAM),
+          nbrOfBanksUtil(nbr_of_banks_util), addrMapping(addr_mapping),
+          rankBits(floorLog2(nbr_of_ranks)),
+          nbrOfRanks(nbr_of_ranks)
+    {
+        if (addrMapping != 1 && addrMapping != 0) {
+            addrMapping = 1;
+            warn("Unknown address mapping specified, using RoRaBaCoCh\n");
+        }
+    }
+
+    PacketPtr getNextPacket();
+
+    /** Insert bank, rank, and column bits into packed
+     *  address to create address for 1st command in a
+     *  series
+     * @param new_bank Bank number of next packet series
+     * @param new_rank Rank value of next packet series
+    */
+    void genStartAddr(unsigned int new_bank , unsigned int new_rank);
+
+  protected:
+
+    /** Number of sequential DRAM packets to be generated per cpu request */
+    const unsigned int numSeqPkts;
+
+    /** Track number of sequential packets generated for a request  */
+    unsigned int countNumSeqPkts;
+
+    /** Address of request */
+    Addr addr;
+
+    /** Remember type of requests to be generated in series */
+    bool isRead;
+
+    /** Page size of DRAM */
+    const unsigned int pageSize;
+
+    /** Number of page bits in DRAM address */
+    const unsigned int pageBits;
+
+    /** Number of bank bits in DRAM address*/
+    const unsigned int bankBits;
+
+    /** Number of block bits in DRAM address */
+    const unsigned int blockBits;
+
+    /** Number of banks in DRAM */
+    const unsigned int nbrOfBanksDRAM;
+
+    /** Number of banks to be utilized for a given configuration */
+    const unsigned int nbrOfBanksUtil;
+
+    /** Address mapping to be used */
+    unsigned int addrMapping;
+
+    /** Number of rank bits in DRAM address*/
+    const unsigned int rankBits;
+
+    /** Number of ranks to be utilized for a given configuration */
+    const unsigned int nbrOfRanks;
+
+};
+
+#endif
diff --git a/src/cpu/testers/traffic_gen/dram_rot_gen.cc b/src/cpu/testers/traffic_gen/dram_rot_gen.cc
new file mode 100644
index 0000000..8d29487
--- /dev/null
+++ b/src/cpu/testers/traffic_gen/dram_rot_gen.cc
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2012-2013, 2016-2017 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed here under.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Thomas Grass
+ *          Andreas Hansson
+ *          Sascha Bischoff
+ *          Neha Agarwal
+ */
+
+#include "cpu/testers/traffic_gen/dram_rot_gen.hh"
+
+#include <algorithm>
+
+#include "base/random.hh"
+#include "base/trace.hh"
+#include "debug/TrafficGen.hh"
+#include "proto/packet.pb.h"
+
+PacketPtr
+DramRotGen::getNextPacket()
+{
+    // if this is the first of the packets in series to be generated,
+    // start counting again
+    if (countNumSeqPkts == 0) {
+        countNumSeqPkts = numSeqPkts;
+
+        // choose if we generate a read or a write here
+        if (readPercent == 50) {
+           if ((nextSeqCount % nbrOfBanksUtil) == 0) {
+               // Change type after all banks have been rotated
+               // Otherwise, keep current value
+               isRead = !isRead;
+           }
+        } else {
+           // Set randomly based on percentage
+           isRead = readPercent != 0;
+        }
+
+        assert((readPercent == 0 && !isRead) ||
+               (readPercent == 100 && isRead) ||
+               readPercent != 100);
+
+         // Overwrite random bank value
+         // Rotate across banks
+         unsigned int new_bank = nextSeqCount % nbrOfBanksUtil;
+
+         // Overwrite random rank value
+         // Will rotate to the next rank after rotating through all banks,
+         // for each specified command type.
+
+         // Use modular function to ensure that calculated rank is within
+         // system limits after state transition
+         unsigned int new_rank = (nextSeqCount / maxSeqCountPerRank) %
+             nbrOfRanks;
+
+         // Increment nextSeqCount
+         // Roll back to 0 after completing a full rotation across
+         // banks, command type, and ranks
+         nextSeqCount = (nextSeqCount + 1) %
+             (nbrOfRanks * maxSeqCountPerRank);
+
+         DPRINTF(TrafficGen, "DramRotGen::getNextPacket nextSeqCount: %d "
+                 "new_rank: %d  new_bank: %d\n",
+                 nextSeqCount, new_rank, new_bank);
+
+        // Generate the start address of the command series
+        // routine will update addr variable with bank, rank, and col
+        // bits updated for rotation scheme
+        genStartAddr(new_bank, new_rank);
+
+    } else {
+        // increment the column by one
+        if (addrMapping == 1)
+            // addrMapping=1: RoRaBaCoCh/RoRaBaChCo
+            // Simply increment addr by blocksize to
+            // increment the column by one
+            addr += blocksize;
+
+        else if (addrMapping == 0) {
+            // addrMapping=0: RoCoRaBaCh
+            // Explicity increment the column bits
+
+                    unsigned int new_col = ((addr / blocksize /
+                                      nbrOfBanksDRAM / nbrOfRanks) %
+                                      (pageSize / blocksize)) + 1;
+            replaceBits(addr, blockBits + bankBits + rankBits + pageBits - 1,
+                        blockBits + bankBits + rankBits, new_col);
+        }
+    }
+
+    DPRINTF(TrafficGen, "DramRotGen::getNextPacket: %c to addr %x, "
+            "size %d, countNumSeqPkts: %d, numSeqPkts: %d\n",
+            isRead ? 'r' : 'w', addr, blocksize, countNumSeqPkts, numSeqPkts);
+
+    // create a new request packet
+    PacketPtr pkt = getPacket(addr, blocksize,
+                              isRead ? MemCmd::ReadReq : MemCmd::WriteReq);
+
+    // add the amount of data manipulated to the total
+    dataManipulated += blocksize;
+
+    // subtract the number of packets remained to be generated
+    --countNumSeqPkts;
+
+    // return the generated packet
+    return pkt;
+}
diff --git a/src/cpu/testers/traffic_gen/dram_rot_gen.hh b/src/cpu/testers/traffic_gen/dram_rot_gen.hh
new file mode 100644
index 0000000..e655376
--- /dev/null
+++ b/src/cpu/testers/traffic_gen/dram_rot_gen.hh
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2012-2013, 2017 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed here under.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Thomas Grass
+ *          Andreas Hansson
+ *          Sascha Bischoff
+ *          Neha Agarwal
+ */
+
+/**
+ * @file
+ * Declaration of DRAM rotation generator that rotates
+ * through each rank.
+ */
+
+#ifndef __CPU_TRAFFIC_GEN_DRAM_ROT_GEN_HH__
+#define __CPU_TRAFFIC_GEN_DRAM_ROT_GEN_HH__
+
+#include "base/bitfield.hh"
+#include "base/intmath.hh"
+#include "dram_gen.hh"
+#include "mem/packet.hh"
+#include "proto/protoio.hh"
+
+class DramRotGen : public DramGen
+{
+
+  public:
+
+    /**
+     * Create a DRAM address sequence generator.
+     * This sequence generator will rotate through:
+     * 1) Banks per rank
+     * 2) Command type (if applicable)
+     * 3) Ranks per channel
+     *
+     * @param _name Name to use for status and debug
+     * @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
+     * @param num_seq_pkts Number of packets per stride, each of _blocksize
+     * @param page_size Page size (bytes) used in the DRAM
+     * @param nbr_of_banks_DRAM Total number of banks in DRAM
+     * @param nbr_of_banks_util Number of banks to utilized,
+     *                          for N banks, we will use banks: 0->(N-1)
+     * @param nbr_of_ranks Number of ranks utilized,
+     * @param addr_mapping Address mapping to be used,
+     *                     0: RoCoRaBaCh, 1: RoRaBaCoCh/RoRaBaChCo
+     *                     assumes single channel system
+     */
+    DramRotGen(const std::string& _name, 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,
+            unsigned int num_seq_pkts, unsigned int page_size,
+            unsigned int nbr_of_banks_DRAM, unsigned int nbr_of_banks_util,
+            unsigned int addr_mapping,
+            unsigned int nbr_of_ranks,
+            unsigned int max_seq_count_per_rank)
+        : DramGen(_name, master_id, _duration, start_addr, end_addr,
+          _blocksize, min_period, max_period, read_percent, data_limit,
+          num_seq_pkts, page_size, nbr_of_banks_DRAM,
+          nbr_of_banks_util, addr_mapping,
+          nbr_of_ranks),
+          maxSeqCountPerRank(max_seq_count_per_rank),
+          nextSeqCount(0)
+    {
+        // Rotating traffic generation can only support a read
+        // percentage of 0, 50, or 100
+        if (readPercent != 50  && readPercent != 100 && readPercent != 0) {
+           fatal("%s: Unsupported read percentage for DramRotGen: %d",
+                 _name, readPercent);
+        }
+    }
+
+    PacketPtr getNextPacket();
+
+  private:
+    /** Number of command series issued before the rank is
+        changed.  Should rotate to the next rank after rorating
+        throughall the banks for each specified command type     */
+    const unsigned int maxSeqCountPerRank;
+
+    /** Next packet series count used to set rank and bank,
+        and update isRead Incremented at the start of a new
+        packet series       */
+    unsigned int nextSeqCount;
+};
+
+#endif
diff --git a/src/cpu/testers/traffic_gen/generators.cc b/src/cpu/testers/traffic_gen/generators.cc
deleted file mode 100644
index 190d0da..0000000
--- a/src/cpu/testers/traffic_gen/generators.cc
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * Copyright (c) 2012-2013, 2016 ARM Limited
- * All rights reserved
- *
- * The license below extends only to copyright in the software and shall
- * not be construed as granting a license to any other intellectual
- * property including but not limited to intellectual property relating
- * to a hardware implementation of the functionality of the software
- * licensed hereunder.  You may use the software subject to the license
- * terms below provided that you ensure that this notice is replicated
- * unmodified and in its entirety in all distributions of the software,
- * modified or unmodified, in source code or in binary form.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Authors: Thomas Grass
- *          Andreas Hansson
- *          Sascha Bischoff
- *          Neha Agarwal
- */
-
-#include <algorithm>
-
-#include "base/random.hh"
-#include "base/trace.hh"
-#include "cpu/testers/traffic_gen/generators.hh"
-#include "debug/TrafficGen.hh"
-#include "proto/packet.pb.h"
-
-BaseGen::BaseGen(const std::string& _name, MasterID master_id, Tick _duration)
-    : _name(_name), masterID(master_id), duration(_duration)
-{
-}
-
-PacketPtr
-BaseGen::getPacket(Addr addr, unsigned size, const MemCmd& cmd,
-                   Request::FlagsType flags)
-{
-    // Create new request
-    Request *req = new Request(addr, size, flags, masterID);
-    // Dummy PC to have PC-based prefetchers latch on; get entropy into higher
-    // bits
-    req->setPC(((Addr)masterID) << 2);
-
-    // Embed it in a packet
-    PacketPtr pkt = new Packet(req, cmd);
-
-    uint8_t* pkt_data = new uint8_t[req->getSize()];
-    pkt->dataDynamic(pkt_data);
-
-    if (cmd.isWrite()) {
-        std::fill_n(pkt_data, req->getSize(), (uint8_t)masterID);
-    }
-
-    return pkt;
-}
-
-void
-LinearGen::enter()
-{
-    // reset the address and the data counter
-    nextAddr = startAddr;
-    dataManipulated = 0;
-}
-
-PacketPtr
-LinearGen::getNextPacket()
-{
-    // choose if we generate a read or a write here
-    bool isRead = readPercent != 0 &&
-        (readPercent == 100 || random_mt.random(0, 100) < readPercent);
-
-    assert((readPercent == 0 && !isRead) || (readPercent == 100 && isRead) ||
-           readPercent != 100);
-
-    DPRINTF(TrafficGen, "LinearGen::getNextPacket: %c to addr %x, size %d\n",
-            isRead ? 'r' : 'w', nextAddr, blocksize);
-
-    // Add the amount of data manipulated to the total
-    dataManipulated += blocksize;
-
-    PacketPtr pkt = getPacket(nextAddr, blocksize,
-                              isRead ? MemCmd::ReadReq : MemCmd::WriteReq);
-
-    // increment the address
-    nextAddr += blocksize;
-
-    // If we have reached the end of the address space, reset the
-    // address to the start of the range
-    if (nextAddr > endAddr) {
-        DPRINTF(TrafficGen, "Wrapping address to the start of "
-                "the range\n");
-        nextAddr = startAddr;
-    }
-
-    return pkt;
-}
-
-Tick
-LinearGen::nextPacketTick(bool elastic, Tick delay) const
-{
-    // Check to see if we have reached the data limit. If dataLimit is
-    // zero we do not have a data limit and therefore we will keep
-    // generating requests for the entire residency in this state.
-    if (dataLimit && dataManipulated >= dataLimit) {
-        DPRINTF(TrafficGen, "Data limit for LinearGen reached.\n");
-        // there are no more requests, therefore return MaxTick
-        return MaxTick;
-    } else {
-        // return the time when the next request should take place
-        Tick wait = random_mt.random(minPeriod, maxPeriod);
-
-        // compensate for the delay experienced to not be elastic, by
-        // default the value we generate is from the time we are
-        // asked, so the elasticity happens automatically
-        if (!elastic) {
-            if (wait < delay)
-                wait = 0;
-            else
-                wait -= delay;
-        }
-
-        return curTick() + wait;
-    }
-}
-
-void
-RandomGen::enter()
-{
-    // reset the counter to zero
-    dataManipulated = 0;
-}
-
-PacketPtr
-RandomGen::getNextPacket()
-{
-    // choose if we generate a read or a write here
-    bool isRead = readPercent != 0 &&
-        (readPercent == 100 || random_mt.random(0, 100) < readPercent);
-
-    assert((readPercent == 0 && !isRead) || (readPercent == 100 && isRead) ||
-           readPercent != 100);
-
-    // address of the request
-    Addr addr = random_mt.random(startAddr, endAddr - 1);
-
-    // round down to start address of block
-    addr -= addr % blocksize;
-
-    DPRINTF(TrafficGen, "RandomGen::getNextPacket: %c to addr %x, size %d\n",
-            isRead ? 'r' : 'w', addr, blocksize);
-
-    // add the amount of data manipulated to the total
-    dataManipulated += blocksize;
-
-    // create a new request packet
-    return getPacket(addr, blocksize,
-                     isRead ? MemCmd::ReadReq : MemCmd::WriteReq);
-}
-
-PacketPtr
-DramGen::getNextPacket()
-{
-    // if this is the first of the packets in series to be generated,
-    // start counting again
-    if (countNumSeqPkts == 0) {
-        countNumSeqPkts = numSeqPkts;
-
-        // choose if we generate a read or a write here
-        isRead = readPercent != 0 &&
-            (readPercent == 100 || random_mt.random(0, 100) < readPercent);
-
-        assert((readPercent == 0 && !isRead) ||
-               (readPercent == 100 && isRead) ||
-               readPercent != 100);
-
-        // pick a random bank
-        unsigned int new_bank =
-            random_mt.random<unsigned int>(0, nbrOfBanksUtil - 1);
-
-        // pick a random rank
-        unsigned int new_rank =
-            random_mt.random<unsigned int>(0, nbrOfRanks - 1);
-
-        // Generate the start address of the command series
-        // routine will update addr variable with bank, rank, and col
-        // bits updated for random traffic mode
-        genStartAddr(new_bank, new_rank);
-
-    } else {
-        // increment the column by one
-        if (addrMapping == 1)
-            // addrMapping=1: RoRaBaCoCh/RoRaBaChCo
-            // Simply increment addr by blocksize to increment the column by one
-            addr += blocksize;
-
-        else if (addrMapping == 0) {
-            // addrMapping=0: RoCoRaBaCh
-            // Explicity increment the column bits
-            unsigned int new_col = ((addr / blocksize / nbrOfBanksDRAM / nbrOfRanks) %
-                                    (pageSize / blocksize)) + 1;
-            replaceBits(addr, blockBits + bankBits + rankBits + pageBits - 1,
-                        blockBits + bankBits + rankBits, new_col);
-        }
-    }
-
-    DPRINTF(TrafficGen, "DramGen::getNextPacket: %c to addr %x, "
-            "size %d, countNumSeqPkts: %d, numSeqPkts: %d\n",
-            isRead ? 'r' : 'w', addr, blocksize, countNumSeqPkts, numSeqPkts);
-
-    // create a new request packet
-    PacketPtr pkt = getPacket(addr, blocksize,
-                              isRead ? MemCmd::ReadReq : MemCmd::WriteReq);
-
-    // add the amount of data manipulated to the total
-    dataManipulated += blocksize;
-
-    // subtract the number of packets remained to be generated
-    --countNumSeqPkts;
-
-    // return the generated packet
-    return pkt;
-}
-
-PacketPtr
-DramRotGen::getNextPacket()
-{
-    // if this is the first of the packets in series to be generated,
-    // start counting again
-    if (countNumSeqPkts == 0) {
-        countNumSeqPkts = numSeqPkts;
-
-        // choose if we generate a read or a write here
-        if (readPercent == 50) {
-           if ((nextSeqCount % nbrOfBanksUtil) == 0) {
-               // Change type after all banks have been rotated
-               // Otherwise, keep current value
-               isRead = !isRead;
-           }
-        } else {
-           // Set randomly based on percentage
-           isRead = readPercent != 0;
-        }
-
-        assert((readPercent == 0 && !isRead) ||
-               (readPercent == 100 && isRead) ||
-               readPercent != 100);
-
-         // Overwrite random bank value
-         // Rotate across banks
-         unsigned int new_bank = nextSeqCount % nbrOfBanksUtil;
-
-         // Overwrite random rank value
-         // Will rotate to the next rank after rotating through all banks,
-         // for each specified command type.
-
-         // Use modular function to ensure that calculated rank is within
-         // system limits after state transition
-         unsigned int new_rank = (nextSeqCount / maxSeqCountPerRank) %
-             nbrOfRanks;
-
-         // Increment nextSeqCount
-         // Roll back to 0 after completing a full rotation across
-         // banks, command type, and ranks
-         nextSeqCount = (nextSeqCount + 1) %
-             (nbrOfRanks * maxSeqCountPerRank);
-
-         DPRINTF(TrafficGen, "DramRotGen::getNextPacket nextSeqCount: %d "
-                 "new_rank: %d  new_bank: %d\n",
-                 nextSeqCount, new_rank, new_bank);
-
-        // Generate the start address of the command series
-        // routine will update addr variable with bank, rank, and col
-        // bits updated for rotation scheme
-        genStartAddr(new_bank, new_rank);
-
-    } else {
-        // increment the column by one
-        if (addrMapping == 1)
-            // addrMapping=1: RoRaBaCoCh/RoRaBaChCo
-            // Simply increment addr by blocksize to increment the column by one
-            addr += blocksize;
-
-        else if (addrMapping == 0) {
-            // addrMapping=0: RoCoRaBaCh
-            // Explicity increment the column bits
-            unsigned int new_col = ((addr / blocksize / nbrOfBanksDRAM / nbrOfRanks) %
-                                    (pageSize / blocksize)) + 1;
-            replaceBits(addr, blockBits + bankBits + rankBits + pageBits - 1,
-                        blockBits + bankBits + rankBits, new_col);
-        }
-    }
-
-    DPRINTF(TrafficGen, "DramRotGen::getNextPacket: %c to addr %x, "
-            "size %d, countNumSeqPkts: %d, numSeqPkts: %d\n",
-            isRead ? 'r' : 'w', addr, blocksize, countNumSeqPkts, numSeqPkts);
-
-    // create a new request packet
-    PacketPtr pkt = getPacket(addr, blocksize,
-                              isRead ? MemCmd::ReadReq : MemCmd::WriteReq);
-
-    // add the amount of data manipulated to the total
-    dataManipulated += blocksize;
-
-    // subtract the number of packets remained to be generated
-    --countNumSeqPkts;
-
-    // return the generated packet
-    return pkt;
-}
-
-void
-DramGen::genStartAddr(unsigned int new_bank, unsigned int new_rank)
-{
-    // start by picking a random address in the range
-    addr = random_mt.random<Addr>(startAddr, endAddr - 1);
-
-    // round down to start address of a block, i.e. a DRAM burst
-    addr -= addr % blocksize;
-
-    // insert the bank bits at the right spot, and align the
-    // address to achieve the required hit length, this involves
-    // finding the appropriate start address such that all
-    // sequential packets target successive columns in the same
-    // page
-
-    // for example, if we have a stride size of 192B, which means
-    // for LPDDR3 where burstsize = 32B we have numSeqPkts = 6,
-    // the address generated previously can be such that these
-    // 192B cross the page boundary, hence it needs to be aligned
-    // so that they all belong to the same page for page hit
-    unsigned int columns_per_page = pageSize / blocksize;
-
-    // pick a random column, but ensure that there is room for
-    // numSeqPkts sequential columns in the same page
-    unsigned int new_col =
-        random_mt.random<unsigned int>(0, columns_per_page - numSeqPkts);
-
-    if (addrMapping == 1) {
-        // addrMapping=1: RoRaBaCoCh/RoRaBaChCo
-        // Block bits, then page bits, then bank bits, then rank bits
-        replaceBits(addr, blockBits + pageBits + bankBits - 1,
-                    blockBits + pageBits, new_bank);
-        replaceBits(addr, blockBits + pageBits - 1, blockBits, new_col);
-        if (rankBits != 0) {
-            replaceBits(addr, blockBits + pageBits + bankBits +rankBits - 1,
-                        blockBits + pageBits + bankBits, new_rank);
-        }
-    } else if (addrMapping == 0) {
-        // addrMapping=0: RoCoRaBaCh
-        // Block bits, then bank bits, then rank bits, then page bits
-        replaceBits(addr, blockBits + bankBits - 1, blockBits, new_bank);
-        replaceBits(addr, blockBits + bankBits + rankBits + pageBits - 1,
-                    blockBits + bankBits + rankBits, new_col);
-        if (rankBits != 0) {
-            replaceBits(addr, blockBits + bankBits + rankBits - 1,
-                        blockBits + bankBits, new_rank);
-        }
-    }
-}
-
-Tick
-RandomGen::nextPacketTick(bool elastic, Tick delay) const
-{
-    // Check to see if we have reached the data limit. If dataLimit is
-    // zero we do not have a data limit and therefore we will keep
-    // generating requests for the entire residency in this state.
-    if (dataLimit && dataManipulated >= dataLimit)
-    {
-        DPRINTF(TrafficGen, "Data limit for RandomGen reached.\n");
-        // No more requests. Return MaxTick.
-        return MaxTick;
-    } else {
-        // return the time when the next request should take place
-        Tick wait = random_mt.random(minPeriod, maxPeriod);
-
-        // compensate for the delay experienced to not be elastic, by
-        // default the value we generate is from the time we are
-        // asked, so the elasticity happens automatically
-        if (!elastic) {
-            if (wait < delay)
-                wait = 0;
-            else
-                wait -= delay;
-        }
-
-        return curTick() + wait;
-    }
-}
-
-TraceGen::InputStream::InputStream(const std::string& filename)
-    : trace(filename)
-{
-    init();
-}
-
-void
-TraceGen::InputStream::init()
-{
-    // Create a protobuf message for the header and read it from the stream
-    ProtoMessage::PacketHeader header_msg;
-    if (!trace.read(header_msg)) {
-        panic("Failed to read packet header from trace\n");
-    } else if (header_msg.tick_freq() != SimClock::Frequency) {
-        panic("Trace was recorded with a different tick frequency %d\n",
-              header_msg.tick_freq());
-    }
-}
-
-void
-TraceGen::InputStream::reset()
-{
-    trace.reset();
-    init();
-}
-
-bool
-TraceGen::InputStream::read(TraceElement& element)
-{
-    ProtoMessage::Packet pkt_msg;
-    if (trace.read(pkt_msg)) {
-        element.cmd = pkt_msg.cmd();
-        element.addr = pkt_msg.addr();
-        element.blocksize = pkt_msg.size();
-        element.tick = pkt_msg.tick();
-        element.flags = pkt_msg.has_flags() ? pkt_msg.flags() : 0;
-        return true;
-    }
-
-    // We have reached the end of the file
-    return false;
-}
-
-Tick
-TraceGen::nextPacketTick(bool elastic, Tick delay) const
-{
-    if (traceComplete) {
-        DPRINTF(TrafficGen, "No next tick as trace is finished\n");
-        // We are at the end of the file, thus we have no more data in
-        // the trace Return MaxTick to signal that there will be no
-        // more transactions in this active period for the state.
-        return MaxTick;
-    }
-
-    assert(nextElement.isValid());
-
-    DPRINTF(TrafficGen, "Next packet tick is %d\n", tickOffset +
-            nextElement.tick);
-
-    // if the playback is supposed to be elastic, add the delay
-    if (elastic)
-        tickOffset += delay;
-
-    return std::max(tickOffset + nextElement.tick, curTick());
-}
-
-void
-TraceGen::enter()
-{
-    // update the trace offset to the time where the state was entered.
-    tickOffset = curTick();
-
-    // clear everything
-    currElement.clear();
-
-    // read the first element in the file and set the complete flag
-    traceComplete = !trace.read(nextElement);
-}
-
-PacketPtr
-TraceGen::getNextPacket()
-{
-    // shift things one step forward
-    currElement = nextElement;
-    nextElement.clear();
-
-    // read the next element and set the complete flag
-    traceComplete = !trace.read(nextElement);
-
-    // it is the responsibility of the traceComplete flag to ensure we
-    // always have a valid element here
-    assert(currElement.isValid());
-
-    DPRINTF(TrafficGen, "TraceGen::getNextPacket: %c %d %d %d 0x%x\n",
-            currElement.cmd.isRead() ? 'r' : 'w',
-            currElement.addr,
-            currElement.blocksize,
-            currElement.tick,
-            currElement.flags);
-
-    PacketPtr pkt = getPacket(currElement.addr + addrOffset,
-                              currElement.blocksize,
-                              currElement.cmd, currElement.flags);
-
-    if (!traceComplete)
-        DPRINTF(TrafficGen, "nextElement: %c addr %d size %d tick %d (%d)\n",
-                nextElement.cmd.isRead() ? 'r' : 'w',
-                nextElement.addr,
-                nextElement.blocksize,
-                nextElement.tick + tickOffset,
-                nextElement.tick);
-
-    return pkt;
-}
-
-void
-TraceGen::exit()
-{
-    // Check if we reached the end of the trace file. If we did not
-    // then we want to generate a warning stating that not the entire
-    // trace was played.
-    if (!traceComplete) {
-        warn("Trace player %s was unable to replay the entire trace!\n",
-             name());
-    }
-
-    // Clear any flags and start over again from the beginning of the
-    // file
-    trace.reset();
-}
diff --git a/src/cpu/testers/traffic_gen/generators.hh b/src/cpu/testers/traffic_gen/generators.hh
deleted file mode 100644
index 5604856..0000000
--- a/src/cpu/testers/traffic_gen/generators.hh
+++ /dev/null
@@ -1,647 +0,0 @@
-/*
- * Copyright (c) 2012-2013 ARM Limited
- * All rights reserved
- *
- * The license below extends only to copyright in the software and shall
- * not be construed as granting a license to any other intellectual
- * property including but not limited to intellectual property relating
- * to a hardware implementation of the functionality of the software
- * licensed hereunder.  You may use the software subject to the license
- * terms below provided that you ensure that this notice is replicated
- * unmodified and in its entirety in all distributions of the software,
- * modified or unmodified, in source code or in binary form.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Authors: Thomas Grass
- *          Andreas Hansson
- *          Sascha Bischoff
- *          Neha Agarwal
- */
-
-/**
- * @file
- * Declaration of a set of generator behaviours that are used by the
- * stand-alone traffic generator, but can also be instantiated
- * elsewhere.
- */
-
-#ifndef __CPU_TRAFFIC_GEN_GENERATORS_HH__
-#define __CPU_TRAFFIC_GEN_GENERATORS_HH__
-
-#include "base/bitfield.hh"
-#include "base/intmath.hh"
-#include "mem/packet.hh"
-#include "proto/protoio.hh"
-
-/**
- * Base class for all generators, with the shared functionality and
- * virtual functions for entering, executing and leaving the
- * generator.
- */
-class BaseGen
-{
-
-  protected:
-
-    /** Name to use for status and debug printing */
-    const std::string _name;
-
-    /** The MasterID used for generating requests */
-    const MasterID masterID;
-
-    /**
-     * Generate a new request and associated packet
-     *
-     * @param addr Physical address to use
-     * @param size Size of the request
-     * @param cmd Memory command to send
-     * @param flags Optional request flags
-     */
-    PacketPtr getPacket(Addr addr, unsigned size, const MemCmd& cmd,
-                        Request::FlagsType flags = 0);
-
-  public:
-
-    /** Time to spend in this state */
-    const Tick duration;
-
-    /**
-     * Create a base generator.
-     *
-     * @param _name Name to use for status and debug
-     * @param master_id MasterID set on each request
-     * @param _duration duration of this state before transitioning
-     */
-    BaseGen(const std::string& _name, MasterID master_id, Tick _duration);
-
-    virtual ~BaseGen() { }
-
-    /**
-     * Get the name, useful for DPRINTFs.
-     *
-     * @return the given name
-     */
-    std::string name() const { return _name; }
-
-    /**
-     * Enter this generator state.
-     */
-    virtual void enter() = 0;
-
-    /**
-     * Get the next generated packet.
-     *
-     * @return A packet to be sent at the current tick
-     */
-    virtual PacketPtr getNextPacket() = 0;
-
-    /**
-     * Exit this generator state. By default do nothing.
-     */
-    virtual void exit() { };
-
-    /**
-     * Determine the tick when the next packet is available. MaxTick
-     * means that there will not be any further packets in the current
-     * activation cycle of the generator.
-     *
-     * @param elastic should the injection respond to flow control or not
-     * @param delay time the previous packet spent waiting
-     * @return next tick when a packet is available
-     */
-    virtual Tick nextPacketTick(bool elastic, Tick delay) const = 0;
-
-};
-
-/**
- * The idle generator does nothing.
- */
-class IdleGen : public BaseGen
-{
-
-  public:
-
-    IdleGen(const std::string& _name, MasterID master_id, Tick _duration)
-        : BaseGen(_name, master_id, _duration)
-    { }
-
-    void enter() { }
-
-    PacketPtr getNextPacket() { return NULL; }
-
-    Tick nextPacketTick(bool elastic, Tick delay) const { 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 _name Name to use for status and debug
-     * @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(const std::string& _name, 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(_name, master_id, _duration),
-          startAddr(start_addr), endAddr(end_addr),
-          blocksize(_blocksize), minPeriod(min_period),
-          maxPeriod(max_period), readPercent(read_percent),
-          dataLimit(data_limit), nextAddr(startAddr), dataManipulated(0)
-    { }
-
-    void enter();
-
-    PacketPtr getNextPacket();
-
-    Tick nextPacketTick(bool elastic, Tick delay) const;
-
-  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 _name Name to use for status and debug
-     * @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(const std::string& _name, 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(_name, master_id, _duration),
-          startAddr(start_addr), endAddr(end_addr),
-          blocksize(_blocksize), minPeriod(min_period),
-          maxPeriod(max_period), readPercent(read_percent),
-          dataLimit(data_limit), dataManipulated(0)
-    { }
-
-    void enter();
-
-    PacketPtr getNextPacket();
-
-    Tick nextPacketTick(bool elastic, Tick delay) const;
-
-  protected:
-
-    /** 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;
-};
-
-/**
- * DRAM specific generator is for issuing request with variable page
- * hit length and bank utilization. Currently assumes a single
- * channel configuration.
- */
-class DramGen : public RandomGen
-{
-
-  public:
-
-    /**
-     * Create a DRAM address sequence generator.
-     *
-     * @param _name Name to use for status and debug
-     * @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
-     * @param num_seq_pkts Number of packets per stride, each of _blocksize
-     * @param page_size Page size (bytes) used in the DRAM
-     * @param nbr_of_banks_DRAM Total number of banks in DRAM
-     * @param nbr_of_banks_util Number of banks to utilized,
-     *                          for N banks, we will use banks: 0->(N-1)
-     * @param addr_mapping Address mapping to be used,
-     *                     0: RoCoRaBaCh, 1: RoRaBaCoCh/RoRaBaChCo
-     *                     assumes single channel system
-     */
-    DramGen(const std::string& _name, 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,
-            unsigned int num_seq_pkts, unsigned int page_size,
-            unsigned int nbr_of_banks_DRAM, unsigned int nbr_of_banks_util,
-            unsigned int addr_mapping,
-            unsigned int nbr_of_ranks)
-        : RandomGen(_name, master_id, _duration, start_addr, end_addr,
-          _blocksize, min_period, max_period, read_percent, data_limit),
-          numSeqPkts(num_seq_pkts), countNumSeqPkts(0), addr(0),
-          isRead(true), pageSize(page_size),
-          pageBits(floorLog2(page_size / _blocksize)),
-          bankBits(floorLog2(nbr_of_banks_DRAM)),
-          blockBits(floorLog2(_blocksize)),
-          nbrOfBanksDRAM(nbr_of_banks_DRAM),
-          nbrOfBanksUtil(nbr_of_banks_util), addrMapping(addr_mapping),
-          rankBits(floorLog2(nbr_of_ranks)),
-          nbrOfRanks(nbr_of_ranks)
-    {
-        if (addrMapping != 1 && addrMapping != 0) {
-            addrMapping = 1;
-            warn("Unknown address mapping specified, using RoRaBaCoCh\n");
-        }
-    }
-
-    PacketPtr getNextPacket();
-
-    /** Insert bank, rank, and column bits into packed
-     *  address to create address for 1st command in a
-     *  series
-     * @param new_bank Bank number of next packet series
-     * @param new_rank Rank value of next packet series
-    */
-    void genStartAddr(unsigned int new_bank , unsigned int new_rank);
-
-  protected:
-
-    /** Number of sequential DRAM packets to be generated per cpu request */
-    const unsigned int numSeqPkts;
-
-    /** Track number of sequential packets generated for a request  */
-    unsigned int countNumSeqPkts;
-
-    /** Address of request */
-    Addr addr;
-
-    /** Remember type of requests to be generated in series */
-    bool isRead;
-
-    /** Page size of DRAM */
-    const unsigned int pageSize;
-
-    /** Number of page bits in DRAM address */
-    const unsigned int pageBits;
-
-    /** Number of bank bits in DRAM address*/
-    const unsigned int bankBits;
-
-    /** Number of block bits in DRAM address */
-    const unsigned int blockBits;
-
-    /** Number of banks in DRAM */
-    const unsigned int nbrOfBanksDRAM;
-
-    /** Number of banks to be utilized for a given configuration */
-    const unsigned int nbrOfBanksUtil;
-
-    /** Address mapping to be used */
-    unsigned int addrMapping;
-
-    /** Number of rank bits in DRAM address*/
-    const unsigned int rankBits;
-
-    /** Number of ranks to be utilized for a given configuration */
-    const unsigned int nbrOfRanks;
-
-};
-
-class DramRotGen : public DramGen
-{
-
-  public:
-
-    /**
-     * Create a DRAM address sequence generator.
-     * This sequence generator will rotate through:
-     * 1) Banks per rank
-     * 2) Command type (if applicable)
-     * 3) Ranks per channel
-     *
-     * @param _name Name to use for status and debug
-     * @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
-     * @param num_seq_pkts Number of packets per stride, each of _blocksize
-     * @param page_size Page size (bytes) used in the DRAM
-     * @param nbr_of_banks_DRAM Total number of banks in DRAM
-     * @param nbr_of_banks_util Number of banks to utilized,
-     *                          for N banks, we will use banks: 0->(N-1)
-     * @param nbr_of_ranks Number of ranks utilized,
-     * @param addr_mapping Address mapping to be used,
-     *                     0: RoCoRaBaCh, 1: RoRaBaCoCh/RoRaBaChCo
-     *                     assumes single channel system
-     */
-    DramRotGen(const std::string& _name, 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,
-            unsigned int num_seq_pkts, unsigned int page_size,
-            unsigned int nbr_of_banks_DRAM, unsigned int nbr_of_banks_util,
-            unsigned int addr_mapping,
-            unsigned int nbr_of_ranks,
-            unsigned int max_seq_count_per_rank)
-        : DramGen(_name, master_id, _duration, start_addr, end_addr,
-          _blocksize, min_period, max_period, read_percent, data_limit,
-          num_seq_pkts, page_size, nbr_of_banks_DRAM,
-          nbr_of_banks_util, addr_mapping,
-          nbr_of_ranks),
-          maxSeqCountPerRank(max_seq_count_per_rank),
-          nextSeqCount(0)
-    {
-        // Rotating traffic generation can only support a read
-        // percentage of 0, 50, or 100
-        if (readPercent != 50  && readPercent != 100 && readPercent != 0) {
-           fatal("%s: Unsupported read percentage for DramRotGen: %d",
-                 _name, readPercent);
-        }
-    }
-
-    PacketPtr getNextPacket();
-
-  private:
-    /** Number of command series issued before the rank is
-        changed.  Should rotate to the next rank after rorating
-        throughall the banks for each specified command type     */
-    const unsigned int maxSeqCountPerRank;
-
-    /** Next packet series count used to set rank and bank,
-        and update isRead Incremented at the start of a new
-        packet series       */
-    unsigned int nextSeqCount;
-};
-
-/**
- * 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;
-
-        /** Potential request flags to use */
-        Request::FlagsType flags;
-
-        /**
-         * 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();
-
-        /**
-         * Check the trace header to make sure that it is of the right
-         * format.
-         */
-        void init();
-
-        /**
-         * 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 _name Name to use for status and debug
-     * @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(const std::string& _name, MasterID master_id, Tick _duration,
-             const std::string& trace_file, Addr addr_offset)
-        : BaseGen(_name, master_id, _duration),
-          trace(trace_file),
-          tickOffset(0),
-          addrOffset(addr_offset),
-          traceComplete(false)
-    {
-    }
-
-    void enter();
-
-    PacketPtr getNextPacket();
-
-    void exit();
-
-    /**
-     * Returns the 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 nextPacketTick(bool elastic, Tick delay) const;
-
-  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. This is mutable
-     * to allow us to change it as part of nextPacketTick.
-     */
-    mutable 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;
-};
-
-#endif
diff --git a/src/cpu/testers/traffic_gen/idle_gen.cc b/src/cpu/testers/traffic_gen/idle_gen.cc
new file mode 100644
index 0000000..9c2ce7f
--- /dev/null
+++ b/src/cpu/testers/traffic_gen/idle_gen.cc
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012-2013, 2016-2017 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed here under.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Thomas Grass
+ *          Andreas Hansson
+ *          Sascha Bischoff
+ *          Neha Agarwal
+ */
+
+#include "cpu/testers/traffic_gen/idle_gen.hh"
+
+#include <algorithm>
+
+#include "base/random.hh"
+#include "base/trace.hh"
+#include "debug/TrafficGen.hh"
+#include "proto/packet.pb.h"
+
+void
+IdleGen::enter() { }
+
+PacketPtr
+IdleGen::getNextPacket()
+{
+        return NULL;
+}
+
+Tick
+IdleGen::nextPacketTick(bool elastic, Tick delay) const
+{
+        return MaxTick;
+}
+
diff --git a/src/cpu/testers/traffic_gen/idle_gen.hh b/src/cpu/testers/traffic_gen/idle_gen.hh
new file mode 100644
index 0000000..d503abe
--- /dev/null
+++ b/src/cpu/testers/traffic_gen/idle_gen.hh
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012-2013, 2017 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed here under.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Thomas Grass
+ *          Andreas Hansson
+ *          Sascha Bischoff
+ *          Neha Agarwal
+ */
+
+/**
+ * @file
+ * Declaration of the idle generator that does nothing.
+ */
+
+#ifndef __CPU_TRAFFIC_GEN_IDLE_GEN_HH__
+#define __CPU_TRAFFIC_GEN_IDLE_GEN_HH__
+
+#include "base/bitfield.hh"
+#include "base/intmath.hh"
+#include "base_gen.hh"
+#include "mem/packet.hh"
+#include "proto/protoio.hh"
+
+/**
+ * The idle generator does nothing.
+ */
+class IdleGen : public BaseGen
+{
+
+  public:
+
+    IdleGen(const std::string& _name, MasterID master_id, Tick _duration)
+        : BaseGen(_name, master_id, _duration)
+    { }
+
+    void enter();
+
+    PacketPtr getNextPacket();
+
+    Tick nextPacketTick(bool elastic, Tick delay) const ;
+};
+
+#endif
diff --git a/src/cpu/testers/traffic_gen/linear_gen.cc b/src/cpu/testers/traffic_gen/linear_gen.cc
new file mode 100644
index 0000000..412c6a3
--- /dev/null
+++ b/src/cpu/testers/traffic_gen/linear_gen.cc
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2012-2013, 2016-2017 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed here under.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Thomas Grass
+ *          Andreas Hansson
+ *          Sascha Bischoff
+ *          Neha Agarwal
+ */
+
+#include "cpu/testers/traffic_gen/linear_gen.hh"
+
+#include <algorithm>
+
+#include "base/random.hh"
+#include "base/trace.hh"
+#include "debug/TrafficGen.hh"
+#include "proto/packet.pb.h"
+
+void
+LinearGen::enter()
+{
+    // reset the address and the data counter
+    nextAddr = startAddr;
+    dataManipulated = 0;
+}
+
+PacketPtr
+LinearGen::getNextPacket()
+{
+    // choose if we generate a read or a write here
+    bool isRead = readPercent != 0 &&
+        (readPercent == 100 || random_mt.random(0, 100) < readPercent);
+
+    assert((readPercent == 0 && !isRead) || (readPercent == 100 && isRead) ||
+           readPercent != 100);
+
+    DPRINTF(TrafficGen, "LinearGen::getNextPacket: %c to addr %x, size %d\n",
+            isRead ? 'r' : 'w', nextAddr, blocksize);
+
+    // Add the amount of data manipulated to the total
+    dataManipulated += blocksize;
+
+    PacketPtr pkt = getPacket(nextAddr, blocksize,
+                              isRead ? MemCmd::ReadReq : MemCmd::WriteReq);
+
+    // increment the address
+    nextAddr += blocksize;
+
+    // If we have reached the end of the address space, reset the
+    // address to the start of the range
+    if (nextAddr > endAddr) {
+        DPRINTF(TrafficGen, "Wrapping address to the start of "
+                "the range\n");
+        nextAddr = startAddr;
+    }
+
+    return pkt;
+}
+
+Tick
+LinearGen::nextPacketTick(bool elastic, Tick delay) const
+{
+    // Check to see if we have reached the data limit. If dataLimit is
+    // zero we do not have a data limit and therefore we will keep
+    // generating requests for the entire residency in this state.
+    if (dataLimit && dataManipulated >= dataLimit) {
+        DPRINTF(TrafficGen, "Data limit for LinearGen reached.\n");
+        // there are no more requests, therefore return MaxTick
+        return MaxTick;
+    } else {
+        // return the time when the next request should take place
+        Tick wait = random_mt.random(minPeriod, maxPeriod);
+
+        // compensate for the delay experienced to not be elastic, by
+        // default the value we generate is from the time we are
+        // asked, so the elasticity happens automatically
+        if (!elastic) {
+            if (wait < delay)
+                wait = 0;
+            else
+                wait -= delay;
+        }
+
+        return curTick() + wait;
+    }
+}
diff --git a/src/cpu/testers/traffic_gen/linear_gen.hh b/src/cpu/testers/traffic_gen/linear_gen.hh
new file mode 100644
index 0000000..18a1eb5
--- /dev/null
+++ b/src/cpu/testers/traffic_gen/linear_gen.hh
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2012-2013, 2017 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed here under.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Thomas Grass
+ *          Andreas Hansson
+ *          Sascha Bischoff
+ *          Neha Agarwal
+ */
+
+/**
+ * @file
+ * Declaration of the linear generator that generates sequential
+ * requests.
+ */
+
+#ifndef __CPU_TRAFFIC_GEN_LINEAR_GEN_HH__
+#define __CPU_TRAFFIC_GEN_LINEAR_GEN_HH__
+
+#include "base/bitfield.hh"
+#include "base/intmath.hh"
+#include "base_gen.hh"
+#include "mem/packet.hh"
+#include "proto/protoio.hh"
+
+/**
+ * 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 _name Name to use for status and debug
+     * @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(const std::string& _name, 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(_name, master_id, _duration),
+          startAddr(start_addr), endAddr(end_addr),
+          blocksize(_blocksize), minPeriod(min_period),
+          maxPeriod(max_period), readPercent(read_percent),
+          dataLimit(data_limit), nextAddr(startAddr), dataManipulated(0)
+    { }
+
+    void enter();
+
+    PacketPtr getNextPacket();
+
+    Tick nextPacketTick(bool elastic, Tick delay) const;
+
+  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;
+};
+
+#endif
diff --git a/src/cpu/testers/traffic_gen/random_gen.cc b/src/cpu/testers/traffic_gen/random_gen.cc
new file mode 100644
index 0000000..bc24175
--- /dev/null
+++ b/src/cpu/testers/traffic_gen/random_gen.cc
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2012-2013, 2016-2017 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed here under.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Thomas Grass
+ *          Andreas Hansson
+ *          Sascha Bischoff
+ *          Neha Agarwal
+ */
+
+#include "cpu/testers/traffic_gen/random_gen.hh"
+
+#include <algorithm>
+
+#include "base/random.hh"
+#include "base/trace.hh"
+#include "debug/TrafficGen.hh"
+#include "proto/packet.pb.h"
+
+void
+RandomGen::enter()
+{
+    // reset the counter to zero
+    dataManipulated = 0;
+}
+
+PacketPtr
+RandomGen::getNextPacket()
+{
+    // choose if we generate a read or a write here
+    bool isRead = readPercent != 0 &&
+        (readPercent == 100 || random_mt.random(0, 100) < readPercent);
+
+    assert((readPercent == 0 && !isRead) || (readPercent == 100 && isRead) ||
+           readPercent != 100);
+
+    // address of the request
+    Addr addr = random_mt.random(startAddr, endAddr - 1);
+
+    // round down to start address of block
+    addr -= addr % blocksize;
+
+    DPRINTF(TrafficGen, "RandomGen::getNextPacket: %c to addr %x, size %d\n",
+            isRead ? 'r' : 'w', addr, blocksize);
+
+    // add the amount of data manipulated to the total
+    dataManipulated += blocksize;
+
+    // create a new request packet
+    return getPacket(addr, blocksize,
+                     isRead ? MemCmd::ReadReq : MemCmd::WriteReq);
+}
+
+Tick
+RandomGen::nextPacketTick(bool elastic, Tick delay) const
+{
+    // Check to see if we have reached the data limit. If dataLimit is
+    // zero we do not have a data limit and therefore we will keep
+    // generating requests for the entire residency in this state.
+    if (dataLimit && dataManipulated >= dataLimit)
+    {
+        DPRINTF(TrafficGen, "Data limit for RandomGen reached.\n");
+        // No more requests. Return MaxTick.
+        return MaxTick;
+    } else {
+        // return the time when the next request should take place
+        Tick wait = random_mt.random(minPeriod, maxPeriod);
+
+        // compensate for the delay experienced to not be elastic, by
+        // default the value we generate is from the time we are
+        // asked, so the elasticity happens automatically
+        if (!elastic) {
+            if (wait < delay)
+                wait = 0;
+            else
+                wait -= delay;
+        }
+
+        return curTick() + wait;
+    }
+}
diff --git a/src/cpu/testers/traffic_gen/random_gen.hh b/src/cpu/testers/traffic_gen/random_gen.hh
new file mode 100644
index 0000000..598abf7
--- /dev/null
+++ b/src/cpu/testers/traffic_gen/random_gen.hh
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2012-2013, 2017 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed here under.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Thomas Grass
+ *          Andreas Hansson
+ *          Sascha Bischoff
+ *          Neha Agarwal
+ */
+
+/**
+ * @file
+ * Declaration of the random generator that randomly selects
+ * addresses within a range.
+ */
+
+#ifndef __CPU_TRAFFIC_GEN_RANDOM_GEN_HH__
+#define __CPU_TRAFFIC_GEN_RANDOM_GEN_HH__
+
+#include "base/bitfield.hh"
+#include "base/intmath.hh"
+#include "base_gen.hh"
+#include "mem/packet.hh"
+#include "proto/protoio.hh"
+
+/**
+ * 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 _name Name to use for status and debug
+     * @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(const std::string& _name, 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(_name, master_id, _duration),
+          startAddr(start_addr), endAddr(end_addr),
+          blocksize(_blocksize), minPeriod(min_period),
+          maxPeriod(max_period), readPercent(read_percent),
+          dataLimit(data_limit), dataManipulated(0)
+    { }
+
+    void enter();
+
+    PacketPtr getNextPacket();
+
+    Tick nextPacketTick(bool elastic, Tick delay) const;
+
+  protected:
+
+    /** 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;
+};
+
+#endif
diff --git a/src/cpu/testers/traffic_gen/trace_gen.cc b/src/cpu/testers/traffic_gen/trace_gen.cc
new file mode 100644
index 0000000..c2555ea
--- /dev/null
+++ b/src/cpu/testers/traffic_gen/trace_gen.cc
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2012-2013, 2016-2017 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed here under.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Thomas Grass
+ *          Andreas Hansson
+ *          Sascha Bischoff
+ *          Neha Agarwal
+ */
+
+#include "cpu/testers/traffic_gen/trace_gen.hh"
+
+#include <algorithm>
+
+#include "base/random.hh"
+#include "base/trace.hh"
+#include "debug/TrafficGen.hh"
+#include "proto/packet.pb.h"
+
+TraceGen::InputStream::InputStream(const std::string& filename)
+    : trace(filename)
+{
+    init();
+}
+
+void
+TraceGen::InputStream::init()
+{
+    // Create a protobuf message for the header and read it from the stream
+    ProtoMessage::PacketHeader header_msg;
+    if (!trace.read(header_msg)) {
+        panic("Failed to read packet header from trace\n");
+    } else if (header_msg.tick_freq() != SimClock::Frequency) {
+        panic("Trace was recorded with a different tick frequency %d\n",
+              header_msg.tick_freq());
+    }
+}
+
+void
+TraceGen::InputStream::reset()
+{
+    trace.reset();
+    init();
+}
+
+bool
+TraceGen::InputStream::read(TraceElement& element)
+{
+    ProtoMessage::Packet pkt_msg;
+    if (trace.read(pkt_msg)) {
+        element.cmd = pkt_msg.cmd();
+        element.addr = pkt_msg.addr();
+        element.blocksize = pkt_msg.size();
+        element.tick = pkt_msg.tick();
+        element.flags = pkt_msg.has_flags() ? pkt_msg.flags() : 0;
+        return true;
+    }
+
+    // We have reached the end of the file
+    return false;
+}
+
+Tick
+TraceGen::nextPacketTick(bool elastic, Tick delay) const
+{
+    if (traceComplete) {
+        DPRINTF(TrafficGen, "No next tick as trace is finished\n");
+        // We are at the end of the file, thus we have no more data in
+        // the trace Return MaxTick to signal that there will be no
+        // more transactions in this active period for the state.
+        return MaxTick;
+    }
+
+    assert(nextElement.isValid());
+
+    DPRINTF(TrafficGen, "Next packet tick is %d\n", tickOffset +
+            nextElement.tick);
+
+    // if the playback is supposed to be elastic, add the delay
+    if (elastic)
+        tickOffset += delay;
+
+    return std::max(tickOffset + nextElement.tick, curTick());
+}
+
+void
+TraceGen::enter()
+{
+    // update the trace offset to the time where the state was entered.
+    tickOffset = curTick();
+
+    // clear everything
+    currElement.clear();
+
+    // read the first element in the file and set the complete flag
+    traceComplete = !trace.read(nextElement);
+}
+
+PacketPtr
+TraceGen::getNextPacket()
+{
+    // shift things one step forward
+    currElement = nextElement;
+    nextElement.clear();
+
+    // read the next element and set the complete flag
+    traceComplete = !trace.read(nextElement);
+
+    // it is the responsibility of the traceComplete flag to ensure we
+    // always have a valid element here
+    assert(currElement.isValid());
+
+    DPRINTF(TrafficGen, "TraceGen::getNextPacket: %c %d %d %d 0x%x\n",
+            currElement.cmd.isRead() ? 'r' : 'w',
+            currElement.addr,
+            currElement.blocksize,
+            currElement.tick,
+            currElement.flags);
+
+    PacketPtr pkt = getPacket(currElement.addr + addrOffset,
+                              currElement.blocksize,
+                              currElement.cmd, currElement.flags);
+
+    if (!traceComplete)
+        DPRINTF(TrafficGen, "nextElement: %c addr %d size %d tick %d (%d)\n",
+                nextElement.cmd.isRead() ? 'r' : 'w',
+                nextElement.addr,
+                nextElement.blocksize,
+                nextElement.tick + tickOffset,
+                nextElement.tick);
+
+    return pkt;
+}
+
+void
+TraceGen::exit()
+{
+    // Check if we reached the end of the trace file. If we did not
+    // then we want to generate a warning stating that not the entire
+    // trace was played.
+    if (!traceComplete) {
+        warn("Trace player %s was unable to replay the entire trace!\n",
+             name());
+    }
+
+    // Clear any flags and start over again from the beginning of the
+    // file
+    trace.reset();
+}
diff --git a/src/cpu/testers/traffic_gen/trace_gen.hh b/src/cpu/testers/traffic_gen/trace_gen.hh
new file mode 100644
index 0000000..cf4d4dd
--- /dev/null
+++ b/src/cpu/testers/traffic_gen/trace_gen.hh
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2012-2013, 2017 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed here under.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Thomas Grass
+ *          Andreas Hansson
+ *          Sascha Bischoff
+ *          Neha Agarwal
+ */
+
+/**
+ * @file
+ * Declaration of the trace generator that reads a trace file
+ * and plays the transactions.
+ */
+
+#ifndef __CPU_TRAFFIC_GEN_TRACE_GEN_HH__
+#define __CPU_TRAFFIC_GEN_TRACE_GEN_HH__
+
+#include "base/bitfield.hh"
+#include "base/intmath.hh"
+#include "base_gen.hh"
+#include "mem/packet.hh"
+#include "proto/protoio.hh"
+
+/**
+ * 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;
+
+        /** Potential request flags to use */
+        Request::FlagsType flags;
+
+        /**
+         * 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();
+
+        /**
+         * Check the trace header to make sure that it is of the right
+         * format.
+         */
+        void init();
+
+        /**
+         * 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 _name Name to use for status and debug
+     * @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(const std::string& _name, MasterID master_id, Tick _duration,
+             const std::string& trace_file, Addr addr_offset)
+        : BaseGen(_name, master_id, _duration),
+          trace(trace_file),
+          tickOffset(0),
+          addrOffset(addr_offset),
+          traceComplete(false)
+    {
+    }
+
+    void enter();
+
+    PacketPtr getNextPacket();
+
+    void exit();
+
+    /**
+     * Returns the 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 nextPacketTick(bool elastic, Tick delay) const;
+
+  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. This is mutable
+     * to allow us to change it as part of nextPacketTick.
+     */
+    mutable 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;
+};
+
+#endif
diff --git a/src/cpu/testers/traffic_gen/traffic_gen.hh b/src/cpu/testers/traffic_gen/traffic_gen.hh
index b2039be..e78b82e 100644
--- a/src/cpu/testers/traffic_gen/traffic_gen.hh
+++ b/src/cpu/testers/traffic_gen/traffic_gen.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013, 2016 ARM Limited
+ * Copyright (c) 2012-2013, 2016-2017 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -38,13 +38,20 @@
  *          Andreas Hansson
  *          Sascha Bischoff
  */
+
 #ifndef __CPU_TRAFFIC_GEN_TRAFFIC_GEN_HH__
 #define __CPU_TRAFFIC_GEN_TRAFFIC_GEN_HH__
 
 #include <unordered_map>
 
 #include "base/statistics.hh"
-#include "cpu/testers/traffic_gen/generators.hh"
+#include "cpu/testers/traffic_gen/base_gen.hh"
+#include "cpu/testers/traffic_gen/dram_gen.hh"
+#include "cpu/testers/traffic_gen/dram_rot_gen.hh"
+#include "cpu/testers/traffic_gen/idle_gen.hh"
+#include "cpu/testers/traffic_gen/linear_gen.hh"
+#include "cpu/testers/traffic_gen/random_gen.hh"
+#include "cpu/testers/traffic_gen/trace_gen.hh"
 #include "mem/mem_object.hh"
 #include "mem/qport.hh"
 #include "params/TrafficGen.hh"