Simulation.py revision 5311
13569Sgblack@eecs.umich.edu# Copyright (c) 2006-2007 The Regents of The University of Michigan 23569Sgblack@eecs.umich.edu# All rights reserved. 33569Sgblack@eecs.umich.edu# 43569Sgblack@eecs.umich.edu# Redistribution and use in source and binary forms, with or without 53569Sgblack@eecs.umich.edu# modification, are permitted provided that the following conditions are 63569Sgblack@eecs.umich.edu# met: redistributions of source code must retain the above copyright 73569Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer; 83569Sgblack@eecs.umich.edu# redistributions in binary form must reproduce the above copyright 93569Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the 103569Sgblack@eecs.umich.edu# documentation and/or other materials provided with the distribution; 113569Sgblack@eecs.umich.edu# neither the name of the copyright holders nor the names of its 123569Sgblack@eecs.umich.edu# contributors may be used to endorse or promote products derived from 133569Sgblack@eecs.umich.edu# this software without specific prior written permission. 143569Sgblack@eecs.umich.edu# 153569Sgblack@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 163569Sgblack@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 173569Sgblack@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 183569Sgblack@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 193569Sgblack@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 203569Sgblack@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 213569Sgblack@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 223569Sgblack@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 233569Sgblack@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 243569Sgblack@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 253569Sgblack@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 263569Sgblack@eecs.umich.edu# 273569Sgblack@eecs.umich.edu# Authors: Lisa Hsu 283804Ssaidi@eecs.umich.edu 293569Sgblack@eecs.umich.edufrom os import getcwd 303569Sgblack@eecs.umich.edufrom os.path import join as joinpath 313918Ssaidi@eecs.umich.eduimport m5 323918Ssaidi@eecs.umich.edufrom m5.objects import * 333804Ssaidi@eecs.umich.edum5.AddToPath('../common') 343811Ssaidi@eecs.umich.edufrom Caches import L1Cache 353569Sgblack@eecs.umich.edu 363824Ssaidi@eecs.umich.edudef setCPUClass(options): 373811Ssaidi@eecs.umich.edu 383811Ssaidi@eecs.umich.edu atomic = False 393823Ssaidi@eecs.umich.edu if options.timing: 403823Ssaidi@eecs.umich.edu TmpClass = TimingSimpleCPU 413823Ssaidi@eecs.umich.edu elif options.detailed: 424103Ssaidi@eecs.umich.edu if not options.caches: 433569Sgblack@eecs.umich.edu print "O3 CPU must be used with caches" 443804Ssaidi@eecs.umich.edu sys.exit(1) 453804Ssaidi@eecs.umich.edu TmpClass = DerivO3CPU 464088Sbinkertn@umich.edu else: 473569Sgblack@eecs.umich.edu TmpClass = AtomicSimpleCPU 485034Smilesck@eecs.umich.edu atomic = True 495358Sgblack@eecs.umich.edu 503881Ssaidi@eecs.umich.edu CPUClass = None 513804Ssaidi@eecs.umich.edu test_mem_mode = 'atomic' 523804Ssaidi@eecs.umich.edu 533804Ssaidi@eecs.umich.edu if not atomic: 545555Snate@binkert.org if options.checkpoint_restore: 553569Sgblack@eecs.umich.edu CPUClass = TmpClass 563804Ssaidi@eecs.umich.edu TmpClass = AtomicSimpleCPU 573918Ssaidi@eecs.umich.edu else: 583881Ssaidi@eecs.umich.edu test_mem_mode = 'timing' 593881Ssaidi@eecs.umich.edu 603881Ssaidi@eecs.umich.edu return (TmpClass, test_mem_mode, CPUClass) 614990Sgblack@eecs.umich.edu 624990Sgblack@eecs.umich.edu 634990Sgblack@eecs.umich.edudef run(options, root, testsys, cpu_class): 644990Sgblack@eecs.umich.edu if options.maxtick: 654990Sgblack@eecs.umich.edu maxtick = options.maxtick 664990Sgblack@eecs.umich.edu elif options.maxtime: 674990Sgblack@eecs.umich.edu simtime = m5.ticks.seconds(simtime) 684990Sgblack@eecs.umich.edu print "simulating for: ", simtime 694990Sgblack@eecs.umich.edu maxtick = simtime 703804Ssaidi@eecs.umich.edu else: 713569Sgblack@eecs.umich.edu maxtick = m5.MaxTick 723804Ssaidi@eecs.umich.edu 733804Ssaidi@eecs.umich.edu if options.checkpoint_dir: 743804Ssaidi@eecs.umich.edu cptdir = options.checkpoint_dir 753804Ssaidi@eecs.umich.edu elif m5.options.outdir: 763881Ssaidi@eecs.umich.edu cptdir = m5.options.outdir 773804Ssaidi@eecs.umich.edu else: 783804Ssaidi@eecs.umich.edu cptdir = getcwd() 793804Ssaidi@eecs.umich.edu 803804Ssaidi@eecs.umich.edu np = options.num_cpus 813804Ssaidi@eecs.umich.edu max_checkpoints = options.max_checkpoints 823804Ssaidi@eecs.umich.edu switch_cpus = None 833804Ssaidi@eecs.umich.edu 843569Sgblack@eecs.umich.edu if cpu_class: 853569Sgblack@eecs.umich.edu switch_cpus = [cpu_class(defer_registration=True, cpu_id=(np+i)) 863804Ssaidi@eecs.umich.edu for i in xrange(np)] 873804Ssaidi@eecs.umich.edu 883826Ssaidi@eecs.umich.edu for i in xrange(np): 893804Ssaidi@eecs.umich.edu switch_cpus[i].system = testsys 903804Ssaidi@eecs.umich.edu if not m5.build_env['FULL_SYSTEM']: 913826Ssaidi@eecs.umich.edu switch_cpus[i].workload = testsys.cpu[i].workload 923907Ssaidi@eecs.umich.edu switch_cpus[i].clock = testsys.cpu[0].clock 933826Ssaidi@eecs.umich.edu 943811Ssaidi@eecs.umich.edu testsys.switch_cpus = switch_cpus 953836Ssaidi@eecs.umich.edu switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] 963915Ssaidi@eecs.umich.edu 973907Ssaidi@eecs.umich.edu if options.standard_switch: 983881Ssaidi@eecs.umich.edu switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(np+i)) 993881Ssaidi@eecs.umich.edu for i in xrange(np)] 1003881Ssaidi@eecs.umich.edu switch_cpus_1 = [DerivO3CPU(defer_registration=True, cpu_id=(2*np+i)) 1013881Ssaidi@eecs.umich.edu for i in xrange(np)] 1023907Ssaidi@eecs.umich.edu 1033881Ssaidi@eecs.umich.edu for i in xrange(np): 1045555Snate@binkert.org switch_cpus[i].system = testsys 1055555Snate@binkert.org switch_cpus_1[i].system = testsys 1065555Snate@binkert.org if not m5.build_env['FULL_SYSTEM']: 1073881Ssaidi@eecs.umich.edu switch_cpus[i].workload = testsys.cpu[i].workload 1083881Ssaidi@eecs.umich.edu switch_cpus_1[i].workload = testsys.cpu[i].workload 1093907Ssaidi@eecs.umich.edu switch_cpus[i].clock = testsys.cpu[0].clock 1103907Ssaidi@eecs.umich.edu switch_cpus_1[i].clock = testsys.cpu[0].clock 1113907Ssaidi@eecs.umich.edu 1123907Ssaidi@eecs.umich.edu if not options.caches: 1133907Ssaidi@eecs.umich.edu # O3 CPU must have a cache to work. 1143907Ssaidi@eecs.umich.edu switch_cpus_1[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'), 1153907Ssaidi@eecs.umich.edu L1Cache(size = '64kB')) 1163907Ssaidi@eecs.umich.edu switch_cpus_1[i].connectMemPorts(testsys.membus) 1173907Ssaidi@eecs.umich.edu 1183907Ssaidi@eecs.umich.edu 1193907Ssaidi@eecs.umich.edu testsys.switch_cpus = switch_cpus 1203907Ssaidi@eecs.umich.edu testsys.switch_cpus_1 = switch_cpus_1 1213907Ssaidi@eecs.umich.edu switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] 1223907Ssaidi@eecs.umich.edu switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)] 1233907Ssaidi@eecs.umich.edu 1243907Ssaidi@eecs.umich.edu m5.instantiate(root) 1253907Ssaidi@eecs.umich.edu 1263907Ssaidi@eecs.umich.edu if options.checkpoint_restore: 1273907Ssaidi@eecs.umich.edu from os.path import isdir 1283907Ssaidi@eecs.umich.edu from os import listdir 1293907Ssaidi@eecs.umich.edu import re 1303907Ssaidi@eecs.umich.edu 1313881Ssaidi@eecs.umich.edu if not isdir(cptdir): 1323881Ssaidi@eecs.umich.edu m5.panic("checkpoint dir %s does not exist!" % cptdir) 1333881Ssaidi@eecs.umich.edu 1343881Ssaidi@eecs.umich.edu dirs = listdir(cptdir) 1353881Ssaidi@eecs.umich.edu expr = re.compile('cpt\.([0-9]*)') 1363881Ssaidi@eecs.umich.edu cpts = [] 1373881Ssaidi@eecs.umich.edu for dir in dirs: 1383881Ssaidi@eecs.umich.edu match = expr.match(dir) 1393881Ssaidi@eecs.umich.edu if match: 1403881Ssaidi@eecs.umich.edu cpts.append(match.group(1)) 1413881Ssaidi@eecs.umich.edu 1423881Ssaidi@eecs.umich.edu cpts.sort(lambda a,b: cmp(long(a), long(b))) 1433907Ssaidi@eecs.umich.edu 1443811Ssaidi@eecs.umich.edu cpt_num = options.checkpoint_restore 1453826Ssaidi@eecs.umich.edu 1463826Ssaidi@eecs.umich.edu if cpt_num > len(cpts): 1473826Ssaidi@eecs.umich.edu m5.panic('Checkpoint %d not found' % cpt_num) 1483826Ssaidi@eecs.umich.edu 1493881Ssaidi@eecs.umich.edu ## Adjust max tick based on our starting tick 1503881Ssaidi@eecs.umich.edu maxtick = maxtick - int(cpts[cpt_num - 1]) 1513881Ssaidi@eecs.umich.edu 1523881Ssaidi@eecs.umich.edu ## Restore the checkpoint 1533881Ssaidi@eecs.umich.edu m5.restoreCheckpoint(root, 1543881Ssaidi@eecs.umich.edu joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1])) 1553881Ssaidi@eecs.umich.edu 1563881Ssaidi@eecs.umich.edu if options.standard_switch or cpu_class: 1573881Ssaidi@eecs.umich.edu exit_event = m5.simulate(10000) 1583881Ssaidi@eecs.umich.edu 1593881Ssaidi@eecs.umich.edu ## when you change to Timing (or Atomic), you halt the system given 1603881Ssaidi@eecs.umich.edu ## as argument. When you are finished with the system changes 1613881Ssaidi@eecs.umich.edu ## (including switchCpus), you must resume the system manually. 1623881Ssaidi@eecs.umich.edu ## You DON'T need to resume after just switching CPUs if you haven't 1633881Ssaidi@eecs.umich.edu ## changed anything on the system level. 1643826Ssaidi@eecs.umich.edu 1653826Ssaidi@eecs.umich.edu m5.changeToTiming(testsys) 1663826Ssaidi@eecs.umich.edu m5.switchCpus(switch_cpu_list) 1673826Ssaidi@eecs.umich.edu m5.resume(testsys) 1683826Ssaidi@eecs.umich.edu 1693881Ssaidi@eecs.umich.edu if options.standard_switch: 1703569Sgblack@eecs.umich.edu exit_event = m5.simulate(options.warmup) 1713569Sgblack@eecs.umich.edu m5.drain(testsys) 1723881Ssaidi@eecs.umich.edu m5.switchCpus(switch_cpu_list1) 1733804Ssaidi@eecs.umich.edu m5.resume(testsys) 1743881Ssaidi@eecs.umich.edu 1753826Ssaidi@eecs.umich.edu num_checkpoints = 0 1763881Ssaidi@eecs.umich.edu exit_cause = '' 1773881Ssaidi@eecs.umich.edu 1783881Ssaidi@eecs.umich.edu ## Checkpoints being taken via the command line at <when> and at subsequent 1793907Ssaidi@eecs.umich.edu ## periods of <period>. Checkpoint instructions received from the benchmark running 1803907Ssaidi@eecs.umich.edu ## are ignored and skipped in favor of command line checkpoint instructions. 1813929Ssaidi@eecs.umich.edu if options.take_checkpoints: 1823929Ssaidi@eecs.umich.edu [when, period] = options.take_checkpoints.split(",", 1) 1833907Ssaidi@eecs.umich.edu when = int(when) 1843907Ssaidi@eecs.umich.edu period = int(period) 1853804Ssaidi@eecs.umich.edu 1863804Ssaidi@eecs.umich.edu exit_event = m5.simulate(when) 1873881Ssaidi@eecs.umich.edu while exit_event.getCause() == "checkpoint": 1883804Ssaidi@eecs.umich.edu exit_event = m5.simulate(when - m5.curTick()) 1893804Ssaidi@eecs.umich.edu 1903804Ssaidi@eecs.umich.edu if exit_event.getCause() == "simulate() limit reached": 1913804Ssaidi@eecs.umich.edu m5.checkpoint(root, joinpath(cptdir, "cpt.%d")) 1923804Ssaidi@eecs.umich.edu num_checkpoints += 1 1933804Ssaidi@eecs.umich.edu 1943804Ssaidi@eecs.umich.edu sim_ticks = when 1953569Sgblack@eecs.umich.edu exit_cause = "maximum %d checkpoints dropped" % max_checkpoints 1963863Ssaidi@eecs.umich.edu while num_checkpoints < max_checkpoints and \ 1973863Ssaidi@eecs.umich.edu exit_event.getCause() == "simulate() limit reached": 1983804Ssaidi@eecs.umich.edu if (sim_ticks + period) > maxtick: 1995555Snate@binkert.org exit_event = m5.simulate(maxtick - sim_ticks) 2005555Snate@binkert.org exit_cause = exit_event.getCause() 2013804Ssaidi@eecs.umich.edu break 2023804Ssaidi@eecs.umich.edu else: 2033804Ssaidi@eecs.umich.edu exit_event = m5.simulate(period) 2043804Ssaidi@eecs.umich.edu sim_ticks += period 2053804Ssaidi@eecs.umich.edu while exit_event.getCause() == "checkpoint": 2063569Sgblack@eecs.umich.edu exit_event = m5.simulate(sim_ticks - m5.curTick()) 2073804Ssaidi@eecs.umich.edu if exit_event.getCause() == "simulate() limit reached": 2083804Ssaidi@eecs.umich.edu m5.checkpoint(root, joinpath(cptdir, "cpt.%d")) 2093804Ssaidi@eecs.umich.edu num_checkpoints += 1 2105555Snate@binkert.org 2115555Snate@binkert.org if exit_event.getCause() != "simulate() limit reached": 2123804Ssaidi@eecs.umich.edu exit_cause = exit_event.getCause(); 2133804Ssaidi@eecs.umich.edu 2143804Ssaidi@eecs.umich.edu 2153804Ssaidi@eecs.umich.edu else: #no checkpoints being taken via this script 2163804Ssaidi@eecs.umich.edu exit_event = m5.simulate(maxtick) 2173811Ssaidi@eecs.umich.edu 2183811Ssaidi@eecs.umich.edu while exit_event.getCause() == "checkpoint": 2193804Ssaidi@eecs.umich.edu m5.checkpoint(root, joinpath(cptdir, "cpt.%d")) 2203804Ssaidi@eecs.umich.edu num_checkpoints += 1 2215312Sgblack@eecs.umich.edu if num_checkpoints == max_checkpoints: 2223804Ssaidi@eecs.umich.edu exit_cause = "maximum %d checkpoints dropped" % max_checkpoints 2233804Ssaidi@eecs.umich.edu break 2243804Ssaidi@eecs.umich.edu 2253804Ssaidi@eecs.umich.edu exit_event = m5.simulate(maxtick - m5.curTick()) 2263804Ssaidi@eecs.umich.edu exit_cause = exit_event.getCause() 2273804Ssaidi@eecs.umich.edu 2283804Ssaidi@eecs.umich.edu if exit_cause == '': 2293811Ssaidi@eecs.umich.edu exit_cause = exit_event.getCause() 2303804Ssaidi@eecs.umich.edu print 'Exiting @ cycle %i because %s' % (m5.curTick(), exit_cause) 2313804Ssaidi@eecs.umich.edu 2323804Ssaidi@eecs.umich.edu