Simulation.py revision 9521:1cd02decbfd3
16019Shines@cs.fsu.edu# Copyright (c) 2012 ARM Limited
26019Shines@cs.fsu.edu# All rights reserved
37178Sgblack@eecs.umich.edu#
47178Sgblack@eecs.umich.edu# The license below extends only to copyright in the software and shall
57178Sgblack@eecs.umich.edu# not be construed as granting a license to any other intellectual
67178Sgblack@eecs.umich.edu# property including but not limited to intellectual property relating
77178Sgblack@eecs.umich.edu# to a hardware implementation of the functionality of the software
87178Sgblack@eecs.umich.edu# licensed hereunder.  You may use the software subject to the license
97178Sgblack@eecs.umich.edu# terms below provided that you ensure that this notice is replicated
107178Sgblack@eecs.umich.edu# unmodified and in its entirety in all distributions of the software,
117178Sgblack@eecs.umich.edu# modified or unmodified, in source code or in binary form.
127178Sgblack@eecs.umich.edu#
137178Sgblack@eecs.umich.edu# Copyright (c) 2006-2008 The Regents of The University of Michigan
147178Sgblack@eecs.umich.edu# Copyright (c) 2010 Advanced Micro Devices, Inc.
156019Shines@cs.fsu.edu# All rights reserved.
166019Shines@cs.fsu.edu#
176019Shines@cs.fsu.edu# Redistribution and use in source and binary forms, with or without
186019Shines@cs.fsu.edu# modification, are permitted provided that the following conditions are
196019Shines@cs.fsu.edu# met: redistributions of source code must retain the above copyright
206019Shines@cs.fsu.edu# notice, this list of conditions and the following disclaimer;
216019Shines@cs.fsu.edu# redistributions in binary form must reproduce the above copyright
226019Shines@cs.fsu.edu# notice, this list of conditions and the following disclaimer in the
236019Shines@cs.fsu.edu# documentation and/or other materials provided with the distribution;
246019Shines@cs.fsu.edu# neither the name of the copyright holders nor the names of its
256019Shines@cs.fsu.edu# contributors may be used to endorse or promote products derived from
266019Shines@cs.fsu.edu# this software without specific prior written permission.
276019Shines@cs.fsu.edu#
286019Shines@cs.fsu.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
296019Shines@cs.fsu.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
306019Shines@cs.fsu.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
316019Shines@cs.fsu.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
326019Shines@cs.fsu.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
336019Shines@cs.fsu.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
346019Shines@cs.fsu.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
356019Shines@cs.fsu.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
366019Shines@cs.fsu.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
376019Shines@cs.fsu.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
386019Shines@cs.fsu.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
396019Shines@cs.fsu.edu#
406019Shines@cs.fsu.edu# Authors: Lisa Hsu
416019Shines@cs.fsu.edu
426019Shines@cs.fsu.eduimport sys
436019Shines@cs.fsu.edufrom os import getcwd
446019Shines@cs.fsu.edufrom os.path import join as joinpath
456019Shines@cs.fsu.edu
466019Shines@cs.fsu.eduimport CpuConfig
476019Shines@cs.fsu.edu
486019Shines@cs.fsu.eduimport m5
496019Shines@cs.fsu.edufrom m5.defines import buildEnv
506019Shines@cs.fsu.edufrom m5.objects import *
516019Shines@cs.fsu.edufrom m5.util import *
526019Shines@cs.fsu.edu
536019Shines@cs.fsu.eduaddToPath('../common')
546019Shines@cs.fsu.edu
556019Shines@cs.fsu.edudef getCPUClass(cpu_type):
566019Shines@cs.fsu.edu    """Returns the required cpu class and the mode of operation."""
576019Shines@cs.fsu.edu    cls = CpuConfig.get(cpu_type)
586243Sgblack@eecs.umich.edu    return cls, cls.memory_mode()
596243Sgblack@eecs.umich.edu
606243Sgblack@eecs.umich.edudef setCPUClass(options):
616243Sgblack@eecs.umich.edu    """Returns two cpu classes and the initial mode of operation.
626243Sgblack@eecs.umich.edu
636019Shines@cs.fsu.edu       Restoring from a checkpoint or fast forwarding through a benchmark
646019Shines@cs.fsu.edu       can be done using one type of cpu, and then the actual
656019Shines@cs.fsu.edu       simulation can be carried out using another type. This function
666019Shines@cs.fsu.edu       returns these two types of cpus and the initial mode of operation
676019Shines@cs.fsu.edu       depending on the options provided.
686019Shines@cs.fsu.edu    """
696019Shines@cs.fsu.edu
706019Shines@cs.fsu.edu    TmpClass, test_mem_mode = getCPUClass(options.cpu_type)
716019Shines@cs.fsu.edu    CPUClass = None
726019Shines@cs.fsu.edu    if TmpClass.require_caches() and \
736019Shines@cs.fsu.edu            not options.caches and not options.ruby:
746019Shines@cs.fsu.edu        fatal("%s must be used with caches" % options.cpu_type)
756019Shines@cs.fsu.edu
766019Shines@cs.fsu.edu    if options.checkpoint_restore != None:
776019Shines@cs.fsu.edu        if options.restore_with_cpu != options.cpu_type:
786019Shines@cs.fsu.edu            CPUClass = TmpClass
796019Shines@cs.fsu.edu            TmpClass, test_mem_mode = getCPUClass(options.restore_with_cpu)
806019Shines@cs.fsu.edu    elif options.fast_forward:
816019Shines@cs.fsu.edu        CPUClass = TmpClass
826019Shines@cs.fsu.edu        TmpClass = AtomicSimpleCPU
836019Shines@cs.fsu.edu        test_mem_mode = 'atomic'
846019Shines@cs.fsu.edu
856019Shines@cs.fsu.edu    return (TmpClass, test_mem_mode, CPUClass)
866019Shines@cs.fsu.edu
876019Shines@cs.fsu.edudef setWorkCountOptions(system, options):
886019Shines@cs.fsu.edu    if options.work_item_id != None:
896019Shines@cs.fsu.edu        system.work_item_id = options.work_item_id
906019Shines@cs.fsu.edu    if options.work_begin_cpu_id_exit != None:
916019Shines@cs.fsu.edu        system.work_begin_cpu_id_exit = options.work_begin_cpu_id_exit
926019Shines@cs.fsu.edu    if options.work_end_exit_count != None:
936019Shines@cs.fsu.edu        system.work_end_exit_count = options.work_end_exit_count
946252Sgblack@eecs.umich.edu    if options.work_end_checkpoint_count != None:
956243Sgblack@eecs.umich.edu        system.work_end_ckpt_count = options.work_end_checkpoint_count
966243Sgblack@eecs.umich.edu    if options.work_begin_exit_count != None:
976243Sgblack@eecs.umich.edu        system.work_begin_exit_count = options.work_begin_exit_count
986019Shines@cs.fsu.edu    if options.work_begin_checkpoint_count != None:
996019Shines@cs.fsu.edu        system.work_begin_ckpt_count = options.work_begin_checkpoint_count
1006019Shines@cs.fsu.edu    if options.work_cpus_checkpoint_count != None:
1016019Shines@cs.fsu.edu        system.work_cpus_ckpt_count = options.work_cpus_checkpoint_count
1026019Shines@cs.fsu.edu
1036252Sgblack@eecs.umich.edudef findCptDir(options, maxtick, cptdir, testsys):
1046243Sgblack@eecs.umich.edu    """Figures out the directory from which the checkpointed state is read.
1056243Sgblack@eecs.umich.edu
1066243Sgblack@eecs.umich.edu    There are two different ways in which the directories holding checkpoints
1076019Shines@cs.fsu.edu    can be named --
1086019Shines@cs.fsu.edu    1. cpt.<benchmark name>.<instruction count when the checkpoint was taken>
1096019Shines@cs.fsu.edu    2. cpt.<some number, usually the tick value when the checkpoint was taken>
1106019Shines@cs.fsu.edu
1116019Shines@cs.fsu.edu    This function parses through the options to figure out which one of the
1126019Shines@cs.fsu.edu    above should be used for selecting the checkpoint, and then figures out
1136019Shines@cs.fsu.edu    the appropriate directory.
1146252Sgblack@eecs.umich.edu
1156243Sgblack@eecs.umich.edu    It also sets the value of the maximum tick value till which the simulation
1166243Sgblack@eecs.umich.edu    will run.
1176243Sgblack@eecs.umich.edu    """
1186019Shines@cs.fsu.edu
1196019Shines@cs.fsu.edu    from os.path import isdir, exists
1206019Shines@cs.fsu.edu    from os import listdir
1216019Shines@cs.fsu.edu    import re
1226019Shines@cs.fsu.edu
1236019Shines@cs.fsu.edu    if not isdir(cptdir):
1246019Shines@cs.fsu.edu        fatal("checkpoint dir %s does not exist!", cptdir)
1256019Shines@cs.fsu.edu
1266019Shines@cs.fsu.edu    if options.at_instruction or options.simpoint:
1276019Shines@cs.fsu.edu        inst = options.checkpoint_restore
1286019Shines@cs.fsu.edu        if options.simpoint:
1296019Shines@cs.fsu.edu            # assume workload 0 has the simpoint
1306019Shines@cs.fsu.edu            if testsys.cpu[0].workload[0].simpoint == 0:
1316019Shines@cs.fsu.edu                fatal('Unable to find simpoint')
1326019Shines@cs.fsu.edu            inst += int(testsys.cpu[0].workload[0].simpoint)
1336019Shines@cs.fsu.edu
1346724Sgblack@eecs.umich.edu        checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % (options.bench, inst))
1356724Sgblack@eecs.umich.edu        if not exists(checkpoint_dir):
1366019Shines@cs.fsu.edu            fatal("Unable to find checkpoint directory %s", checkpoint_dir)
1376019Shines@cs.fsu.edu    else:
1386019Shines@cs.fsu.edu        dirs = listdir(cptdir)
1396019Shines@cs.fsu.edu        expr = re.compile('cpt\.([0-9]*)')
1406019Shines@cs.fsu.edu        cpts = []
1416252Sgblack@eecs.umich.edu        for dir in dirs:
1426243Sgblack@eecs.umich.edu            match = expr.match(dir)
1436243Sgblack@eecs.umich.edu            if match:
1446243Sgblack@eecs.umich.edu                cpts.append(match.group(1))
1456019Shines@cs.fsu.edu
1466019Shines@cs.fsu.edu        cpts.sort(lambda a,b: cmp(long(a), long(b)))
1476019Shines@cs.fsu.edu
1486019Shines@cs.fsu.edu        cpt_num = options.checkpoint_restore
1496019Shines@cs.fsu.edu        if cpt_num > len(cpts):
1506019Shines@cs.fsu.edu            fatal('Checkpoint %d not found', cpt_num)
1517356Sgblack@eecs.umich.edu
1527356Sgblack@eecs.umich.edu        maxtick = maxtick - int(cpts[cpt_num - 1])
1537356Sgblack@eecs.umich.edu        checkpoint_dir = joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1])
1547356Sgblack@eecs.umich.edu
1557356Sgblack@eecs.umich.edu    return maxtick, checkpoint_dir
1567356Sgblack@eecs.umich.edu
1577356Sgblack@eecs.umich.edudef scriptCheckpoints(options, maxtick, cptdir):
1587356Sgblack@eecs.umich.edu    if options.at_instruction or options.simpoint:
1597178Sgblack@eecs.umich.edu        checkpoint_inst = int(options.take_checkpoints)
1607178Sgblack@eecs.umich.edu
1617178Sgblack@eecs.umich.edu        # maintain correct offset if we restored from some instruction
1627337Sgblack@eecs.umich.edu        if options.checkpoint_restore != None:
1637178Sgblack@eecs.umich.edu            checkpoint_inst += options.checkpoint_restore
1647178Sgblack@eecs.umich.edu
1657178Sgblack@eecs.umich.edu        print "Creating checkpoint at inst:%d" % (checkpoint_inst)
1667178Sgblack@eecs.umich.edu        exit_event = m5.simulate()
1677178Sgblack@eecs.umich.edu        exit_cause = exit_event.getCause()
1687178Sgblack@eecs.umich.edu        print "exit cause = %s" % exit_cause
1697178Sgblack@eecs.umich.edu
1707178Sgblack@eecs.umich.edu        # skip checkpoint instructions should they exist
1717178Sgblack@eecs.umich.edu        while exit_cause == "checkpoint":
1727178Sgblack@eecs.umich.edu            exit_event = m5.simulate()
1737178Sgblack@eecs.umich.edu            exit_cause = exit_event.getCause()
1747335Sgblack@eecs.umich.edu
1757335Sgblack@eecs.umich.edu        if exit_cause == "a thread reached the max instruction count":
1767335Sgblack@eecs.umich.edu            m5.checkpoint(joinpath(cptdir, "cpt.%s.%d" % \
1777335Sgblack@eecs.umich.edu                    (options.bench, checkpoint_inst)))
1787335Sgblack@eecs.umich.edu            print "Checkpoint written."
1797335Sgblack@eecs.umich.edu
1807335Sgblack@eecs.umich.edu    else:
1817335Sgblack@eecs.umich.edu        when, period = options.take_checkpoints.split(",", 1)
1827335Sgblack@eecs.umich.edu        when = int(when)
1837335Sgblack@eecs.umich.edu        period = int(period)
1847335Sgblack@eecs.umich.edu        num_checkpoints = 0
1857335Sgblack@eecs.umich.edu
1867337Sgblack@eecs.umich.edu        exit_event = m5.simulate(when)
1877335Sgblack@eecs.umich.edu        exit_cause = exit_event.getCause()
1887335Sgblack@eecs.umich.edu        while exit_cause == "checkpoint":
1897335Sgblack@eecs.umich.edu            exit_event = m5.simulate(when - m5.curTick())
1907335Sgblack@eecs.umich.edu            exit_cause = exit_event.getCause()
1917335Sgblack@eecs.umich.edu
1927335Sgblack@eecs.umich.edu        if exit_cause == "simulate() limit reached":
1937335Sgblack@eecs.umich.edu            m5.checkpoint(joinpath(cptdir, "cpt.%d"))
1947335Sgblack@eecs.umich.edu            num_checkpoints += 1
1957335Sgblack@eecs.umich.edu
1967335Sgblack@eecs.umich.edu        sim_ticks = when
1977335Sgblack@eecs.umich.edu        max_checkpoints = options.max_checkpoints
1987335Sgblack@eecs.umich.edu
1997178Sgblack@eecs.umich.edu        while num_checkpoints < max_checkpoints and \
2007178Sgblack@eecs.umich.edu                exit_cause == "simulate() limit reached":
2017178Sgblack@eecs.umich.edu            if (sim_ticks + period) > maxtick:
2027178Sgblack@eecs.umich.edu                exit_event = m5.simulate(maxtick - sim_ticks)
2037178Sgblack@eecs.umich.edu                exit_cause = exit_event.getCause()
2047178Sgblack@eecs.umich.edu                break
2057178Sgblack@eecs.umich.edu            else:
2067178Sgblack@eecs.umich.edu                exit_event = m5.simulate(period)
2077178Sgblack@eecs.umich.edu                exit_cause = exit_event.getCause()
2087178Sgblack@eecs.umich.edu                sim_ticks += period
2097178Sgblack@eecs.umich.edu                while exit_event.getCause() == "checkpoint":
2107178Sgblack@eecs.umich.edu                    exit_event = m5.simulate(sim_ticks - m5.curTick())
2117178Sgblack@eecs.umich.edu                if exit_event.getCause() == "simulate() limit reached":
2127178Sgblack@eecs.umich.edu                    m5.checkpoint(joinpath(cptdir, "cpt.%d"))
2137178Sgblack@eecs.umich.edu                    num_checkpoints += 1
2147178Sgblack@eecs.umich.edu
2157178Sgblack@eecs.umich.edu    return exit_cause
2167178Sgblack@eecs.umich.edu
2177178Sgblack@eecs.umich.edudef benchCheckpoints(options, maxtick, cptdir):
2187178Sgblack@eecs.umich.edu    exit_event = m5.simulate(maxtick)
2197178Sgblack@eecs.umich.edu    exit_cause = exit_event.getCause()
2207178Sgblack@eecs.umich.edu
2217178Sgblack@eecs.umich.edu    num_checkpoints = 0
2227178Sgblack@eecs.umich.edu    max_checkpoints = options.max_checkpoints
2237178Sgblack@eecs.umich.edu
2247178Sgblack@eecs.umich.edu    while exit_cause == "checkpoint":
2257178Sgblack@eecs.umich.edu        m5.checkpoint(joinpath(cptdir, "cpt.%d"))
2267178Sgblack@eecs.umich.edu        num_checkpoints += 1
2277178Sgblack@eecs.umich.edu        if num_checkpoints == max_checkpoints:
2287346Sgblack@eecs.umich.edu            exit_cause = "maximum %d checkpoints dropped" % max_checkpoints
2297346Sgblack@eecs.umich.edu            break
2307346Sgblack@eecs.umich.edu
2317346Sgblack@eecs.umich.edu        exit_event = m5.simulate(maxtick - m5.curTick())
2327346Sgblack@eecs.umich.edu        exit_cause = exit_event.getCause()
2337346Sgblack@eecs.umich.edu
2347346Sgblack@eecs.umich.edu    return exit_event
2357346Sgblack@eecs.umich.edu
2367346Sgblack@eecs.umich.edudef repeatSwitch(testsys, repeat_switch_cpu_list, maxtick, switch_freq):
2377346Sgblack@eecs.umich.edu    print "starting switch loop"
2387178Sgblack@eecs.umich.edu    while True:
2397346Sgblack@eecs.umich.edu        exit_event = m5.simulate(switch_freq)
2407346Sgblack@eecs.umich.edu        exit_cause = exit_event.getCause()
2417346Sgblack@eecs.umich.edu
2427346Sgblack@eecs.umich.edu        if exit_cause != "simulate() limit reached":
2437346Sgblack@eecs.umich.edu            return exit_event
2447346Sgblack@eecs.umich.edu
2457346Sgblack@eecs.umich.edu        m5.switchCpus(testsys, repeat_switch_cpu_list)
2467346Sgblack@eecs.umich.edu
2477346Sgblack@eecs.umich.edu        tmp_cpu_list = []
2487346Sgblack@eecs.umich.edu        for old_cpu, new_cpu in repeat_switch_cpu_list:
2497346Sgblack@eecs.umich.edu            tmp_cpu_list.append((new_cpu, old_cpu))
2507346Sgblack@eecs.umich.edu        repeat_switch_cpu_list = tmp_cpu_list
2517346Sgblack@eecs.umich.edu
2527346Sgblack@eecs.umich.edu        if (maxtick - m5.curTick()) <= switch_freq:
2537346Sgblack@eecs.umich.edu            exit_event = m5.simulate(maxtick - m5.curTick())
2547178Sgblack@eecs.umich.edu            return exit_event
2557337Sgblack@eecs.umich.edu
2567337Sgblack@eecs.umich.edudef run(options, root, testsys, cpu_class):
2577337Sgblack@eecs.umich.edu    if options.maxtick:
2587337Sgblack@eecs.umich.edu        maxtick = options.maxtick
2597337Sgblack@eecs.umich.edu    elif options.maxtime:
2607337Sgblack@eecs.umich.edu        simtime = m5.ticks.seconds(simtime)
2617337Sgblack@eecs.umich.edu        print "simulating for: ", simtime
2627337Sgblack@eecs.umich.edu        maxtick = simtime
2637337Sgblack@eecs.umich.edu    else:
2647337Sgblack@eecs.umich.edu        maxtick = m5.MaxTick
2657337Sgblack@eecs.umich.edu
2667337Sgblack@eecs.umich.edu    if options.checkpoint_dir:
2677337Sgblack@eecs.umich.edu        cptdir = options.checkpoint_dir
2687337Sgblack@eecs.umich.edu    elif m5.options.outdir:
2697337Sgblack@eecs.umich.edu        cptdir = m5.options.outdir
2707178Sgblack@eecs.umich.edu    else:
2717178Sgblack@eecs.umich.edu        cptdir = getcwd()
2727178Sgblack@eecs.umich.edu
2737178Sgblack@eecs.umich.edu    if options.fast_forward and options.checkpoint_restore != None:
2747337Sgblack@eecs.umich.edu        fatal("Can't specify both --fast-forward and --checkpoint-restore")
2757337Sgblack@eecs.umich.edu
2767337Sgblack@eecs.umich.edu    if options.standard_switch and not options.caches:
2777337Sgblack@eecs.umich.edu        fatal("Must specify --caches when using --standard-switch")
2787346Sgblack@eecs.umich.edu
2797346Sgblack@eecs.umich.edu    if options.standard_switch and options.repeat_switch:
2807346Sgblack@eecs.umich.edu        fatal("Can't specify both --standard-switch and --repeat-switch")
2817346Sgblack@eecs.umich.edu
2827346Sgblack@eecs.umich.edu    if options.repeat_switch and options.take_checkpoints:
2837337Sgblack@eecs.umich.edu        fatal("Can't specify both --repeat-switch and --take-checkpoints")
2847178Sgblack@eecs.umich.edu
2857321Sgblack@eecs.umich.edu    np = options.num_cpus
2867356Sgblack@eecs.umich.edu    switch_cpus = None
2877321Sgblack@eecs.umich.edu
2887356Sgblack@eecs.umich.edu    if options.prog_interval:
2897356Sgblack@eecs.umich.edu        for i in xrange(np):
2907356Sgblack@eecs.umich.edu            testsys.cpu[i].progress_interval = options.prog_interval
2917356Sgblack@eecs.umich.edu
2927356Sgblack@eecs.umich.edu    if options.maxinsts:
2937356Sgblack@eecs.umich.edu        for i in xrange(np):
2947356Sgblack@eecs.umich.edu            testsys.cpu[i].max_insts_any_thread = options.maxinsts
2957356Sgblack@eecs.umich.edu
2967356Sgblack@eecs.umich.edu    if cpu_class:
2977356Sgblack@eecs.umich.edu        switch_cpus = [cpu_class(switched_out=True, cpu_id=(i))
2987356Sgblack@eecs.umich.edu                       for i in xrange(np)]
2997356Sgblack@eecs.umich.edu
3007321Sgblack@eecs.umich.edu        for i in xrange(np):
3017321Sgblack@eecs.umich.edu            if options.fast_forward:
3027321Sgblack@eecs.umich.edu                testsys.cpu[i].max_insts_any_thread = int(options.fast_forward)
3037321Sgblack@eecs.umich.edu            switch_cpus[i].system =  testsys
3047321Sgblack@eecs.umich.edu            switch_cpus[i].workload = testsys.cpu[i].workload
3057321Sgblack@eecs.umich.edu            switch_cpus[i].clock = testsys.cpu[i].clock
3067321Sgblack@eecs.umich.edu            # simulation period
3077321Sgblack@eecs.umich.edu            if options.maxinsts:
3087321Sgblack@eecs.umich.edu                switch_cpus[i].max_insts_any_thread = options.maxinsts
3097321Sgblack@eecs.umich.edu            # Add checker cpu if selected
3107321Sgblack@eecs.umich.edu            if options.checker:
3117335Sgblack@eecs.umich.edu                switch_cpus[i].addCheckerCpu()
3127335Sgblack@eecs.umich.edu
3137335Sgblack@eecs.umich.edu        testsys.switch_cpus = switch_cpus
3147335Sgblack@eecs.umich.edu        switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
3157335Sgblack@eecs.umich.edu
3167335Sgblack@eecs.umich.edu    if options.repeat_switch:
3177335Sgblack@eecs.umich.edu        switch_class = getCPUClass(options.cpu_type)[0]
3187335Sgblack@eecs.umich.edu        if switch_class.require_caches() and \
3197335Sgblack@eecs.umich.edu                not options.caches:
3207321Sgblack@eecs.umich.edu            print "%s: Must be used with caches" % str(switch_class)
3217323Sgblack@eecs.umich.edu            sys.exit(1)
3227323Sgblack@eecs.umich.edu        if not switch_class.support_take_over():
3237323Sgblack@eecs.umich.edu            print "%s: CPU switching not supported" % str(switch_class)
3247323Sgblack@eecs.umich.edu            sys.exit(1)
3257323Sgblack@eecs.umich.edu
3267323Sgblack@eecs.umich.edu        repeat_switch_cpus = [switch_class(switched_out=True, \
3277323Sgblack@eecs.umich.edu                                               cpu_id=(i)) for i in xrange(np)]
3287323Sgblack@eecs.umich.edu
3297323Sgblack@eecs.umich.edu        for i in xrange(np):
3307323Sgblack@eecs.umich.edu            repeat_switch_cpus[i].system = testsys
3317323Sgblack@eecs.umich.edu            repeat_switch_cpus[i].workload = testsys.cpu[i].workload
3327323Sgblack@eecs.umich.edu            repeat_switch_cpus[i].clock = testsys.cpu[i].clock
3337323Sgblack@eecs.umich.edu
3347323Sgblack@eecs.umich.edu            if options.maxinsts:
3357323Sgblack@eecs.umich.edu                repeat_switch_cpus[i].max_insts_any_thread = options.maxinsts
3367323Sgblack@eecs.umich.edu
3377323Sgblack@eecs.umich.edu            if options.checker:
3387321Sgblack@eecs.umich.edu                repeat_switch_cpus[i].addCheckerCpu()
3397321Sgblack@eecs.umich.edu
3407321Sgblack@eecs.umich.edu        testsys.repeat_switch_cpus = repeat_switch_cpus
3417335Sgblack@eecs.umich.edu
3427335Sgblack@eecs.umich.edu        if cpu_class:
3437335Sgblack@eecs.umich.edu            repeat_switch_cpu_list = [(switch_cpus[i], repeat_switch_cpus[i])
3447335Sgblack@eecs.umich.edu                                      for i in xrange(np)]
3457335Sgblack@eecs.umich.edu        else:
3467335Sgblack@eecs.umich.edu            repeat_switch_cpu_list = [(testsys.cpu[i], repeat_switch_cpus[i])
3477335Sgblack@eecs.umich.edu                                      for i in xrange(np)]
3487335Sgblack@eecs.umich.edu
3497335Sgblack@eecs.umich.edu    if options.standard_switch:
3507335Sgblack@eecs.umich.edu        switch_cpus = [TimingSimpleCPU(switched_out=True, cpu_id=(i))
3517335Sgblack@eecs.umich.edu                       for i in xrange(np)]
3527335Sgblack@eecs.umich.edu        switch_cpus_1 = [DerivO3CPU(switched_out=True, cpu_id=(i))
3537335Sgblack@eecs.umich.edu                        for i in xrange(np)]
3547335Sgblack@eecs.umich.edu
3557335Sgblack@eecs.umich.edu        for i in xrange(np):
3567335Sgblack@eecs.umich.edu            switch_cpus[i].system =  testsys
3577335Sgblack@eecs.umich.edu            switch_cpus_1[i].system =  testsys
3587335Sgblack@eecs.umich.edu            switch_cpus[i].workload = testsys.cpu[i].workload
3597335Sgblack@eecs.umich.edu            switch_cpus_1[i].workload = testsys.cpu[i].workload
3607335Sgblack@eecs.umich.edu            switch_cpus[i].clock = testsys.cpu[i].clock
3617335Sgblack@eecs.umich.edu            switch_cpus_1[i].clock = testsys.cpu[i].clock
3627335Sgblack@eecs.umich.edu
3637335Sgblack@eecs.umich.edu            # if restoring, make atomic cpu simulate only a few instructions
3647335Sgblack@eecs.umich.edu            if options.checkpoint_restore != None:
3657335Sgblack@eecs.umich.edu                testsys.cpu[i].max_insts_any_thread = 1
3667335Sgblack@eecs.umich.edu            # Fast forward to specified location if we are not restoring
3677335Sgblack@eecs.umich.edu            elif options.fast_forward:
3687335Sgblack@eecs.umich.edu                testsys.cpu[i].max_insts_any_thread = int(options.fast_forward)
3697335Sgblack@eecs.umich.edu            # Fast forward to a simpoint (warning: time consuming)
3707335Sgblack@eecs.umich.edu            elif options.simpoint:
3717335Sgblack@eecs.umich.edu                if testsys.cpu[i].workload[0].simpoint == 0:
3727335Sgblack@eecs.umich.edu                    fatal('simpoint not found')
3737335Sgblack@eecs.umich.edu                testsys.cpu[i].max_insts_any_thread = \
3747321Sgblack@eecs.umich.edu                    testsys.cpu[i].workload[0].simpoint
3757321Sgblack@eecs.umich.edu            # No distance specified, just switch
3767321Sgblack@eecs.umich.edu            else:
3777321Sgblack@eecs.umich.edu                testsys.cpu[i].max_insts_any_thread = 1
3787321Sgblack@eecs.umich.edu
3797321Sgblack@eecs.umich.edu            # warmup period
3807335Sgblack@eecs.umich.edu            if options.warmup_insts:
3817335Sgblack@eecs.umich.edu                switch_cpus[i].max_insts_any_thread =  options.warmup_insts
3827335Sgblack@eecs.umich.edu
3837335Sgblack@eecs.umich.edu            # simulation period
3847335Sgblack@eecs.umich.edu            if options.maxinsts:
3857335Sgblack@eecs.umich.edu                switch_cpus_1[i].max_insts_any_thread = options.maxinsts
3867335Sgblack@eecs.umich.edu
3877335Sgblack@eecs.umich.edu            # attach the checker cpu if selected
3887335Sgblack@eecs.umich.edu            if options.checker:
3897321Sgblack@eecs.umich.edu                switch_cpus[i].addCheckerCpu()
3907326Sgblack@eecs.umich.edu                switch_cpus_1[i].addCheckerCpu()
3917326Sgblack@eecs.umich.edu
3927326Sgblack@eecs.umich.edu        testsys.switch_cpus = switch_cpus
3937326Sgblack@eecs.umich.edu        testsys.switch_cpus_1 = switch_cpus_1
3947326Sgblack@eecs.umich.edu        switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
3957326Sgblack@eecs.umich.edu        switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)]
3967326Sgblack@eecs.umich.edu
3977326Sgblack@eecs.umich.edu    # set the checkpoint in the cpu before m5.instantiate is called
3987326Sgblack@eecs.umich.edu    if options.take_checkpoints != None and \
3997326Sgblack@eecs.umich.edu           (options.simpoint or options.at_instruction):
4007326Sgblack@eecs.umich.edu        offset = int(options.take_checkpoints)
4017326Sgblack@eecs.umich.edu        # Set an instruction break point
4027326Sgblack@eecs.umich.edu        if options.simpoint:
4037326Sgblack@eecs.umich.edu            for i in xrange(np):
4047326Sgblack@eecs.umich.edu                if testsys.cpu[i].workload[0].simpoint == 0:
4057326Sgblack@eecs.umich.edu                    fatal('no simpoint for testsys.cpu[%d].workload[0]', i)
4067326Sgblack@eecs.umich.edu                checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset
4077326Sgblack@eecs.umich.edu                testsys.cpu[i].max_insts_any_thread = checkpoint_inst
4087326Sgblack@eecs.umich.edu                # used for output below
4097326Sgblack@eecs.umich.edu                options.take_checkpoints = checkpoint_inst
4107326Sgblack@eecs.umich.edu        else:
4117326Sgblack@eecs.umich.edu            options.take_checkpoints = offset
4127326Sgblack@eecs.umich.edu            # Set all test cpus with the right number of instructions
4137321Sgblack@eecs.umich.edu            # for the upcoming simulation
4147321Sgblack@eecs.umich.edu            for i in xrange(np):
4157335Sgblack@eecs.umich.edu                testsys.cpu[i].max_insts_any_thread = offset
4167335Sgblack@eecs.umich.edu
4177335Sgblack@eecs.umich.edu    checkpoint_dir = None
4187335Sgblack@eecs.umich.edu    if options.checkpoint_restore != None:
4197335Sgblack@eecs.umich.edu        maxtick, checkpoint_dir = findCptDir(options, maxtick, cptdir, testsys)
4207335Sgblack@eecs.umich.edu    m5.instantiate(checkpoint_dir)
4217335Sgblack@eecs.umich.edu
4227335Sgblack@eecs.umich.edu    if options.standard_switch or cpu_class:
4237335Sgblack@eecs.umich.edu        if options.standard_switch:
4247335Sgblack@eecs.umich.edu            print "Switch at instruction count:%s" % \
4257335Sgblack@eecs.umich.edu                    str(testsys.cpu[0].max_insts_any_thread)
4267335Sgblack@eecs.umich.edu            exit_event = m5.simulate()
4277335Sgblack@eecs.umich.edu        elif cpu_class and options.fast_forward:
4287335Sgblack@eecs.umich.edu            print "Switch at instruction count:%s" % \
4297335Sgblack@eecs.umich.edu                    str(testsys.cpu[0].max_insts_any_thread)
4307335Sgblack@eecs.umich.edu            exit_event = m5.simulate()
4317335Sgblack@eecs.umich.edu        else:
4327335Sgblack@eecs.umich.edu            print "Switch at curTick count:%s" % str(10000)
4337335Sgblack@eecs.umich.edu            exit_event = m5.simulate(10000)
4347335Sgblack@eecs.umich.edu        print "Switched CPUS @ tick %s" % (m5.curTick())
4357335Sgblack@eecs.umich.edu
4367335Sgblack@eecs.umich.edu        m5.switchCpus(testsys, switch_cpu_list)
4377335Sgblack@eecs.umich.edu
4387335Sgblack@eecs.umich.edu        if options.standard_switch:
4397335Sgblack@eecs.umich.edu            print "Switch at instruction count:%d" % \
4407335Sgblack@eecs.umich.edu                    (testsys.switch_cpus[0].max_insts_any_thread)
4417335Sgblack@eecs.umich.edu
4427335Sgblack@eecs.umich.edu            #warmup instruction count may have already been set
4437335Sgblack@eecs.umich.edu            if options.warmup_insts:
4447335Sgblack@eecs.umich.edu                exit_event = m5.simulate()
4457335Sgblack@eecs.umich.edu            else:
4467335Sgblack@eecs.umich.edu                exit_event = m5.simulate(options.standard_switch)
4477335Sgblack@eecs.umich.edu            print "Switching CPUS @ tick %s" % (m5.curTick())
4487335Sgblack@eecs.umich.edu            print "Simulation ends instruction count:%d" % \
4497335Sgblack@eecs.umich.edu                    (testsys.switch_cpus_1[0].max_insts_any_thread)
4507335Sgblack@eecs.umich.edu            m5.switchCpus(testsys, switch_cpu_list1)
4517335Sgblack@eecs.umich.edu
4527335Sgblack@eecs.umich.edu    # If we're taking and restoring checkpoints, use checkpoint_dir
4537335Sgblack@eecs.umich.edu    # option only for finding the checkpoints to restore from.  This
4547335Sgblack@eecs.umich.edu    # lets us test checkpointing by restoring from one set of
4557335Sgblack@eecs.umich.edu    # checkpoints, generating a second set, and then comparing them.
4567335Sgblack@eecs.umich.edu    if options.take_checkpoints and options.checkpoint_restore:
4577335Sgblack@eecs.umich.edu        if m5.options.outdir:
4587335Sgblack@eecs.umich.edu            cptdir = m5.options.outdir
4597321Sgblack@eecs.umich.edu        else:
4607321Sgblack@eecs.umich.edu            cptdir = getcwd()
4617321Sgblack@eecs.umich.edu
4627321Sgblack@eecs.umich.edu    if options.take_checkpoints != None :
4637321Sgblack@eecs.umich.edu        # Checkpoints being taken via the command line at <when> and at
4647356Sgblack@eecs.umich.edu        # subsequent periods of <period>.  Checkpoint instructions
4657356Sgblack@eecs.umich.edu        # received from the benchmark running are ignored and skipped in
4667356Sgblack@eecs.umich.edu        # favor of command line checkpoint instructions.
4677356Sgblack@eecs.umich.edu        exit_cause = scriptCheckpoints(options, maxtick, cptdir)
4687356Sgblack@eecs.umich.edu    else:
4697356Sgblack@eecs.umich.edu        if options.fast_forward:
4707363Sgblack@eecs.umich.edu            m5.stats.reset()
4717363Sgblack@eecs.umich.edu        print "**** REAL SIMULATION ****"
4727363Sgblack@eecs.umich.edu
4737363Sgblack@eecs.umich.edu        # If checkpoints are being taken, then the checkpoint instruction
4747363Sgblack@eecs.umich.edu        # will occur in the benchmark code it self.
4757363Sgblack@eecs.umich.edu        if options.repeat_switch and maxtick > options.repeat_switch:
4767363Sgblack@eecs.umich.edu            exit_event = repeatSwitch(testsys, repeat_switch_cpu_list,
4777363Sgblack@eecs.umich.edu                                      maxtick, options.repeat_switch)
4787363Sgblack@eecs.umich.edu        else:
4797363Sgblack@eecs.umich.edu            exit_event = benchCheckpoints(options, maxtick, cptdir)
4807363Sgblack@eecs.umich.edu
4817363Sgblack@eecs.umich.edu    print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_event.getCause())
4827363Sgblack@eecs.umich.edu    if options.checkpoint_at_end:
4837363Sgblack@eecs.umich.edu        m5.checkpoint(joinpath(cptdir, "cpt.%d"))
4847363Sgblack@eecs.umich.edu
4857363Sgblack@eecs.umich.edu    if not m5.options.interactive:
4867363Sgblack@eecs.umich.edu        sys.exit(exit_event.getCode())
4877363Sgblack@eecs.umich.edu