se.py revision 13684:076506a21535
1# Copyright (c) 2012-2013 ARM Limited 2# All rights reserved. 3# 4# The license below extends only to copyright in the software and shall 5# not be construed as granting a license to any other intellectual 6# property including but not limited to intellectual property relating 7# to a hardware implementation of the functionality of the software 8# licensed hereunder. You may use the software subject to the license 9# terms below provided that you ensure that this notice is replicated 10# unmodified and in its entirety in all distributions of the software, 11# modified or unmodified, in source code or in binary form. 12# 13# Copyright (c) 2006-2008 The Regents of The University of Michigan 14# All rights reserved. 15# 16# Redistribution and use in source and binary forms, with or without 17# modification, are permitted provided that the following conditions are 18# met: redistributions of source code must retain the above copyright 19# notice, this list of conditions and the following disclaimer; 20# redistributions in binary form must reproduce the above copyright 21# notice, this list of conditions and the following disclaimer in the 22# documentation and/or other materials provided with the distribution; 23# neither the name of the copyright holders nor the names of its 24# contributors may be used to endorse or promote products derived from 25# this software without specific prior written permission. 26# 27# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 30# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 31# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 32# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 35# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 37# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38# 39# Authors: Steve Reinhardt 40 41# Simple test script 42# 43# "m5 test.py" 44 45from __future__ import print_function 46 47import optparse 48import sys 49import os 50 51import m5 52from m5.defines import buildEnv 53from m5.objects import * 54from m5.util import addToPath, fatal, warn 55 56addToPath('../') 57 58from ruby import Ruby 59 60from common import Options 61from common import Simulation 62from common import CacheConfig 63from common import CpuConfig 64from common import BPConfig 65from common import MemConfig 66from common.Caches import * 67from common.cpu2000 import * 68 69def get_processes(options): 70 """Interprets provided options and returns a list of processes""" 71 72 multiprocesses = [] 73 inputs = [] 74 outputs = [] 75 errouts = [] 76 pargs = [] 77 78 workloads = options.cmd.split(';') 79 if options.input != "": 80 inputs = options.input.split(';') 81 if options.output != "": 82 outputs = options.output.split(';') 83 if options.errout != "": 84 errouts = options.errout.split(';') 85 if options.options != "": 86 pargs = options.options.split(';') 87 88 idx = 0 89 for wrkld in workloads: 90 process = Process(pid = 100 + idx) 91 process.executable = wrkld 92 process.cwd = os.getcwd() 93 94 if options.env: 95 with open(options.env, 'r') as f: 96 process.env = [line.rstrip() for line in f] 97 98 if len(pargs) > idx: 99 process.cmd = [wrkld] + pargs[idx].split() 100 else: 101 process.cmd = [wrkld] 102 103 if len(inputs) > idx: 104 process.input = inputs[idx] 105 if len(outputs) > idx: 106 process.output = outputs[idx] 107 if len(errouts) > idx: 108 process.errout = errouts[idx] 109 110 multiprocesses.append(process) 111 idx += 1 112 113 if options.smt: 114 assert(options.cpu_type == "DerivO3CPU") 115 return multiprocesses, idx 116 else: 117 return multiprocesses, 1 118 119 120parser = optparse.OptionParser() 121Options.addCommonOptions(parser) 122Options.addSEOptions(parser) 123 124if '--ruby' in sys.argv: 125 Ruby.define_options(parser) 126 127(options, args) = parser.parse_args() 128 129if args: 130 print("Error: script doesn't take any positional arguments") 131 sys.exit(1) 132 133multiprocesses = [] 134numThreads = 1 135 136if options.bench: 137 apps = options.bench.split("-") 138 if len(apps) != options.num_cpus: 139 print("number of benchmarks not equal to set num_cpus!") 140 sys.exit(1) 141 142 for app in apps: 143 try: 144 if buildEnv['TARGET_ISA'] == 'alpha': 145 exec("workload = %s('alpha', 'tru64', '%s')" % ( 146 app, options.spec_input)) 147 elif buildEnv['TARGET_ISA'] == 'arm': 148 exec("workload = %s('arm_%s', 'linux', '%s')" % ( 149 app, options.arm_iset, options.spec_input)) 150 else: 151 exec("workload = %s(buildEnv['TARGET_ISA', 'linux', '%s')" % ( 152 app, options.spec_input)) 153 multiprocesses.append(workload.makeProcess()) 154 except: 155 print("Unable to find workload for %s: %s" % 156 (buildEnv['TARGET_ISA'], app), 157 file=sys.stderr) 158 sys.exit(1) 159elif options.cmd: 160 multiprocesses, numThreads = get_processes(options) 161else: 162 print("No workload specified. Exiting!\n", file=sys.stderr) 163 sys.exit(1) 164 165 166(CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options) 167CPUClass.numThreads = numThreads 168 169# Check -- do not allow SMT with multiple CPUs 170if options.smt and options.num_cpus > 1: 171 fatal("You cannot use SMT with multiple CPUs!") 172 173np = options.num_cpus 174system = System(cpu = [CPUClass(cpu_id=i) for i in xrange(np)], 175 mem_mode = test_mem_mode, 176 mem_ranges = [AddrRange(options.mem_size)], 177 cache_line_size = options.cacheline_size) 178 179if numThreads > 1: 180 system.multi_thread = True 181 182# Create a top-level voltage domain 183system.voltage_domain = VoltageDomain(voltage = options.sys_voltage) 184 185# Create a source clock for the system and set the clock period 186system.clk_domain = SrcClockDomain(clock = options.sys_clock, 187 voltage_domain = system.voltage_domain) 188 189# Create a CPU voltage domain 190system.cpu_voltage_domain = VoltageDomain() 191 192# Create a separate clock domain for the CPUs 193system.cpu_clk_domain = SrcClockDomain(clock = options.cpu_clock, 194 voltage_domain = 195 system.cpu_voltage_domain) 196 197# If elastic tracing is enabled, then configure the cpu and attach the elastic 198# trace probe 199if options.elastic_trace_en: 200 CpuConfig.config_etrace(CPUClass, system.cpu, options) 201 202# All cpus belong to a common cpu_clk_domain, therefore running at a common 203# frequency. 204for cpu in system.cpu: 205 cpu.clk_domain = system.cpu_clk_domain 206 207if CpuConfig.is_kvm_cpu(CPUClass) or CpuConfig.is_kvm_cpu(FutureClass): 208 if buildEnv['TARGET_ISA'] == 'x86': 209 system.kvm_vm = KvmVM() 210 for process in multiprocesses: 211 process.useArchPT = True 212 process.kvmInSE = True 213 else: 214 fatal("KvmCPU can only be used in SE mode with x86") 215 216# Sanity check 217if options.simpoint_profile: 218 if not CpuConfig.is_noncaching_cpu(CPUClass): 219 fatal("SimPoint/BPProbe should be done with an atomic cpu") 220 if np > 1: 221 fatal("SimPoint generation not supported with more than one CPUs") 222 223for i in xrange(np): 224 if options.smt: 225 system.cpu[i].workload = multiprocesses 226 elif len(multiprocesses) == 1: 227 system.cpu[i].workload = multiprocesses[0] 228 else: 229 system.cpu[i].workload = multiprocesses[i] 230 231 if options.simpoint_profile: 232 system.cpu[i].addSimPointProbe(options.simpoint_interval) 233 234 if options.checker: 235 system.cpu[i].addCheckerCpu() 236 237 if options.bp_type: 238 bpClass = BPConfig.get(options.bp_type) 239 system.cpu[i].branchPred = bpClass() 240 241 system.cpu[i].createThreads() 242 243if options.ruby: 244 Ruby.create_system(options, False, system) 245 assert(options.num_cpus == len(system.ruby._cpu_ports)) 246 247 system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock, 248 voltage_domain = system.voltage_domain) 249 for i in xrange(np): 250 ruby_port = system.ruby._cpu_ports[i] 251 252 # Create the interrupt controller and connect its ports to Ruby 253 # Note that the interrupt controller is always present but only 254 # in x86 does it have message ports that need to be connected 255 system.cpu[i].createInterruptController() 256 257 # Connect the cpu's cache ports to Ruby 258 system.cpu[i].icache_port = ruby_port.slave 259 system.cpu[i].dcache_port = ruby_port.slave 260 if buildEnv['TARGET_ISA'] == 'x86': 261 system.cpu[i].interrupts[0].pio = ruby_port.master 262 system.cpu[i].interrupts[0].int_master = ruby_port.slave 263 system.cpu[i].interrupts[0].int_slave = ruby_port.master 264 system.cpu[i].itb.walker.port = ruby_port.slave 265 system.cpu[i].dtb.walker.port = ruby_port.slave 266else: 267 MemClass = Simulation.setMemClass(options) 268 system.membus = SystemXBar() 269 system.system_port = system.membus.slave 270 CacheConfig.config_cache(options, system) 271 MemConfig.config_mem(options, system) 272 273root = Root(full_system = False, system = system) 274Simulation.run(options, root, system, FutureClass) 275