memtest.py revision 9267:f8c85a7d109f
16157Snate@binkert.org# Copyright (c) 2006-2007 The Regents of The University of Michigan
26157Snate@binkert.org# All rights reserved.
36157Snate@binkert.org#
46157Snate@binkert.org# Redistribution and use in source and binary forms, with or without
56157Snate@binkert.org# modification, are permitted provided that the following conditions are
66157Snate@binkert.org# met: redistributions of source code must retain the above copyright
76157Snate@binkert.org# notice, this list of conditions and the following disclaimer;
86157Snate@binkert.org# redistributions in binary form must reproduce the above copyright
96157Snate@binkert.org# notice, this list of conditions and the following disclaimer in the
106157Snate@binkert.org# documentation and/or other materials provided with the distribution;
116157Snate@binkert.org# neither the name of the copyright holders nor the names of its
126157Snate@binkert.org# contributors may be used to endorse or promote products derived from
136157Snate@binkert.org# this software without specific prior written permission.
146157Snate@binkert.org#
156157Snate@binkert.org# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
166157Snate@binkert.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
176157Snate@binkert.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
186157Snate@binkert.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
196157Snate@binkert.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
206157Snate@binkert.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
216157Snate@binkert.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
226157Snate@binkert.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
236157Snate@binkert.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
246157Snate@binkert.org# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
256157Snate@binkert.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
266157Snate@binkert.org#
276157Snate@binkert.org# Authors: Ron Dreslinski
286157Snate@binkert.org
296157Snate@binkert.orgimport optparse
306157Snate@binkert.orgimport sys
3112563Sgabeblack@google.com
3212563Sgabeblack@google.comimport m5
336157Snate@binkert.orgfrom m5.objects import *
346157Snate@binkert.org
356157Snate@binkert.orgparser = optparse.OptionParser()
366157Snate@binkert.org
376157Snate@binkert.orgparser.add_option("-a", "--atomic", action="store_true",
386157Snate@binkert.org                  help="Use atomic (non-timing) mode")
396157Snate@binkert.orgparser.add_option("-b", "--blocking", action="store_true",
4012246Sgabeblack@google.com                  help="Use blocking caches")
4112246Sgabeblack@google.comparser.add_option("-l", "--maxloads", metavar="N", default=0,
426157Snate@binkert.org                  help="Stop after N loads")
436157Snate@binkert.orgparser.add_option("-m", "--maxtick", type="int", default=m5.MaxTick,
4412892Sbrandon.potter@amd.com                  metavar="T",
4512892Sbrandon.potter@amd.com                  help="Stop after T ticks")
4612892Sbrandon.potter@amd.com
4710133Sandreas.hansson@arm.com#
4810133Sandreas.hansson@arm.com# The "tree" specification is a colon-separated list of one or more
4910133Sandreas.hansson@arm.com# integers.  The first integer is the number of caches/testers
5010133Sandreas.hansson@arm.com# connected directly to main memory.  The last integer in the list is
5110133Sandreas.hansson@arm.com# the number of testers associated with the uppermost level of memory
5210133Sandreas.hansson@arm.com# (L1 cache, if there are caches, or main memory if no caches).  Thus
5310133Sandreas.hansson@arm.com# if there is only one integer, there are no caches, and the integer
5410133Sandreas.hansson@arm.com# specifies the number of testers connected directly to main memory.
5510133Sandreas.hansson@arm.com# The other integers (if any) specify the number of caches at each
5610133Sandreas.hansson@arm.com# level of the hierarchy between.
5710133Sandreas.hansson@arm.com#
5810133Sandreas.hansson@arm.com# Examples:
5910133Sandreas.hansson@arm.com#
6010133Sandreas.hansson@arm.com#  "2:1"    Two caches connected to memory with a single tester behind each
6110133Sandreas.hansson@arm.com#           (single-level hierarchy, two testers total)
6210133Sandreas.hansson@arm.com#
6310133Sandreas.hansson@arm.com#  "2:2:1"  Two-level hierarchy, 2 L1s behind each of 2 L2s, 4 testers total
6410133Sandreas.hansson@arm.com#
6511755Sandreas.hansson@arm.comparser.add_option("-t", "--treespec", type="string", default="8:1",
6610133Sandreas.hansson@arm.com                  help="Colon-separated multilevel tree specification, "
6710133Sandreas.hansson@arm.com                  "see script comments for details "
686157Snate@binkert.org                  "[default: %default]")
696157Snate@binkert.org
706157Snate@binkert.orgparser.add_option("--force-bus", action="store_true",
716157Snate@binkert.org                  help="Use bus between levels even with single cache")
726157Snate@binkert.org
736157Snate@binkert.orgparser.add_option("-f", "--functional", type="int", default=0,
746157Snate@binkert.org                  metavar="PCT",
756157Snate@binkert.org                  help="Target percentage of functional accesses "
766157Snate@binkert.org                  "[default: %default]")
776157Snate@binkert.orgparser.add_option("-u", "--uncacheable", type="int", default=0,
786157Snate@binkert.org                  metavar="PCT",
796157Snate@binkert.org                  help="Target percentage of uncacheable accesses "
806157Snate@binkert.org                  "[default: %default]")
816157Snate@binkert.org
826157Snate@binkert.orgparser.add_option("--progress", type="int", default=1000,
836157Snate@binkert.org                  metavar="NLOADS",
846157Snate@binkert.org                  help="Progress message interval "
856157Snate@binkert.org                  "[default: %default]")
866157Snate@binkert.org
876157Snate@binkert.org(options, args) = parser.parse_args()
886157Snate@binkert.org
896157Snate@binkert.orgif args:
906157Snate@binkert.org     print "Error: script doesn't take any positional arguments"
916157Snate@binkert.org     sys.exit(1)
926157Snate@binkert.org
936157Snate@binkert.orgblock_size = 64
946157Snate@binkert.org
956157Snate@binkert.orgtry:
966157Snate@binkert.org     treespec = [int(x) for x in options.treespec.split(':')]
976157Snate@binkert.org     numtesters = reduce(lambda x,y: x*y, treespec)
986157Snate@binkert.orgexcept:
996157Snate@binkert.org     print "Error parsing treespec option"
1006157Snate@binkert.org     sys.exit(1)
1016157Snate@binkert.org
1026157Snate@binkert.orgif numtesters > block_size:
1036157Snate@binkert.org     print "Error: Number of testers limited to %s because of false sharing" \
1046157Snate@binkert.org           % (block_size)
1056157Snate@binkert.org     sys.exit(1)
10612563Sgabeblack@google.com
1076157Snate@binkert.orgif len(treespec) < 1:
1086157Snate@binkert.org     print "Error parsing treespec"
1096157Snate@binkert.org     sys.exit(1)
1106157Snate@binkert.org
1118483Sgblack@eecs.umich.edu# define prototype L1 cache
1128483Sgblack@eecs.umich.eduproto_l1 = BaseCache(size = '32kB', assoc = 4, block_size = block_size,
1136157Snate@binkert.org                     hit_latency = '1ns', response_latency = '1ns',
1146882SBrad.Beckmann@amd.com                     tgts_per_mshr = 8)
1156286Snate@binkert.org
1166286Snate@binkert.orgif options.blocking:
1178092Snilay@cs.wisc.edu     proto_l1.mshrs = 1
1186286Snate@binkert.orgelse:
1196286Snate@binkert.org     proto_l1.mshrs = 4
1206157Snate@binkert.org
12111208Sjoseph.gross@amd.com# build a list of prototypes, one for each level of treespec, starting
1226157Snate@binkert.org# at the end (last entry is tester objects)
12311210SBrad.Beckmann@amd.comprototypes = [ MemTest(atomic=options.atomic, max_loads=options.maxloads,
12410301Snilay@cs.wisc.edu                       percent_functional=options.functional,
1256157Snate@binkert.org                       percent_uncacheable=options.uncacheable,
1266157Snate@binkert.org                       progress_interval=options.progress) ]
12711307Santhony.gutierrez@amd.com
12811122Snilay@cs.wisc.edu# next comes L1 cache, if any
12910301Snilay@cs.wisc.eduif len(treespec) > 1:
13010301Snilay@cs.wisc.edu     prototypes.insert(0, proto_l1)
13110301Snilay@cs.wisc.edu
13210301Snilay@cs.wisc.edu# now add additional cache levels (if any) by scaling L1 params
13310301Snilay@cs.wisc.edufor scale in treespec[:-2]:
13411308Santhony.gutierrez@amd.com     # clone previous level and update params
13510301Snilay@cs.wisc.edu     prev = prototypes[0]
13610301Snilay@cs.wisc.edu     next = prev()
13711308Santhony.gutierrez@amd.com     next.size = prev.size * scale
13811308Santhony.gutierrez@amd.com     next.latency = prev.latency * 10
13911308Santhony.gutierrez@amd.com     next.assoc = prev.assoc * scale
14011308Santhony.gutierrez@amd.com     next.mshrs = prev.mshrs * scale
14111308Santhony.gutierrez@amd.com     prototypes.insert(0, next)
14211308Santhony.gutierrez@amd.com
14311308Santhony.gutierrez@amd.com# system simulated
14411308Santhony.gutierrez@amd.comsystem = System(funcmem = SimpleMemory(in_addr_map = False),
14511308Santhony.gutierrez@amd.com                funcbus = NoncoherentBus(),
14611308Santhony.gutierrez@amd.com                physmem = SimpleMemory(latency = "100ns"))
147
148def make_level(spec, prototypes, attach_obj, attach_port):
149     fanout = spec[0]
150     parent = attach_obj # use attach obj as config parent too
151     if len(spec) > 1 and (fanout > 1 or options.force_bus):
152          port = getattr(attach_obj, attach_port)
153          new_bus = CoherentBus(clock="500MHz", width=16)
154          if (port.role == 'MASTER'):
155               new_bus.slave = port
156               attach_port = "master"
157          else:
158               new_bus.master = port
159               attach_port = "slave"
160          parent.cpu_side_bus = new_bus
161          attach_obj = new_bus
162     objs = [prototypes[0]() for i in xrange(fanout)]
163     if len(spec) > 1:
164          # we just built caches, more levels to go
165          parent.cache = objs
166          for cache in objs:
167               cache.mem_side = getattr(attach_obj, attach_port)
168               make_level(spec[1:], prototypes[1:], cache, "cpu_side")
169     else:
170          # we just built the MemTest objects
171          parent.cpu = objs
172          for t in objs:
173               t.test = getattr(attach_obj, attach_port)
174               t.functional = system.funcbus.slave
175
176make_level(treespec, prototypes, system.physmem, "port")
177
178# connect reference memory to funcbus
179system.funcbus.master = system.funcmem.port
180
181# -----------------------
182# run simulation
183# -----------------------
184
185root = Root( full_system = False, system = system )
186if options.atomic:
187    root.system.mem_mode = 'atomic'
188else:
189    root.system.mem_mode = 'timing'
190
191# The system port is never used in the tester so merely connect it
192# to avoid problems
193root.system.system_port = root.system.funcbus.slave
194
195# Not much point in this being higher than the L1 latency
196m5.ticks.setGlobalFrequency('1ns')
197
198# instantiate configuration
199m5.instantiate()
200
201# simulate until program terminates
202exit_event = m5.simulate(options.maxtick)
203
204print 'Exiting @ tick', m5.curTick(), 'because', exit_event.getCause()
205