memtest.py revision 6654
110690Sandreas.hansson@arm.com# Copyright (c) 2006-2007 The Regents of The University of Michigan 210690Sandreas.hansson@arm.com# All rights reserved. 310690Sandreas.hansson@arm.com# 410690Sandreas.hansson@arm.com# Redistribution and use in source and binary forms, with or without 510690Sandreas.hansson@arm.com# modification, are permitted provided that the following conditions are 610690Sandreas.hansson@arm.com# met: redistributions of source code must retain the above copyright 710690Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer; 810690Sandreas.hansson@arm.com# redistributions in binary form must reproduce the above copyright 910690Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer in the 1010690Sandreas.hansson@arm.com# documentation and/or other materials provided with the distribution; 1110690Sandreas.hansson@arm.com# neither the name of the copyright holders nor the names of its 1210690Sandreas.hansson@arm.com# contributors may be used to endorse or promote products derived from 134467Sstever@eecs.umich.edu# this software without specific prior written permission. 143354Srdreslin@umich.edu# 153354Srdreslin@umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 163354Srdreslin@umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 173354Srdreslin@umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 183354Srdreslin@umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 193354Srdreslin@umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 203354Srdreslin@umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 213354Srdreslin@umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 223354Srdreslin@umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 233354Srdreslin@umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 243354Srdreslin@umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 253354Srdreslin@umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 263354Srdreslin@umich.edu# 273354Srdreslin@umich.edu# Authors: Ron Dreslinski 283354Srdreslin@umich.edu 293354Srdreslin@umich.eduimport optparse 303354Srdreslin@umich.eduimport sys 313354Srdreslin@umich.edu 323354Srdreslin@umich.eduimport m5 333354Srdreslin@umich.edufrom m5.objects import * 343354Srdreslin@umich.edu 353354Srdreslin@umich.eduparser = optparse.OptionParser() 363354Srdreslin@umich.edu 373354Srdreslin@umich.eduparser.add_option("-a", "--atomic", action="store_true", 383354Srdreslin@umich.edu help="Use atomic (non-timing) mode") 393354Srdreslin@umich.eduparser.add_option("-b", "--blocking", action="store_true", 4010690Sandreas.hansson@arm.com help="Use blocking caches") 413354Srdreslin@umich.eduparser.add_option("-l", "--maxloads", metavar="N", default=0, 426654Snate@binkert.org help="Stop after N loads") 436654Snate@binkert.orgparser.add_option("-m", "--maxtick", type="int", default=m5.MaxTick, 446654Snate@binkert.org metavar="T", 453354Srdreslin@umich.edu help="Stop after T ticks") 463354Srdreslin@umich.edu 473354Srdreslin@umich.edu# 483354Srdreslin@umich.edu# The "tree" specification is a colon-separated list of one or more 493354Srdreslin@umich.edu# integers. The first integer is the number of caches/testers 504626Sstever@eecs.umich.edu# connected directly to main memory. The last integer in the list is 514626Sstever@eecs.umich.edu# the number of testers associated with the uppermost level of memory 524626Sstever@eecs.umich.edu# (L1 cache, if there are caches, or main memory if no caches). Thus 534626Sstever@eecs.umich.edu# if there is only one integer, there are no caches, and the integer 544893Sstever@eecs.umich.edu# specifies the number of testers connected directly to main memory. 554892Sstever@eecs.umich.edu# The other integers (if any) specify the number of caches at each 564626Sstever@eecs.umich.edu# level of the hierarchy between. 574626Sstever@eecs.umich.edu# 584626Sstever@eecs.umich.edu# Examples: 594626Sstever@eecs.umich.edu# 6010690Sandreas.hansson@arm.com# "2:1" Two caches connected to memory with a single tester behind each 6110690Sandreas.hansson@arm.com# (single-level hierarchy, two testers total) 6210690Sandreas.hansson@arm.com# 6310690Sandreas.hansson@arm.com# "2:2:1" Two-level hierarchy, 2 L1s behind each of 2 L2s, 4 testers total 6410690Sandreas.hansson@arm.com# 6510690Sandreas.hansson@arm.comparser.add_option("-t", "--treespec", type="string", default="8:1", 6610690Sandreas.hansson@arm.com help="Colon-separated multilevel tree specification, " 674892Sstever@eecs.umich.edu "see script comments for details " 6810690Sandreas.hansson@arm.com "[default: %default]") 6910690Sandreas.hansson@arm.com 7010690Sandreas.hansson@arm.comparser.add_option("--force-bus", action="store_true", 7110690Sandreas.hansson@arm.com help="Use bus between levels even with single cache") 7210690Sandreas.hansson@arm.com 7310690Sandreas.hansson@arm.comparser.add_option("-f", "--functional", type="int", default=0, 7410690Sandreas.hansson@arm.com metavar="PCT", 7510690Sandreas.hansson@arm.com help="Target percentage of functional accesses " 7610690Sandreas.hansson@arm.com "[default: %default]") 7710690Sandreas.hansson@arm.comparser.add_option("-u", "--uncacheable", type="int", default=0, 7810690Sandreas.hansson@arm.com metavar="PCT", 7910690Sandreas.hansson@arm.com help="Target percentage of uncacheable accesses " 8010690Sandreas.hansson@arm.com "[default: %default]") 814892Sstever@eecs.umich.edu 824892Sstever@eecs.umich.eduparser.add_option("--progress", type="int", default=1000, 8310690Sandreas.hansson@arm.com metavar="NLOADS", 8410690Sandreas.hansson@arm.com help="Progress message interval " 8510690Sandreas.hansson@arm.com "[default: %default]") 8610690Sandreas.hansson@arm.com 874626Sstever@eecs.umich.edu(options, args) = parser.parse_args() 884626Sstever@eecs.umich.edu 894626Sstever@eecs.umich.eduif args: 904626Sstever@eecs.umich.edu print "Error: script doesn't take any positional arguments" 914626Sstever@eecs.umich.edu sys.exit(1) 924626Sstever@eecs.umich.edu 934626Sstever@eecs.umich.edublock_size = 64 944626Sstever@eecs.umich.edu 953354Srdreslin@umich.edutry: 9610690Sandreas.hansson@arm.com treespec = [int(x) for x in options.treespec.split(':')] 974628Sstever@eecs.umich.edu numtesters = reduce(lambda x,y: x*y, treespec) 984628Sstever@eecs.umich.eduexcept: 994628Sstever@eecs.umich.edu print "Error parsing treespec option" 1009928SAli.Saidi@ARM.com sys.exit(1) 1019928SAli.Saidi@ARM.com 1029928SAli.Saidi@ARM.comif numtesters > block_size: 1039928SAli.Saidi@ARM.com print "Error: Number of testers limited to %s because of false sharing" \ 1044628Sstever@eecs.umich.edu % (block_size) 1053354Srdreslin@umich.edu sys.exit(1) 1063354Srdreslin@umich.edu 1073354Srdreslin@umich.eduif len(treespec) < 1: 1083354Srdreslin@umich.edu print "Error parsing treespec" 1093354Srdreslin@umich.edu sys.exit(1) 1103354Srdreslin@umich.edu 1114626Sstever@eecs.umich.edu# define prototype L1 cache 1124626Sstever@eecs.umich.eduproto_l1 = BaseCache(size = '32kB', assoc = 4, block_size = block_size, 11310705Sandreas.hansson@arm.com latency = '1ns', tgts_per_mshr = 8) 11410690Sandreas.hansson@arm.com 1154892Sstever@eecs.umich.eduif options.blocking: 11610690Sandreas.hansson@arm.com proto_l1.mshrs = 1 11710690Sandreas.hansson@arm.comelse: 1184892Sstever@eecs.umich.edu proto_l1.mshrs = 8 11910690Sandreas.hansson@arm.com 1204892Sstever@eecs.umich.edu# build a list of prototypes, one for each level of treespec, starting 1213354Srdreslin@umich.edu# at the end (last entry is tester objects) 12210690Sandreas.hansson@arm.comprototypes = [ MemTest(atomic=options.atomic, max_loads=options.maxloads, 12310690Sandreas.hansson@arm.com percent_functional=options.functional, 12410690Sandreas.hansson@arm.com percent_uncacheable=options.uncacheable, 12510690Sandreas.hansson@arm.com progress_interval=options.progress) ] 12610690Sandreas.hansson@arm.com 12710690Sandreas.hansson@arm.com# next comes L1 cache, if any 12810690Sandreas.hansson@arm.comif len(treespec) > 1: 12910690Sandreas.hansson@arm.com prototypes.insert(0, proto_l1) 13010690Sandreas.hansson@arm.com 13110690Sandreas.hansson@arm.com# now add additional cache levels (if any) by scaling L1 params 13210690Sandreas.hansson@arm.comwhile len(prototypes) < len(treespec): 13310690Sandreas.hansson@arm.com # clone previous level and update params 13410690Sandreas.hansson@arm.com prev = prototypes[0] 13510690Sandreas.hansson@arm.com next = prev() 13610690Sandreas.hansson@arm.com next.size = prev.size * 4 13710690Sandreas.hansson@arm.com next.latency = prev.latency * 10 13810690Sandreas.hansson@arm.com next.assoc = prev.assoc * 2 13910690Sandreas.hansson@arm.com prototypes.insert(0, next) 14010690Sandreas.hansson@arm.com 14110690Sandreas.hansson@arm.com# system simulated 14210690Sandreas.hansson@arm.comsystem = System(funcmem = PhysicalMemory(), 14310690Sandreas.hansson@arm.com physmem = PhysicalMemory(latency = "100ns")) 14410690Sandreas.hansson@arm.com 14510690Sandreas.hansson@arm.comdef make_level(spec, prototypes, attach_obj, attach_port): 14610690Sandreas.hansson@arm.com fanout = spec[0] 14710690Sandreas.hansson@arm.com parent = attach_obj # use attach obj as config parent too 14810690Sandreas.hansson@arm.com if len(spec) > 1 and (fanout > 1 or options.force_bus): 14910690Sandreas.hansson@arm.com new_bus = Bus(clock="500MHz", width=16) 15010690Sandreas.hansson@arm.com new_bus.port = getattr(attach_obj, attach_port) 15110690Sandreas.hansson@arm.com parent.cpu_side_bus = new_bus 15210690Sandreas.hansson@arm.com attach_obj = new_bus 15310690Sandreas.hansson@arm.com attach_port = "port" 15410690Sandreas.hansson@arm.com objs = [prototypes[0]() for i in xrange(fanout)] 15510690Sandreas.hansson@arm.com if len(spec) > 1: 1564890Sstever@eecs.umich.edu # we just built caches, more levels to go 1574626Sstever@eecs.umich.edu parent.cache = objs 1584626Sstever@eecs.umich.edu for cache in objs: 1594626Sstever@eecs.umich.edu cache.mem_side = getattr(attach_obj, attach_port) 1603354Srdreslin@umich.edu make_level(spec[1:], prototypes[1:], cache, "cpu_side") 16110690Sandreas.hansson@arm.com else: 1629815SAndreas Hansson <andreas.hansson> # we just built the MemTest objects 1639928SAli.Saidi@ARM.com parent.cpu = objs 16410690Sandreas.hansson@arm.com for t in objs: 1654890Sstever@eecs.umich.edu t.test = getattr(attach_obj, attach_port) 1664890Sstever@eecs.umich.edu t.functional = system.funcmem.port 1674890Sstever@eecs.umich.edu 1684890Sstever@eecs.umich.edumake_level(treespec, prototypes, system.physmem, "port") 1697656Ssteve.reinhardt@amd.com 1704890Sstever@eecs.umich.edu# ----------------------- 17110690Sandreas.hansson@arm.com# run simulation 1724890Sstever@eecs.umich.edu# ----------------------- 17310690Sandreas.hansson@arm.com 17410690Sandreas.hansson@arm.comroot = Root( system = system ) 17510690Sandreas.hansson@arm.comif options.atomic: 17610690Sandreas.hansson@arm.com root.system.mem_mode = 'atomic' 17710690Sandreas.hansson@arm.comelse: 1784890Sstever@eecs.umich.edu root.system.mem_mode = 'timing' 1797656Ssteve.reinhardt@amd.com 18010270Sradhika.jagtap@ARM.com# Not much point in this being higher than the L1 latency 18110270Sradhika.jagtap@ARM.comm5.ticks.setGlobalFrequency('1ns') 1827656Ssteve.reinhardt@amd.com 1837656Ssteve.reinhardt@amd.com# instantiate configuration 18410690Sandreas.hansson@arm.comm5.instantiate(root) 18510690Sandreas.hansson@arm.com 1864467Sstever@eecs.umich.edu# simulate until program terminates 18710690Sandreas.hansson@arm.comexit_event = m5.simulate(options.maxtick) 18810690Sandreas.hansson@arm.com 18910690Sandreas.hansson@arm.comprint 'Exiting @ tick', m5.curTick(), 'because', exit_event.getCause() 19010690Sandreas.hansson@arm.com