low_power_sweep.py revision 12268:54566b73dc61
110612SMarco.Elver@ARM.com# Copyright (c) 2014-2015, 2017 ARM Limited
210612SMarco.Elver@ARM.com# All rights reserved.
310612SMarco.Elver@ARM.com#
410612SMarco.Elver@ARM.com# The license below extends only to copyright in the software and shall
510612SMarco.Elver@ARM.com# not be construed as granting a license to any other intellectual
610612SMarco.Elver@ARM.com# property including but not limited to intellectual property relating
710612SMarco.Elver@ARM.com# to a hardware implementation of the functionality of the software
810612SMarco.Elver@ARM.com# licensed hereunder.  You may use the software subject to the license
910612SMarco.Elver@ARM.com# terms below provided that you ensure that this notice is replicated
1010612SMarco.Elver@ARM.com# unmodified and in its entirety in all distributions of the software,
1110612SMarco.Elver@ARM.com# modified or unmodified, in source code or in binary form.
1210612SMarco.Elver@ARM.com#
1310612SMarco.Elver@ARM.com# Redistribution and use in source and binary forms, with or without
1410612SMarco.Elver@ARM.com# modification, are permitted provided that the following conditions are
1510612SMarco.Elver@ARM.com# met: redistributions of source code must retain the above copyright
1610612SMarco.Elver@ARM.com# notice, this list of conditions and the following disclaimer;
1710612SMarco.Elver@ARM.com# redistributions in binary form must reproduce the above copyright
1810612SMarco.Elver@ARM.com# notice, this list of conditions and the following disclaimer in the
1910612SMarco.Elver@ARM.com# documentation and/or other materials provided with the distribution;
2010612SMarco.Elver@ARM.com# neither the name of the copyright holders nor the names of its
2110612SMarco.Elver@ARM.com# contributors may be used to endorse or promote products derived from
2210612SMarco.Elver@ARM.com# this software without specific prior written permission.
2310612SMarco.Elver@ARM.com#
2410612SMarco.Elver@ARM.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2510612SMarco.Elver@ARM.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2610612SMarco.Elver@ARM.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2710612SMarco.Elver@ARM.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2810612SMarco.Elver@ARM.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2910612SMarco.Elver@ARM.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3010612SMarco.Elver@ARM.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3110612SMarco.Elver@ARM.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3210612SMarco.Elver@ARM.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3310612SMarco.Elver@ARM.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3410612SMarco.Elver@ARM.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3510612SMarco.Elver@ARM.com#
3610612SMarco.Elver@ARM.com# Authors: Radhika Jagtap
3710612SMarco.Elver@ARM.com#          Andreas Hansson
3810612SMarco.Elver@ARM.com
3910612SMarco.Elver@ARM.comimport argparse
4010612SMarco.Elver@ARM.com
4110612SMarco.Elver@ARM.comimport m5
4210612SMarco.Elver@ARM.comfrom m5.objects import *
4310612SMarco.Elver@ARM.comfrom m5.util import addToPath
4410612SMarco.Elver@ARM.comfrom m5.stats import periodicStatDump
4510612SMarco.Elver@ARM.com
4613892Sgabeblack@google.comaddToPath(os.getcwd() + '/configs/common')
4710612SMarco.Elver@ARM.comimport MemConfig
4810612SMarco.Elver@ARM.com
4910612SMarco.Elver@ARM.com# This script aims at triggering low power state transitions in the DRAM
5010612SMarco.Elver@ARM.com# controller. The traffic generator is used in DRAM mode and traffic
5110612SMarco.Elver@ARM.com# states target a different levels of bank utilization and strides.
5210612SMarco.Elver@ARM.com# At the end after sweeping through bank utilization and strides, we go
5310612SMarco.Elver@ARM.com# through an idle state with no requests to enforce self-refresh.
5410612SMarco.Elver@ARM.com
5510612SMarco.Elver@ARM.comparser = argparse.ArgumentParser(
5610612SMarco.Elver@ARM.com  formatter_class=argparse.ArgumentDefaultsHelpFormatter)
5710612SMarco.Elver@ARM.com
58# Use a single-channel DDR4-2400 in 16x4 configuration by default
59parser.add_argument("--mem-type", default="DDR4_2400_16x4",
60                    choices=MemConfig.mem_names(),
61                    help = "type of memory to use")
62
63parser.add_argument("--mem-ranks", "-r", type=int, default=1,
64                    help = "Number of ranks to iterate across")
65
66parser.add_argument("--page-policy", "-p",
67                    choices=["close_adaptive", "open_adaptive"],
68                    default="close_adaptive", help="controller page policy")
69
70parser.add_argument("--itt-list", "-t", default="1 20 100",
71                    help="a list of multipliers for the max value of itt, " \
72                    "e.g. \"1 20 100\"")
73
74parser.add_argument("--rd-perc", type=int, default=100,
75                    help = "Percentage of read commands")
76
77parser.add_argument("--addr-map", type=int, default=1,
78                    help = "0: RoCoRaBaCh; 1: RoRaBaCoCh/RoRaBaChCo")
79
80parser.add_argument("--idle-end", type=int, default=50000000,
81                    help = "time in ps of an idle period at the end ")
82
83args = parser.parse_args()
84
85# Start with the system itself, using a multi-layer 2.0 GHz
86# crossbar, delivering 64 bytes / 3 cycles (one header cycle)
87# which amounts to 42.7 GByte/s per layer and thus per port.
88system = System(membus = IOXBar(width = 32))
89system.clk_domain = SrcClockDomain(clock = '2.0GHz',
90                                   voltage_domain =
91                                   VoltageDomain(voltage = '1V'))
92
93# We are fine with 256 MB memory for now.
94mem_range = AddrRange('256MB')
95# Start address is 0
96system.mem_ranges = [mem_range]
97
98# Do not worry about reserving space for the backing store
99system.mmap_using_noreserve = True
100
101# Force a single channel to match the assumptions in the DRAM traffic
102# generator
103args.mem_channels = 1
104args.external_memory_system = 0
105args.tlm_memory = 0
106args.elastic_trace_en = 0
107MemConfig.config_mem(args, system)
108
109# Sanity check for memory controller class.
110if not isinstance(system.mem_ctrls[0], m5.objects.DRAMCtrl):
111    fatal("This script assumes the memory is a DRAMCtrl subclass")
112
113# There is no point slowing things down by saving any data.
114system.mem_ctrls[0].null = True
115
116# Set the address mapping based on input argument
117# Default to RoRaBaCoCh
118if args.addr_map == 0:
119   system.mem_ctrls[0].addr_mapping = "RoCoRaBaCh"
120elif args.addr_map == 1:
121   system.mem_ctrls[0].addr_mapping = "RoRaBaCoCh"
122else:
123    fatal("Did not specify a valid address map argument")
124
125system.mem_ctrls[0].page_policy = args.page_policy
126
127# We create a traffic generator state for each param combination we want to
128# test. Each traffic generator state is specified in the config file and the
129# generator remains in the state for specific period. This period is 0.25 ms.
130# Stats are dumped and reset at the state transition.
131period = 250000000
132
133# We specify the states in a config file input to the traffic generator.
134cfg_file_name = "configs/dram/lowp_sweep.cfg"
135cfg_file = open(cfg_file_name, 'w')
136
137# Get the number of banks
138nbr_banks = int(system.mem_ctrls[0].banks_per_rank.value)
139
140# determine the burst size in bytes
141burst_size = int((system.mem_ctrls[0].devices_per_rank.value *
142                  system.mem_ctrls[0].device_bus_width.value *
143                  system.mem_ctrls[0].burst_length.value) / 8)
144
145# next, get the page size in bytes (the rowbuffer size is already in bytes)
146page_size = system.mem_ctrls[0].devices_per_rank.value * \
147    system.mem_ctrls[0].device_rowbuffer_size.value
148
149# Inter-request delay should be such that we can hit as many transitions
150# to/from low power states as possible to. We provide a min and max itt to the
151# traffic generator and it randomises in the range. The parameter is in
152# seconds and we need it in ticks (ps).
153itt_min = system.mem_ctrls[0].tBURST.value * 1000000000000
154
155#The itt value when set to (tRAS + tRP + tCK) covers the case where
156# a read command is delayed beyond the delay from ACT to PRE_PDN entry of the
157# previous command. For write command followed by precharge, this delay
158# between a write and power down entry will be tRCD + tCL + tWR + tRP + tCK.
159# As we use this delay as a unit and create multiples of it as bigger delays
160# for the sweep, this parameter works for reads, writes and mix of them.
161pd_entry_time = (system.mem_ctrls[0].tRAS.value +
162                 system.mem_ctrls[0].tRP.value +
163                 system.mem_ctrls[0].tCK.value) * 1000000000000
164
165# We sweep itt max using the multipliers specified by the user.
166itt_max_str = args.itt_list.strip().split()
167itt_max_multiples = map(lambda x : int(x), itt_max_str)
168if len(itt_max_multiples) == 0:
169    fatal("String for itt-max-list detected empty\n")
170
171itt_max_values = map(lambda m : pd_entry_time * m, itt_max_multiples)
172
173# Generate request addresses in the entire range, assume we start at 0
174max_addr = mem_range.end
175
176# For max stride, use min of the page size and 512 bytes as that should be
177# more than enough
178max_stride = min(512, page_size)
179mid_stride = 4 * burst_size
180stride_values = [burst_size, mid_stride, max_stride]
181
182# be selective about bank utilization instead of going from 1 to the number of
183# banks
184bank_util_values = [1, int(nbr_banks/2), nbr_banks]
185
186# Next we create the config file, but first a comment
187cfg_file.write("""# STATE state# period mode=DRAM
188# read_percent start_addr end_addr req_size min_itt max_itt data_limit
189# stride_size page_size #banks #banks_util addr_map #ranks\n""")
190
191nxt_state = 0
192for itt_max in itt_max_values:
193    for bank in bank_util_values:
194        for stride_size in stride_values:
195            cfg_file.write("STATE %d %d %s %d 0 %d %d "
196                           "%d %d %d %d %d %d %d %d %d\n" %
197                           (nxt_state, period, "DRAM", args.rd_perc, max_addr,
198                            burst_size, itt_min, itt_max, 0, stride_size,
199                            page_size, nbr_banks, bank, args.addr_map,
200                            args.mem_ranks))
201            nxt_state = nxt_state + 1
202
203# State for idle period
204idle_period = args.idle_end
205cfg_file.write("STATE %d %d IDLE\n" % (nxt_state, idle_period))
206
207# Init state is state 0
208cfg_file.write("INIT 0\n")
209
210# Go through the states one by one
211for state in range(1, nxt_state + 1):
212    cfg_file.write("TRANSITION %d %d 1\n" % (state - 1, state))
213
214# Transition from last state to itself to not break the probability math
215cfg_file.write("TRANSITION %d %d 1\n" % (nxt_state, nxt_state))
216cfg_file.close()
217
218# create a traffic generator, and point it to the file we just created
219system.tgen = TrafficGen(config_file = cfg_file_name)
220
221# add a communication monitor
222system.monitor = CommMonitor()
223
224# connect the traffic generator to the bus via a communication monitor
225system.tgen.port = system.monitor.slave
226system.monitor.master = system.membus.slave
227
228# connect the system port even if it is not used in this example
229system.system_port = system.membus.slave
230
231# every period, dump and reset all stats
232periodicStatDump(period)
233
234root = Root(full_system = False, system = system)
235root.system.mem_mode = 'timing'
236
237m5.instantiate()
238
239# Simulate for exactly as long as it takes to go through all the states
240# This is why sim exists.
241m5.simulate(nxt_state * period + idle_period)
242print "--- Done DRAM low power sweep ---"
243print "Fixed params - "
244print "\tburst: %d, banks: %d, max stride: %d, itt min: %s ns" %  \
245  (burst_size, nbr_banks, max_stride, itt_min)
246print "Swept params - "
247print "\titt max multiples input:", itt_max_multiples
248print "\titt max values", itt_max_values
249print "\tbank utilization values", bank_util_values
250print "\tstride values:", stride_values
251print "Traffic gen config file:", cfg_file_name
252