ruby_mem_test.py revision 8929:4148f9af0b70
111482Sandreas.sandberg@arm.com# Copyright (c) 2006-2007 The Regents of The University of Michigan 211482Sandreas.sandberg@arm.com# Copyright (c) 2009 Advanced Micro Devices, Inc. 311482Sandreas.sandberg@arm.com# All rights reserved. 411482Sandreas.sandberg@arm.com# 511482Sandreas.sandberg@arm.com# Redistribution and use in source and binary forms, with or without 611482Sandreas.sandberg@arm.com# modification, are permitted provided that the following conditions are 711482Sandreas.sandberg@arm.com# met: redistributions of source code must retain the above copyright 811482Sandreas.sandberg@arm.com# notice, this list of conditions and the following disclaimer; 911482Sandreas.sandberg@arm.com# redistributions in binary form must reproduce the above copyright 1011482Sandreas.sandberg@arm.com# notice, this list of conditions and the following disclaimer in the 1111482Sandreas.sandberg@arm.com# documentation and/or other materials provided with the distribution; 1211482Sandreas.sandberg@arm.com# neither the name of the copyright holders nor the names of its 1311482Sandreas.sandberg@arm.com# contributors may be used to endorse or promote products derived from 1411482Sandreas.sandberg@arm.com# this software without specific prior written permission. 1511482Sandreas.sandberg@arm.com# 1611482Sandreas.sandberg@arm.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1711482Sandreas.sandberg@arm.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1811482Sandreas.sandberg@arm.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1911482Sandreas.sandberg@arm.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2011482Sandreas.sandberg@arm.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2111482Sandreas.sandberg@arm.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2211482Sandreas.sandberg@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2311482Sandreas.sandberg@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2411482Sandreas.sandberg@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2511482Sandreas.sandberg@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2611482Sandreas.sandberg@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2711482Sandreas.sandberg@arm.com# 2811482Sandreas.sandberg@arm.com# Authors: Ron Dreslinski 2911482Sandreas.sandberg@arm.com# Brad Beckmann 3011482Sandreas.sandberg@arm.com 3111482Sandreas.sandberg@arm.comimport m5 3211482Sandreas.sandberg@arm.comfrom m5.objects import * 3311482Sandreas.sandberg@arm.comfrom m5.defines import buildEnv 3411482Sandreas.sandberg@arm.comfrom m5.util import addToPath 3511482Sandreas.sandberg@arm.comimport os, optparse, sys 3611482Sandreas.sandberg@arm.comaddToPath('../common') 3711482Sandreas.sandberg@arm.comaddToPath('../ruby') 3811482Sandreas.sandberg@arm.com 3911482Sandreas.sandberg@arm.comimport Options 4011482Sandreas.sandberg@arm.comimport Ruby 4111482Sandreas.sandberg@arm.com 4211482Sandreas.sandberg@arm.com# Get paths we might need. It's expected this file is in m5/configs/example. 4311482Sandreas.sandberg@arm.comconfig_path = os.path.dirname(os.path.abspath(__file__)) 4411482Sandreas.sandberg@arm.comconfig_root = os.path.dirname(config_path) 4511482Sandreas.sandberg@arm.comm5_root = os.path.dirname(config_root) 4611482Sandreas.sandberg@arm.com 4711482Sandreas.sandberg@arm.comparser = optparse.OptionParser() 4811482Sandreas.sandberg@arm.comOptions.addCommonOptions(parser) 4911482Sandreas.sandberg@arm.com 5011482Sandreas.sandberg@arm.comparser.add_option("-l", "--maxloads", metavar="N", default=0, 5111482Sandreas.sandberg@arm.com help="Stop after N loads") 5211482Sandreas.sandberg@arm.comparser.add_option("--progress", type="int", default=1000, 5311482Sandreas.sandberg@arm.com metavar="NLOADS", 5411482Sandreas.sandberg@arm.com help="Progress message interval " 5511482Sandreas.sandberg@arm.com "[default: %default]") 5611482Sandreas.sandberg@arm.comparser.add_option("--num-dmas", type="int", default=0, help="# of dma testers") 5711482Sandreas.sandberg@arm.comparser.add_option("--functional", type="int", default=0, 5811482Sandreas.sandberg@arm.com help="percentage of accesses that should be functional") 5911482Sandreas.sandberg@arm.comparser.add_option("--suppress-func-warnings", action="store_true", 6011482Sandreas.sandberg@arm.com help="suppress warnings when functional accesses fail") 6111482Sandreas.sandberg@arm.com 6211482Sandreas.sandberg@arm.com# 6311482Sandreas.sandberg@arm.com# Add the ruby specific and protocol specific options 6411482Sandreas.sandberg@arm.com# 6511482Sandreas.sandberg@arm.comRuby.define_options(parser) 6611482Sandreas.sandberg@arm.com 6711482Sandreas.sandberg@arm.comexecfile(os.path.join(config_root, "common", "Options.py")) 6811482Sandreas.sandberg@arm.com 6911482Sandreas.sandberg@arm.com(options, args) = parser.parse_args() 7011482Sandreas.sandberg@arm.com 7111482Sandreas.sandberg@arm.com# 7211482Sandreas.sandberg@arm.com# Set the default cache size and associativity to be very small to encourage 7311482Sandreas.sandberg@arm.com# races between requests and writebacks. 7411482Sandreas.sandberg@arm.com# 7511482Sandreas.sandberg@arm.comoptions.l1d_size="256B" 7611482Sandreas.sandberg@arm.comoptions.l1i_size="256B" 7711482Sandreas.sandberg@arm.comoptions.l2_size="512B" 7811482Sandreas.sandberg@arm.comoptions.l3_size="1kB" 7911482Sandreas.sandberg@arm.comoptions.l1d_assoc=2 8011482Sandreas.sandberg@arm.comoptions.l1i_assoc=2 8111482Sandreas.sandberg@arm.comoptions.l2_assoc=2 8211482Sandreas.sandberg@arm.comoptions.l3_assoc=2 8311482Sandreas.sandberg@arm.com 8411482Sandreas.sandberg@arm.comif args: 8511482Sandreas.sandberg@arm.com print "Error: script doesn't take any positional arguments" 8611482Sandreas.sandberg@arm.com sys.exit(1) 8711482Sandreas.sandberg@arm.com 8811482Sandreas.sandberg@arm.comblock_size = 64 8911482Sandreas.sandberg@arm.com 9011482Sandreas.sandberg@arm.comif options.num_cpus > block_size: 9111482Sandreas.sandberg@arm.com print "Error: Number of testers %d limited to %d because of false sharing" \ 9211482Sandreas.sandberg@arm.com % (options.num_cpus, block_size) 9311482Sandreas.sandberg@arm.com sys.exit(1) 9411482Sandreas.sandberg@arm.com 9511482Sandreas.sandberg@arm.com# 9611482Sandreas.sandberg@arm.com# Currently ruby does not support atomic or uncacheable accesses 9711482Sandreas.sandberg@arm.com# 9811482Sandreas.sandberg@arm.comcpus = [ MemTest(atomic = False, 9911482Sandreas.sandberg@arm.com max_loads = options.maxloads, 10011482Sandreas.sandberg@arm.com issue_dmas = False, 10111482Sandreas.sandberg@arm.com percent_functional = options.functional, 10211482Sandreas.sandberg@arm.com percent_uncacheable = 0, 10311482Sandreas.sandberg@arm.com progress_interval = options.progress, 10411482Sandreas.sandberg@arm.com suppress_func_warnings = options.suppress_func_warnings) \ 10511482Sandreas.sandberg@arm.com for i in xrange(options.num_cpus) ] 10611482Sandreas.sandberg@arm.com 10711482Sandreas.sandberg@arm.comsystem = System(cpu = cpus, 10811482Sandreas.sandberg@arm.com funcmem = PhysicalMemory(), 10911482Sandreas.sandberg@arm.com physmem = PhysicalMemory()) 11011482Sandreas.sandberg@arm.com 11111482Sandreas.sandberg@arm.comif options.num_dmas > 0: 11211482Sandreas.sandberg@arm.com dmas = [ MemTest(atomic = False, 11311482Sandreas.sandberg@arm.com max_loads = options.maxloads, 11411482Sandreas.sandberg@arm.com issue_dmas = True, 11511482Sandreas.sandberg@arm.com percent_functional = 0, 11611482Sandreas.sandberg@arm.com percent_uncacheable = 0, 11711482Sandreas.sandberg@arm.com progress_interval = options.progress, 11811482Sandreas.sandberg@arm.com suppress_func_warnings = 11911482Sandreas.sandberg@arm.com not options.suppress_func_warnings) \ 12011482Sandreas.sandberg@arm.com for i in xrange(options.num_dmas) ] 12111482Sandreas.sandberg@arm.com system.dma_devices = dmas 12211482Sandreas.sandberg@arm.comelse: 12311482Sandreas.sandberg@arm.com dmas = [] 12411482Sandreas.sandberg@arm.com 12511482Sandreas.sandberg@arm.comdma_ports = [] 12611482Sandreas.sandberg@arm.comfor (i, dma) in enumerate(dmas): 12711482Sandreas.sandberg@arm.com dma_ports.append(dma.test) 12811482Sandreas.sandberg@arm.comRuby.create_system(options, system, dma_ports = dma_ports) 12911482Sandreas.sandberg@arm.com 13011482Sandreas.sandberg@arm.com# 13111482Sandreas.sandberg@arm.com# The tester is most effective when randomization is turned on and 13211482Sandreas.sandberg@arm.com# artifical delay is randomly inserted on messages 13311482Sandreas.sandberg@arm.com# 13411482Sandreas.sandberg@arm.comsystem.ruby.randomization = True 13511482Sandreas.sandberg@arm.com 13611482Sandreas.sandberg@arm.comassert(len(cpus) == len(system.ruby._cpu_ruby_ports)) 13711482Sandreas.sandberg@arm.com 13811482Sandreas.sandberg@arm.comfor (i, cpu) in enumerate(cpus): 13911482Sandreas.sandberg@arm.com # 14011482Sandreas.sandberg@arm.com # Tie the cpu memtester ports to the correct system ports 14111482Sandreas.sandberg@arm.com # 14211482Sandreas.sandberg@arm.com cpu.test = system.ruby._cpu_ruby_ports[i].slave 14311482Sandreas.sandberg@arm.com cpu.functional = system.funcmem.port 14411482Sandreas.sandberg@arm.com 14511482Sandreas.sandberg@arm.com # 14611482Sandreas.sandberg@arm.com # Since the memtester is incredibly bursty, increase the deadlock 14711482Sandreas.sandberg@arm.com # threshold to 5 million cycles 14811482Sandreas.sandberg@arm.com # 14911482Sandreas.sandberg@arm.com system.ruby._cpu_ruby_ports[i].deadlock_threshold = 5000000 15011482Sandreas.sandberg@arm.com 15111482Sandreas.sandberg@arm.com # 15211482Sandreas.sandberg@arm.com # Ruby doesn't need the backing image of memory when running with 15311482Sandreas.sandberg@arm.com # the tester. 15411482Sandreas.sandberg@arm.com # 15511482Sandreas.sandberg@arm.com system.ruby._cpu_ruby_ports[i].access_phys_mem = False 15611482Sandreas.sandberg@arm.com 15711482Sandreas.sandberg@arm.comfor (i, dma) in enumerate(dmas): 15811482Sandreas.sandberg@arm.com # 15911482Sandreas.sandberg@arm.com # Tie the dma memtester ports to the correct functional port 16011482Sandreas.sandberg@arm.com # Note that the test port has already been connected to the dma_sequencer 16111482Sandreas.sandberg@arm.com # 16211482Sandreas.sandberg@arm.com dma.functional = system.funcmem.port 16311482Sandreas.sandberg@arm.com 16411482Sandreas.sandberg@arm.com# ----------------------- 16511482Sandreas.sandberg@arm.com# run simulation 16611482Sandreas.sandberg@arm.com# ----------------------- 16711482Sandreas.sandberg@arm.com 16811482Sandreas.sandberg@arm.comroot = Root( full_system = False, system = system ) 16911482Sandreas.sandberg@arm.comroot.system.mem_mode = 'timing' 17011482Sandreas.sandberg@arm.com 17111482Sandreas.sandberg@arm.com# Not much point in this being higher than the L1 latency 17211482Sandreas.sandberg@arm.comm5.ticks.setGlobalFrequency('1ns') 17311482Sandreas.sandberg@arm.com 17411482Sandreas.sandberg@arm.com# instantiate configuration 17511482Sandreas.sandberg@arm.comm5.instantiate() 17611482Sandreas.sandberg@arm.com 17711482Sandreas.sandberg@arm.com# simulate until program terminates 17811482Sandreas.sandberg@arm.comexit_event = m5.simulate(options.maxtick) 17911482Sandreas.sandberg@arm.com 18011482Sandreas.sandberg@arm.comprint 'Exiting @ tick', m5.curTick(), 'because', exit_event.getCause() 18111482Sandreas.sandberg@arm.com