gem5  v20.1.0.0
hybrid_gen.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed here under. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *
37  * Authors: Wendy Elsasser
38  */
39 
41 
42 #include <algorithm>
43 
44 #include "base/random.hh"
45 #include "base/trace.hh"
46 #include "debug/TrafficGen.hh"
47 #include "enums/AddrMap.hh"
48 
49 using namespace std;
50 
52  RequestorID requestor_id, Tick _duration,
53  Addr start_addr_dram, Addr end_addr_dram,
54  Addr blocksize_dram,
55  Addr start_addr_nvm, Addr end_addr_nvm,
56  Addr blocksize_nvm,
57  Addr cacheline_size,
58  Tick min_period, Tick max_period,
59  uint8_t read_percent, Addr data_limit,
60  unsigned int num_seq_pkts_dram, unsigned int page_size_dram,
61  unsigned int nbr_of_banks_dram,
62  unsigned int nbr_of_banks_util_dram,
63  unsigned int num_seq_pkts_nvm, unsigned int buffer_size_nvm,
64  unsigned int nbr_of_banks_nvm,
65  unsigned int nbr_of_banks_util_nvm,
66  Enums::AddrMap addr_mapping,
67  unsigned int nbr_of_ranks_dram,
68  unsigned int nbr_of_ranks_nvm,
69  uint8_t nvm_percent)
70  : BaseGen(obj, requestor_id, _duration),
71  startAddrDram(start_addr_dram),
72  endAddrDram(end_addr_dram),
73  blocksizeDram(blocksize_dram),
74  startAddrNvm(start_addr_nvm),
75  endAddrNvm(end_addr_nvm),
76  blocksizeNvm(blocksize_nvm),
77  cacheLineSize(cacheline_size),
78  minPeriod(min_period), maxPeriod(max_period),
79  readPercent(read_percent), dataLimit(data_limit),
80  numSeqPktsDram(num_seq_pkts_dram),
81  numSeqPktsNvm(num_seq_pkts_nvm),
82  countNumSeqPkts(0), addr(0),
83  pageSizeDram(page_size_dram),
84  pageBitsDram(floorLog2(pageSizeDram / blocksizeDram)),
85  bankBitsDram(floorLog2(nbr_of_banks_dram)),
86  blockBitsDram(floorLog2(blocksizeDram)),
87  nbrOfBanksDram(nbr_of_banks_dram),
88  nbrOfBanksUtilDram(nbr_of_banks_util_dram),
89  bufferSizeNvm(buffer_size_nvm),
90  pageBitsNvm(floorLog2(bufferSizeNvm / blocksizeNvm)),
91  bankBitsNvm(floorLog2(nbr_of_banks_nvm)),
92  blockBitsNvm(floorLog2(blocksizeNvm)),
93  nbrOfBanksNvm(nbr_of_banks_nvm),
94  nbrOfBanksUtilNvm(nbr_of_banks_util_nvm),
95  addrMapping(addr_mapping),
96  nbrOfRanksDram(nbr_of_ranks_dram),
97  rankBitsDram(floorLog2(nbrOfRanksDram)),
98  nbrOfRanksNvm(nbr_of_ranks_nvm),
99  rankBitsNvm(floorLog2(nbrOfRanksNvm)),
100  nvmPercent(nvm_percent),
101  isRead(true),
102  isNvm(false),
103  dataManipulated(0)
104 {
106  fatal("TrafficGen %s Dram block size (%d) is larger than "
107  "cache line size (%d)\n", name(),
109 
111  fatal("TrafficGen %s Nvm block size (%d) is larger than "
112  "cache line size (%d)\n", name(),
114 
115  if (readPercent > 100)
116  fatal("%s cannot have more than 100% reads", name());
117 
118  if (minPeriod > maxPeriod)
119  fatal("%s cannot have min_period > max_period", name());
120 
122  fatal("Attempting to use more Dram banks (%d) than "
123  "what is available (%d)\n",
125 
127  fatal("Attempting to use more Nvm banks (%d) than "
128  "what is available (%d)\n",
130 }
131 
132 void
134 {
135  // reset the counter to zero
136  dataManipulated = 0;
137 }
138 
139 PacketPtr
141 {
142  // if this is the first of the packets in series to be generated,
143  // start counting again
144  if (countNumSeqPkts == 0) {
145  isNvm = nvmPercent != 0 &&
146  (nvmPercent == 100 || random_mt.random(0, 100) < nvmPercent);
147 
148  // choose if we generate a read or a write here
149  isRead = readPercent != 0 &&
150  (readPercent == 100 || random_mt.random(0, 100) < readPercent);
151 
152  assert((readPercent == 0 && !isRead) ||
153  (readPercent == 100 && isRead) ||
154  readPercent != 100);
155 
156  if (isNvm) {
157  // Select the appropriate parameters for this interface
170  } else {
171  // Select the appropriate parameters for this interface
184  }
185 
187 
188  // pick a random bank
189  unsigned int new_bank =
190  random_mt.random<unsigned int>(0, nbrOfBanksUtil - 1);
191 
192  // pick a random rank
193  unsigned int new_rank =
194  random_mt.random<unsigned int>(0, nbrOfRanks - 1);
195 
196  // Generate the start address of the command series
197  // routine will update addr variable with bank, rank, and col
198  // bits updated for random traffic mode
199  genStartAddr(new_bank, new_rank);
200 
201 
202  } else {
203  // increment the column by one
204  if (addrMapping == Enums::RoRaBaCoCh ||
205  addrMapping == Enums::RoRaBaChCo)
206  // Simply increment addr by blocksize to increment
207  // the column by one
208  addr += blocksize;
209 
210  else if (addrMapping == Enums::RoCoRaBaCh) {
211  // Explicity increment the column bits
212  unsigned int new_col = ((addr / blocksize /
214  (pageSize / blocksize)) + 1;
216  blockBits + bankBits + rankBits, new_col);
217  }
218  }
219 
220  DPRINTF(TrafficGen, "HybridGen::getNextPacket: %c to addr %x, "
221  "size %d, countNumSeqPkts: %d, numSeqPkts: %d\n",
223 
224  // create a new request packet
227 
228  // add the amount of data manipulated to the total
230 
231  // subtract the number of packets remained to be generated
232  --countNumSeqPkts;
233 
234  // return the generated packet
235  return pkt;
236 }
237 
238 void
239 HybridGen::genStartAddr(unsigned int new_bank, unsigned int new_rank)
240 {
241  // start by picking a random address in the range
243 
244  // round down to start address of a block, i.e. a DRAM burst
245  addr -= addr % blocksize;
246 
247  // insert the bank bits at the right spot, and align the
248  // address to achieve the required hit length, this involves
249  // finding the appropriate start address such that all
250  // sequential packets target successive columns in the same
251  // page
252 
253  // for example, if we have a stride size of 192B, which means
254  // for LPDDR3 where burstsize = 32B we have numSeqPkts = 6,
255  // the address generated previously can be such that these
256  // 192B cross the page boundary, hence it needs to be aligned
257  // so that they all belong to the same page for page hit
258  unsigned int burst_per_page = pageSize / blocksize;
259 
260  // pick a random column, but ensure that there is room for
261  // numSeqPkts sequential columns in the same page
262  unsigned int new_col =
263  random_mt.random<unsigned int>(0, burst_per_page - numSeqPkts);
264 
265  if (addrMapping == Enums::RoRaBaCoCh ||
266  addrMapping == Enums::RoRaBaChCo) {
267  // Block bits, then page bits, then bank bits, then rank bits
269  blockBits + pageBits, new_bank);
270  replaceBits(addr, blockBits + pageBits - 1, blockBits, new_col);
271  if (rankBits != 0) {
273  blockBits + pageBits + bankBits, new_rank);
274  }
275  } else if (addrMapping == Enums::RoCoRaBaCh) {
276  // Block bits, then bank bits, then rank bits, then page bits
277  replaceBits(addr, blockBits + bankBits - 1, blockBits, new_bank);
279  blockBits + bankBits + rankBits, new_col);
280  if (rankBits != 0) {
282  blockBits + bankBits, new_rank);
283  }
284  }
285 }
286 
287 Tick
288 HybridGen::nextPacketTick(bool elastic, Tick delay) const
289 {
290  // Check to see if we have reached the data limit. If dataLimit is
291  // zero we do not have a data limit and therefore we will keep
292  // generating requests for the entire residency in this state.
294  {
295  DPRINTF(TrafficGen, "Data limit for RandomGen reached.\n");
296  // No more requests. Return MaxTick.
297  return MaxTick;
298  } else {
299  // return the time when the next request should take place
301 
302  // compensate for the delay experienced to not be elastic, by
303  // default the value we generate is from the time we are
304  // asked, so the elasticity happens automatically
305  if (!elastic) {
306  if (wait < delay)
307  wait = 0;
308  else
309  wait -= delay;
310  }
311 
312  return curTick() + wait;
313  }
314 }
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:183
HybridGen::addr
Addr addr
Address of request.
Definition: hybrid_gen.hh:170
BaseGen
Base class for all generators, with the shared functionality and virtual functions for entering,...
Definition: base_gen.hh:57
HybridGen::endAddr
Addr endAddr
End of address range.
Definition: hybrid_gen.hh:246
HybridGen::blockBitsDram
const unsigned int blockBitsDram
Number of block bits in DRAM address.
Definition: hybrid_gen.hh:182
HybridGen::addrMapping
Enums::AddrMap addrMapping
Address mapping to be used.
Definition: hybrid_gen.hh:209
replaceBits
void replaceBits(T &val, int first, int last, B bit_val)
A convenience function to replace bits first to last of val with bit_val in place.
Definition: bitfield.hh:179
HybridGen::cacheLineSize
const Addr cacheLineSize
Cache line size in the simulated system.
Definition: hybrid_gen.hh:150
HybridGen::startAddrNvm
const Addr startAddrNvm
Start of DRAM address range.
Definition: hybrid_gen.hh:141
HybridGen::bufferSizeNvm
const unsigned int bufferSizeNvm
Buffer size of NVM.
Definition: hybrid_gen.hh:191
HybridGen::dataManipulated
Addr dataManipulated
Counter to determine the amount of data manipulated.
Definition: hybrid_gen.hh:237
random.hh
MemCmd::ReadReq
@ ReadReq
Definition: packet.hh:82
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:63
HybridGen::readPercent
const uint8_t readPercent
Percent of generated transactions that should be reads.
Definition: hybrid_gen.hh:157
HybridGen::pageBitsNvm
const unsigned int pageBitsNvm
Number of buffer bits in NVM address.
Definition: hybrid_gen.hh:194
HybridGen::countNumSeqPkts
unsigned int countNumSeqPkts
Track number of sequential packets generated for a request
Definition: hybrid_gen.hh:167
HybridGen::isNvm
bool isNvm
Remember the interface to be generated in series.
Definition: hybrid_gen.hh:230
HybridGen::blockBits
unsigned int blockBits
Number of block bits in DRAM address.
Definition: hybrid_gen.hh:261
HybridGen::blocksizeNvm
const Addr blocksizeNvm
Blocksize and address increment for DRAM.
Definition: hybrid_gen.hh:147
HybridGen::numSeqPktsNvm
const unsigned int numSeqPktsNvm
Definition: hybrid_gen.hh:164
floorLog2
std::enable_if< std::is_integral< T >::value, int >::type floorLog2(T x)
Definition: intmath.hh:63
BaseGen::name
std::string name() const
Get the name, useful for DPRINTFs.
Definition: base_gen.hh:100
HybridGen::pageBitsDram
const unsigned int pageBitsDram
Number of page bits in DRAM address.
Definition: hybrid_gen.hh:176
HybridGen::bankBitsDram
const unsigned int bankBitsDram
Number of bank bits in DRAM address.
Definition: hybrid_gen.hh:179
HybridGen::dataLimit
const Addr dataLimit
Maximum amount of data to manipulate.
Definition: hybrid_gen.hh:160
HybridGen::getNextPacket
PacketPtr getNextPacket()
Get the next generated packet.
Definition: hybrid_gen.cc:140
HybridGen::startAddr
Addr startAddr
Start of address range.
Definition: hybrid_gen.hh:243
MemCmd::WriteReq
@ WriteReq
Definition: packet.hh:85
HybridGen::endAddrNvm
const Addr endAddrNvm
End of DRAM address range.
Definition: hybrid_gen.hh:144
random_mt
Random random_mt
Definition: random.cc:96
RequestorID
uint16_t RequestorID
Definition: request.hh:85
HybridGen::pageSizeDram
const unsigned int pageSizeDram
Page size of DRAM.
Definition: hybrid_gen.hh:173
HybridGen::nbrOfRanks
unsigned int nbrOfRanks
Number of ranks to be utilized for a given configuration.
Definition: hybrid_gen.hh:270
hybrid_gen.hh
HybridGen::numSeqPktsDram
const unsigned int numSeqPktsDram
Number of sequential packets to be generated per cpu request.
Definition: hybrid_gen.hh:163
HybridGen::nbrOfRanksDram
const unsigned int nbrOfRanksDram
Number of ranks to be utilized for a given configuration.
Definition: hybrid_gen.hh:212
HybridGen::nvmPercent
const uint8_t nvmPercent
Percent of generated transactions that should go to NVM.
Definition: hybrid_gen.hh:224
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
HybridGen::nbrOfBanksUtilNvm
const unsigned int nbrOfBanksUtilNvm
Number of banks to be utilized for a given configuration.
Definition: hybrid_gen.hh:206
HybridGen::rankBits
unsigned int rankBits
Number of rank bits in DRAM address.
Definition: hybrid_gen.hh:273
HybridGen::startAddrDram
const Addr startAddrDram
Start of DRAM address range.
Definition: hybrid_gen.hh:132
HybridGen::pageBits
unsigned int pageBits
Number of page bits in DRAM address.
Definition: hybrid_gen.hh:255
HybridGen::nbrOfRanksNvm
const unsigned int nbrOfRanksNvm
Number of ranks to be utilized for a given configuration.
Definition: hybrid_gen.hh:218
HybridGen::rankBitsDram
const unsigned int rankBitsDram
Number of rank bits in DRAM address.
Definition: hybrid_gen.hh:215
HybridGen::bankBits
unsigned int bankBits
Number of bank bits in DRAM address.
Definition: hybrid_gen.hh:258
HybridGen::nbrOfBanksUtilDram
const unsigned int nbrOfBanksUtilDram
Number of banks to be utilized for a given configuration.
Definition: hybrid_gen.hh:188
HybridGen::enter
void enter()
Enter this generator state.
Definition: hybrid_gen.cc:133
HybridGen::rankBitsNvm
const unsigned int rankBitsNvm
Number of rank bits in DRAM address.
Definition: hybrid_gen.hh:221
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
HybridGen::nextPacketTick
Tick nextPacketTick(bool elastic, Tick delay) const
Determine the tick when the next packet is available.
Definition: hybrid_gen.cc:288
HybridGen::pageSize
unsigned int pageSize
Page size of DRAM.
Definition: hybrid_gen.hh:252
HybridGen::blockBitsNvm
const unsigned int blockBitsNvm
Number of block bits in NVM address.
Definition: hybrid_gen.hh:200
HybridGen::blocksize
Addr blocksize
Blocksize and address increment.
Definition: hybrid_gen.hh:249
HybridGen::genStartAddr
void genStartAddr(unsigned int new_bank, unsigned int new_rank)
Insert bank, rank, and column bits into packed address to create address for 1st command in a series.
Definition: hybrid_gen.cc:239
HybridGen::HybridGen
HybridGen(SimObject &obj, RequestorID requestor_id, Tick _duration, Addr start_addr_dram, Addr end_addr_dram, Addr blocksize_dram, Addr start_addr_nvm, Addr end_addr_nvm, Addr blocksize_nvm, Addr cacheline_size, Tick min_period, Tick max_period, uint8_t read_percent, Addr data_limit, unsigned int num_seq_pkts_dram, unsigned int page_size_dram, unsigned int nbr_of_banks_dram, unsigned int nbr_of_banks_util_dram, unsigned int num_seq_pkts_nvm, unsigned int buffer_size_nvm, unsigned int nbr_of_banks_nvm, unsigned int nbr_of_banks_util_nvm, Enums::AddrMap addr_mapping, unsigned int nbr_of_ranks_dram, unsigned int nbr_of_ranks_nvm, uint8_t nvm_percent)
Create a hybrid DRAM + NVM address sequence generator.
Definition: hybrid_gen.cc:51
BaseGen::getPacket
PacketPtr getPacket(Addr addr, unsigned size, const MemCmd &cmd, Request::FlagsType flags=0)
Generate a new request and associated packet.
Definition: base_gen.cc:56
HybridGen::numSeqPkts
unsigned int numSeqPkts
Number of sequential DRAM packets to be generated per cpu request.
Definition: hybrid_gen.hh:240
HybridGen::nbrOfBanksUtil
unsigned int nbrOfBanksUtil
Number of banks to be utilized for a given configuration.
Definition: hybrid_gen.hh:267
HybridGen::nbrOfBanksNvm
const unsigned int nbrOfBanksNvm
Number of banks in NVM.
Definition: hybrid_gen.hh:203
HybridGen::maxPeriod
const Tick maxPeriod
Definition: hybrid_gen.hh:154
sc_core::wait
void wait()
Definition: sc_module.cc:653
HybridGen::nbrOfBanks
unsigned int nbrOfBanks
Number of banks in DRAM.
Definition: hybrid_gen.hh:264
std
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:587
HybridGen::minPeriod
const Tick minPeriod
Request generation period.
Definition: hybrid_gen.hh:153
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:257
addr
ip6_addr_t addr
Definition: inet.hh:423
HybridGen::endAddrDram
const Addr endAddrDram
End of DRAM address range.
Definition: hybrid_gen.hh:135
Random::random
std::enable_if< std::is_integral< T >::value, T >::type random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
Definition: random.hh:86
trace.hh
HybridGen::isRead
bool isRead
Remember type of requests to be generated in series.
Definition: hybrid_gen.hh:227
HybridGen::blocksizeDram
const Addr blocksizeDram
Blocksize and address increment for DRAM.
Definition: hybrid_gen.hh:138
HybridGen::bankBitsNvm
const unsigned int bankBitsNvm
Number of bank bits in NVM address.
Definition: hybrid_gen.hh:197
MaxTick
const Tick MaxTick
Definition: types.hh:65
TrafficGen
The traffic generator is a module that generates stimuli for the memory system, based on a collection...
Definition: traffic_gen.hh:67
curTick
Tick curTick()
The current simulated tick.
Definition: core.hh:45
HybridGen::nbrOfBanksDram
const unsigned int nbrOfBanksDram
Number of banks in DRAM.
Definition: hybrid_gen.hh:185
SimObject
Abstract superclass for simulation objects.
Definition: sim_object.hh:92

Generated on Wed Sep 30 2020 14:02:09 for gem5 by doxygen 1.8.17