Simulation.py revision 12374
15409Sgblack@eecs.umich.edu# Copyright (c) 2012-2013 ARM Limited
24519Sgblack@eecs.umich.edu# All rights reserved
34519Sgblack@eecs.umich.edu#
44519Sgblack@eecs.umich.edu# The license below extends only to copyright in the software and shall
54519Sgblack@eecs.umich.edu# not be construed as granting a license to any other intellectual
64519Sgblack@eecs.umich.edu# property including but not limited to intellectual property relating
74519Sgblack@eecs.umich.edu# to a hardware implementation of the functionality of the software
84519Sgblack@eecs.umich.edu# licensed hereunder.  You may use the software subject to the license
94519Sgblack@eecs.umich.edu# terms below provided that you ensure that this notice is replicated
104519Sgblack@eecs.umich.edu# unmodified and in its entirety in all distributions of the software,
114519Sgblack@eecs.umich.edu# modified or unmodified, in source code or in binary form.
124519Sgblack@eecs.umich.edu#
134519Sgblack@eecs.umich.edu# Copyright (c) 2006-2008 The Regents of The University of Michigan
144519Sgblack@eecs.umich.edu# Copyright (c) 2010 Advanced Micro Devices, Inc.
154519Sgblack@eecs.umich.edu# All rights reserved.
164519Sgblack@eecs.umich.edu#
174519Sgblack@eecs.umich.edu# Redistribution and use in source and binary forms, with or without
184519Sgblack@eecs.umich.edu# modification, are permitted provided that the following conditions are
194519Sgblack@eecs.umich.edu# met: redistributions of source code must retain the above copyright
204519Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer;
214519Sgblack@eecs.umich.edu# redistributions in binary form must reproduce the above copyright
224519Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the
234519Sgblack@eecs.umich.edu# documentation and/or other materials provided with the distribution;
244519Sgblack@eecs.umich.edu# neither the name of the copyright holders nor the names of its
254519Sgblack@eecs.umich.edu# contributors may be used to endorse or promote products derived from
264519Sgblack@eecs.umich.edu# this software without specific prior written permission.
274519Sgblack@eecs.umich.edu#
284519Sgblack@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
294519Sgblack@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
304519Sgblack@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
314519Sgblack@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
324519Sgblack@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
334519Sgblack@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
344519Sgblack@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
354519Sgblack@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
364519Sgblack@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
374519Sgblack@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
384519Sgblack@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
394519Sgblack@eecs.umich.edu#
404519Sgblack@eecs.umich.edu# Authors: Lisa Hsu
414519Sgblack@eecs.umich.edu
424519Sgblack@eecs.umich.eduimport sys
434519Sgblack@eecs.umich.edufrom os import getcwd
444519Sgblack@eecs.umich.edufrom os.path import join as joinpath
454519Sgblack@eecs.umich.edu
464519Sgblack@eecs.umich.edufrom common import CpuConfig
474519Sgblack@eecs.umich.edufrom common import MemConfig
484519Sgblack@eecs.umich.edu
494519Sgblack@eecs.umich.eduimport m5
504519Sgblack@eecs.umich.edufrom m5.defines import buildEnv
514519Sgblack@eecs.umich.edufrom m5.objects import *
524519Sgblack@eecs.umich.edufrom m5.util import *
534519Sgblack@eecs.umich.edu
544519Sgblack@eecs.umich.eduaddToPath('../common')
554519Sgblack@eecs.umich.edu
564519Sgblack@eecs.umich.edudef getCPUClass(cpu_type):
574519Sgblack@eecs.umich.edu    """Returns the required cpu class and the mode of operation."""
584519Sgblack@eecs.umich.edu    cls = CpuConfig.get(cpu_type)
594519Sgblack@eecs.umich.edu    return cls, cls.memory_mode()
604519Sgblack@eecs.umich.edu
614519Sgblack@eecs.umich.edudef setCPUClass(options):
624519Sgblack@eecs.umich.edu    """Returns two cpu classes and the initial mode of operation.
634519Sgblack@eecs.umich.edu
644519Sgblack@eecs.umich.edu       Restoring from a checkpoint or fast forwarding through a benchmark
654519Sgblack@eecs.umich.edu       can be done using one type of cpu, and then the actual
664519Sgblack@eecs.umich.edu       simulation can be carried out using another type. This function
674519Sgblack@eecs.umich.edu       returns these two types of cpus and the initial mode of operation
684809Sgblack@eecs.umich.edu       depending on the options provided.
694519Sgblack@eecs.umich.edu    """
704519Sgblack@eecs.umich.edu
714688Sgblack@eecs.umich.edu    TmpClass, test_mem_mode = getCPUClass(options.cpu_type)
724688Sgblack@eecs.umich.edu    CPUClass = None
734688Sgblack@eecs.umich.edu    if TmpClass.require_caches() and \
744688Sgblack@eecs.umich.edu            not options.caches and not options.ruby:
754688Sgblack@eecs.umich.edu        fatal("%s must be used with caches" % options.cpu_type)
764688Sgblack@eecs.umich.edu
774708Sgblack@eecs.umich.edu    if options.checkpoint_restore != None:
784708Sgblack@eecs.umich.edu        if options.restore_with_cpu != options.cpu_type:
794708Sgblack@eecs.umich.edu            CPUClass = TmpClass
804708Sgblack@eecs.umich.edu            TmpClass, test_mem_mode = getCPUClass(options.restore_with_cpu)
814519Sgblack@eecs.umich.edu    elif options.fast_forward:
824519Sgblack@eecs.umich.edu        CPUClass = TmpClass
834519Sgblack@eecs.umich.edu        TmpClass = AtomicSimpleCPU
844519Sgblack@eecs.umich.edu        test_mem_mode = 'atomic'
854519Sgblack@eecs.umich.edu
864519Sgblack@eecs.umich.edu    return (TmpClass, test_mem_mode, CPUClass)
874519Sgblack@eecs.umich.edu
884519Sgblack@eecs.umich.edudef setMemClass(options):
894519Sgblack@eecs.umich.edu    """Returns a memory controller class."""
904519Sgblack@eecs.umich.edu
914519Sgblack@eecs.umich.edu    return MemConfig.get(options.mem_type)
924951Sgblack@eecs.umich.edu
934519Sgblack@eecs.umich.edudef setWorkCountOptions(system, options):
944519Sgblack@eecs.umich.edu    if options.work_item_id != None:
954519Sgblack@eecs.umich.edu        system.work_item_id = options.work_item_id
964519Sgblack@eecs.umich.edu    if options.num_work_ids != None:
974519Sgblack@eecs.umich.edu        system.num_work_ids = options.num_work_ids
984519Sgblack@eecs.umich.edu    if options.work_begin_cpu_id_exit != None:
994688Sgblack@eecs.umich.edu        system.work_begin_cpu_id_exit = options.work_begin_cpu_id_exit
1004688Sgblack@eecs.umich.edu    if options.work_end_exit_count != None:
1014688Sgblack@eecs.umich.edu        system.work_end_exit_count = options.work_end_exit_count
1024688Sgblack@eecs.umich.edu    if options.work_end_checkpoint_count != None:
1034688Sgblack@eecs.umich.edu        system.work_end_ckpt_count = options.work_end_checkpoint_count
1044688Sgblack@eecs.umich.edu    if options.work_begin_exit_count != None:
1054708Sgblack@eecs.umich.edu        system.work_begin_exit_count = options.work_begin_exit_count
1064708Sgblack@eecs.umich.edu    if options.work_begin_checkpoint_count != None:
1074708Sgblack@eecs.umich.edu        system.work_begin_ckpt_count = options.work_begin_checkpoint_count
1084708Sgblack@eecs.umich.edu    if options.work_cpus_checkpoint_count != None:
1094519Sgblack@eecs.umich.edu        system.work_cpus_ckpt_count = options.work_cpus_checkpoint_count
1104519Sgblack@eecs.umich.edu
1114519Sgblack@eecs.umich.edudef findCptDir(options, cptdir, testsys):
1124519Sgblack@eecs.umich.edu    """Figures out the directory from which the checkpointed state is read.
1134519Sgblack@eecs.umich.edu
1144519Sgblack@eecs.umich.edu    There are two different ways in which the directories holding checkpoints
1154519Sgblack@eecs.umich.edu    can be named --
1164519Sgblack@eecs.umich.edu    1. cpt.<benchmark name>.<instruction count when the checkpoint was taken>
1174519Sgblack@eecs.umich.edu    2. cpt.<some number, usually the tick value when the checkpoint was taken>
1184519Sgblack@eecs.umich.edu
1194519Sgblack@eecs.umich.edu    This function parses through the options to figure out which one of the
1204519Sgblack@eecs.umich.edu    above should be used for selecting the checkpoint, and then figures out
1214519Sgblack@eecs.umich.edu    the appropriate directory.
1224519Sgblack@eecs.umich.edu    """
1234519Sgblack@eecs.umich.edu
1244519Sgblack@eecs.umich.edu    from os.path import isdir, exists
1254519Sgblack@eecs.umich.edu    from os import listdir
1264519Sgblack@eecs.umich.edu    import re
1274519Sgblack@eecs.umich.edu
1284519Sgblack@eecs.umich.edu    if not isdir(cptdir):
1296345Sgblack@eecs.umich.edu        fatal("checkpoint dir %s does not exist!", cptdir)
1304712Sgblack@eecs.umich.edu
1314519Sgblack@eecs.umich.edu    cpt_starttick = 0
1324519Sgblack@eecs.umich.edu    if options.at_instruction or options.simpoint:
1334519Sgblack@eecs.umich.edu        inst = options.checkpoint_restore
1346345Sgblack@eecs.umich.edu        if options.simpoint:
1354712Sgblack@eecs.umich.edu            # assume workload 0 has the simpoint
1364519Sgblack@eecs.umich.edu            if testsys.cpu[0].workload[0].simpoint == 0:
1374519Sgblack@eecs.umich.edu                fatal('Unable to find simpoint')
1384519Sgblack@eecs.umich.edu            inst += int(testsys.cpu[0].workload[0].simpoint)
1394519Sgblack@eecs.umich.edu
1404519Sgblack@eecs.umich.edu        checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % (options.bench, inst))
1414519Sgblack@eecs.umich.edu        if not exists(checkpoint_dir):
1424519Sgblack@eecs.umich.edu            fatal("Unable to find checkpoint directory %s", checkpoint_dir)
1434951Sgblack@eecs.umich.edu
1444519Sgblack@eecs.umich.edu    elif options.restore_simpoint_checkpoint:
1454519Sgblack@eecs.umich.edu        # Restore from SimPoint checkpoints
1464519Sgblack@eecs.umich.edu        # Assumes that the checkpoint dir names are formatted as follows:
1474519Sgblack@eecs.umich.edu        dirs = listdir(cptdir)
1484519Sgblack@eecs.umich.edu        expr = re.compile('cpt\.simpoint_(\d+)_inst_(\d+)' +
1494951Sgblack@eecs.umich.edu                    '_weight_([\d\.e\-]+)_interval_(\d+)_warmup_(\d+)')
1504519Sgblack@eecs.umich.edu        cpts = []
1514519Sgblack@eecs.umich.edu        for dir in dirs:
1526345Sgblack@eecs.umich.edu            match = expr.match(dir)
1534712Sgblack@eecs.umich.edu            if match:
1544519Sgblack@eecs.umich.edu                cpts.append(dir)
1554951Sgblack@eecs.umich.edu        cpts.sort()
1564519Sgblack@eecs.umich.edu
1576345Sgblack@eecs.umich.edu        cpt_num = options.checkpoint_restore
1584712Sgblack@eecs.umich.edu        if cpt_num > len(cpts):
1594519Sgblack@eecs.umich.edu            fatal('Checkpoint %d not found', cpt_num)
1604519Sgblack@eecs.umich.edu        checkpoint_dir = joinpath(cptdir, cpts[cpt_num - 1])
1614519Sgblack@eecs.umich.edu        match = expr.match(cpts[cpt_num - 1])
1624519Sgblack@eecs.umich.edu        if match:
1634519Sgblack@eecs.umich.edu            index = int(match.group(1))
1644519Sgblack@eecs.umich.edu            start_inst = int(match.group(2))
1654519Sgblack@eecs.umich.edu            weight_inst = float(match.group(3))
1664519Sgblack@eecs.umich.edu            interval_length = int(match.group(4))
1674519Sgblack@eecs.umich.edu            warmup_length = int(match.group(5))
1684519Sgblack@eecs.umich.edu        print "Resuming from", checkpoint_dir
1694519Sgblack@eecs.umich.edu        simpoint_start_insts = []
1704519Sgblack@eecs.umich.edu        simpoint_start_insts.append(warmup_length)
1714519Sgblack@eecs.umich.edu        simpoint_start_insts.append(warmup_length + interval_length)
1724519Sgblack@eecs.umich.edu        testsys.cpu[0].simpoint_start_insts = simpoint_start_insts
1736345Sgblack@eecs.umich.edu        if testsys.switch_cpus != None:
1744712Sgblack@eecs.umich.edu            testsys.switch_cpus[0].simpoint_start_insts = simpoint_start_insts
1754519Sgblack@eecs.umich.edu
1764581Sgblack@eecs.umich.edu        print "Resuming from SimPoint",
1774688Sgblack@eecs.umich.edu        print "#%d, start_inst:%d, weight:%f, interval:%d, warmup:%d" % \
1784581Sgblack@eecs.umich.edu            (index, start_inst, weight_inst, interval_length, warmup_length)
1794519Sgblack@eecs.umich.edu
1804519Sgblack@eecs.umich.edu    else:
1814519Sgblack@eecs.umich.edu        dirs = listdir(cptdir)
1824519Sgblack@eecs.umich.edu        expr = re.compile('cpt\.([0-9]+)')
1834519Sgblack@eecs.umich.edu        cpts = []
1844519Sgblack@eecs.umich.edu        for dir in dirs:
1854519Sgblack@eecs.umich.edu            match = expr.match(dir)
1866345Sgblack@eecs.umich.edu            if match:
1874712Sgblack@eecs.umich.edu                cpts.append(match.group(1))
1884519Sgblack@eecs.umich.edu
1894581Sgblack@eecs.umich.edu        cpts.sort(lambda a,b: cmp(long(a), long(b)))
1904688Sgblack@eecs.umich.edu
1914581Sgblack@eecs.umich.edu        cpt_num = options.checkpoint_restore
1924519Sgblack@eecs.umich.edu        if cpt_num > len(cpts):
1934519Sgblack@eecs.umich.edu            fatal('Checkpoint %d not found', cpt_num)
1944519Sgblack@eecs.umich.edu
1954519Sgblack@eecs.umich.edu        cpt_starttick = int(cpts[cpt_num - 1])
1964519Sgblack@eecs.umich.edu        checkpoint_dir = joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1])
1974519Sgblack@eecs.umich.edu
1984519Sgblack@eecs.umich.edu    return cpt_starttick, checkpoint_dir
1994951Sgblack@eecs.umich.edu
2004519Sgblack@eecs.umich.edudef scriptCheckpoints(options, maxtick, cptdir):
2014519Sgblack@eecs.umich.edu    if options.at_instruction or options.simpoint:
2024519Sgblack@eecs.umich.edu        checkpoint_inst = int(options.take_checkpoints)
2034519Sgblack@eecs.umich.edu
2044951Sgblack@eecs.umich.edu        # maintain correct offset if we restored from some instruction
2054519Sgblack@eecs.umich.edu        if options.checkpoint_restore != None:
2066345Sgblack@eecs.umich.edu            checkpoint_inst += options.checkpoint_restore
2074712Sgblack@eecs.umich.edu
2084519Sgblack@eecs.umich.edu        print "Creating checkpoint at inst:%d" % (checkpoint_inst)
2094581Sgblack@eecs.umich.edu        exit_event = m5.simulate()
2104688Sgblack@eecs.umich.edu        exit_cause = exit_event.getCause()
2114581Sgblack@eecs.umich.edu        print "exit cause = %s" % exit_cause
2124519Sgblack@eecs.umich.edu
2134519Sgblack@eecs.umich.edu        # skip checkpoint instructions should they exist
2144519Sgblack@eecs.umich.edu        while exit_cause == "checkpoint":
2154519Sgblack@eecs.umich.edu            exit_event = m5.simulate()
2164951Sgblack@eecs.umich.edu            exit_cause = exit_event.getCause()
2174519Sgblack@eecs.umich.edu
2184519Sgblack@eecs.umich.edu        if exit_cause == "a thread reached the max instruction count":
2196345Sgblack@eecs.umich.edu            m5.checkpoint(joinpath(cptdir, "cpt.%s.%d" % \
2204712Sgblack@eecs.umich.edu                    (options.bench, checkpoint_inst)))
2214519Sgblack@eecs.umich.edu            print "Checkpoint written."
2224581Sgblack@eecs.umich.edu
2234688Sgblack@eecs.umich.edu    else:
2244581Sgblack@eecs.umich.edu        when, period = options.take_checkpoints.split(",", 1)
2254519Sgblack@eecs.umich.edu        when = int(when)
2264519Sgblack@eecs.umich.edu        period = int(period)
2274519Sgblack@eecs.umich.edu        num_checkpoints = 0
2284519Sgblack@eecs.umich.edu
2294519Sgblack@eecs.umich.edu        exit_event = m5.simulate(when - m5.curTick())
2305075Sgblack@eecs.umich.edu        exit_cause = exit_event.getCause()
2315075Sgblack@eecs.umich.edu        while exit_cause == "checkpoint":
2325075Sgblack@eecs.umich.edu            exit_event = m5.simulate(when - m5.curTick())
2335075Sgblack@eecs.umich.edu            exit_cause = exit_event.getCause()
2345428Sgblack@eecs.umich.edu
2355428Sgblack@eecs.umich.edu        if exit_cause == "simulate() limit reached":
2365674Sgblack@eecs.umich.edu            m5.checkpoint(joinpath(cptdir, "cpt.%d"))
2375899Sgblack@eecs.umich.edu            num_checkpoints += 1
2385936Sgblack@eecs.umich.edu
2395428Sgblack@eecs.umich.edu        sim_ticks = when
2405678Sgblack@eecs.umich.edu        max_checkpoints = options.max_checkpoints
2415678Sgblack@eecs.umich.edu
2425678Sgblack@eecs.umich.edu        while num_checkpoints < max_checkpoints and \
2435678Sgblack@eecs.umich.edu                exit_cause == "simulate() limit reached":
2445678Sgblack@eecs.umich.edu            if (sim_ticks + period) > maxtick:
2455678Sgblack@eecs.umich.edu                exit_event = m5.simulate(maxtick - sim_ticks)
2465678Sgblack@eecs.umich.edu                exit_cause = exit_event.getCause()
2475678Sgblack@eecs.umich.edu                break
2485678Sgblack@eecs.umich.edu            else:
2495075Sgblack@eecs.umich.edu                exit_event = m5.simulate(period)
2505075Sgblack@eecs.umich.edu                exit_cause = exit_event.getCause()
2515075Sgblack@eecs.umich.edu                sim_ticks += period
2525075Sgblack@eecs.umich.edu                while exit_event.getCause() == "checkpoint":
2535075Sgblack@eecs.umich.edu                    exit_event = m5.simulate(sim_ticks - m5.curTick())
2545075Sgblack@eecs.umich.edu                if exit_event.getCause() == "simulate() limit reached":
2555075Sgblack@eecs.umich.edu                    m5.checkpoint(joinpath(cptdir, "cpt.%d"))
2565075Sgblack@eecs.umich.edu                    num_checkpoints += 1
2575075Sgblack@eecs.umich.edu
2585075Sgblack@eecs.umich.edu    return exit_event
2595075Sgblack@eecs.umich.edu
2605075Sgblack@eecs.umich.edudef benchCheckpoints(options, maxtick, cptdir):
2615075Sgblack@eecs.umich.edu    exit_event = m5.simulate(maxtick - m5.curTick())
2625075Sgblack@eecs.umich.edu    exit_cause = exit_event.getCause()
2635075Sgblack@eecs.umich.edu
2645075Sgblack@eecs.umich.edu    num_checkpoints = 0
2655075Sgblack@eecs.umich.edu    max_checkpoints = options.max_checkpoints
2665075Sgblack@eecs.umich.edu
2675075Sgblack@eecs.umich.edu    while exit_cause == "checkpoint":
2685075Sgblack@eecs.umich.edu        m5.checkpoint(joinpath(cptdir, "cpt.%d"))
2695075Sgblack@eecs.umich.edu        num_checkpoints += 1
2705075Sgblack@eecs.umich.edu        if num_checkpoints == max_checkpoints:
2715075Sgblack@eecs.umich.edu            exit_cause = "maximum %d checkpoints dropped" % max_checkpoints
2725075Sgblack@eecs.umich.edu            break
2735075Sgblack@eecs.umich.edu
2745075Sgblack@eecs.umich.edu        exit_event = m5.simulate(maxtick - m5.curTick())
2755075Sgblack@eecs.umich.edu        exit_cause = exit_event.getCause()
2765075Sgblack@eecs.umich.edu
2775075Sgblack@eecs.umich.edu    return exit_event
2785075Sgblack@eecs.umich.edu
2795075Sgblack@eecs.umich.edu# Set up environment for taking SimPoint checkpoints
2805075Sgblack@eecs.umich.edu# Expecting SimPoint files generated by SimPoint 3.2
2815075Sgblack@eecs.umich.edudef parseSimpointAnalysisFile(options, testsys):
2825075Sgblack@eecs.umich.edu    import re
2835075Sgblack@eecs.umich.edu
2844519Sgblack@eecs.umich.edu    simpoint_filename, weight_filename, interval_length, warmup_length = \
2855040Sgblack@eecs.umich.edu        options.take_simpoint_checkpoints.split(",", 3)
2865040Sgblack@eecs.umich.edu    print "simpoint analysis file:", simpoint_filename
2875040Sgblack@eecs.umich.edu    print "simpoint weight file:", weight_filename
2885040Sgblack@eecs.umich.edu    print "interval length:", interval_length
2895040Sgblack@eecs.umich.edu    print "warmup length:", warmup_length
2905040Sgblack@eecs.umich.edu
2915040Sgblack@eecs.umich.edu    interval_length = int(interval_length)
2925040Sgblack@eecs.umich.edu    warmup_length = int(warmup_length)
2935040Sgblack@eecs.umich.edu
2945040Sgblack@eecs.umich.edu    # Simpoint analysis output starts interval counts with 0.
2955040Sgblack@eecs.umich.edu    simpoints = []
2965040Sgblack@eecs.umich.edu    simpoint_start_insts = []
2975040Sgblack@eecs.umich.edu
2985040Sgblack@eecs.umich.edu    # Read in SimPoint analysis files
2995040Sgblack@eecs.umich.edu    simpoint_file = open(simpoint_filename)
3005040Sgblack@eecs.umich.edu    weight_file = open(weight_filename)
3015040Sgblack@eecs.umich.edu    while True:
3025040Sgblack@eecs.umich.edu        line = simpoint_file.readline()
3035040Sgblack@eecs.umich.edu        if not line:
3045040Sgblack@eecs.umich.edu            break
3055040Sgblack@eecs.umich.edu        m = re.match("(\d+)\s+(\d+)", line)
3065040Sgblack@eecs.umich.edu        if m:
3075040Sgblack@eecs.umich.edu            interval = int(m.group(1))
3085040Sgblack@eecs.umich.edu        else:
3095040Sgblack@eecs.umich.edu            fatal('unrecognized line in simpoint file!')
3105040Sgblack@eecs.umich.edu
3115040Sgblack@eecs.umich.edu        line = weight_file.readline()
3125040Sgblack@eecs.umich.edu        if not line:
3135040Sgblack@eecs.umich.edu            fatal('not enough lines in simpoint weight file!')
3145040Sgblack@eecs.umich.edu        m = re.match("([0-9\.e\-]+)\s+(\d+)", line)
3155062Sgblack@eecs.umich.edu        if m:
3165062Sgblack@eecs.umich.edu            weight = float(m.group(1))
3175062Sgblack@eecs.umich.edu        else:
3185062Sgblack@eecs.umich.edu            fatal('unrecognized line in simpoint weight file!')
3195062Sgblack@eecs.umich.edu
3205062Sgblack@eecs.umich.edu        if (interval * interval_length - warmup_length > 0):
3215062Sgblack@eecs.umich.edu            starting_inst_count = \
3225040Sgblack@eecs.umich.edu                interval * interval_length - warmup_length
3235062Sgblack@eecs.umich.edu            actual_warmup_length = warmup_length
3245062Sgblack@eecs.umich.edu        else:
3255062Sgblack@eecs.umich.edu            # Not enough room for proper warmup
3265062Sgblack@eecs.umich.edu            # Just starting from the beginning
3275040Sgblack@eecs.umich.edu            starting_inst_count = 0
3285040Sgblack@eecs.umich.edu            actual_warmup_length = interval * interval_length
3295040Sgblack@eecs.umich.edu
3305040Sgblack@eecs.umich.edu        simpoints.append((interval, weight, starting_inst_count,
3315040Sgblack@eecs.umich.edu            actual_warmup_length))
3325040Sgblack@eecs.umich.edu
3335040Sgblack@eecs.umich.edu    # Sort SimPoints by starting inst count
3345040Sgblack@eecs.umich.edu    simpoints.sort(key=lambda obj: obj[2])
3355040Sgblack@eecs.umich.edu    for s in simpoints:
3365239Sgblack@eecs.umich.edu        interval, weight, starting_inst_count, actual_warmup_length = s
3375040Sgblack@eecs.umich.edu        print str(interval), str(weight), starting_inst_count, \
3385040Sgblack@eecs.umich.edu            actual_warmup_length
3395040Sgblack@eecs.umich.edu        simpoint_start_insts.append(starting_inst_count)
3405040Sgblack@eecs.umich.edu
3415040Sgblack@eecs.umich.edu    print "Total # of simpoints:", len(simpoints)
3425040Sgblack@eecs.umich.edu    testsys.cpu[0].simpoint_start_insts = simpoint_start_insts
3435040Sgblack@eecs.umich.edu
3445040Sgblack@eecs.umich.edu    return (simpoints, interval_length)
3455061Sgblack@eecs.umich.edu
3465040Sgblack@eecs.umich.edudef takeSimpointCheckpoints(simpoints, interval_length, cptdir):
3475040Sgblack@eecs.umich.edu    num_checkpoints = 0
3485061Sgblack@eecs.umich.edu    index = 0
3495061Sgblack@eecs.umich.edu    last_chkpnt_inst_count = -1
3505061Sgblack@eecs.umich.edu    for simpoint in simpoints:
3515061Sgblack@eecs.umich.edu        interval, weight, starting_inst_count, actual_warmup_length = simpoint
3525061Sgblack@eecs.umich.edu        if starting_inst_count == last_chkpnt_inst_count:
3535061Sgblack@eecs.umich.edu            # checkpoint starting point same as last time
3545061Sgblack@eecs.umich.edu            # (when warmup period longer than starting point)
3555061Sgblack@eecs.umich.edu            exit_cause = "simpoint starting point found"
3565040Sgblack@eecs.umich.edu            code = 0
3575040Sgblack@eecs.umich.edu        else:
3585040Sgblack@eecs.umich.edu            exit_event = m5.simulate()
3595040Sgblack@eecs.umich.edu
3605040Sgblack@eecs.umich.edu            # skip checkpoint instructions should they exist
3615040Sgblack@eecs.umich.edu            while exit_event.getCause() == "checkpoint":
3625040Sgblack@eecs.umich.edu                print "Found 'checkpoint' exit event...ignoring..."
3635040Sgblack@eecs.umich.edu                exit_event = m5.simulate()
3645040Sgblack@eecs.umich.edu
3655040Sgblack@eecs.umich.edu            exit_cause = exit_event.getCause()
3665040Sgblack@eecs.umich.edu            code = exit_event.getCode()
3675040Sgblack@eecs.umich.edu
3685040Sgblack@eecs.umich.edu        if exit_cause == "simpoint starting point found":
3695040Sgblack@eecs.umich.edu            m5.checkpoint(joinpath(cptdir,
3705040Sgblack@eecs.umich.edu                "cpt.simpoint_%02d_inst_%d_weight_%f_interval_%d_warmup_%d"
3715040Sgblack@eecs.umich.edu                % (index, starting_inst_count, weight, interval_length,
3725040Sgblack@eecs.umich.edu                actual_warmup_length)))
3735040Sgblack@eecs.umich.edu            print "Checkpoint #%d written. start inst:%d weight:%f" % \
3745040Sgblack@eecs.umich.edu                (num_checkpoints, starting_inst_count, weight)
3755040Sgblack@eecs.umich.edu            num_checkpoints += 1
3765040Sgblack@eecs.umich.edu            last_chkpnt_inst_count = starting_inst_count
3775040Sgblack@eecs.umich.edu        else:
3785040Sgblack@eecs.umich.edu            break
3795040Sgblack@eecs.umich.edu        index += 1
3805040Sgblack@eecs.umich.edu
3814688Sgblack@eecs.umich.edu    print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_cause)
3825040Sgblack@eecs.umich.edu    print "%d checkpoints taken" % num_checkpoints
3834688Sgblack@eecs.umich.edu    sys.exit(code)
3844688Sgblack@eecs.umich.edu
3854688Sgblack@eecs.umich.edudef restoreSimpointCheckpoint():
3864688Sgblack@eecs.umich.edu    exit_event = m5.simulate()
3875040Sgblack@eecs.umich.edu    exit_cause = exit_event.getCause()
3884688Sgblack@eecs.umich.edu
3895040Sgblack@eecs.umich.edu    if exit_cause == "simpoint starting point found":
3905040Sgblack@eecs.umich.edu        print "Warmed up! Dumping and resetting stats!"
3915040Sgblack@eecs.umich.edu        m5.stats.dump()
3925040Sgblack@eecs.umich.edu        m5.stats.reset()
3935040Sgblack@eecs.umich.edu
3945040Sgblack@eecs.umich.edu        exit_event = m5.simulate()
3955040Sgblack@eecs.umich.edu        exit_cause = exit_event.getCause()
3965040Sgblack@eecs.umich.edu
3975040Sgblack@eecs.umich.edu        if exit_cause == "simpoint starting point found":
3985040Sgblack@eecs.umich.edu            print "Done running SimPoint!"
3995040Sgblack@eecs.umich.edu            sys.exit(exit_event.getCode())
4005040Sgblack@eecs.umich.edu
4015040Sgblack@eecs.umich.edu    print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_cause)
4025040Sgblack@eecs.umich.edu    sys.exit(exit_event.getCode())
4035040Sgblack@eecs.umich.edu
4045040Sgblack@eecs.umich.edudef repeatSwitch(testsys, repeat_switch_cpu_list, maxtick, switch_freq):
4055040Sgblack@eecs.umich.edu    print "starting switch loop"
4065040Sgblack@eecs.umich.edu    while True:
4075040Sgblack@eecs.umich.edu        exit_event = m5.simulate(switch_freq)
4085040Sgblack@eecs.umich.edu        exit_cause = exit_event.getCause()
4095040Sgblack@eecs.umich.edu
4105040Sgblack@eecs.umich.edu        if exit_cause != "simulate() limit reached":
4114688Sgblack@eecs.umich.edu            return exit_event
4124688Sgblack@eecs.umich.edu
4135040Sgblack@eecs.umich.edu        m5.switchCpus(testsys, repeat_switch_cpu_list)
4145040Sgblack@eecs.umich.edu
4155040Sgblack@eecs.umich.edu        tmp_cpu_list = []
4165040Sgblack@eecs.umich.edu        for old_cpu, new_cpu in repeat_switch_cpu_list:
4174688Sgblack@eecs.umich.edu            tmp_cpu_list.append((new_cpu, old_cpu))
4184688Sgblack@eecs.umich.edu        repeat_switch_cpu_list = tmp_cpu_list
4195040Sgblack@eecs.umich.edu
4205040Sgblack@eecs.umich.edu        if (maxtick - m5.curTick()) <= switch_freq:
4215040Sgblack@eecs.umich.edu            exit_event = m5.simulate(maxtick - m5.curTick())
4225040Sgblack@eecs.umich.edu            return exit_event
4235040Sgblack@eecs.umich.edu
4245040Sgblack@eecs.umich.edudef run(options, root, testsys, cpu_class):
4254519Sgblack@eecs.umich.edu    if options.checkpoint_dir:
4264519Sgblack@eecs.umich.edu        cptdir = options.checkpoint_dir
4275040Sgblack@eecs.umich.edu    elif m5.options.outdir:
4284688Sgblack@eecs.umich.edu        cptdir = m5.options.outdir
4294701Sgblack@eecs.umich.edu    else:
4304688Sgblack@eecs.umich.edu        cptdir = getcwd()
4314688Sgblack@eecs.umich.edu
4324688Sgblack@eecs.umich.edu    if options.fast_forward and options.checkpoint_restore != None:
4334688Sgblack@eecs.umich.edu        fatal("Can't specify both --fast-forward and --checkpoint-restore")
4344688Sgblack@eecs.umich.edu
4354688Sgblack@eecs.umich.edu    if options.standard_switch and not options.caches:
4364688Sgblack@eecs.umich.edu        fatal("Must specify --caches when using --standard-switch")
4374519Sgblack@eecs.umich.edu
4384519Sgblack@eecs.umich.edu    if options.standard_switch and options.repeat_switch:
4395040Sgblack@eecs.umich.edu        fatal("Can't specify both --standard-switch and --repeat-switch")
4405040Sgblack@eecs.umich.edu
4415040Sgblack@eecs.umich.edu    if options.repeat_switch and options.take_checkpoints:
4425788Sgblack@eecs.umich.edu        fatal("Can't specify both --repeat-switch and --take-checkpoints")
4435040Sgblack@eecs.umich.edu
4444688Sgblack@eecs.umich.edu    np = options.num_cpus
4455040Sgblack@eecs.umich.edu    switch_cpus = None
4464519Sgblack@eecs.umich.edu
4475040Sgblack@eecs.umich.edu    if options.prog_interval:
4484519Sgblack@eecs.umich.edu        for i in xrange(np):
4494519Sgblack@eecs.umich.edu            testsys.cpu[i].progress_interval = options.prog_interval
4504519Sgblack@eecs.umich.edu
4514539Sgblack@eecs.umich.edu    if options.maxinsts:
4524519Sgblack@eecs.umich.edu        for i in xrange(np):
4535040Sgblack@eecs.umich.edu            testsys.cpu[i].max_insts_any_thread = options.maxinsts
4544688Sgblack@eecs.umich.edu
4555040Sgblack@eecs.umich.edu    if cpu_class:
4565040Sgblack@eecs.umich.edu        switch_cpus = [cpu_class(switched_out=True, cpu_id=(i))
4575115Sgblack@eecs.umich.edu                       for i in xrange(np)]
4585040Sgblack@eecs.umich.edu
4595040Sgblack@eecs.umich.edu        for i in xrange(np):
4605040Sgblack@eecs.umich.edu            if options.fast_forward:
4615115Sgblack@eecs.umich.edu                testsys.cpu[i].max_insts_any_thread = int(options.fast_forward)
4625040Sgblack@eecs.umich.edu            switch_cpus[i].system = testsys
4635040Sgblack@eecs.umich.edu            switch_cpus[i].workload = testsys.cpu[i].workload
4644519Sgblack@eecs.umich.edu            switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain
4655040Sgblack@eecs.umich.edu            switch_cpus[i].progress_interval = \
4665040Sgblack@eecs.umich.edu                testsys.cpu[i].progress_interval
4675040Sgblack@eecs.umich.edu            switch_cpus[i].isa = testsys.cpu[i].isa
4685040Sgblack@eecs.umich.edu            # simulation period
4694519Sgblack@eecs.umich.edu            if options.maxinsts:
4705040Sgblack@eecs.umich.edu                switch_cpus[i].max_insts_any_thread = options.maxinsts
4715040Sgblack@eecs.umich.edu            # Add checker cpu if selected
4725040Sgblack@eecs.umich.edu            if options.checker:
4735040Sgblack@eecs.umich.edu                switch_cpus[i].addCheckerCpu()
4744519Sgblack@eecs.umich.edu
4755040Sgblack@eecs.umich.edu        # If elastic tracing is enabled attach the elastic trace probe
4765040Sgblack@eecs.umich.edu        # to the switch CPUs
4775083Sgblack@eecs.umich.edu        if options.elastic_trace_en:
4784519Sgblack@eecs.umich.edu            CpuConfig.config_etrace(cpu_class, switch_cpus, options)
4795063Sgblack@eecs.umich.edu
4805063Sgblack@eecs.umich.edu        testsys.switch_cpus = switch_cpus
4815063Sgblack@eecs.umich.edu        switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
4825063Sgblack@eecs.umich.edu
4835063Sgblack@eecs.umich.edu    if options.repeat_switch:
4846345Sgblack@eecs.umich.edu        switch_class = getCPUClass(options.cpu_type)[0]
4856345Sgblack@eecs.umich.edu        if switch_class.require_caches() and \
4865063Sgblack@eecs.umich.edu                not options.caches:
4875063Sgblack@eecs.umich.edu            print "%s: Must be used with caches" % str(switch_class)
4885063Sgblack@eecs.umich.edu            sys.exit(1)
4895063Sgblack@eecs.umich.edu        if not switch_class.support_take_over():
4906345Sgblack@eecs.umich.edu            print "%s: CPU switching not supported" % str(switch_class)
4916345Sgblack@eecs.umich.edu            sys.exit(1)
4925063Sgblack@eecs.umich.edu
4935040Sgblack@eecs.umich.edu        repeat_switch_cpus = [switch_class(switched_out=True, \
4945040Sgblack@eecs.umich.edu                                               cpu_id=(i)) for i in xrange(np)]
4954595Sgblack@eecs.umich.edu
4965040Sgblack@eecs.umich.edu        for i in xrange(np):
4975040Sgblack@eecs.umich.edu            repeat_switch_cpus[i].system = testsys
4984595Sgblack@eecs.umich.edu            repeat_switch_cpus[i].workload = testsys.cpu[i].workload
4995040Sgblack@eecs.umich.edu            repeat_switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain
5005040Sgblack@eecs.umich.edu            repeat_switch_cpus[i].isa = testsys.cpu[i].isa
5014732Sgblack@eecs.umich.edu
5025138Sgblack@eecs.umich.edu            if options.maxinsts:
5035040Sgblack@eecs.umich.edu                repeat_switch_cpus[i].max_insts_any_thread = options.maxinsts
5045040Sgblack@eecs.umich.edu
5055040Sgblack@eecs.umich.edu            if options.checker:
5065040Sgblack@eecs.umich.edu                repeat_switch_cpus[i].addCheckerCpu()
5074732Sgblack@eecs.umich.edu
5085138Sgblack@eecs.umich.edu        testsys.repeat_switch_cpus = repeat_switch_cpus
5095040Sgblack@eecs.umich.edu
5105040Sgblack@eecs.umich.edu        if cpu_class:
5115040Sgblack@eecs.umich.edu            repeat_switch_cpu_list = [(switch_cpus[i], repeat_switch_cpus[i])
5125040Sgblack@eecs.umich.edu                                      for i in xrange(np)]
5135040Sgblack@eecs.umich.edu        else:
5145040Sgblack@eecs.umich.edu            repeat_switch_cpu_list = [(testsys.cpu[i], repeat_switch_cpus[i])
5155040Sgblack@eecs.umich.edu                                      for i in xrange(np)]
5165040Sgblack@eecs.umich.edu
5175040Sgblack@eecs.umich.edu    if options.standard_switch:
5185040Sgblack@eecs.umich.edu        switch_cpus = [TimingSimpleCPU(switched_out=True, cpu_id=(i))
5195040Sgblack@eecs.umich.edu                       for i in xrange(np)]
5205063Sgblack@eecs.umich.edu        switch_cpus_1 = [DerivO3CPU(switched_out=True, cpu_id=(i))
5215040Sgblack@eecs.umich.edu                        for i in xrange(np)]
5225063Sgblack@eecs.umich.edu
5235063Sgblack@eecs.umich.edu        for i in xrange(np):
5246430Sgblack@eecs.umich.edu            switch_cpus[i].system =  testsys
5256430Sgblack@eecs.umich.edu            switch_cpus_1[i].system =  testsys
5266430Sgblack@eecs.umich.edu            switch_cpus[i].workload = testsys.cpu[i].workload
5276430Sgblack@eecs.umich.edu            switch_cpus_1[i].workload = testsys.cpu[i].workload
5286430Sgblack@eecs.umich.edu            switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain
5296430Sgblack@eecs.umich.edu            switch_cpus_1[i].clk_domain = testsys.cpu[i].clk_domain
5306430Sgblack@eecs.umich.edu            switch_cpus[i].isa = testsys.cpu[i].isa
5316430Sgblack@eecs.umich.edu            switch_cpus_1[i].isa = testsys.cpu[i].isa
5326430Sgblack@eecs.umich.edu
5336430Sgblack@eecs.umich.edu            # if restoring, make atomic cpu simulate only a few instructions
5346430Sgblack@eecs.umich.edu            if options.checkpoint_restore != None:
5356430Sgblack@eecs.umich.edu                testsys.cpu[i].max_insts_any_thread = 1
5366430Sgblack@eecs.umich.edu            # Fast forward to specified location if we are not restoring
5376430Sgblack@eecs.umich.edu            elif options.fast_forward:
5386430Sgblack@eecs.umich.edu                testsys.cpu[i].max_insts_any_thread = int(options.fast_forward)
5395040Sgblack@eecs.umich.edu            # Fast forward to a simpoint (warning: time consuming)
5405040Sgblack@eecs.umich.edu            elif options.simpoint:
5415063Sgblack@eecs.umich.edu                if testsys.cpu[i].workload[0].simpoint == 0:
5425040Sgblack@eecs.umich.edu                    fatal('simpoint not found')
5435063Sgblack@eecs.umich.edu                testsys.cpu[i].max_insts_any_thread = \
5444809Sgblack@eecs.umich.edu                    testsys.cpu[i].workload[0].simpoint
5456430Sgblack@eecs.umich.edu            # No distance specified, just switch
5466430Sgblack@eecs.umich.edu            else:
5475063Sgblack@eecs.umich.edu                testsys.cpu[i].max_insts_any_thread = 1
5486430Sgblack@eecs.umich.edu
5495063Sgblack@eecs.umich.edu            # warmup period
5505063Sgblack@eecs.umich.edu            if options.warmup_insts:
5516430Sgblack@eecs.umich.edu                switch_cpus[i].max_insts_any_thread =  options.warmup_insts
5525063Sgblack@eecs.umich.edu
5535040Sgblack@eecs.umich.edu            # simulation period
5545040Sgblack@eecs.umich.edu            if options.maxinsts:
5555063Sgblack@eecs.umich.edu                switch_cpus_1[i].max_insts_any_thread = options.maxinsts
5565063Sgblack@eecs.umich.edu
5575040Sgblack@eecs.umich.edu            # attach the checker cpu if selected
5585063Sgblack@eecs.umich.edu            if options.checker:
5595063Sgblack@eecs.umich.edu                switch_cpus[i].addCheckerCpu()
5605063Sgblack@eecs.umich.edu                switch_cpus_1[i].addCheckerCpu()
5615063Sgblack@eecs.umich.edu
5626345Sgblack@eecs.umich.edu        testsys.switch_cpus = switch_cpus
5636345Sgblack@eecs.umich.edu        testsys.switch_cpus_1 = switch_cpus_1
5645063Sgblack@eecs.umich.edu        switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
5655063Sgblack@eecs.umich.edu        switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)]
5665063Sgblack@eecs.umich.edu
5675063Sgblack@eecs.umich.edu    # set the checkpoint in the cpu before m5.instantiate is called
5685063Sgblack@eecs.umich.edu    if options.take_checkpoints != None and \
5695063Sgblack@eecs.umich.edu           (options.simpoint or options.at_instruction):
5705063Sgblack@eecs.umich.edu        offset = int(options.take_checkpoints)
5715062Sgblack@eecs.umich.edu        # Set an instruction break point
5725075Sgblack@eecs.umich.edu        if options.simpoint:
5735075Sgblack@eecs.umich.edu            for i in xrange(np):
5745040Sgblack@eecs.umich.edu                if testsys.cpu[i].workload[0].simpoint == 0:
5755075Sgblack@eecs.umich.edu                    fatal('no simpoint for testsys.cpu[%d].workload[0]', i)
5765075Sgblack@eecs.umich.edu                checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset
5775075Sgblack@eecs.umich.edu                testsys.cpu[i].max_insts_any_thread = checkpoint_inst
5785075Sgblack@eecs.umich.edu                # used for output below
5795075Sgblack@eecs.umich.edu                options.take_checkpoints = checkpoint_inst
5805075Sgblack@eecs.umich.edu        else:
5815075Sgblack@eecs.umich.edu            options.take_checkpoints = offset
5825075Sgblack@eecs.umich.edu            # Set all test cpus with the right number of instructions
5835075Sgblack@eecs.umich.edu            # for the upcoming simulation
5845075Sgblack@eecs.umich.edu            for i in xrange(np):
5855075Sgblack@eecs.umich.edu                testsys.cpu[i].max_insts_any_thread = offset
5865075Sgblack@eecs.umich.edu
5875075Sgblack@eecs.umich.edu    if options.take_simpoint_checkpoints != None:
5885075Sgblack@eecs.umich.edu        simpoints, interval_length = parseSimpointAnalysisFile(options, testsys)
5895075Sgblack@eecs.umich.edu
5905040Sgblack@eecs.umich.edu    checkpoint_dir = None
5914823Sgblack@eecs.umich.edu    if options.checkpoint_restore:
5925075Sgblack@eecs.umich.edu        cpt_starttick, checkpoint_dir = findCptDir(options, cptdir, testsys)
5935075Sgblack@eecs.umich.edu    m5.instantiate(checkpoint_dir)
5945075Sgblack@eecs.umich.edu
5955075Sgblack@eecs.umich.edu    # Initialization is complete.  If we're not in control of simulation
5965075Sgblack@eecs.umich.edu    # (that is, if we're a slave simulator acting as a component in another
5975075Sgblack@eecs.umich.edu    #  'master' simulator) then we're done here.  The other simulator will
5985075Sgblack@eecs.umich.edu    # call simulate() directly. --initialize-only is used to indicate this.
5995075Sgblack@eecs.umich.edu    if options.initialize_only:
6005075Sgblack@eecs.umich.edu        return
6015075Sgblack@eecs.umich.edu
6025075Sgblack@eecs.umich.edu    # Handle the max tick settings now that tick frequency was resolved
6035075Sgblack@eecs.umich.edu    # during system instantiation
6045075Sgblack@eecs.umich.edu    # NOTE: the maxtick variable here is in absolute ticks, so it must
6055075Sgblack@eecs.umich.edu    # include any simulated ticks before a checkpoint
6065075Sgblack@eecs.umich.edu    explicit_maxticks = 0
6075075Sgblack@eecs.umich.edu    maxtick_from_abs = m5.MaxTick
6085075Sgblack@eecs.umich.edu    maxtick_from_rel = m5.MaxTick
6095075Sgblack@eecs.umich.edu    maxtick_from_maxtime = m5.MaxTick
6105075Sgblack@eecs.umich.edu    if options.abs_max_tick:
6115075Sgblack@eecs.umich.edu        maxtick_from_abs = options.abs_max_tick
6125075Sgblack@eecs.umich.edu        explicit_maxticks += 1
6135075Sgblack@eecs.umich.edu    if options.rel_max_tick:
6145075Sgblack@eecs.umich.edu        maxtick_from_rel = options.rel_max_tick
6155075Sgblack@eecs.umich.edu        if options.checkpoint_restore:
6165075Sgblack@eecs.umich.edu            # NOTE: this may need to be updated if checkpoints ever store
6175075Sgblack@eecs.umich.edu            # the ticks per simulated second
6185075Sgblack@eecs.umich.edu            maxtick_from_rel += cpt_starttick
6195075Sgblack@eecs.umich.edu            if options.at_instruction or options.simpoint:
6205075Sgblack@eecs.umich.edu                warn("Relative max tick specified with --at-instruction or" \
6215075Sgblack@eecs.umich.edu                     " --simpoint\n      These options don't specify the " \
6225075Sgblack@eecs.umich.edu                     "checkpoint start tick, so assuming\n      you mean " \
6235075Sgblack@eecs.umich.edu                     "absolute max tick")
6245075Sgblack@eecs.umich.edu        explicit_maxticks += 1
6254732Sgblack@eecs.umich.edu    if options.maxtime:
6265075Sgblack@eecs.umich.edu        maxtick_from_maxtime = m5.ticks.fromSeconds(options.maxtime)
6275075Sgblack@eecs.umich.edu        explicit_maxticks += 1
6285075Sgblack@eecs.umich.edu    if explicit_maxticks > 1:
6295075Sgblack@eecs.umich.edu        warn("Specified multiple of --abs-max-tick, --rel-max-tick, --maxtime."\
6305075Sgblack@eecs.umich.edu             " Using least")
6315040Sgblack@eecs.umich.edu    maxtick = min([maxtick_from_abs, maxtick_from_rel, maxtick_from_maxtime])
6325040Sgblack@eecs.umich.edu
6335040Sgblack@eecs.umich.edu    if options.checkpoint_restore != None and maxtick < cpt_starttick:
6345040Sgblack@eecs.umich.edu        fatal("Bad maxtick (%d) specified: " \
6355040Sgblack@eecs.umich.edu              "Checkpoint starts starts from tick: %d", maxtick, cpt_starttick)
6364732Sgblack@eecs.umich.edu
6375040Sgblack@eecs.umich.edu    if options.standard_switch or cpu_class:
6385076Sgblack@eecs.umich.edu        if options.standard_switch:
6395040Sgblack@eecs.umich.edu            print "Switch at instruction count:%s" % \
6404756Sgblack@eecs.umich.edu                    str(testsys.cpu[0].max_insts_any_thread)
6414823Sgblack@eecs.umich.edu            exit_event = m5.simulate()
6425040Sgblack@eecs.umich.edu        elif cpu_class and options.fast_forward:
6435076Sgblack@eecs.umich.edu            print "Switch at instruction count:%s" % \
6445076Sgblack@eecs.umich.edu                    str(testsys.cpu[0].max_insts_any_thread)
6455076Sgblack@eecs.umich.edu            exit_event = m5.simulate()
6465076Sgblack@eecs.umich.edu        else:
6475076Sgblack@eecs.umich.edu            print "Switch at curTick count:%s" % str(10000)
6485076Sgblack@eecs.umich.edu            exit_event = m5.simulate(10000)
6495076Sgblack@eecs.umich.edu        print "Switched CPUS @ tick %s" % (m5.curTick())
6505076Sgblack@eecs.umich.edu
6516441Sgblack@eecs.umich.edu        m5.switchCpus(testsys, switch_cpu_list)
6526441Sgblack@eecs.umich.edu
6535076Sgblack@eecs.umich.edu        if options.standard_switch:
6546441Sgblack@eecs.umich.edu            print "Switch at instruction count:%d" % \
6555076Sgblack@eecs.umich.edu                    (testsys.switch_cpus[0].max_insts_any_thread)
6565076Sgblack@eecs.umich.edu
6575076Sgblack@eecs.umich.edu            #warmup instruction count may have already been set
6585076Sgblack@eecs.umich.edu            if options.warmup_insts:
6595076Sgblack@eecs.umich.edu                exit_event = m5.simulate()
6605076Sgblack@eecs.umich.edu            else:
6615076Sgblack@eecs.umich.edu                exit_event = m5.simulate(options.standard_switch)
6625076Sgblack@eecs.umich.edu            print "Switching CPUS @ tick %s" % (m5.curTick())
6635076Sgblack@eecs.umich.edu            print "Simulation ends instruction count:%d" % \
6645076Sgblack@eecs.umich.edu                    (testsys.switch_cpus_1[0].max_insts_any_thread)
6655076Sgblack@eecs.umich.edu            m5.switchCpus(testsys, switch_cpu_list1)
6665040Sgblack@eecs.umich.edu
6675076Sgblack@eecs.umich.edu    # If we're taking and restoring checkpoints, use checkpoint_dir
6685040Sgblack@eecs.umich.edu    # option only for finding the checkpoints to restore from.  This
6694756Sgblack@eecs.umich.edu    # lets us test checkpointing by restoring from one set of
6704732Sgblack@eecs.umich.edu    # checkpoints, generating a second set, and then comparing them.
6714732Sgblack@eecs.umich.edu    if (options.take_checkpoints or options.take_simpoint_checkpoints) \
6724732Sgblack@eecs.umich.edu        and options.checkpoint_restore:
6734732Sgblack@eecs.umich.edu
6744823Sgblack@eecs.umich.edu        if m5.options.outdir:
6755040Sgblack@eecs.umich.edu            cptdir = m5.options.outdir
6765076Sgblack@eecs.umich.edu        else:
6775076Sgblack@eecs.umich.edu            cptdir = getcwd()
6785076Sgblack@eecs.umich.edu
6795076Sgblack@eecs.umich.edu    if options.take_checkpoints != None :
6805076Sgblack@eecs.umich.edu        # Checkpoints being taken via the command line at <when> and at
6815076Sgblack@eecs.umich.edu        # subsequent periods of <period>.  Checkpoint instructions
6825076Sgblack@eecs.umich.edu        # received from the benchmark running are ignored and skipped in
6836442Sgblack@eecs.umich.edu        # favor of command line checkpoint instructions.
6846442Sgblack@eecs.umich.edu        exit_event = scriptCheckpoints(options, maxtick, cptdir)
6856442Sgblack@eecs.umich.edu
6865076Sgblack@eecs.umich.edu    # Take SimPoint checkpoints
6876442Sgblack@eecs.umich.edu    elif options.take_simpoint_checkpoints != None:
6885076Sgblack@eecs.umich.edu        takeSimpointCheckpoints(simpoints, interval_length, cptdir)
6895076Sgblack@eecs.umich.edu
6905076Sgblack@eecs.umich.edu    # Restore from SimPoint checkpoints
6915076Sgblack@eecs.umich.edu    elif options.restore_simpoint_checkpoint != None:
6925076Sgblack@eecs.umich.edu        restoreSimpointCheckpoint()
6935076Sgblack@eecs.umich.edu
6945076Sgblack@eecs.umich.edu    else:
6955076Sgblack@eecs.umich.edu        if options.fast_forward:
6965040Sgblack@eecs.umich.edu            m5.stats.reset()
6975076Sgblack@eecs.umich.edu        print "**** REAL SIMULATION ****"
6985040Sgblack@eecs.umich.edu
6994756Sgblack@eecs.umich.edu        # If checkpoints are being taken, then the checkpoint instruction
7004732Sgblack@eecs.umich.edu        # will occur in the benchmark code it self.
7014732Sgblack@eecs.umich.edu        if options.repeat_switch and maxtick > options.repeat_switch:
7024732Sgblack@eecs.umich.edu            exit_event = repeatSwitch(testsys, repeat_switch_cpu_list,
7036443Sgblack@eecs.umich.edu                                      maxtick, options.repeat_switch)
7045032Sgblack@eecs.umich.edu        else:
7054823Sgblack@eecs.umich.edu            exit_event = benchCheckpoints(options, maxtick, cptdir)
7065040Sgblack@eecs.umich.edu
7075076Sgblack@eecs.umich.edu    print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_event.getCause())
7085076Sgblack@eecs.umich.edu    if options.checkpoint_at_end:
7095076Sgblack@eecs.umich.edu        m5.checkpoint(joinpath(cptdir, "cpt.%d"))
7105076Sgblack@eecs.umich.edu
7115076Sgblack@eecs.umich.edu    if not m5.options.interactive:
7125076Sgblack@eecs.umich.edu        sys.exit(exit_event.getCode())
7135076Sgblack@eecs.umich.edu