summaryrefslogtreecommitdiff
path: root/src/cpu/testers/traffic_gen/generators.cc
diff options
context:
space:
mode:
authorNeha Agarwal <neha.agarwal@arm.com>2014-03-23 11:11:58 -0400
committerNeha Agarwal <neha.agarwal@arm.com>2014-03-23 11:11:58 -0400
commit364a51181ea4fb09ee24f5a57eb293744075b326 (patch)
tree71e076ca860a5b53971ee294c6d8444e755412e2 /src/cpu/testers/traffic_gen/generators.cc
parent43abaf518f00c38415e08b7c96941d192316208f (diff)
downloadgem5-364a51181ea4fb09ee24f5a57eb293744075b326.tar.xz
cpu: DRAM Traffic Generator
This patch enables a new 'DRAM' mode to the existing traffic generator, catered to generate specific requests to DRAM based on required hit length (stride size) and bank utilization. It is an add on to the Random mode. The basic idea is to control how many successive packets target the same page, and how many banks are being used in parallel. This gives a two-dimensional space that stresses different aspects of the DRAM timing. The configuration file needed to use this patch has to be changed as follow: (reference to Random Mode, LPDDR3 memory type) 'STATE 0 10000000000 RANDOM 50 0 134217728 64 3004 5002 0' -> 'STATE 0 10000000000 DRAM 50 0 134217728 32 3004 5002 0 96 1024 8 6 1' The last 4 parameters to be added are: <stride size (bytes), page size(bytes), number of banks available in DRAM, number of banks to be utilized, address mapping scheme> The address mapping information is used to get the stride address stream of the specified size and to know where to find the bank bits. The configuration file has a parameter where '0'-> RoCoRaBaCh, '1'-> RoRaBaCoCh/RoRaBaChCo address-mapping schemes. Note that the generator currently assumes a single channel and a single rank. This is to avoid overwhelming the traffic generator with information about the memory organisation.
Diffstat (limited to 'src/cpu/testers/traffic_gen/generators.cc')
-rw-r--r--src/cpu/testers/traffic_gen/generators.cc89
1 files changed, 89 insertions, 0 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
{