diff options
Diffstat (limited to 'src/cpu/testers/traffic_gen')
-rw-r--r-- | src/cpu/testers/traffic_gen/generators.cc | 89 | ||||
-rw-r--r-- | src/cpu/testers/traffic_gen/generators.hh | 98 | ||||
-rw-r--r-- | src/cpu/testers/traffic_gen/traffic_gen.cc | 54 |
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", |