summaryrefslogtreecommitdiff
path: root/src/cpu/testers
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/testers')
-rw-r--r--src/cpu/testers/traffic_gen/generators.cc89
-rw-r--r--src/cpu/testers/traffic_gen/generators.hh98
-rw-r--r--src/cpu/testers/traffic_gen/traffic_gen.cc54
3 files changed, 238 insertions, 3 deletions
diff --git a/src/cpu/testers/traffic_gen/generators.cc b/src/cpu/testers/traffic_gen/generators.cc
index 9d0c7e02c..f0c126a81 100644
--- a/src/cpu/testers/traffic_gen/generators.cc
+++ b/src/cpu/testers/traffic_gen/generators.cc
@@ -37,6 +37,7 @@
* Authors: Thomas Grass
* Andreas Hansson
* Sascha Bischoff
+ * Neha Agarwal
*/
#include "base/random.hh"
@@ -173,6 +174,94 @@ RandomGen::getNextPacket()
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<uint8_t>(0, 100) < readPercent);
+
+ assert((readPercent == 0 && !isRead) ||
+ (readPercent == 100 && isRead) ||
+ readPercent != 100);
+
+ // 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;
+
+ // pick a random bank
+ unsigned int new_bank =
+ random_mt.random<unsigned int>(0, nbrOfBanksUtil - 1);
+
+ // next, inser 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) {
+ // assuming block bits, then page bits, then bank bits
+ replaceBits(addr, blockBits + pageBits + bankBits - 1,
+ blockBits + pageBits, new_bank);
+ replaceBits(addr, blockBits + pageBits - 1, blockBits, new_col);
+ } else if (addrMapping == 0) {
+ // assuming bank bits in the bottom
+ replaceBits(addr, blockBits + bankBits - 1, blockBits, new_bank);
+ replaceBits(addr, blockBits + bankBits + pageBits - 1,
+ blockBits + bankBits, new_col);
+ }
+ } else {
+ // increment the column by one
+ if (addrMapping == 1)
+ // column bits in the bottom, so just add a block
+ addr += blocksize;
+ else if (addrMapping == 0) {
+ // column bits are above the bank bits, so increment the column bits
+ unsigned int new_col = ((addr / blocksize / nbrOfBanksDRAM) %
+ (pageSize / blocksize)) + 1;
+ replaceBits(addr, blockBits + bankBits + pageBits - 1,
+ blockBits + bankBits, 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;
+}
+
Tick
RandomGen::nextPacketTick(bool elastic, Tick delay) const
{
diff --git a/src/cpu/testers/traffic_gen/generators.hh b/src/cpu/testers/traffic_gen/generators.hh
index fe5c5995c..498ef8f37 100644
--- a/src/cpu/testers/traffic_gen/generators.hh
+++ b/src/cpu/testers/traffic_gen/generators.hh
@@ -37,6 +37,7 @@
* Authors: Thomas Grass
* Andreas Hansson
* Sascha Bischoff
+ * Neha Agarwal
*/
/**
@@ -49,6 +50,8 @@
#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"
@@ -273,7 +276,7 @@ class RandomGen : public BaseGen
Tick nextPacketTick(bool elastic, Tick delay) const;
- private:
+ protected:
/** Start of address range */
const Addr startAddr;
@@ -305,6 +308,99 @@ class RandomGen : public BaseGen
};
/**
+ * DRAM specific generator is for issuing request with variable page
+ * hit length and bank utilization. Currently assumes a single
+ * channel, single rank 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 and single rank 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)
+ : RandomGen(_name, master_id, _duration, start_addr, end_addr,
+ _blocksize, min_period, max_period, read_percent, data_limit),
+ numSeqPkts(num_seq_pkts), countNumSeqPkts(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)
+ {
+ if (addrMapping != 1 && addrMapping != 0) {
+ addrMapping = 1;
+ warn("Unknown address mapping specified, using RoRaBaCoCh\n");
+ }
+ }
+
+ PacketPtr getNextPacket();
+
+ private:
+
+ /** 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;
+};
+
+/**
* 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.
diff --git a/src/cpu/testers/traffic_gen/traffic_gen.cc b/src/cpu/testers/traffic_gen/traffic_gen.cc
index 4b2259bd9..d53c9b000 100644
--- a/src/cpu/testers/traffic_gen/traffic_gen.cc
+++ b/src/cpu/testers/traffic_gen/traffic_gen.cc
@@ -41,6 +41,7 @@
#include <sstream>
+#include "base/intmath.hh"
#include "base/random.hh"
#include "cpu/testers/traffic_gen/traffic_gen.hh"
#include "debug/Checkpoint.hh"
@@ -257,7 +258,8 @@ TrafficGen::parseConfig()
} else if (mode == "IDLE") {
states[id] = new IdleGen(name(), masterID, duration);
DPRINTF(TrafficGen, "State: %d IdleGen\n", id);
- } else if (mode == "LINEAR" || mode == "RANDOM") {
+ } else if (mode == "LINEAR" || mode == "RANDOM" ||
+ mode == "DRAM") {
uint32_t read_percent;
Addr start_addr;
Addr end_addr;
@@ -277,7 +279,7 @@ TrafficGen::parseConfig()
if (blocksize > system->cacheLineSize())
fatal("TrafficGen %s block size (%d) is larger than "
- "system block size (%d)\n", name(),
+ "cache line size (%d)\n", name(),
blocksize, system->cacheLineSize());
if (read_percent > 100)
@@ -300,6 +302,54 @@ TrafficGen::parseConfig()
min_period, max_period,
read_percent, data_limit);
DPRINTF(TrafficGen, "State: %d RandomGen\n", id);
+ } else if (mode == "DRAM") {
+ // stride size (bytes) of the request for achieving
+ // required hit length
+ unsigned int stride_size;
+ unsigned int page_size;
+ unsigned int nbr_of_banks_DRAM;
+ unsigned int nbr_of_banks_util;
+ unsigned int addr_mapping;
+
+ is >> stride_size >> page_size >> nbr_of_banks_DRAM >>
+ nbr_of_banks_util >> addr_mapping;
+
+ if (stride_size > page_size)
+ warn("DRAM generator stride size (%d) is greater "
+ "than page size (%d) of the memory\n",
+ blocksize, page_size);
+
+ if (nbr_of_banks_util > nbr_of_banks_DRAM)
+ fatal("Attempting to use more banks (%) than "
+ "what is available (%)\n",
+ nbr_of_banks_util, nbr_of_banks_DRAM);
+
+ if (nbr_of_banks_util > nbr_of_banks_DRAM)
+ fatal("Attempting to use more banks (%) than "
+ "what is available (%)\n",
+ nbr_of_banks_util, nbr_of_banks_DRAM);
+
+ // count the number of sequential packets to
+ // generate
+ unsigned int num_seq_pkts = 1;
+
+ if (stride_size > blocksize) {
+ num_seq_pkts = divCeil(stride_size, blocksize);
+ DPRINTF(TrafficGen, "stride size: %d "
+ "block size: %d, num_seq_pkts: %d\n",
+ stride_size, blocksize, num_seq_pkts);
+ }
+
+ states[id] = new DramGen(name(), masterID,
+ 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);
+ DPRINTF(TrafficGen, "State: %d DramGen\n", id);
}
} else {
fatal("%s: Unknown traffic generator mode: %s",