Simulation.py revision 5211:f7412cfae319
16019Shines@cs.fsu.edu# Copyright (c) 2006-2007 The Regents of The University of Michigan 26019Shines@cs.fsu.edu# All rights reserved. 313120SEdmund.Grimley-Evans@arm.com# 47178Sgblack@eecs.umich.edu# Redistribution and use in source and binary forms, with or without 57178Sgblack@eecs.umich.edu# modification, are permitted provided that the following conditions are 67178Sgblack@eecs.umich.edu# met: redistributions of source code must retain the above copyright 77178Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer; 87178Sgblack@eecs.umich.edu# redistributions in binary form must reproduce the above copyright 97178Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the 107178Sgblack@eecs.umich.edu# documentation and/or other materials provided with the distribution; 117178Sgblack@eecs.umich.edu# neither the name of the copyright holders nor the names of its 127178Sgblack@eecs.umich.edu# contributors may be used to endorse or promote products derived from 137178Sgblack@eecs.umich.edu# this software without specific prior written permission. 147178Sgblack@eecs.umich.edu# 156019Shines@cs.fsu.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 166019Shines@cs.fsu.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 176019Shines@cs.fsu.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 186019Shines@cs.fsu.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 196019Shines@cs.fsu.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 206019Shines@cs.fsu.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 216019Shines@cs.fsu.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 226019Shines@cs.fsu.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 236019Shines@cs.fsu.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 246019Shines@cs.fsu.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 256019Shines@cs.fsu.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 266019Shines@cs.fsu.edu# 276019Shines@cs.fsu.edu# Authors: Lisa Hsu 286019Shines@cs.fsu.edu 296019Shines@cs.fsu.edufrom os import getcwd 306019Shines@cs.fsu.edufrom os.path import join as joinpath 316019Shines@cs.fsu.eduimport m5 326019Shines@cs.fsu.edufrom m5.objects import * 336019Shines@cs.fsu.edum5.AddToPath('../common') 346019Shines@cs.fsu.edufrom Caches import L1Cache 356019Shines@cs.fsu.edu 366019Shines@cs.fsu.edudef setCPUClass(options): 376019Shines@cs.fsu.edu 386019Shines@cs.fsu.edu atomic = False 396019Shines@cs.fsu.edu if options.timing: 406019Shines@cs.fsu.edu TmpClass = TimingSimpleCPU 416019Shines@cs.fsu.edu elif options.detailed: 426019Shines@cs.fsu.edu if not options.caches: 436019Shines@cs.fsu.edu print "O3 CPU must be used with caches" 446019Shines@cs.fsu.edu sys.exit(1) 456019Shines@cs.fsu.edu TmpClass = DerivO3CPU 466019Shines@cs.fsu.edu else: 476019Shines@cs.fsu.edu TmpClass = AtomicSimpleCPU 487639Sgblack@eecs.umich.edu atomic = True 497639Sgblack@eecs.umich.edu 507639Sgblack@eecs.umich.edu CPUClass = None 517639Sgblack@eecs.umich.edu test_mem_mode = 'atomic' 527639Sgblack@eecs.umich.edu 537639Sgblack@eecs.umich.edu if not atomic: 547639Sgblack@eecs.umich.edu if options.checkpoint_restore: 557639Sgblack@eecs.umich.edu CPUClass = TmpClass 567639Sgblack@eecs.umich.edu TmpClass = AtomicSimpleCPU 577639Sgblack@eecs.umich.edu else: 587639Sgblack@eecs.umich.edu test_mem_mode = 'timing' 597639Sgblack@eecs.umich.edu 607639Sgblack@eecs.umich.edu return (TmpClass, test_mem_mode, CPUClass) 617639Sgblack@eecs.umich.edu 627639Sgblack@eecs.umich.edu 637639Sgblack@eecs.umich.edudef run(options, root, testsys, cpu_class): 647639Sgblack@eecs.umich.edu if options.maxtick: 657639Sgblack@eecs.umich.edu maxtick = options.maxtick 667639Sgblack@eecs.umich.edu elif options.maxtime: 677639Sgblack@eecs.umich.edu simtime = m5.ticks.seconds(simtime) 687639Sgblack@eecs.umich.edu print "simulating for: ", simtime 697639Sgblack@eecs.umich.edu maxtick = simtime 707639Sgblack@eecs.umich.edu else: 717639Sgblack@eecs.umich.edu maxtick = m5.MaxTick 727639Sgblack@eecs.umich.edu 737639Sgblack@eecs.umich.edu if options.checkpoint_dir: 747639Sgblack@eecs.umich.edu cptdir = options.checkpoint_dir 757639Sgblack@eecs.umich.edu elif m5.options.outdir: 767639Sgblack@eecs.umich.edu cptdir = m5.options.outdir 777639Sgblack@eecs.umich.edu else: 787639Sgblack@eecs.umich.edu cptdir = getcwd() 797639Sgblack@eecs.umich.edu 807639Sgblack@eecs.umich.edu np = options.num_cpus 817639Sgblack@eecs.umich.edu max_checkpoints = options.max_checkpoints 827639Sgblack@eecs.umich.edu switch_cpus = None 837639Sgblack@eecs.umich.edu 847639Sgblack@eecs.umich.edu if cpu_class: 857639Sgblack@eecs.umich.edu switch_cpus = [cpu_class(defer_registration=True, cpu_id=(np+i)) 867639Sgblack@eecs.umich.edu for i in xrange(np)] 877639Sgblack@eecs.umich.edu 887639Sgblack@eecs.umich.edu for i in xrange(np): 897639Sgblack@eecs.umich.edu switch_cpus[i].system = testsys 907639Sgblack@eecs.umich.edu if not m5.build_env['FULL_SYSTEM']: 917639Sgblack@eecs.umich.edu switch_cpus[i].workload = testsys.cpu[i].workload 927639Sgblack@eecs.umich.edu switch_cpus[i].clock = testsys.cpu[0].clock 937639Sgblack@eecs.umich.edu 947356Sgblack@eecs.umich.edu root.switch_cpus = switch_cpus 957356Sgblack@eecs.umich.edu switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] 967356Sgblack@eecs.umich.edu 977435Sgblack@eecs.umich.edu if options.standard_switch: 987435Sgblack@eecs.umich.edu switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(np+i)) 997435Sgblack@eecs.umich.edu for i in xrange(np)] 1007435Sgblack@eecs.umich.edu switch_cpus_1 = [DerivO3CPU(defer_registration=True, cpu_id=(2*np+i)) 1017435Sgblack@eecs.umich.edu for i in xrange(np)] 1027435Sgblack@eecs.umich.edu 1037435Sgblack@eecs.umich.edu for i in xrange(np): 1047435Sgblack@eecs.umich.edu switch_cpus[i].system = testsys 1057435Sgblack@eecs.umich.edu switch_cpus_1[i].system = testsys 1067435Sgblack@eecs.umich.edu if not m5.build_env['FULL_SYSTEM']: 1077435Sgblack@eecs.umich.edu switch_cpus[i].workload = testsys.cpu[i].workload 1087639Sgblack@eecs.umich.edu switch_cpus_1[i].workload = testsys.cpu[i].workload 1097639Sgblack@eecs.umich.edu switch_cpus[i].clock = testsys.cpu[0].clock 1107639Sgblack@eecs.umich.edu switch_cpus_1[i].clock = testsys.cpu[0].clock 1117435Sgblack@eecs.umich.edu 1127639Sgblack@eecs.umich.edu if not options.caches: 1137639Sgblack@eecs.umich.edu # O3 CPU must have a cache to work. 1147639Sgblack@eecs.umich.edu switch_cpus_1[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'), 1157639Sgblack@eecs.umich.edu L1Cache(size = '64kB')) 1167639Sgblack@eecs.umich.edu switch_cpus_1[i].connectMemPorts(testsys.membus) 1177639Sgblack@eecs.umich.edu 1187639Sgblack@eecs.umich.edu 1197639Sgblack@eecs.umich.edu testsys.switch_cpus = switch_cpus 1207639Sgblack@eecs.umich.edu testsys.switch_cpus_1 = switch_cpus_1 1217639Sgblack@eecs.umich.edu switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] 1227639Sgblack@eecs.umich.edu switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)] 1237639Sgblack@eecs.umich.edu 1247639Sgblack@eecs.umich.edu m5.instantiate(root) 1257639Sgblack@eecs.umich.edu 1267639Sgblack@eecs.umich.edu if options.checkpoint_restore: 1277639Sgblack@eecs.umich.edu from os.path import isdir 1287639Sgblack@eecs.umich.edu from os import listdir 1297639Sgblack@eecs.umich.edu import re 1307639Sgblack@eecs.umich.edu 1317639Sgblack@eecs.umich.edu if not isdir(cptdir): 1327639Sgblack@eecs.umich.edu m5.panic("checkpoint dir %s does not exist!" % cptdir) 13312595Ssiddhesh.poyarekar@gmail.com 1347639Sgblack@eecs.umich.edu dirs = listdir(cptdir) 1357639Sgblack@eecs.umich.edu expr = re.compile('cpt\.([0-9]*)') 1367639Sgblack@eecs.umich.edu cpts = [] 1377639Sgblack@eecs.umich.edu for dir in dirs: 1387639Sgblack@eecs.umich.edu match = expr.match(dir) 1397639Sgblack@eecs.umich.edu if match: 1407639Sgblack@eecs.umich.edu cpts.append(match.group(1)) 1417639Sgblack@eecs.umich.edu 1427639Sgblack@eecs.umich.edu cpts.sort(lambda a,b: cmp(long(a), long(b))) 1437639Sgblack@eecs.umich.edu 1447639Sgblack@eecs.umich.edu cpt_num = options.checkpoint_restore 1457639Sgblack@eecs.umich.edu 1468144SAli.Saidi@ARM.com if cpt_num > len(cpts): 1477639Sgblack@eecs.umich.edu m5.panic('Checkpoint %d not found' % cpt_num) 1487639Sgblack@eecs.umich.edu 1497639Sgblack@eecs.umich.edu ## Adjust max tick based on our starting tick 1507639Sgblack@eecs.umich.edu maxtick = maxtick - int(cpts[cpt_num - 1]) 1517639Sgblack@eecs.umich.edu 1527639Sgblack@eecs.umich.edu ## Restore the checkpoint 1537639Sgblack@eecs.umich.edu m5.restoreCheckpoint(root, 15410037SARM gem5 Developers joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1])) 1557639Sgblack@eecs.umich.edu 1567639Sgblack@eecs.umich.edu if options.standard_switch or cpu_class: 1577639Sgblack@eecs.umich.edu exit_event = m5.simulate(10000) 1587639Sgblack@eecs.umich.edu 1597639Sgblack@eecs.umich.edu ## when you change to Timing (or Atomic), you halt the system given 1607639Sgblack@eecs.umich.edu ## as argument. When you are finished with the system changes 1617639Sgblack@eecs.umich.edu ## (including switchCpus), you must resume the system manually. 1627639Sgblack@eecs.umich.edu ## You DON'T need to resume after just switching CPUs if you haven't 1637639Sgblack@eecs.umich.edu ## changed anything on the system level. 1647639Sgblack@eecs.umich.edu 1657639Sgblack@eecs.umich.edu m5.changeToTiming(testsys) 16610037SARM gem5 Developers m5.switchCpus(switch_cpu_list) 1677639Sgblack@eecs.umich.edu m5.resume(testsys) 1687639Sgblack@eecs.umich.edu 1697639Sgblack@eecs.umich.edu if options.standard_switch: 1707639Sgblack@eecs.umich.edu exit_event = m5.simulate(options.warmup) 1717639Sgblack@eecs.umich.edu m5.drain(testsys) 1727639Sgblack@eecs.umich.edu m5.switchCpus(switch_cpu_list1) 1737639Sgblack@eecs.umich.edu m5.resume(testsys) 1747639Sgblack@eecs.umich.edu 17510037SARM gem5 Developers num_checkpoints = 0 1767639Sgblack@eecs.umich.edu exit_cause = '' 1777639Sgblack@eecs.umich.edu 17810037SARM gem5 Developers ## Checkpoints being taken via the command line at <when> and at subsequent 1797639Sgblack@eecs.umich.edu ## periods of <period>. Checkpoint instructions received from the benchmark running 1807639Sgblack@eecs.umich.edu ## are ignored and skipped in favor of command line checkpoint instructions. 18110037SARM gem5 Developers if options.take_checkpoints: 1827591SAli.Saidi@ARM.com [when, period] = options.take_checkpoints.split(",", 1) 1837639Sgblack@eecs.umich.edu when = int(when) 1847435Sgblack@eecs.umich.edu period = int(period) 1857435Sgblack@eecs.umich.edu 1867639Sgblack@eecs.umich.edu exit_event = m5.simulate(when) 18710037SARM gem5 Developers while exit_event.getCause() == "checkpoint": 1887639Sgblack@eecs.umich.edu exit_event = m5.simulate(when - m5.curTick()) 1897639Sgblack@eecs.umich.edu 1907639Sgblack@eecs.umich.edu if exit_event.getCause() == "simulate() limit reached": 1917639Sgblack@eecs.umich.edu m5.checkpoint(root, joinpath(cptdir, "cpt.%d")) 1927639Sgblack@eecs.umich.edu num_checkpoints += 1 1937639Sgblack@eecs.umich.edu 1947639Sgblack@eecs.umich.edu sim_ticks = when 1957639Sgblack@eecs.umich.edu exit_cause = "maximum %d checkpoints dropped" % max_checkpoints 1967639Sgblack@eecs.umich.edu while num_checkpoints < max_checkpoints and \ 1977639Sgblack@eecs.umich.edu exit_event.getCause() == "simulate() limit reached": 1987639Sgblack@eecs.umich.edu if (sim_ticks + period) > maxtick: 1997639Sgblack@eecs.umich.edu exit_event = m5.simulate(maxtick - sim_ticks) 2007639Sgblack@eecs.umich.edu exit_cause = exit_event.getCause() 2017639Sgblack@eecs.umich.edu break 2027639Sgblack@eecs.umich.edu else: 2037639Sgblack@eecs.umich.edu exit_event = m5.simulate(period) 2047639Sgblack@eecs.umich.edu sim_ticks += period 2057639Sgblack@eecs.umich.edu while exit_event.getCause() == "checkpoint": 2067639Sgblack@eecs.umich.edu exit_event = m5.simulate(sim_ticks - m5.curTick()) 2077639Sgblack@eecs.umich.edu if exit_event.getCause() == "simulate() limit reached": 2087639Sgblack@eecs.umich.edu m5.checkpoint(root, joinpath(cptdir, "cpt.%d")) 2097639Sgblack@eecs.umich.edu num_checkpoints += 1 2107639Sgblack@eecs.umich.edu 2117639Sgblack@eecs.umich.edu if exit_event.getCause() != "simulate() limit reached": 2127639Sgblack@eecs.umich.edu exit_cause = exit_event.getCause(); 2137639Sgblack@eecs.umich.edu 2147639Sgblack@eecs.umich.edu 2157639Sgblack@eecs.umich.edu else: #no checkpoints being taken via this script 2167639Sgblack@eecs.umich.edu exit_event = m5.simulate(maxtick) 2177639Sgblack@eecs.umich.edu 2187639Sgblack@eecs.umich.edu while exit_event.getCause() == "checkpoint": 2197639Sgblack@eecs.umich.edu m5.checkpoint(root, joinpath(cptdir, "cpt.%d")) 22010037SARM gem5 Developers num_checkpoints += 1 2217591SAli.Saidi@ARM.com if num_checkpoints == max_checkpoints: 2227591SAli.Saidi@ARM.com exit_cause = "maximum %d checkpoints dropped" % max_checkpoints 2237639Sgblack@eecs.umich.edu break 2247639Sgblack@eecs.umich.edu 2257639Sgblack@eecs.umich.edu exit_event = m5.simulate(maxtick - m5.curTick()) 22610037SARM gem5 Developers exit_cause = exit_event.getCause() 2277639Sgblack@eecs.umich.edu 2287639Sgblack@eecs.umich.edu if exit_cause == '': 2297639Sgblack@eecs.umich.edu exit_cause = exit_event.getCause() 2307639Sgblack@eecs.umich.edu print 'Exiting @ cycle %i because %s' % (m5.curTick(), exit_cause) 2317639Sgblack@eecs.umich.edu 2327639Sgblack@eecs.umich.edu