Simulation.py revision 11688
1955SN/A# Copyright (c) 2012-2013 ARM Limited
2955SN/A# All rights reserved
31762SN/A#
4955SN/A# The license below extends only to copyright in the software and shall
5955SN/A# not be construed as granting a license to any other intellectual
6955SN/A# property including but not limited to intellectual property relating
7955SN/A# to a hardware implementation of the functionality of the software
8955SN/A# licensed hereunder.  You may use the software subject to the license
9955SN/A# terms below provided that you ensure that this notice is replicated
10955SN/A# unmodified and in its entirety in all distributions of the software,
11955SN/A# modified or unmodified, in source code or in binary form.
12955SN/A#
13955SN/A# Copyright (c) 2006-2008 The Regents of The University of Michigan
14955SN/A# Copyright (c) 2010 Advanced Micro Devices, Inc.
15955SN/A# All rights reserved.
16955SN/A#
17955SN/A# Redistribution and use in source and binary forms, with or without
18955SN/A# modification, are permitted provided that the following conditions are
19955SN/A# met: redistributions of source code must retain the above copyright
20955SN/A# notice, this list of conditions and the following disclaimer;
21955SN/A# redistributions in binary form must reproduce the above copyright
22955SN/A# notice, this list of conditions and the following disclaimer in the
23955SN/A# documentation and/or other materials provided with the distribution;
24955SN/A# neither the name of the copyright holders nor the names of its
25955SN/A# contributors may be used to endorse or promote products derived from
26955SN/A# this software without specific prior written permission.
27955SN/A#
282665Ssaidi@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
294762Snate@binkert.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30955SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
315522Snate@binkert.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
326143Snate@binkert.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
334762Snate@binkert.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
345522Snate@binkert.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35955SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
365522Snate@binkert.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37955SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
385522Snate@binkert.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
394202Sbinkertn@umich.edu#
405742Snate@binkert.org# Authors: Lisa Hsu
41955SN/A
424381Sbinkertn@umich.eduimport sys
434381Sbinkertn@umich.edufrom os import getcwd
448334Snate@binkert.orgfrom os.path import join as joinpath
45955SN/A
46955SN/Afrom common import CpuConfig
474202Sbinkertn@umich.edufrom common import MemConfig
48955SN/A
494382Sbinkertn@umich.eduimport m5
504382Sbinkertn@umich.edufrom m5.defines import buildEnv
514382Sbinkertn@umich.edufrom m5.objects import *
526654Snate@binkert.orgfrom m5.util import *
535517Snate@binkert.org
548614Sgblack@eecs.umich.eduaddToPath('../common')
557674Snate@binkert.org
566143Snate@binkert.orgdef getCPUClass(cpu_type):
576143Snate@binkert.org    """Returns the required cpu class and the mode of operation."""
586143Snate@binkert.org    cls = CpuConfig.get(cpu_type)
598233Snate@binkert.org    return cls, cls.memory_mode()
608233Snate@binkert.org
618233Snate@binkert.orgdef setCPUClass(options):
628233Snate@binkert.org    """Returns two cpu classes and the initial mode of operation.
638233Snate@binkert.org
648334Snate@binkert.org       Restoring from a checkpoint or fast forwarding through a benchmark
658334Snate@binkert.org       can be done using one type of cpu, and then the actual
6610453SAndrew.Bardsley@arm.com       simulation can be carried out using another type. This function
6710453SAndrew.Bardsley@arm.com       returns these two types of cpus and the initial mode of operation
688233Snate@binkert.org       depending on the options provided.
698233Snate@binkert.org    """
708233Snate@binkert.org
718233Snate@binkert.org    TmpClass, test_mem_mode = getCPUClass(options.cpu_type)
728233Snate@binkert.org    CPUClass = None
738233Snate@binkert.org    if TmpClass.require_caches() and \
746143Snate@binkert.org            not options.caches and not options.ruby:
758233Snate@binkert.org        fatal("%s must be used with caches" % options.cpu_type)
768233Snate@binkert.org
778233Snate@binkert.org    if options.checkpoint_restore != None:
786143Snate@binkert.org        if options.restore_with_cpu != options.cpu_type:
796143Snate@binkert.org            CPUClass = TmpClass
806143Snate@binkert.org            TmpClass, test_mem_mode = getCPUClass(options.restore_with_cpu)
8111308Santhony.gutierrez@amd.com    elif options.fast_forward:
828233Snate@binkert.org        CPUClass = TmpClass
838233Snate@binkert.org        TmpClass = AtomicSimpleCPU
848233Snate@binkert.org        test_mem_mode = 'atomic'
856143Snate@binkert.org
868233Snate@binkert.org    return (TmpClass, test_mem_mode, CPUClass)
878233Snate@binkert.org
888233Snate@binkert.orgdef setMemClass(options):
898233Snate@binkert.org    """Returns a memory controller class."""
906143Snate@binkert.org
916143Snate@binkert.org    return MemConfig.get(options.mem_type)
926143Snate@binkert.org
934762Snate@binkert.orgdef setWorkCountOptions(system, options):
946143Snate@binkert.org    if options.work_item_id != None:
958233Snate@binkert.org        system.work_item_id = options.work_item_id
968233Snate@binkert.org    if options.num_work_ids != None:
978233Snate@binkert.org        system.num_work_ids = options.num_work_ids
988233Snate@binkert.org    if options.work_begin_cpu_id_exit != None:
998233Snate@binkert.org        system.work_begin_cpu_id_exit = options.work_begin_cpu_id_exit
1006143Snate@binkert.org    if options.work_end_exit_count != None:
1018233Snate@binkert.org        system.work_end_exit_count = options.work_end_exit_count
1028233Snate@binkert.org    if options.work_end_checkpoint_count != None:
1038233Snate@binkert.org        system.work_end_ckpt_count = options.work_end_checkpoint_count
1048233Snate@binkert.org    if options.work_begin_exit_count != None:
1056143Snate@binkert.org        system.work_begin_exit_count = options.work_begin_exit_count
1066143Snate@binkert.org    if options.work_begin_checkpoint_count != None:
1076143Snate@binkert.org        system.work_begin_ckpt_count = options.work_begin_checkpoint_count
1086143Snate@binkert.org    if options.work_cpus_checkpoint_count != None:
1096143Snate@binkert.org        system.work_cpus_ckpt_count = options.work_cpus_checkpoint_count
1106143Snate@binkert.org
1116143Snate@binkert.orgdef findCptDir(options, cptdir, testsys):
1126143Snate@binkert.org    """Figures out the directory from which the checkpointed state is read.
1136143Snate@binkert.org
1147065Snate@binkert.org    There are two different ways in which the directories holding checkpoints
1156143Snate@binkert.org    can be named --
1168233Snate@binkert.org    1. cpt.<benchmark name>.<instruction count when the checkpoint was taken>
1178233Snate@binkert.org    2. cpt.<some number, usually the tick value when the checkpoint was taken>
1188233Snate@binkert.org
1198233Snate@binkert.org    This function parses through the options to figure out which one of the
1208233Snate@binkert.org    above should be used for selecting the checkpoint, and then figures out
1218233Snate@binkert.org    the appropriate directory.
1228233Snate@binkert.org    """
1238233Snate@binkert.org
1248233Snate@binkert.org    from os.path import isdir, exists
1258233Snate@binkert.org    from os import listdir
1268233Snate@binkert.org    import re
1278233Snate@binkert.org
1288233Snate@binkert.org    if not isdir(cptdir):
1298233Snate@binkert.org        fatal("checkpoint dir %s does not exist!", cptdir)
1308233Snate@binkert.org
1318233Snate@binkert.org    cpt_starttick = 0
1328233Snate@binkert.org    if options.at_instruction or options.simpoint:
1338233Snate@binkert.org        inst = options.checkpoint_restore
1348233Snate@binkert.org        if options.simpoint:
1358233Snate@binkert.org            # assume workload 0 has the simpoint
1368233Snate@binkert.org            if testsys.cpu[0].workload[0].simpoint == 0:
1378233Snate@binkert.org                fatal('Unable to find simpoint')
1388233Snate@binkert.org            inst += int(testsys.cpu[0].workload[0].simpoint)
1398233Snate@binkert.org
1408233Snate@binkert.org        checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % (options.bench, inst))
1418233Snate@binkert.org        if not exists(checkpoint_dir):
1428233Snate@binkert.org            fatal("Unable to find checkpoint directory %s", checkpoint_dir)
1438233Snate@binkert.org
1448233Snate@binkert.org    elif options.restore_simpoint_checkpoint:
1458233Snate@binkert.org        # Restore from SimPoint checkpoints
1468233Snate@binkert.org        # Assumes that the checkpoint dir names are formatted as follows:
1476143Snate@binkert.org        dirs = listdir(cptdir)
1486143Snate@binkert.org        expr = re.compile('cpt\.simpoint_(\d+)_inst_(\d+)' +
1496143Snate@binkert.org                    '_weight_([\d\.e\-]+)_interval_(\d+)_warmup_(\d+)')
1506143Snate@binkert.org        cpts = []
1516143Snate@binkert.org        for dir in dirs:
1526143Snate@binkert.org            match = expr.match(dir)
1539982Satgutier@umich.edu            if match:
15410196SCurtis.Dunham@arm.com                cpts.append(dir)
15510196SCurtis.Dunham@arm.com        cpts.sort()
15610196SCurtis.Dunham@arm.com
15710196SCurtis.Dunham@arm.com        cpt_num = options.checkpoint_restore
15810196SCurtis.Dunham@arm.com        if cpt_num > len(cpts):
15910196SCurtis.Dunham@arm.com            fatal('Checkpoint %d not found', cpt_num)
16010196SCurtis.Dunham@arm.com        checkpoint_dir = joinpath(cptdir, cpts[cpt_num - 1])
16110196SCurtis.Dunham@arm.com        match = expr.match(cpts[cpt_num - 1])
1626143Snate@binkert.org        if match:
1636143Snate@binkert.org            index = int(match.group(1))
1648945Ssteve.reinhardt@amd.com            start_inst = int(match.group(2))
1658233Snate@binkert.org            weight_inst = float(match.group(3))
1668233Snate@binkert.org            interval_length = int(match.group(4))
1676143Snate@binkert.org            warmup_length = int(match.group(5))
1688945Ssteve.reinhardt@amd.com        print "Resuming from", checkpoint_dir
1696143Snate@binkert.org        simpoint_start_insts = []
1706143Snate@binkert.org        simpoint_start_insts.append(warmup_length)
1716143Snate@binkert.org        simpoint_start_insts.append(warmup_length + interval_length)
1726143Snate@binkert.org        testsys.cpu[0].simpoint_start_insts = simpoint_start_insts
1735522Snate@binkert.org        if testsys.switch_cpus != None:
1746143Snate@binkert.org            testsys.switch_cpus[0].simpoint_start_insts = simpoint_start_insts
1756143Snate@binkert.org
1766143Snate@binkert.org        print "Resuming from SimPoint",
1779982Satgutier@umich.edu        print "#%d, start_inst:%d, weight:%f, interval:%d, warmup:%d" % \
1788233Snate@binkert.org            (index, start_inst, weight_inst, interval_length, warmup_length)
1798233Snate@binkert.org
1808233Snate@binkert.org    else:
1816143Snate@binkert.org        dirs = listdir(cptdir)
1826143Snate@binkert.org        expr = re.compile('cpt\.([0-9]+)')
1836143Snate@binkert.org        cpts = []
1846143Snate@binkert.org        for dir in dirs:
1855522Snate@binkert.org            match = expr.match(dir)
1865522Snate@binkert.org            if match:
1875522Snate@binkert.org                cpts.append(match.group(1))
1885522Snate@binkert.org
1895604Snate@binkert.org        cpts.sort(lambda a,b: cmp(long(a), long(b)))
1905604Snate@binkert.org
1916143Snate@binkert.org        cpt_num = options.checkpoint_restore
1926143Snate@binkert.org        if cpt_num > len(cpts):
1934762Snate@binkert.org            fatal('Checkpoint %d not found', cpt_num)
1944762Snate@binkert.org
1956143Snate@binkert.org        cpt_starttick = int(cpts[cpt_num - 1])
1966727Ssteve.reinhardt@amd.com        checkpoint_dir = joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1])
1976727Ssteve.reinhardt@amd.com
1986727Ssteve.reinhardt@amd.com    return cpt_starttick, checkpoint_dir
1994762Snate@binkert.org
2006143Snate@binkert.orgdef scriptCheckpoints(options, maxtick, cptdir):
2016143Snate@binkert.org    if options.at_instruction or options.simpoint:
2026143Snate@binkert.org        checkpoint_inst = int(options.take_checkpoints)
2036143Snate@binkert.org
2046727Ssteve.reinhardt@amd.com        # maintain correct offset if we restored from some instruction
2056143Snate@binkert.org        if options.checkpoint_restore != None:
2067674Snate@binkert.org            checkpoint_inst += options.checkpoint_restore
2077674Snate@binkert.org
2085604Snate@binkert.org        print "Creating checkpoint at inst:%d" % (checkpoint_inst)
2096143Snate@binkert.org        exit_event = m5.simulate()
2106143Snate@binkert.org        exit_cause = exit_event.getCause()
2116143Snate@binkert.org        print "exit cause = %s" % exit_cause
2124762Snate@binkert.org
2136143Snate@binkert.org        # skip checkpoint instructions should they exist
2144762Snate@binkert.org        while exit_cause == "checkpoint":
2154762Snate@binkert.org            exit_event = m5.simulate()
2164762Snate@binkert.org            exit_cause = exit_event.getCause()
2176143Snate@binkert.org
2186143Snate@binkert.org        if exit_cause == "a thread reached the max instruction count":
2194762Snate@binkert.org            m5.checkpoint(joinpath(cptdir, "cpt.%s.%d" % \
2208233Snate@binkert.org                    (options.bench, checkpoint_inst)))
2218233Snate@binkert.org            print "Checkpoint written."
2228233Snate@binkert.org
2238233Snate@binkert.org    else:
2246143Snate@binkert.org        when, period = options.take_checkpoints.split(",", 1)
2256143Snate@binkert.org        when = int(when)
2264762Snate@binkert.org        period = int(period)
2276143Snate@binkert.org        num_checkpoints = 0
2284762Snate@binkert.org
2296143Snate@binkert.org        exit_event = m5.simulate(when - m5.curTick())
2304762Snate@binkert.org        exit_cause = exit_event.getCause()
2316143Snate@binkert.org        while exit_cause == "checkpoint":
2328233Snate@binkert.org            exit_event = m5.simulate(when - m5.curTick())
2338233Snate@binkert.org            exit_cause = exit_event.getCause()
23410453SAndrew.Bardsley@arm.com
2356143Snate@binkert.org        if exit_cause == "simulate() limit reached":
2366143Snate@binkert.org            m5.checkpoint(joinpath(cptdir, "cpt.%d"))
2376143Snate@binkert.org            num_checkpoints += 1
2386143Snate@binkert.org
2396143Snate@binkert.org        sim_ticks = when
2406143Snate@binkert.org        max_checkpoints = options.max_checkpoints
2416143Snate@binkert.org
2426143Snate@binkert.org        while num_checkpoints < max_checkpoints and \
24310453SAndrew.Bardsley@arm.com                exit_cause == "simulate() limit reached":
24410453SAndrew.Bardsley@arm.com            if (sim_ticks + period) > maxtick:
245955SN/A                exit_event = m5.simulate(maxtick - sim_ticks)
2469396Sandreas.hansson@arm.com                exit_cause = exit_event.getCause()
2479396Sandreas.hansson@arm.com                break
2489396Sandreas.hansson@arm.com            else:
2499396Sandreas.hansson@arm.com                exit_event = m5.simulate(period)
2509396Sandreas.hansson@arm.com                exit_cause = exit_event.getCause()
2519396Sandreas.hansson@arm.com                sim_ticks += period
2529396Sandreas.hansson@arm.com                while exit_event.getCause() == "checkpoint":
2539396Sandreas.hansson@arm.com                    exit_event = m5.simulate(sim_ticks - m5.curTick())
2549396Sandreas.hansson@arm.com                if exit_event.getCause() == "simulate() limit reached":
2559396Sandreas.hansson@arm.com                    m5.checkpoint(joinpath(cptdir, "cpt.%d"))
2569396Sandreas.hansson@arm.com                    num_checkpoints += 1
2579396Sandreas.hansson@arm.com
2589396Sandreas.hansson@arm.com    return exit_event
2599930Sandreas.hansson@arm.com
2609930Sandreas.hansson@arm.comdef benchCheckpoints(options, maxtick, cptdir):
2619396Sandreas.hansson@arm.com    exit_event = m5.simulate(maxtick - m5.curTick())
2628235Snate@binkert.org    exit_cause = exit_event.getCause()
2638235Snate@binkert.org
2646143Snate@binkert.org    num_checkpoints = 0
2658235Snate@binkert.org    max_checkpoints = options.max_checkpoints
2669003SAli.Saidi@ARM.com
2678235Snate@binkert.org    while exit_cause == "checkpoint":
2688235Snate@binkert.org        m5.checkpoint(joinpath(cptdir, "cpt.%d"))
2698235Snate@binkert.org        num_checkpoints += 1
2708235Snate@binkert.org        if num_checkpoints == max_checkpoints:
2718235Snate@binkert.org            exit_cause = "maximum %d checkpoints dropped" % max_checkpoints
2728235Snate@binkert.org            break
2738235Snate@binkert.org
2748235Snate@binkert.org        exit_event = m5.simulate(maxtick - m5.curTick())
2758235Snate@binkert.org        exit_cause = exit_event.getCause()
2768235Snate@binkert.org
2778235Snate@binkert.org    return exit_event
2788235Snate@binkert.org
2798235Snate@binkert.org# Set up environment for taking SimPoint checkpoints
2808235Snate@binkert.org# Expecting SimPoint files generated by SimPoint 3.2
2819003SAli.Saidi@ARM.comdef parseSimpointAnalysisFile(options, testsys):
2828235Snate@binkert.org    import re
2835584Snate@binkert.org
2844382Sbinkertn@umich.edu    simpoint_filename, weight_filename, interval_length, warmup_length = \
2854202Sbinkertn@umich.edu        options.take_simpoint_checkpoints.split(",", 3)
2864382Sbinkertn@umich.edu    print "simpoint analysis file:", simpoint_filename
2874382Sbinkertn@umich.edu    print "simpoint weight file:", weight_filename
2884382Sbinkertn@umich.edu    print "interval length:", interval_length
2899396Sandreas.hansson@arm.com    print "warmup length:", warmup_length
2905584Snate@binkert.org
2914382Sbinkertn@umich.edu    interval_length = int(interval_length)
2924382Sbinkertn@umich.edu    warmup_length = int(warmup_length)
2934382Sbinkertn@umich.edu
2948232Snate@binkert.org    # Simpoint analysis output starts interval counts with 0.
2955192Ssaidi@eecs.umich.edu    simpoints = []
2968232Snate@binkert.org    simpoint_start_insts = []
2978232Snate@binkert.org
2988232Snate@binkert.org    # Read in SimPoint analysis files
2995192Ssaidi@eecs.umich.edu    simpoint_file = open(simpoint_filename)
3008232Snate@binkert.org    weight_file = open(weight_filename)
3015192Ssaidi@eecs.umich.edu    while True:
3025799Snate@binkert.org        line = simpoint_file.readline()
3038232Snate@binkert.org        if not line:
3045192Ssaidi@eecs.umich.edu            break
3055192Ssaidi@eecs.umich.edu        m = re.match("(\d+)\s+(\d+)", line)
3065192Ssaidi@eecs.umich.edu        if m:
3078232Snate@binkert.org            interval = int(m.group(1))
3085192Ssaidi@eecs.umich.edu        else:
3098232Snate@binkert.org            fatal('unrecognized line in simpoint file!')
3105192Ssaidi@eecs.umich.edu
3115192Ssaidi@eecs.umich.edu        line = weight_file.readline()
3125192Ssaidi@eecs.umich.edu        if not line:
3135192Ssaidi@eecs.umich.edu            fatal('not enough lines in simpoint weight file!')
3144382Sbinkertn@umich.edu        m = re.match("([0-9\.e\-]+)\s+(\d+)", line)
3154382Sbinkertn@umich.edu        if m:
3164382Sbinkertn@umich.edu            weight = float(m.group(1))
3172667Sstever@eecs.umich.edu        else:
3182667Sstever@eecs.umich.edu            fatal('unrecognized line in simpoint weight file!')
3192667Sstever@eecs.umich.edu
3202667Sstever@eecs.umich.edu        if (interval * interval_length - warmup_length > 0):
3212667Sstever@eecs.umich.edu            starting_inst_count = \
3222667Sstever@eecs.umich.edu                interval * interval_length - warmup_length
3235742Snate@binkert.org            actual_warmup_length = warmup_length
3245742Snate@binkert.org        else:
3255742Snate@binkert.org            # Not enough room for proper warmup
3265793Snate@binkert.org            # Just starting from the beginning
3278334Snate@binkert.org            starting_inst_count = 0
3285793Snate@binkert.org            actual_warmup_length = interval * interval_length
3295793Snate@binkert.org
3305793Snate@binkert.org        simpoints.append((interval, weight, starting_inst_count,
3314382Sbinkertn@umich.edu            actual_warmup_length))
3324762Snate@binkert.org
3335344Sstever@gmail.com    # Sort SimPoints by starting inst count
3344382Sbinkertn@umich.edu    simpoints.sort(key=lambda obj: obj[2])
3355341Sstever@gmail.com    for s in simpoints:
3365742Snate@binkert.org        interval, weight, starting_inst_count, actual_warmup_length = s
3375742Snate@binkert.org        print str(interval), str(weight), starting_inst_count, \
3385742Snate@binkert.org            actual_warmup_length
3395742Snate@binkert.org        simpoint_start_insts.append(starting_inst_count)
3405742Snate@binkert.org
3414762Snate@binkert.org    print "Total # of simpoints:", len(simpoints)
3425742Snate@binkert.org    testsys.cpu[0].simpoint_start_insts = simpoint_start_insts
3435742Snate@binkert.org
3447722Sgblack@eecs.umich.edu    return (simpoints, interval_length)
3455742Snate@binkert.org
3465742Snate@binkert.orgdef takeSimpointCheckpoints(simpoints, interval_length, cptdir):
3475742Snate@binkert.org    num_checkpoints = 0
3489930Sandreas.hansson@arm.com    index = 0
3499930Sandreas.hansson@arm.com    last_chkpnt_inst_count = -1
3509930Sandreas.hansson@arm.com    for simpoint in simpoints:
3519930Sandreas.hansson@arm.com        interval, weight, starting_inst_count, actual_warmup_length = simpoint
3529930Sandreas.hansson@arm.com        if starting_inst_count == last_chkpnt_inst_count:
3535742Snate@binkert.org            # checkpoint starting point same as last time
3548242Sbradley.danofsky@amd.com            # (when warmup period longer than starting point)
3558242Sbradley.danofsky@amd.com            exit_cause = "simpoint starting point found"
3568242Sbradley.danofsky@amd.com            code = 0
3578242Sbradley.danofsky@amd.com        else:
3585341Sstever@gmail.com            exit_event = m5.simulate()
3595742Snate@binkert.org
3607722Sgblack@eecs.umich.edu            # skip checkpoint instructions should they exist
3614773Snate@binkert.org            while exit_event.getCause() == "checkpoint":
3626108Snate@binkert.org                print "Found 'checkpoint' exit event...ignoring..."
3631858SN/A                exit_event = m5.simulate()
3641085SN/A
3656658Snate@binkert.org            exit_cause = exit_event.getCause()
3666658Snate@binkert.org            code = exit_event.getCode()
3677673Snate@binkert.org
3686658Snate@binkert.org        if exit_cause == "simpoint starting point found":
3696658Snate@binkert.org            m5.checkpoint(joinpath(cptdir,
37011308Santhony.gutierrez@amd.com                "cpt.simpoint_%02d_inst_%d_weight_%f_interval_%d_warmup_%d"
3716658Snate@binkert.org                % (index, starting_inst_count, weight, interval_length,
37211308Santhony.gutierrez@amd.com                actual_warmup_length)))
3736658Snate@binkert.org            print "Checkpoint #%d written. start inst:%d weight:%f" % \
3746658Snate@binkert.org                (num_checkpoints, starting_inst_count, weight)
3757673Snate@binkert.org            num_checkpoints += 1
3767673Snate@binkert.org            last_chkpnt_inst_count = starting_inst_count
3777673Snate@binkert.org        else:
3787673Snate@binkert.org            break
3797673Snate@binkert.org        index += 1
3807673Snate@binkert.org
3817673Snate@binkert.org    print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_cause)
38210467Sandreas.hansson@arm.com    print "%d checkpoints taken" % num_checkpoints
3836658Snate@binkert.org    sys.exit(code)
3847673Snate@binkert.org
38510467Sandreas.hansson@arm.comdef restoreSimpointCheckpoint():
38610467Sandreas.hansson@arm.com    exit_event = m5.simulate()
38710467Sandreas.hansson@arm.com    exit_cause = exit_event.getCause()
38810467Sandreas.hansson@arm.com
38910467Sandreas.hansson@arm.com    if exit_cause == "simpoint starting point found":
39010467Sandreas.hansson@arm.com        print "Warmed up! Dumping and resetting stats!"
39110467Sandreas.hansson@arm.com        m5.stats.dump()
39210467Sandreas.hansson@arm.com        m5.stats.reset()
39310467Sandreas.hansson@arm.com
39410467Sandreas.hansson@arm.com        exit_event = m5.simulate()
39510467Sandreas.hansson@arm.com        exit_cause = exit_event.getCause()
3967673Snate@binkert.org
3977673Snate@binkert.org        if exit_cause == "simpoint starting point found":
3987673Snate@binkert.org            print "Done running SimPoint!"
3997673Snate@binkert.org            sys.exit(exit_event.getCode())
4007673Snate@binkert.org
4019048SAli.Saidi@ARM.com    print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_cause)
4027673Snate@binkert.org    sys.exit(exit_event.getCode())
4037673Snate@binkert.org
4047673Snate@binkert.orgdef repeatSwitch(testsys, repeat_switch_cpu_list, maxtick, switch_freq):
4057673Snate@binkert.org    print "starting switch loop"
4066658Snate@binkert.org    while True:
4077756SAli.Saidi@ARM.com        exit_event = m5.simulate(switch_freq)
4087816Ssteve.reinhardt@amd.com        exit_cause = exit_event.getCause()
4096658Snate@binkert.org
41011308Santhony.gutierrez@amd.com        if exit_cause != "simulate() limit reached":
41111308Santhony.gutierrez@amd.com            return exit_event
41211308Santhony.gutierrez@amd.com
41311308Santhony.gutierrez@amd.com        m5.switchCpus(testsys, repeat_switch_cpu_list)
41411308Santhony.gutierrez@amd.com
41511308Santhony.gutierrez@amd.com        tmp_cpu_list = []
41611308Santhony.gutierrez@amd.com        for old_cpu, new_cpu in repeat_switch_cpu_list:
41711308Santhony.gutierrez@amd.com            tmp_cpu_list.append((new_cpu, old_cpu))
41811308Santhony.gutierrez@amd.com        repeat_switch_cpu_list = tmp_cpu_list
41911308Santhony.gutierrez@amd.com
42011308Santhony.gutierrez@amd.com        if (maxtick - m5.curTick()) <= switch_freq:
42111308Santhony.gutierrez@amd.com            exit_event = m5.simulate(maxtick - m5.curTick())
42211308Santhony.gutierrez@amd.com            return exit_event
42311308Santhony.gutierrez@amd.com
42411308Santhony.gutierrez@amd.comdef run(options, root, testsys, cpu_class):
42511308Santhony.gutierrez@amd.com    if options.checkpoint_dir:
42611308Santhony.gutierrez@amd.com        cptdir = options.checkpoint_dir
42711308Santhony.gutierrez@amd.com    elif m5.options.outdir:
42811308Santhony.gutierrez@amd.com        cptdir = m5.options.outdir
42911308Santhony.gutierrez@amd.com    else:
43011308Santhony.gutierrez@amd.com        cptdir = getcwd()
43111308Santhony.gutierrez@amd.com
43211308Santhony.gutierrez@amd.com    if options.fast_forward and options.checkpoint_restore != None:
43311308Santhony.gutierrez@amd.com        fatal("Can't specify both --fast-forward and --checkpoint-restore")
43411308Santhony.gutierrez@amd.com
43511308Santhony.gutierrez@amd.com    if options.standard_switch and not options.caches:
43611308Santhony.gutierrez@amd.com        fatal("Must specify --caches when using --standard-switch")
43711308Santhony.gutierrez@amd.com
43811308Santhony.gutierrez@amd.com    if options.standard_switch and options.repeat_switch:
43911308Santhony.gutierrez@amd.com        fatal("Can't specify both --standard-switch and --repeat-switch")
44011308Santhony.gutierrez@amd.com
44111308Santhony.gutierrez@amd.com    if options.repeat_switch and options.take_checkpoints:
44211308Santhony.gutierrez@amd.com        fatal("Can't specify both --repeat-switch and --take-checkpoints")
44311308Santhony.gutierrez@amd.com
44411308Santhony.gutierrez@amd.com    np = options.num_cpus
44511308Santhony.gutierrez@amd.com    switch_cpus = None
44611308Santhony.gutierrez@amd.com
44711308Santhony.gutierrez@amd.com    if options.prog_interval:
44811308Santhony.gutierrez@amd.com        for i in xrange(np):
44911308Santhony.gutierrez@amd.com            testsys.cpu[i].progress_interval = options.prog_interval
45011308Santhony.gutierrez@amd.com
45111308Santhony.gutierrez@amd.com    if options.maxinsts:
45211308Santhony.gutierrez@amd.com        for i in xrange(np):
45311308Santhony.gutierrez@amd.com            testsys.cpu[i].max_insts_any_thread = options.maxinsts
45411308Santhony.gutierrez@amd.com
4554382Sbinkertn@umich.edu    if cpu_class:
4564382Sbinkertn@umich.edu        switch_cpus = [cpu_class(switched_out=True, cpu_id=(i))
4574762Snate@binkert.org                       for i in xrange(np)]
4584762Snate@binkert.org
4594762Snate@binkert.org        for i in xrange(np):
4606654Snate@binkert.org            if options.fast_forward:
4616654Snate@binkert.org                testsys.cpu[i].max_insts_any_thread = int(options.fast_forward)
4625517Snate@binkert.org            switch_cpus[i].system = testsys
4635517Snate@binkert.org            switch_cpus[i].workload = testsys.cpu[i].workload
4645517Snate@binkert.org            switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain
4655517Snate@binkert.org            switch_cpus[i].progress_interval = \
4665517Snate@binkert.org                testsys.cpu[i].progress_interval
4675517Snate@binkert.org            # simulation period
4685517Snate@binkert.org            if options.maxinsts:
4695517Snate@binkert.org                switch_cpus[i].max_insts_any_thread = options.maxinsts
4705517Snate@binkert.org            # Add checker cpu if selected
4715517Snate@binkert.org            if options.checker:
4725517Snate@binkert.org                switch_cpus[i].addCheckerCpu()
4735517Snate@binkert.org
4745517Snate@binkert.org        # If elastic tracing is enabled attach the elastic trace probe
4755517Snate@binkert.org        # to the switch CPUs
4765517Snate@binkert.org        if options.elastic_trace_en:
4775517Snate@binkert.org            CpuConfig.config_etrace(cpu_class, switch_cpus, options)
4785517Snate@binkert.org
4796654Snate@binkert.org        testsys.switch_cpus = switch_cpus
4805517Snate@binkert.org        switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
4815517Snate@binkert.org
4825517Snate@binkert.org    if options.repeat_switch:
4835517Snate@binkert.org        switch_class = getCPUClass(options.cpu_type)[0]
4845517Snate@binkert.org        if switch_class.require_caches() and \
4855517Snate@binkert.org                not options.caches:
4865517Snate@binkert.org            print "%s: Must be used with caches" % str(switch_class)
4875517Snate@binkert.org            sys.exit(1)
4886143Snate@binkert.org        if not switch_class.support_take_over():
4896654Snate@binkert.org            print "%s: CPU switching not supported" % str(switch_class)
4905517Snate@binkert.org            sys.exit(1)
4915517Snate@binkert.org
4925517Snate@binkert.org        repeat_switch_cpus = [switch_class(switched_out=True, \
4935517Snate@binkert.org                                               cpu_id=(i)) for i in xrange(np)]
4945517Snate@binkert.org
4955517Snate@binkert.org        for i in xrange(np):
4965517Snate@binkert.org            repeat_switch_cpus[i].system = testsys
4975517Snate@binkert.org            repeat_switch_cpus[i].workload = testsys.cpu[i].workload
4985517Snate@binkert.org            repeat_switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain
4995517Snate@binkert.org
5005517Snate@binkert.org            if options.maxinsts:
5015517Snate@binkert.org                repeat_switch_cpus[i].max_insts_any_thread = options.maxinsts
5025517Snate@binkert.org
5035517Snate@binkert.org            if options.checker:
5046654Snate@binkert.org                repeat_switch_cpus[i].addCheckerCpu()
5056654Snate@binkert.org
5065517Snate@binkert.org        testsys.repeat_switch_cpus = repeat_switch_cpus
5075517Snate@binkert.org
5086143Snate@binkert.org        if cpu_class:
5096143Snate@binkert.org            repeat_switch_cpu_list = [(switch_cpus[i], repeat_switch_cpus[i])
5106143Snate@binkert.org                                      for i in xrange(np)]
5116727Ssteve.reinhardt@amd.com        else:
5125517Snate@binkert.org            repeat_switch_cpu_list = [(testsys.cpu[i], repeat_switch_cpus[i])
5136727Ssteve.reinhardt@amd.com                                      for i in xrange(np)]
5145517Snate@binkert.org
5155517Snate@binkert.org    if options.standard_switch:
5165517Snate@binkert.org        switch_cpus = [TimingSimpleCPU(switched_out=True, cpu_id=(i))
5176654Snate@binkert.org                       for i in xrange(np)]
5186654Snate@binkert.org        switch_cpus_1 = [DerivO3CPU(switched_out=True, cpu_id=(i))
5197673Snate@binkert.org                        for i in xrange(np)]
5206654Snate@binkert.org
5216654Snate@binkert.org        for i in xrange(np):
5226654Snate@binkert.org            switch_cpus[i].system =  testsys
5236654Snate@binkert.org            switch_cpus_1[i].system =  testsys
5245517Snate@binkert.org            switch_cpus[i].workload = testsys.cpu[i].workload
5255517Snate@binkert.org            switch_cpus_1[i].workload = testsys.cpu[i].workload
5265517Snate@binkert.org            switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain
5276143Snate@binkert.org            switch_cpus_1[i].clk_domain = testsys.cpu[i].clk_domain
5285517Snate@binkert.org
5294762Snate@binkert.org            # if restoring, make atomic cpu simulate only a few instructions
5305517Snate@binkert.org            if options.checkpoint_restore != None:
5315517Snate@binkert.org                testsys.cpu[i].max_insts_any_thread = 1
5326143Snate@binkert.org            # Fast forward to specified location if we are not restoring
5336143Snate@binkert.org            elif options.fast_forward:
5345517Snate@binkert.org                testsys.cpu[i].max_insts_any_thread = int(options.fast_forward)
5355517Snate@binkert.org            # Fast forward to a simpoint (warning: time consuming)
5365517Snate@binkert.org            elif options.simpoint:
5375517Snate@binkert.org                if testsys.cpu[i].workload[0].simpoint == 0:
5385517Snate@binkert.org                    fatal('simpoint not found')
5395517Snate@binkert.org                testsys.cpu[i].max_insts_any_thread = \
5405517Snate@binkert.org                    testsys.cpu[i].workload[0].simpoint
5415517Snate@binkert.org            # No distance specified, just switch
5425517Snate@binkert.org            else:
5439338SAndreas.Sandberg@arm.com                testsys.cpu[i].max_insts_any_thread = 1
5449338SAndreas.Sandberg@arm.com
5459338SAndreas.Sandberg@arm.com            # warmup period
5469338SAndreas.Sandberg@arm.com            if options.warmup_insts:
5479338SAndreas.Sandberg@arm.com                switch_cpus[i].max_insts_any_thread =  options.warmup_insts
5489338SAndreas.Sandberg@arm.com
5498596Ssteve.reinhardt@amd.com            # simulation period
5508596Ssteve.reinhardt@amd.com            if options.maxinsts:
5518596Ssteve.reinhardt@amd.com                switch_cpus_1[i].max_insts_any_thread = options.maxinsts
5528596Ssteve.reinhardt@amd.com
5538596Ssteve.reinhardt@amd.com            # attach the checker cpu if selected
5548596Ssteve.reinhardt@amd.com            if options.checker:
5558596Ssteve.reinhardt@amd.com                switch_cpus[i].addCheckerCpu()
5566143Snate@binkert.org                switch_cpus_1[i].addCheckerCpu()
5575517Snate@binkert.org
5586654Snate@binkert.org        testsys.switch_cpus = switch_cpus
5596654Snate@binkert.org        testsys.switch_cpus_1 = switch_cpus_1
5606654Snate@binkert.org        switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
5616654Snate@binkert.org        switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)]
5626654Snate@binkert.org
5636654Snate@binkert.org    # set the checkpoint in the cpu before m5.instantiate is called
5645517Snate@binkert.org    if options.take_checkpoints != None and \
5655517Snate@binkert.org           (options.simpoint or options.at_instruction):
5665517Snate@binkert.org        offset = int(options.take_checkpoints)
5678596Ssteve.reinhardt@amd.com        # Set an instruction break point
5688596Ssteve.reinhardt@amd.com        if options.simpoint:
5694762Snate@binkert.org            for i in xrange(np):
5704762Snate@binkert.org                if testsys.cpu[i].workload[0].simpoint == 0:
5714762Snate@binkert.org                    fatal('no simpoint for testsys.cpu[%d].workload[0]', i)
5724762Snate@binkert.org                checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset
5734762Snate@binkert.org                testsys.cpu[i].max_insts_any_thread = checkpoint_inst
5744762Snate@binkert.org                # used for output below
5757675Snate@binkert.org                options.take_checkpoints = checkpoint_inst
57610584Sandreas.hansson@arm.com        else:
5774762Snate@binkert.org            options.take_checkpoints = offset
5784762Snate@binkert.org            # Set all test cpus with the right number of instructions
5794762Snate@binkert.org            # for the upcoming simulation
5804762Snate@binkert.org            for i in xrange(np):
5814382Sbinkertn@umich.edu                testsys.cpu[i].max_insts_any_thread = offset
5824382Sbinkertn@umich.edu
5835517Snate@binkert.org    if options.take_simpoint_checkpoints != None:
5846654Snate@binkert.org        simpoints, interval_length = parseSimpointAnalysisFile(options, testsys)
5855517Snate@binkert.org
5868126Sgblack@eecs.umich.edu    checkpoint_dir = None
5876654Snate@binkert.org    if options.checkpoint_restore:
5887673Snate@binkert.org        cpt_starttick, checkpoint_dir = findCptDir(options, cptdir, testsys)
5896654Snate@binkert.org    m5.instantiate(checkpoint_dir)
5906654Snate@binkert.org
5916654Snate@binkert.org    # Initialization is complete.  If we're not in control of simulation
5926654Snate@binkert.org    # (that is, if we're a slave simulator acting as a component in another
5936654Snate@binkert.org    #  'master' simulator) then we're done here.  The other simulator will
5946654Snate@binkert.org    # call simulate() directly. --initialize-only is used to indicate this.
5956654Snate@binkert.org    if options.initialize_only:
5966669Snate@binkert.org        return
5976669Snate@binkert.org
5986669Snate@binkert.org    # Handle the max tick settings now that tick frequency was resolved
5996669Snate@binkert.org    # during system instantiation
6006669Snate@binkert.org    # NOTE: the maxtick variable here is in absolute ticks, so it must
6016669Snate@binkert.org    # include any simulated ticks before a checkpoint
6026654Snate@binkert.org    explicit_maxticks = 0
6037673Snate@binkert.org    maxtick_from_abs = m5.MaxTick
6045517Snate@binkert.org    maxtick_from_rel = m5.MaxTick
6058126Sgblack@eecs.umich.edu    maxtick_from_maxtime = m5.MaxTick
6065798Snate@binkert.org    if options.abs_max_tick:
6077756SAli.Saidi@ARM.com        maxtick_from_abs = options.abs_max_tick
6087816Ssteve.reinhardt@amd.com        explicit_maxticks += 1
6095798Snate@binkert.org    if options.rel_max_tick:
6105798Snate@binkert.org        maxtick_from_rel = options.rel_max_tick
6115517Snate@binkert.org        if options.checkpoint_restore:
6125517Snate@binkert.org            # NOTE: this may need to be updated if checkpoints ever store
6137673Snate@binkert.org            # the ticks per simulated second
6145517Snate@binkert.org            maxtick_from_rel += cpt_starttick
6155517Snate@binkert.org            if options.at_instruction or options.simpoint:
6167673Snate@binkert.org                warn("Relative max tick specified with --at-instruction or" \
6177673Snate@binkert.org                     " --simpoint\n      These options don't specify the " \
6185517Snate@binkert.org                     "checkpoint start tick, so assuming\n      you mean " \
6195798Snate@binkert.org                     "absolute max tick")
6205798Snate@binkert.org        explicit_maxticks += 1
6218333Snate@binkert.org    if options.maxtime:
6227816Ssteve.reinhardt@amd.com        maxtick_from_maxtime = m5.ticks.fromSeconds(options.maxtime)
6235798Snate@binkert.org        explicit_maxticks += 1
6245798Snate@binkert.org    if explicit_maxticks > 1:
6254762Snate@binkert.org        warn("Specified multiple of --abs-max-tick, --rel-max-tick, --maxtime."\
6264762Snate@binkert.org             " Using least")
6274762Snate@binkert.org    maxtick = min([maxtick_from_abs, maxtick_from_rel, maxtick_from_maxtime])
6284762Snate@binkert.org
6294762Snate@binkert.org    if options.checkpoint_restore != None and maxtick < cpt_starttick:
6308596Ssteve.reinhardt@amd.com        fatal("Bad maxtick (%d) specified: " \
6315517Snate@binkert.org              "Checkpoint starts starts from tick: %d", maxtick, cpt_starttick)
6325517Snate@binkert.org
6335517Snate@binkert.org    if options.standard_switch or cpu_class:
6345517Snate@binkert.org        if options.standard_switch:
6355517Snate@binkert.org            print "Switch at instruction count:%s" % \
6367673Snate@binkert.org                    str(testsys.cpu[0].max_insts_any_thread)
6378596Ssteve.reinhardt@amd.com            exit_event = m5.simulate()
6387673Snate@binkert.org        elif cpu_class and options.fast_forward:
6395517Snate@binkert.org            print "Switch at instruction count:%s" % \
64010458Sandreas.hansson@arm.com                    str(testsys.cpu[0].max_insts_any_thread)
64110458Sandreas.hansson@arm.com            exit_event = m5.simulate()
64210458Sandreas.hansson@arm.com        else:
64310458Sandreas.hansson@arm.com            print "Switch at curTick count:%s" % str(10000)
64410458Sandreas.hansson@arm.com            exit_event = m5.simulate(10000)
64510458Sandreas.hansson@arm.com        print "Switched CPUS @ tick %s" % (m5.curTick())
64610458Sandreas.hansson@arm.com
64710458Sandreas.hansson@arm.com        m5.switchCpus(testsys, switch_cpu_list)
64810458Sandreas.hansson@arm.com
64910458Sandreas.hansson@arm.com        if options.standard_switch:
65010458Sandreas.hansson@arm.com            print "Switch at instruction count:%d" % \
65110458Sandreas.hansson@arm.com                    (testsys.switch_cpus[0].max_insts_any_thread)
6528596Ssteve.reinhardt@amd.com
6535517Snate@binkert.org            #warmup instruction count may have already been set
6545517Snate@binkert.org            if options.warmup_insts:
6555517Snate@binkert.org                exit_event = m5.simulate()
6568596Ssteve.reinhardt@amd.com            else:
6575517Snate@binkert.org                exit_event = m5.simulate(options.standard_switch)
6587673Snate@binkert.org            print "Switching CPUS @ tick %s" % (m5.curTick())
6597673Snate@binkert.org            print "Simulation ends instruction count:%d" % \
6607673Snate@binkert.org                    (testsys.switch_cpus_1[0].max_insts_any_thread)
6615517Snate@binkert.org            m5.switchCpus(testsys, switch_cpu_list1)
6625517Snate@binkert.org
6635517Snate@binkert.org    # If we're taking and restoring checkpoints, use checkpoint_dir
6645517Snate@binkert.org    # option only for finding the checkpoints to restore from.  This
6655517Snate@binkert.org    # lets us test checkpointing by restoring from one set of
6665517Snate@binkert.org    # checkpoints, generating a second set, and then comparing them.
6675517Snate@binkert.org    if (options.take_checkpoints or options.take_simpoint_checkpoints) \
6687673Snate@binkert.org        and options.checkpoint_restore:
6697673Snate@binkert.org
6707673Snate@binkert.org        if m5.options.outdir:
6715517Snate@binkert.org            cptdir = m5.options.outdir
6728596Ssteve.reinhardt@amd.com        else:
6735517Snate@binkert.org            cptdir = getcwd()
6745517Snate@binkert.org
6755517Snate@binkert.org    if options.take_checkpoints != None :
6765517Snate@binkert.org        # Checkpoints being taken via the command line at <when> and at
6775517Snate@binkert.org        # subsequent periods of <period>.  Checkpoint instructions
6787673Snate@binkert.org        # received from the benchmark running are ignored and skipped in
6797673Snate@binkert.org        # favor of command line checkpoint instructions.
6807673Snate@binkert.org        exit_event = scriptCheckpoints(options, maxtick, cptdir)
6815517Snate@binkert.org
6828596Ssteve.reinhardt@amd.com    # Take SimPoint checkpoints
6837675Snate@binkert.org    elif options.take_simpoint_checkpoints != None:
6847675Snate@binkert.org        takeSimpointCheckpoints(simpoints, interval_length, cptdir)
6857675Snate@binkert.org
6867675Snate@binkert.org    # Restore from SimPoint checkpoints
6877675Snate@binkert.org    elif options.restore_simpoint_checkpoint != None:
6887675Snate@binkert.org        restoreSimpointCheckpoint()
6898596Ssteve.reinhardt@amd.com
6907675Snate@binkert.org    else:
6917675Snate@binkert.org        if options.fast_forward:
6928596Ssteve.reinhardt@amd.com            m5.stats.reset()
6938596Ssteve.reinhardt@amd.com        print "**** REAL SIMULATION ****"
6948596Ssteve.reinhardt@amd.com
6958596Ssteve.reinhardt@amd.com        # If checkpoints are being taken, then the checkpoint instruction
6968596Ssteve.reinhardt@amd.com        # will occur in the benchmark code it self.
6978596Ssteve.reinhardt@amd.com        if options.repeat_switch and maxtick > options.repeat_switch:
6988596Ssteve.reinhardt@amd.com            exit_event = repeatSwitch(testsys, repeat_switch_cpu_list,
6998596Ssteve.reinhardt@amd.com                                      maxtick, options.repeat_switch)
70010454SCurtis.Dunham@arm.com        else:
70110454SCurtis.Dunham@arm.com            exit_event = benchCheckpoints(options, maxtick, cptdir)
70210454SCurtis.Dunham@arm.com
70310454SCurtis.Dunham@arm.com    print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_event.getCause())
7048596Ssteve.reinhardt@amd.com    if options.checkpoint_at_end:
7054762Snate@binkert.org        m5.checkpoint(joinpath(cptdir, "cpt.%d"))
7066143Snate@binkert.org
7076143Snate@binkert.org    if not m5.options.interactive:
7086143Snate@binkert.org        sys.exit(exit_event.getCode())
7094762Snate@binkert.org