dram_gen.cc revision 12804:f47e75dce5c6
1/*
2 * Copyright (c) 2012-2013, 2016-2017 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: Thomas Grass
38 *          Andreas Hansson
39 *          Sascha Bischoff
40 *          Neha Agarwal
41 */
42
43#include "cpu/testers/traffic_gen/dram_gen.hh"
44
45#include <algorithm>
46
47#include "base/random.hh"
48#include "base/trace.hh"
49#include "debug/TrafficGen.hh"
50
51PacketPtr
52DramGen::getNextPacket()
53{
54    // if this is the first of the packets in series to be generated,
55    // start counting again
56    if (countNumSeqPkts == 0) {
57        countNumSeqPkts = numSeqPkts;
58
59        // choose if we generate a read or a write here
60        isRead = readPercent != 0 &&
61            (readPercent == 100 || random_mt.random(0, 100) < readPercent);
62
63        assert((readPercent == 0 && !isRead) ||
64               (readPercent == 100 && isRead) ||
65               readPercent != 100);
66
67        // pick a random bank
68        unsigned int new_bank =
69            random_mt.random<unsigned int>(0, nbrOfBanksUtil - 1);
70
71        // pick a random rank
72        unsigned int new_rank =
73            random_mt.random<unsigned int>(0, nbrOfRanks - 1);
74
75        // Generate the start address of the command series
76        // routine will update addr variable with bank, rank, and col
77        // bits updated for random traffic mode
78        genStartAddr(new_bank, new_rank);
79
80    } else {
81        // increment the column by one
82        if (addrMapping == 1)
83            // addrMapping=1: RoRaBaCoCh/RoRaBaChCo
84            // Simply increment addr by blocksize to increment
85            // the column by one
86            addr += blocksize;
87
88        else if (addrMapping == 0) {
89            // addrMapping=0: RoCoRaBaCh
90            // Explicity increment the column bits
91            unsigned int new_col = ((addr / blocksize /
92                                       nbrOfBanksDRAM / nbrOfRanks) %
93                                   (pageSize / blocksize)) + 1;
94            replaceBits(addr, blockBits + bankBits + rankBits + pageBits - 1,
95                        blockBits + bankBits + rankBits, new_col);
96        }
97    }
98
99    DPRINTF(TrafficGen, "DramGen::getNextPacket: %c to addr %x, "
100            "size %d, countNumSeqPkts: %d, numSeqPkts: %d\n",
101            isRead ? 'r' : 'w', addr, blocksize, countNumSeqPkts, numSeqPkts);
102
103    // create a new request packet
104    PacketPtr pkt = getPacket(addr, blocksize,
105                              isRead ? MemCmd::ReadReq : MemCmd::WriteReq);
106
107    // add the amount of data manipulated to the total
108    dataManipulated += blocksize;
109
110    // subtract the number of packets remained to be generated
111    --countNumSeqPkts;
112
113    // return the generated packet
114    return pkt;
115}
116
117void
118DramGen::genStartAddr(unsigned int new_bank, unsigned int new_rank)
119{
120    // start by picking a random address in the range
121    addr = random_mt.random<Addr>(startAddr, endAddr - 1);
122
123    // round down to start address of a block, i.e. a DRAM burst
124    addr -= addr % blocksize;
125
126    // insert the bank bits at the right spot, and align the
127    // address to achieve the required hit length, this involves
128    // finding the appropriate start address such that all
129    // sequential packets target successive columns in the same
130    // page
131
132    // for example, if we have a stride size of 192B, which means
133    // for LPDDR3 where burstsize = 32B we have numSeqPkts = 6,
134    // the address generated previously can be such that these
135    // 192B cross the page boundary, hence it needs to be aligned
136    // so that they all belong to the same page for page hit
137    unsigned int columns_per_page = pageSize / blocksize;
138
139    // pick a random column, but ensure that there is room for
140    // numSeqPkts sequential columns in the same page
141    unsigned int new_col =
142        random_mt.random<unsigned int>(0, columns_per_page - numSeqPkts);
143
144    if (addrMapping == 1) {
145        // addrMapping=1: RoRaBaCoCh/RoRaBaChCo
146        // Block bits, then page bits, then bank bits, then rank bits
147        replaceBits(addr, blockBits + pageBits + bankBits - 1,
148                    blockBits + pageBits, new_bank);
149        replaceBits(addr, blockBits + pageBits - 1, blockBits, new_col);
150        if (rankBits != 0) {
151            replaceBits(addr, blockBits + pageBits + bankBits +rankBits - 1,
152                        blockBits + pageBits + bankBits, new_rank);
153        }
154    } else if (addrMapping == 0) {
155        // addrMapping=0: RoCoRaBaCh
156        // Block bits, then bank bits, then rank bits, then page bits
157        replaceBits(addr, blockBits + bankBits - 1, blockBits, new_bank);
158        replaceBits(addr, blockBits + bankBits + rankBits + pageBits - 1,
159                    blockBits + bankBits + rankBits, new_col);
160        if (rankBits != 0) {
161            replaceBits(addr, blockBits + bankBits + rankBits - 1,
162                        blockBits + bankBits, new_rank);
163        }
164    }
165}
166