memtest.py revision 8847
14467Sstever@eecs.umich.edu# Copyright (c) 2006-2007 The Regents of The University of Michigan 23354Srdreslin@umich.edu# All rights reserved. 33354Srdreslin@umich.edu# 43354Srdreslin@umich.edu# Redistribution and use in source and binary forms, with or without 53354Srdreslin@umich.edu# modification, are permitted provided that the following conditions are 63354Srdreslin@umich.edu# met: redistributions of source code must retain the above copyright 73354Srdreslin@umich.edu# notice, this list of conditions and the following disclaimer; 83354Srdreslin@umich.edu# redistributions in binary form must reproduce the above copyright 93354Srdreslin@umich.edu# notice, this list of conditions and the following disclaimer in the 103354Srdreslin@umich.edu# documentation and/or other materials provided with the distribution; 113354Srdreslin@umich.edu# neither the name of the copyright holders nor the names of its 123354Srdreslin@umich.edu# contributors may be used to endorse or promote products derived from 133354Srdreslin@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 296654Snate@binkert.orgimport optparse 306654Snate@binkert.orgimport sys 316654Snate@binkert.org 323354Srdreslin@umich.eduimport m5 333354Srdreslin@umich.edufrom m5.objects import * 343354Srdreslin@umich.edu 353354Srdreslin@umich.eduparser = optparse.OptionParser() 363354Srdreslin@umich.edu 374626Sstever@eecs.umich.eduparser.add_option("-a", "--atomic", action="store_true", 384626Sstever@eecs.umich.edu help="Use atomic (non-timing) mode") 394626Sstever@eecs.umich.eduparser.add_option("-b", "--blocking", action="store_true", 404626Sstever@eecs.umich.edu help="Use blocking caches") 414893Sstever@eecs.umich.eduparser.add_option("-l", "--maxloads", metavar="N", default=0, 424892Sstever@eecs.umich.edu help="Stop after N loads") 434626Sstever@eecs.umich.eduparser.add_option("-m", "--maxtick", type="int", default=m5.MaxTick, 444626Sstever@eecs.umich.edu metavar="T", 454626Sstever@eecs.umich.edu help="Stop after T ticks") 464626Sstever@eecs.umich.edu 474892Sstever@eecs.umich.edu# 484892Sstever@eecs.umich.edu# The "tree" specification is a colon-separated list of one or more 494892Sstever@eecs.umich.edu# integers. The first integer is the number of caches/testers 504892Sstever@eecs.umich.edu# connected directly to main memory. The last integer in the list is 514892Sstever@eecs.umich.edu# the number of testers associated with the uppermost level of memory 524892Sstever@eecs.umich.edu# (L1 cache, if there are caches, or main memory if no caches). Thus 534892Sstever@eecs.umich.edu# if there is only one integer, there are no caches, and the integer 544892Sstever@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 564892Sstever@eecs.umich.edu# level of the hierarchy between. 574892Sstever@eecs.umich.edu# 584892Sstever@eecs.umich.edu# Examples: 594892Sstever@eecs.umich.edu# 604892Sstever@eecs.umich.edu# "2:1" Two caches connected to memory with a single tester behind each 614892Sstever@eecs.umich.edu# (single-level hierarchy, two testers total) 624892Sstever@eecs.umich.edu# 634892Sstever@eecs.umich.edu# "2:2:1" Two-level hierarchy, 2 L1s behind each of 2 L2s, 4 testers total 644892Sstever@eecs.umich.edu# 654892Sstever@eecs.umich.eduparser.add_option("-t", "--treespec", type="string", default="8:1", 664892Sstever@eecs.umich.edu help="Colon-separated multilevel tree specification, " 674892Sstever@eecs.umich.edu "see script comments for details " 684892Sstever@eecs.umich.edu "[default: %default]") 694890Sstever@eecs.umich.edu 704891Sstever@eecs.umich.eduparser.add_option("--force-bus", action="store_true", 714891Sstever@eecs.umich.edu help="Use bus between levels even with single cache") 724890Sstever@eecs.umich.edu 734626Sstever@eecs.umich.eduparser.add_option("-f", "--functional", type="int", default=0, 744626Sstever@eecs.umich.edu metavar="PCT", 754626Sstever@eecs.umich.edu help="Target percentage of functional accesses " 764626Sstever@eecs.umich.edu "[default: %default]") 774626Sstever@eecs.umich.eduparser.add_option("-u", "--uncacheable", type="int", default=0, 784626Sstever@eecs.umich.edu metavar="PCT", 794626Sstever@eecs.umich.edu help="Target percentage of uncacheable accesses " 804626Sstever@eecs.umich.edu "[default: %default]") 813354Srdreslin@umich.edu 824628Sstever@eecs.umich.eduparser.add_option("--progress", type="int", default=1000, 834628Sstever@eecs.umich.edu metavar="NLOADS", 844628Sstever@eecs.umich.edu help="Progress message interval " 854628Sstever@eecs.umich.edu "[default: %default]") 864628Sstever@eecs.umich.edu 873354Srdreslin@umich.edu(options, args) = parser.parse_args() 883354Srdreslin@umich.edu 893354Srdreslin@umich.eduif args: 903354Srdreslin@umich.edu print "Error: script doesn't take any positional arguments" 913354Srdreslin@umich.edu sys.exit(1) 923354Srdreslin@umich.edu 934626Sstever@eecs.umich.edublock_size = 64 944626Sstever@eecs.umich.edu 954892Sstever@eecs.umich.edutry: 964892Sstever@eecs.umich.edu treespec = [int(x) for x in options.treespec.split(':')] 974892Sstever@eecs.umich.edu numtesters = reduce(lambda x,y: x*y, treespec) 984892Sstever@eecs.umich.eduexcept: 994892Sstever@eecs.umich.edu print "Error parsing treespec option" 1004892Sstever@eecs.umich.edu sys.exit(1) 1013354Srdreslin@umich.edu 1024890Sstever@eecs.umich.eduif numtesters > block_size: 1034626Sstever@eecs.umich.edu print "Error: Number of testers limited to %s because of false sharing" \ 1044626Sstever@eecs.umich.edu % (block_size) 1054626Sstever@eecs.umich.edu sys.exit(1) 1063354Srdreslin@umich.edu 1074890Sstever@eecs.umich.eduif len(treespec) < 1: 1084890Sstever@eecs.umich.edu print "Error parsing treespec" 1094890Sstever@eecs.umich.edu sys.exit(1) 1104890Sstever@eecs.umich.edu 1114890Sstever@eecs.umich.edu# define prototype L1 cache 1124890Sstever@eecs.umich.eduproto_l1 = BaseCache(size = '32kB', assoc = 4, block_size = block_size, 1134890Sstever@eecs.umich.edu latency = '1ns', tgts_per_mshr = 8) 1144890Sstever@eecs.umich.edu 1154890Sstever@eecs.umich.eduif options.blocking: 1164890Sstever@eecs.umich.edu proto_l1.mshrs = 1 1174890Sstever@eecs.umich.eduelse: 1187656Ssteve.reinhardt@amd.com proto_l1.mshrs = 4 1194890Sstever@eecs.umich.edu 1204893Sstever@eecs.umich.edu# build a list of prototypes, one for each level of treespec, starting 1214893Sstever@eecs.umich.edu# at the end (last entry is tester objects) 1224893Sstever@eecs.umich.eduprototypes = [ MemTest(atomic=options.atomic, max_loads=options.maxloads, 1234890Sstever@eecs.umich.edu percent_functional=options.functional, 1244890Sstever@eecs.umich.edu percent_uncacheable=options.uncacheable, 1254890Sstever@eecs.umich.edu progress_interval=options.progress) ] 1264890Sstever@eecs.umich.edu 1274893Sstever@eecs.umich.edu# next comes L1 cache, if any 1284893Sstever@eecs.umich.eduif len(treespec) > 1: 1294893Sstever@eecs.umich.edu prototypes.insert(0, proto_l1) 1304893Sstever@eecs.umich.edu 1314893Sstever@eecs.umich.edu# now add additional cache levels (if any) by scaling L1 params 1327656Ssteve.reinhardt@amd.comfor scale in treespec[:-2]: 1334890Sstever@eecs.umich.edu # clone previous level and update params 1344890Sstever@eecs.umich.edu prev = prototypes[0] 1354890Sstever@eecs.umich.edu next = prev() 1367656Ssteve.reinhardt@amd.com next.size = prev.size * scale 1374890Sstever@eecs.umich.edu next.latency = prev.latency * 10 1387656Ssteve.reinhardt@amd.com next.assoc = prev.assoc * scale 1397656Ssteve.reinhardt@amd.com next.mshrs = prev.mshrs * scale 1404890Sstever@eecs.umich.edu prototypes.insert(0, next) 1414467Sstever@eecs.umich.edu 1423354Srdreslin@umich.edu# system simulated 1434890Sstever@eecs.umich.edusystem = System(funcmem = PhysicalMemory(), 1444890Sstever@eecs.umich.edu physmem = PhysicalMemory(latency = "100ns")) 1453354Srdreslin@umich.edu 1464890Sstever@eecs.umich.edudef make_level(spec, prototypes, attach_obj, attach_port): 1474890Sstever@eecs.umich.edu fanout = spec[0] 1484890Sstever@eecs.umich.edu parent = attach_obj # use attach obj as config parent too 1494895Sstever@eecs.umich.edu if len(spec) > 1 and (fanout > 1 or options.force_bus): 1508847Sandreas.hansson@arm.com port = getattr(attach_obj, attach_port) 1514890Sstever@eecs.umich.edu new_bus = Bus(clock="500MHz", width=16) 1528847Sandreas.hansson@arm.com if (port.role == 'MASTER'): 1538847Sandreas.hansson@arm.com new_bus.slave = port 1548847Sandreas.hansson@arm.com attach_port = "master" 1558847Sandreas.hansson@arm.com else: 1568847Sandreas.hansson@arm.com new_bus.master = port 1578847Sandreas.hansson@arm.com attach_port = "slave" 1584890Sstever@eecs.umich.edu parent.cpu_side_bus = new_bus 1594890Sstever@eecs.umich.edu attach_obj = new_bus 1604890Sstever@eecs.umich.edu objs = [prototypes[0]() for i in xrange(fanout)] 1614890Sstever@eecs.umich.edu if len(spec) > 1: 1624890Sstever@eecs.umich.edu # we just built caches, more levels to go 1634890Sstever@eecs.umich.edu parent.cache = objs 1644890Sstever@eecs.umich.edu for cache in objs: 1654890Sstever@eecs.umich.edu cache.mem_side = getattr(attach_obj, attach_port) 1664890Sstever@eecs.umich.edu make_level(spec[1:], prototypes[1:], cache, "cpu_side") 1674890Sstever@eecs.umich.edu else: 1684890Sstever@eecs.umich.edu # we just built the MemTest objects 1694890Sstever@eecs.umich.edu parent.cpu = objs 1704890Sstever@eecs.umich.edu for t in objs: 1714890Sstever@eecs.umich.edu t.test = getattr(attach_obj, attach_port) 1724890Sstever@eecs.umich.edu t.functional = system.funcmem.port 1733354Srdreslin@umich.edu 1744890Sstever@eecs.umich.edumake_level(treespec, prototypes, system.physmem, "port") 1753354Srdreslin@umich.edu 1763354Srdreslin@umich.edu# ----------------------- 1773354Srdreslin@umich.edu# run simulation 1783354Srdreslin@umich.edu# ----------------------- 1793354Srdreslin@umich.edu 1808801Sgblack@eecs.umich.eduroot = Root( full_system = False, system = system ) 1814626Sstever@eecs.umich.eduif options.atomic: 1824626Sstever@eecs.umich.edu root.system.mem_mode = 'atomic' 1834626Sstever@eecs.umich.eduelse: 1843354Srdreslin@umich.edu root.system.mem_mode = 'timing' 1853354Srdreslin@umich.edu 1868847Sandreas.hansson@arm.com# The system port is never used in the tester so merely connect it 1878847Sandreas.hansson@arm.com# to avoid problems 1888847Sandreas.hansson@arm.comroot.system.system_port = root.system.physmem.port 1898847Sandreas.hansson@arm.com 1904476Sstever@eecs.umich.edu# Not much point in this being higher than the L1 latency 1914476Sstever@eecs.umich.edum5.ticks.setGlobalFrequency('1ns') 1924476Sstever@eecs.umich.edu 1933354Srdreslin@umich.edu# instantiate configuration 1947525Ssteve.reinhardt@amd.comm5.instantiate() 1953354Srdreslin@umich.edu 1963354Srdreslin@umich.edu# simulate until program terminates 1974626Sstever@eecs.umich.eduexit_event = m5.simulate(options.maxtick) 1983354Srdreslin@umich.edu 1993354Srdreslin@umich.eduprint 'Exiting @ tick', m5.curTick(), 'because', exit_event.getCause() 200