# -*- 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
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')
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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
+++ /dev/null
-/*
- * 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();
-}
+++ /dev/null
-/*
- * 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
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+/*
+ * 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
/*
- * 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
* 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"