sweep.py revision 11682
1803SN/A# Copyright (c) 2014-2015 ARM Limited
21363SN/A# All rights reserved.
3803SN/A#
4803SN/A# The license below extends only to copyright in the software and shall
5803SN/A# not be construed as granting a license to any other intellectual
6803SN/A# property including but not limited to intellectual property relating
7803SN/A# to a hardware implementation of the functionality of the software
8803SN/A# licensed hereunder.  You may use the software subject to the license
9803SN/A# terms below provided that you ensure that this notice is replicated
10803SN/A# unmodified and in its entirety in all distributions of the software,
11803SN/A# modified or unmodified, in source code or in binary form.
12803SN/A#
13803SN/A# Redistribution and use in source and binary forms, with or without
14803SN/A# modification, are permitted provided that the following conditions are
15803SN/A# met: redistributions of source code must retain the above copyright
16803SN/A# notice, this list of conditions and the following disclaimer;
17803SN/A# redistributions in binary form must reproduce the above copyright
18803SN/A# notice, this list of conditions and the following disclaimer in the
19803SN/A# documentation and/or other materials provided with the distribution;
20803SN/A# neither the name of the copyright holders nor the names of its
21803SN/A# contributors may be used to endorse or promote products derived from
22803SN/A# this software without specific prior written permission.
23803SN/A#
24803SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25803SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26803SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
272665SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
282665SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
292665SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
302665SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31803SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32768SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
331730SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34773SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35768SN/A#
36768SN/A# Authors: Andreas Hansson
37773SN/A
38773SN/Aimport optparse
39768SN/A
40768SN/Aimport m5
41768SN/Afrom m5.objects import *
42768SN/Afrom m5.util import addToPath
434762Snate@binkert.orgfrom m5.internal.stats import periodicStatDump
44768SN/A
456658Snate@binkert.orgaddToPath('../')
468232Snate@binkert.org
478229Snate@binkert.orgfrom common import MemConfig
483540Sgblack@eecs.umich.edu
493540Sgblack@eecs.umich.edu# this script is helpful to sweep the efficiency of a specific memory
503540Sgblack@eecs.umich.edu# controller configuration, by varying the number of banks accessed,
518229Snate@binkert.org# and the sequential stride size (how many bytes per activate), and
523348SN/A# observe what bus utilisation (bandwidth) is achieved
533348SN/A
542542SN/Aparser = optparse.OptionParser()
552542SN/A
56768SN/A# Use a single-channel DDR3-1600 x64 by default
578737Skoansin.tan@gmail.comparser.add_option("--mem-type", type="choice", default="DDR3_1600_x64",
588737Skoansin.tan@gmail.com                  choices=MemConfig.mem_names(),
598737Skoansin.tan@gmail.com                  help = "type of memory to use")
608737Skoansin.tan@gmail.com
618737Skoansin.tan@gmail.comparser.add_option("--mem-ranks", "-r", type="int", default=1,
622107SN/A                  help = "Number of ranks to iterate across")
632107SN/A
64773SN/Aparser.add_option("--rd_perc", type="int", default=100,
655606Snate@binkert.org                  help = "Percentage of read commands")
665606Snate@binkert.org
675606Snate@binkert.orgparser.add_option("--mode", type="choice", default="DRAM",
681817SN/A                  choices=["DRAM", "DRAM_ROTATE"],
69772SN/A                  help = "DRAM: Random traffic; \
70772SN/A                          DRAM_ROTATE: Traffic rotating across banks and ranks")
714762Snate@binkert.org
725606Snate@binkert.orgparser.add_option("--addr_map", type="int", default=1,
735606Snate@binkert.org                  help = "0: RoCoRaBaCh; 1: RoRaBaCoCh/RoRaBaChCo")
74768SN/A
753846Shsul@eecs.umich.edu(options, args) = parser.parse_args()
76909SN/A
77803SN/Aif args:
78803SN/A    print "Error: script doesn't take any positional arguments"
79803SN/A    sys.exit(1)
80771SN/A
81777SN/A# at the moment we stay with the default open-adaptive page policy,
82777SN/A# and address mapping
83773SN/A
84773SN/A# start with the system itself, using a multi-layer 2.0 GHz
851634SN/A# crossbar, delivering 64 bytes / 3 cycles (one header cycle)
861634SN/A# which amounts to 42.7 GByte/s per layer and thus per port
871634SN/Asystem = System(membus = IOXBar(width = 32))
887064Snate@binkert.orgsystem.clk_domain = SrcClockDomain(clock = '2.0GHz',
891634SN/A                                   voltage_domain =
901634SN/A                                   VoltageDomain(voltage = '1V'))
912542SN/A
923349SN/A# we are fine with 256 MB memory for now
93768SN/Amem_range = AddrRange('256MB')
942641SN/Asystem.mem_ranges = [mem_range]
95768SN/A
962641SN/A# do not worry about reserving space for the backing store
97865SN/Asystem.mmap_using_noreserve = True
982641SN/A
992641SN/A# force a single channel to match the assumptions in the DRAM traffic
100771SN/A# generator
1012630SN/Aoptions.mem_channels = 1
1022539SN/Aoptions.external_memory_system = 0
1032641SN/Aoptions.tlm_memory = 0
104803SN/Aoptions.elastic_trace_en = 0
1051817SN/AMemConfig.config_mem(options, system)
1061817SN/A
1072630SN/A# the following assumes that we are using the native DRAM
1082539SN/A# controller, check to be sure
1091817SN/Aif not isinstance(system.mem_ctrls[0], m5.objects.DRAMCtrl):
1102630SN/A    fatal("This script assumes the memory is a DRAMCtrl subclass")
1112539SN/A
112865SN/A# there is no point slowing things down by saving any data
113865SN/Asystem.mem_ctrls[0].null = True
114865SN/A
115865SN/A# Set the address mapping based on input argument
1162630SN/A# Default to RoRaBaCoCh
1172539SN/Aif options.addr_map == 0:
118865SN/A   system.mem_ctrls[0].addr_mapping = "RoCoRaBaCh"
119865SN/Aelif options.addr_map == 1:
1202630SN/A   system.mem_ctrls[0].addr_mapping = "RoRaBaCoCh"
1212539SN/Aelse:
1221817SN/A    fatal("Did not specify a valid address map argument")
1235635Sgblack@eecs.umich.edu
1242542SN/A# stay in each state for 0.25 ms, long enough to warm things up, and
1251817SN/A# short enough to avoid hitting a refresh
1265635Sgblack@eecs.umich.eduperiod = 250000000
1272542SN/A
1281817SN/A# this is where we go off piste, and print the traffic generator
1295635Sgblack@eecs.umich.edu# configuration that we will later use, crazy but it works
1302539SN/Acfg_file_name = "configs/dram/sweep.cfg"
131803SN/Acfg_file = open(cfg_file_name, 'w')
1325392Sgblack@eecs.umich.edu
1332539SN/A# stay in each state as long as the dump/reset period, use the entire
1341817SN/A# range, issue transactions of the right DRAM burst size, and match
1355635Sgblack@eecs.umich.edu# the DRAM maximum bandwidth to ensure that it is saturated
1362630SN/A
1371817SN/A# get the number of banks
1382630SN/Anbr_banks = system.mem_ctrls[0].banks_per_rank.value
1392539SN/A
140803SN/A# determine the burst length in bytes
1412641SN/Aburst_size = int((system.mem_ctrls[0].devices_per_rank.value *
142803SN/A                  system.mem_ctrls[0].device_bus_width.value *
1432641SN/A                  system.mem_ctrls[0].burst_length.value) / 8)
1442539SN/A
1452630SN/A# next, get the page size in bytes
1462539SN/Apage_size = system.mem_ctrls[0].devices_per_rank.value * \
1472539SN/A    system.mem_ctrls[0].device_rowbuffer_size.value
1482641SN/A
1492539SN/A# match the maximum bandwidth of the memory, the parameter is in seconds
1502641SN/A# and we need it in ticks (ps)
151771SN/Aitt = system.mem_ctrls[0].tBURST.value * 1000000000000
1524870Sstever@eecs.umich.edu
1532539SN/A# assume we start at 0
154768SN/Amax_addr = mem_range.end
155768SN/A
1562539SN/A# use min of the page size and 512 bytes as that should be more than
1573349SN/A# enough
158768SN/Amax_stride = min(512, page_size)
1592641SN/A
1602641SN/A# now we create the state by iterating over the stride size from burst
161779SN/A# size to the max stride, and from using only a single bank up to the
162779SN/A# number of banks available
1632641SN/Anxt_state = 0
164768SN/Afor bank in range(1, nbr_banks + 1):
1652641SN/A    for stride_size in range(burst_size, max_stride + 1, burst_size):
166769SN/A        cfg_file.write("STATE %d %d %s %d 0 %d %d "
1672539SN/A                       "%d %d %d %d %d %d %d %d %d\n" %
1682539SN/A                       (nxt_state, period, options.mode, options.rd_perc,
1692630SN/A                        max_addr, burst_size, itt, itt, 0, stride_size,
1702539SN/A                        page_size, nbr_banks, bank, options.addr_map,
1712539SN/A                        options.mem_ranks))
1722539SN/A        nxt_state = nxt_state + 1
1732539SN/A
174803SN/Acfg_file.write("INIT 0\n")
1752539SN/A
1762539SN/A# go through the states one by one
1772539SN/Afor state in range(1, nxt_state):
1782539SN/A    cfg_file.write("TRANSITION %d %d 1\n" % (state - 1, state))
1792539SN/A
1802539SN/Acfg_file.write("TRANSITION %d %d 1\n" % (nxt_state - 1, nxt_state - 1))
1812539SN/A
1822630SN/Acfg_file.close()
1832539SN/A
1842539SN/A# create a traffic generator, and point it to the file we just created
1852539SN/Asystem.tgen = TrafficGen(config_file = cfg_file_name)
1862539SN/A
1872630SN/A# add a communication monitor
1882539SN/Asystem.monitor = CommMonitor()
1892539SN/A
1902539SN/A# connect the traffic generator to the bus via a communication monitor
1912539SN/Asystem.tgen.port = system.monitor.slave
1922630SN/Asystem.monitor.master = system.membus.slave
1932539SN/A
1942539SN/A# connect the system port even if it is not used in this example
1952630SN/Asystem.system_port = system.membus.slave
1962539SN/A
1972539SN/A# every period, dump and reset all stats
1985635Sgblack@eecs.umich.eduperiodicStatDump(period)
1992539SN/A
2002539SN/A# run Forrest, run!
2015635Sgblack@eecs.umich.eduroot = Root(full_system = False, system = system)
2022539SN/Aroot.system.mem_mode = 'timing'
2032539SN/A
2045635Sgblack@eecs.umich.edum5.instantiate()
2052539SN/Am5.simulate(nxt_state * period)
2062539SN/A
2072630SN/Aprint "DRAM sweep with burst: %d, banks: %d, max stride: %d" % \
2082539SN/A    (burst_size, nbr_banks, max_stride)
2092539SN/A