changeset 0100f00a229e in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=0100f00a229e
description:
cpu: Update DRAM traffic gen
Add new DRAM_ROTATE mode to traffic generator.
This mode will generate DRAM traffic that rotates across
banks per rank, command types, and ranks per channel
The looping order is illustrated below:
for (ranks per channel)
for (command types)
for (banks per rank)
// Generate DRAM Command Series
This patch also adds the read percentage as an input argument to the
DRAM sweep script. If the simulated read percentage is 0 or 100, the
middle for loop does not generate additional commands. This loop is
used only when the read percentage is set to 50, in which case the
middle loop will toggle between read and write commands.
Modified sweep.py script, which generates DRAM traffic.
Added input arguments and support for new DRAM_ROTATE mode.
The script now has input arguments for:
1) Read percentage
2) Number of ranks
3) Address mapping
4) Traffic generator mode (DRAM or DRAM_ROTATE)
The default values are:
100% reads, 1 rank, RoRaBaCoCh address mapping, and DRAM traffic gen
mode
For the DRAM traffic mode, added multi-rank support.
diffstat:
configs/dram/sweep.py | 37 ++++-
src/cpu/testers/traffic_gen/generators.cc | 190 +++++++++++++++++++++++-----
src/cpu/testers/traffic_gen/generators.hh | 99 ++++++++++++++-
src/cpu/testers/traffic_gen/traffic_gen.cc | 52 +++++-
4 files changed, 316 insertions(+), 62 deletions(-)
diffs (truncated from 509 to 300 lines):
diff -r 4a501e0f7540 -r 0100f00a229e configs/dram/sweep.py
--- a/configs/dram/sweep.py Sat Sep 20 17:17:54 2014 -0400
+++ b/configs/dram/sweep.py Sat Sep 20 17:17:55 2014 -0400
@@ -58,6 +58,20 @@
choices=MemConfig.mem_names(),
help = "type of memory to use")
+parser.add_option("--ranks", "-r", type="int", default=1,
+ help = "Number of ranks to iterate across")
+
+parser.add_option("--rd_perc", type="int", default=100,
+ help = "Percentage of read commands")
+
+parser.add_option("--mode", type="choice", default="DRAM",
+ choices=["DRAM", "DRAM_ROTATE"],
+ help = "DRAM: Random traffic; \
+ DRAM_ROTATE: Traffic rotating across banks and
ranks")
+
+parser.add_option("--addr_map", type="int", default=1,
+ help = "0: RoCoRaBaCh; 1: RoRaBaCoCh/RoRaBaChCo")
+
(options, args) = parser.parse_args()
if args:
@@ -89,8 +103,17 @@
if not isinstance(system.mem_ctrls[0], m5.objects.DRAMCtrl):
fatal("This script assumes the memory is a DRAMCtrl subclass")
-# for now the generator assumes a single rank
-system.mem_ctrls[0].ranks_per_channel = 1
+# Set number of ranks based on input argument; default is 1 rank
+system.mem_ctrls[0].ranks_per_channel = options.ranks
+
+# Set the address mapping based on input argument
+# Default to RoRaBaCoCh
+if options.addr_map == 0:
+ system.mem_ctrls[0].addr_mapping = "RoCoRaBaCh"
+elif options.addr_map == 1:
+ system.mem_ctrls[0].addr_mapping = "RoRaBaCoCh"
+else:
+ fatal("Did not specify a valid address map argument")
# stay in each state for 0.25 ms, long enough to warm things up, and
# short enough to avoid hitting a refresh
@@ -134,10 +157,12 @@
nxt_state = 0
for bank in range(1, nbr_banks + 1):
for stride_size in range(burst_size, max_stride + 1, burst_size):
- cfg_file.write("STATE %d %d DRAM 100 0 %d "
- "%d %d %d %d %d %d %d %d 1\n" %
- (nxt_state, period, max_addr, burst_size, itt, itt, 0,
- stride_size, page_size, nbr_banks, bank))
+ cfg_file.write("STATE %d %d %s %d 0 %d %d "
+ "%d %d %d %d %d %d %d %d %d\n" %
+ (nxt_state, period, options.mode, options.rd_perc,
+ max_addr, burst_size, itt, itt, 0, stride_size,
+ page_size, nbr_banks, bank, options.addr_map,
+ options.ranks))
nxt_state = nxt_state + 1
cfg_file.write("INIT 0\n")
diff -r 4a501e0f7540 -r 0100f00a229e src/cpu/testers/traffic_gen/generators.cc
--- a/src/cpu/testers/traffic_gen/generators.cc Sat Sep 20 17:17:54 2014 -0400
+++ b/src/cpu/testers/traffic_gen/generators.cc Sat Sep 20 17:17:55 2014 -0400
@@ -190,56 +190,33 @@
(readPercent == 100 && isRead) ||
readPercent != 100);
- // start by picking a random address in the range
- addr = random_mt.random(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
+ // pick a random rank
+ unsigned int new_rank =
+ random_mt.random<unsigned int>(0, nbrOfRanks - 1);
- // 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;
+ // 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);
- // 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
+ // addrMapping=1: RoRaBaCoCh/RoRaBaChCo
+ // Simply increment addr by blocksize to increment the column by
one
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) %
+ // addrMapping=0: RoCoRaBaCh
+ // Explicity increment the column bits
+ unsigned int new_col = ((addr / blocksize / nbrOfBanksDRAM /
nbrOfRanks) %
(pageSize / blocksize)) + 1;
- replaceBits(addr, blockBits + bankBits + pageBits - 1,
- blockBits + bankBits, new_col);
+ replaceBits(addr, blockBits + bankBits + rankBits + pageBits - 1,
+ blockBits + bankBits + rankBits, new_col);
}
}
@@ -261,6 +238,143 @@
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
{
diff -r 4a501e0f7540 -r 0100f00a229e src/cpu/testers/traffic_gen/generators.hh
--- a/src/cpu/testers/traffic_gen/generators.hh Sat Sep 20 17:17:54 2014 -0400
+++ b/src/cpu/testers/traffic_gen/generators.hh Sat Sep 20 17:17:55 2014 -0400
@@ -310,7 +310,7 @@
/**
* DRAM specific generator is for issuing request with variable page
* hit length and bank utilization. Currently assumes a single
- * channel, single rank configuration.
+ * channel configuration.
*/
class DramGen : public RandomGen
{
@@ -337,7 +337,7 @@
* 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
+ * assumes single channel system
*/
DramGen(const std::string& _name, MasterID master_id, Tick _duration,
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev