memtest.py revision 4891
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 293354Srdreslin@umich.eduimport m5 303354Srdreslin@umich.edufrom m5.objects import * 313354Srdreslin@umich.eduimport os, optparse, sys 323354Srdreslin@umich.edum5.AddToPath('../common') 333354Srdreslin@umich.edu 343354Srdreslin@umich.eduparser = optparse.OptionParser() 353354Srdreslin@umich.edu 364626Sstever@eecs.umich.eduparser.add_option("-c", "--cache-levels", type="int", default=2, 374626Sstever@eecs.umich.edu metavar="LEVELS", 384626Sstever@eecs.umich.edu help="Number of cache levels [default: %default]") 394626Sstever@eecs.umich.eduparser.add_option("-a", "--atomic", action="store_true", 404626Sstever@eecs.umich.edu help="Use atomic (non-timing) mode") 414626Sstever@eecs.umich.eduparser.add_option("-b", "--blocking", action="store_true", 424626Sstever@eecs.umich.edu help="Use blocking caches") 434626Sstever@eecs.umich.eduparser.add_option("-l", "--maxloads", default="1G", metavar="N", 444626Sstever@eecs.umich.edu help="Stop after N loads [default: %default]") 454626Sstever@eecs.umich.eduparser.add_option("-m", "--maxtick", type="int", default=m5.MaxTick, 464626Sstever@eecs.umich.edu metavar="T", 474626Sstever@eecs.umich.edu help="Stop after T ticks") 484626Sstever@eecs.umich.eduparser.add_option("-n", "--numtesters", type="int", default=8, 494626Sstever@eecs.umich.edu metavar="N", 504626Sstever@eecs.umich.edu help="Number of tester pseudo-CPUs [default: %default]") 514626Sstever@eecs.umich.edu 524890Sstever@eecs.umich.eduparser.add_option("-t", "--treespec", type="string", 534890Sstever@eecs.umich.edu help="Colon-separated multilevel tree specification") 544890Sstever@eecs.umich.edu 554891Sstever@eecs.umich.eduparser.add_option("--force-bus", action="store_true", 564891Sstever@eecs.umich.edu help="Use bus between levels even with single cache") 574890Sstever@eecs.umich.edu 584626Sstever@eecs.umich.eduparser.add_option("-f", "--functional", type="int", default=0, 594626Sstever@eecs.umich.edu metavar="PCT", 604626Sstever@eecs.umich.edu help="Target percentage of functional accesses " 614626Sstever@eecs.umich.edu "[default: %default]") 624626Sstever@eecs.umich.eduparser.add_option("-u", "--uncacheable", type="int", default=0, 634626Sstever@eecs.umich.edu metavar="PCT", 644626Sstever@eecs.umich.edu help="Target percentage of uncacheable accesses " 654626Sstever@eecs.umich.edu "[default: %default]") 663354Srdreslin@umich.edu 674628Sstever@eecs.umich.eduparser.add_option("--progress", type="int", default=1000, 684628Sstever@eecs.umich.edu metavar="NLOADS", 694628Sstever@eecs.umich.edu help="Progress message interval " 704628Sstever@eecs.umich.edu "[default: %default]") 714628Sstever@eecs.umich.edu 723354Srdreslin@umich.edu(options, args) = parser.parse_args() 733354Srdreslin@umich.edu 743354Srdreslin@umich.eduif args: 753354Srdreslin@umich.edu print "Error: script doesn't take any positional arguments" 763354Srdreslin@umich.edu sys.exit(1) 773354Srdreslin@umich.edu 784626Sstever@eecs.umich.edublock_size = 64 794626Sstever@eecs.umich.edu 804890Sstever@eecs.umich.eduif not options.treespec: 814890Sstever@eecs.umich.edu # convert simple cache_levels option to treespec 824890Sstever@eecs.umich.edu treespec = [options.numtesters, 1] 834890Sstever@eecs.umich.edu numtesters = options.numtesters 844890Sstever@eecs.umich.eduelse: 854890Sstever@eecs.umich.edu try: 864890Sstever@eecs.umich.edu treespec = [int(x) for x in options.treespec.split(':')] 874890Sstever@eecs.umich.edu numtesters = reduce(lambda x,y: x*y, treespec) 884890Sstever@eecs.umich.edu except: 894890Sstever@eecs.umich.edu print "Error parsing treespec option" 904890Sstever@eecs.umich.edu sys.exit(1) 913354Srdreslin@umich.edu 924890Sstever@eecs.umich.eduif numtesters > block_size: 934626Sstever@eecs.umich.edu print "Error: Number of testers limited to %s because of false sharing" \ 944626Sstever@eecs.umich.edu % (block_size) 954626Sstever@eecs.umich.edu sys.exit(1) 963354Srdreslin@umich.edu 974890Sstever@eecs.umich.eduif len(treespec) < 1: 984890Sstever@eecs.umich.edu print "Error parsing treespec" 994890Sstever@eecs.umich.edu sys.exit(1) 1004890Sstever@eecs.umich.edu 1014890Sstever@eecs.umich.edu# define prototype L1 cache 1024890Sstever@eecs.umich.eduproto_l1 = BaseCache(size = '32kB', assoc = 4, block_size = block_size, 1034890Sstever@eecs.umich.edu latency = '1ns', tgts_per_mshr = 8) 1044890Sstever@eecs.umich.edu 1054890Sstever@eecs.umich.eduif options.blocking: 1064890Sstever@eecs.umich.edu proto_l1.mshrs = 1 1074890Sstever@eecs.umich.eduelse: 1084890Sstever@eecs.umich.edu proto_l1.mshrs = 8 1094890Sstever@eecs.umich.edu 1104890Sstever@eecs.umich.edu# build a list of prototypes, one for each cache level (L1 is at end, 1114890Sstever@eecs.umich.edu# followed by the tester pseudo-cpu objects) 1124890Sstever@eecs.umich.eduprototypes = [ proto_l1, 1134890Sstever@eecs.umich.edu MemTest(atomic=options.atomic, max_loads=options.maxloads, 1144890Sstever@eecs.umich.edu percent_functional=options.functional, 1154890Sstever@eecs.umich.edu percent_uncacheable=options.uncacheable, 1164890Sstever@eecs.umich.edu progress_interval=options.progress) ] 1174890Sstever@eecs.umich.edu 1184890Sstever@eecs.umich.eduwhile len(prototypes) < len(treespec): 1194890Sstever@eecs.umich.edu # clone previous level and update params 1204890Sstever@eecs.umich.edu prev = prototypes[0] 1214890Sstever@eecs.umich.edu next = prev() 1224890Sstever@eecs.umich.edu next.size = prev.size * 4 1234890Sstever@eecs.umich.edu next.latency = prev.latency * 10 1244890Sstever@eecs.umich.edu next.assoc = prev.assoc * 2 1254890Sstever@eecs.umich.edu prototypes.insert(0, next) 1264467Sstever@eecs.umich.edu 1273354Srdreslin@umich.edu# system simulated 1284890Sstever@eecs.umich.edusystem = System(funcmem = PhysicalMemory(), 1294890Sstever@eecs.umich.edu physmem = PhysicalMemory(latency = "100ns")) 1303354Srdreslin@umich.edu 1314890Sstever@eecs.umich.edudef make_level(spec, prototypes, attach_obj, attach_port): 1324890Sstever@eecs.umich.edu fanout = spec[0] 1334890Sstever@eecs.umich.edu parent = attach_obj # use attach obj as config parent too 1344891Sstever@eecs.umich.edu if fanout > 1 or options.force_bus: 1354890Sstever@eecs.umich.edu new_bus = Bus(clock="500MHz", width=16) 1364890Sstever@eecs.umich.edu new_bus.port = getattr(attach_obj, attach_port) 1374890Sstever@eecs.umich.edu parent.cpu_side_bus = new_bus 1384890Sstever@eecs.umich.edu attach_obj = new_bus 1394890Sstever@eecs.umich.edu attach_port = "port" 1404890Sstever@eecs.umich.edu objs = [prototypes[0]() for i in xrange(fanout)] 1414890Sstever@eecs.umich.edu if len(spec) > 1: 1424890Sstever@eecs.umich.edu # we just built caches, more levels to go 1434890Sstever@eecs.umich.edu parent.cache = objs 1444890Sstever@eecs.umich.edu for cache in objs: 1454890Sstever@eecs.umich.edu cache.mem_side = getattr(attach_obj, attach_port) 1464890Sstever@eecs.umich.edu make_level(spec[1:], prototypes[1:], cache, "cpu_side") 1474890Sstever@eecs.umich.edu else: 1484890Sstever@eecs.umich.edu # we just built the MemTest objects 1494890Sstever@eecs.umich.edu parent.cpu = objs 1504890Sstever@eecs.umich.edu for t in objs: 1514890Sstever@eecs.umich.edu t.test = getattr(attach_obj, attach_port) 1524890Sstever@eecs.umich.edu t.functional = system.funcmem.port 1533354Srdreslin@umich.edu 1544890Sstever@eecs.umich.edumake_level(treespec, prototypes, system.physmem, "port") 1553354Srdreslin@umich.edu 1563354Srdreslin@umich.edu# ----------------------- 1573354Srdreslin@umich.edu# run simulation 1583354Srdreslin@umich.edu# ----------------------- 1593354Srdreslin@umich.edu 1603354Srdreslin@umich.eduroot = Root( system = system ) 1614626Sstever@eecs.umich.eduif options.atomic: 1624626Sstever@eecs.umich.edu root.system.mem_mode = 'atomic' 1634626Sstever@eecs.umich.eduelse: 1643354Srdreslin@umich.edu root.system.mem_mode = 'timing' 1653354Srdreslin@umich.edu 1664476Sstever@eecs.umich.edu# Not much point in this being higher than the L1 latency 1674476Sstever@eecs.umich.edum5.ticks.setGlobalFrequency('1ns') 1684476Sstever@eecs.umich.edu 1693354Srdreslin@umich.edu# instantiate configuration 1703354Srdreslin@umich.edum5.instantiate(root) 1713354Srdreslin@umich.edu 1723354Srdreslin@umich.edu# simulate until program terminates 1734626Sstever@eecs.umich.eduexit_event = m5.simulate(options.maxtick) 1743354Srdreslin@umich.edu 1753354Srdreslin@umich.eduprint 'Exiting @ tick', m5.curTick(), 'because', exit_event.getCause() 176