Simulation.py revision 9793
111308Santhony.gutierrez@amd.com# Copyright (c) 2012-2013 ARM Limited
212697Santhony.gutierrez@amd.com# All rights reserved
311308Santhony.gutierrez@amd.com#
411308Santhony.gutierrez@amd.com# The license below extends only to copyright in the software and shall
511308Santhony.gutierrez@amd.com# not be construed as granting a license to any other intellectual
611308Santhony.gutierrez@amd.com# property including but not limited to intellectual property relating
711308Santhony.gutierrez@amd.com# to a hardware implementation of the functionality of the software
811308Santhony.gutierrez@amd.com# licensed hereunder.  You may use the software subject to the license
911308Santhony.gutierrez@amd.com# terms below provided that you ensure that this notice is replicated
1011308Santhony.gutierrez@amd.com# unmodified and in its entirety in all distributions of the software,
1111308Santhony.gutierrez@amd.com# modified or unmodified, in source code or in binary form.
1211308Santhony.gutierrez@amd.com#
1311308Santhony.gutierrez@amd.com# Copyright (c) 2006-2008 The Regents of The University of Michigan
1411308Santhony.gutierrez@amd.com# Copyright (c) 2010 Advanced Micro Devices, Inc.
1511308Santhony.gutierrez@amd.com# All rights reserved.
1611308Santhony.gutierrez@amd.com#
1712697Santhony.gutierrez@amd.com# Redistribution and use in source and binary forms, with or without
1812697Santhony.gutierrez@amd.com# modification, are permitted provided that the following conditions are
1912697Santhony.gutierrez@amd.com# met: redistributions of source code must retain the above copyright
2011308Santhony.gutierrez@amd.com# notice, this list of conditions and the following disclaimer;
2111308Santhony.gutierrez@amd.com# redistributions in binary form must reproduce the above copyright
2211308Santhony.gutierrez@amd.com# notice, this list of conditions and the following disclaimer in the
2311308Santhony.gutierrez@amd.com# documentation and/or other materials provided with the distribution;
2411308Santhony.gutierrez@amd.com# neither the name of the copyright holders nor the names of its
2511308Santhony.gutierrez@amd.com# contributors may be used to endorse or promote products derived from
2611308Santhony.gutierrez@amd.com# this software without specific prior written permission.
2711308Santhony.gutierrez@amd.com#
2811308Santhony.gutierrez@amd.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2911308Santhony.gutierrez@amd.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3011308Santhony.gutierrez@amd.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3111308Santhony.gutierrez@amd.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3211308Santhony.gutierrez@amd.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3312697Santhony.gutierrez@amd.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3412697Santhony.gutierrez@amd.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3512697Santhony.gutierrez@amd.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3611308Santhony.gutierrez@amd.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3711308Santhony.gutierrez@amd.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3811308Santhony.gutierrez@amd.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3911308Santhony.gutierrez@amd.com#
4011308Santhony.gutierrez@amd.com# Authors: Lisa Hsu
4111308Santhony.gutierrez@amd.com
4211308Santhony.gutierrez@amd.comimport sys
4311308Santhony.gutierrez@amd.comfrom os import getcwd
4411308Santhony.gutierrez@amd.comfrom os.path import join as joinpath
4511308Santhony.gutierrez@amd.com
4611308Santhony.gutierrez@amd.comimport CpuConfig
4711308Santhony.gutierrez@amd.comimport MemConfig
4811308Santhony.gutierrez@amd.com
4911308Santhony.gutierrez@amd.comimport m5
5011308Santhony.gutierrez@amd.comfrom m5.defines import buildEnv
5111308Santhony.gutierrez@amd.comfrom m5.objects import *
5212680Sgiacomo.travaglini@arm.comfrom m5.util import *
5311308Santhony.gutierrez@amd.com
5411308Santhony.gutierrez@amd.comaddToPath('../common')
5512126Sspwilson2@wisc.edu
5612126Sspwilson2@wisc.edudef getCPUClass(cpu_type):
5712126Sspwilson2@wisc.edu    """Returns the required cpu class and the mode of operation."""
5811308Santhony.gutierrez@amd.com    cls = CpuConfig.get(cpu_type)
5911308Santhony.gutierrez@amd.com    return cls, cls.memory_mode()
6011308Santhony.gutierrez@amd.com
6111308Santhony.gutierrez@amd.comdef setCPUClass(options):
6211308Santhony.gutierrez@amd.com    """Returns two cpu classes and the initial mode of operation.
6311308Santhony.gutierrez@amd.com
6411308Santhony.gutierrez@amd.com       Restoring from a checkpoint or fast forwarding through a benchmark
6511308Santhony.gutierrez@amd.com       can be done using one type of cpu, and then the actual
6611308Santhony.gutierrez@amd.com       simulation can be carried out using another type. This function
6711308Santhony.gutierrez@amd.com       returns these two types of cpus and the initial mode of operation
6811308Santhony.gutierrez@amd.com       depending on the options provided.
6911308Santhony.gutierrez@amd.com    """
7011308Santhony.gutierrez@amd.com
7111308Santhony.gutierrez@amd.com    TmpClass, test_mem_mode = getCPUClass(options.cpu_type)
7211308Santhony.gutierrez@amd.com    CPUClass = None
7311308Santhony.gutierrez@amd.com    if TmpClass.require_caches() and \
7411308Santhony.gutierrez@amd.com            not options.caches and not options.ruby:
7511308Santhony.gutierrez@amd.com        fatal("%s must be used with caches" % options.cpu_type)
7611308Santhony.gutierrez@amd.com
7711308Santhony.gutierrez@amd.com    if options.checkpoint_restore != None:
7811308Santhony.gutierrez@amd.com        if options.restore_with_cpu != options.cpu_type:
7911308Santhony.gutierrez@amd.com            CPUClass = TmpClass
8011308Santhony.gutierrez@amd.com            TmpClass, test_mem_mode = getCPUClass(options.restore_with_cpu)
8111308Santhony.gutierrez@amd.com    elif options.fast_forward:
8211308Santhony.gutierrez@amd.com        CPUClass = TmpClass
8311308Santhony.gutierrez@amd.com        TmpClass = AtomicSimpleCPU
8411308Santhony.gutierrez@amd.com        test_mem_mode = 'atomic'
8511308Santhony.gutierrez@amd.com
8611308Santhony.gutierrez@amd.com    return (TmpClass, test_mem_mode, CPUClass)
8711308Santhony.gutierrez@amd.com
8811308Santhony.gutierrez@amd.comdef setMemClass(options):
8911308Santhony.gutierrez@amd.com    """Returns a memory controller class."""
9011308Santhony.gutierrez@amd.com
9111308Santhony.gutierrez@amd.com    return MemConfig.get(options.mem_type)
9211308Santhony.gutierrez@amd.com
9311308Santhony.gutierrez@amd.comdef setWorkCountOptions(system, options):
9411308Santhony.gutierrez@amd.com    if options.work_item_id != None:
9511308Santhony.gutierrez@amd.com        system.work_item_id = options.work_item_id
9611308Santhony.gutierrez@amd.com    if options.work_begin_cpu_id_exit != None:
9711308Santhony.gutierrez@amd.com        system.work_begin_cpu_id_exit = options.work_begin_cpu_id_exit
9811308Santhony.gutierrez@amd.com    if options.work_end_exit_count != None:
9911308Santhony.gutierrez@amd.com        system.work_end_exit_count = options.work_end_exit_count
10011308Santhony.gutierrez@amd.com    if options.work_end_checkpoint_count != None:
10111308Santhony.gutierrez@amd.com        system.work_end_ckpt_count = options.work_end_checkpoint_count
10211308Santhony.gutierrez@amd.com    if options.work_begin_exit_count != None:
10311308Santhony.gutierrez@amd.com        system.work_begin_exit_count = options.work_begin_exit_count
10411308Santhony.gutierrez@amd.com    if options.work_begin_checkpoint_count != None:
10511308Santhony.gutierrez@amd.com        system.work_begin_ckpt_count = options.work_begin_checkpoint_count
10611308Santhony.gutierrez@amd.com    if options.work_cpus_checkpoint_count != None:
10711308Santhony.gutierrez@amd.com        system.work_cpus_ckpt_count = options.work_cpus_checkpoint_count
10811308Santhony.gutierrez@amd.com
10911308Santhony.gutierrez@amd.comdef findCptDir(options, maxtick, cptdir, testsys):
11011308Santhony.gutierrez@amd.com    """Figures out the directory from which the checkpointed state is read.
11111308Santhony.gutierrez@amd.com
11211308Santhony.gutierrez@amd.com    There are two different ways in which the directories holding checkpoints
11311308Santhony.gutierrez@amd.com    can be named --
11411308Santhony.gutierrez@amd.com    1. cpt.<benchmark name>.<instruction count when the checkpoint was taken>
11511308Santhony.gutierrez@amd.com    2. cpt.<some number, usually the tick value when the checkpoint was taken>
11611308Santhony.gutierrez@amd.com
11711308Santhony.gutierrez@amd.com    This function parses through the options to figure out which one of the
11811308Santhony.gutierrez@amd.com    above should be used for selecting the checkpoint, and then figures out
11911308Santhony.gutierrez@amd.com    the appropriate directory.
12011308Santhony.gutierrez@amd.com
12111308Santhony.gutierrez@amd.com    It also sets the value of the maximum tick value till which the simulation
12211308Santhony.gutierrez@amd.com    will run.
12311308Santhony.gutierrez@amd.com    """
12411308Santhony.gutierrez@amd.com
12511308Santhony.gutierrez@amd.com    from os.path import isdir, exists
12611308Santhony.gutierrez@amd.com    from os import listdir
12711308Santhony.gutierrez@amd.com    import re
12811308Santhony.gutierrez@amd.com
12911308Santhony.gutierrez@amd.com    if not isdir(cptdir):
13011308Santhony.gutierrez@amd.com        fatal("checkpoint dir %s does not exist!", cptdir)
13111308Santhony.gutierrez@amd.com
13211308Santhony.gutierrez@amd.com    if options.at_instruction or options.simpoint:
13311308Santhony.gutierrez@amd.com        inst = options.checkpoint_restore
13411308Santhony.gutierrez@amd.com        if options.simpoint:
13511308Santhony.gutierrez@amd.com            # assume workload 0 has the simpoint
13611308Santhony.gutierrez@amd.com            if testsys.cpu[0].workload[0].simpoint == 0:
13711308Santhony.gutierrez@amd.com                fatal('Unable to find simpoint')
13811308Santhony.gutierrez@amd.com            inst += int(testsys.cpu[0].workload[0].simpoint)
13911308Santhony.gutierrez@amd.com
14011308Santhony.gutierrez@amd.com        checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % (options.bench, inst))
14111308Santhony.gutierrez@amd.com        if not exists(checkpoint_dir):
14213345Sgabeblack@google.com            fatal("Unable to find checkpoint directory %s", checkpoint_dir)
14311308Santhony.gutierrez@amd.com    else:
14411308Santhony.gutierrez@amd.com        dirs = listdir(cptdir)
14511308Santhony.gutierrez@amd.com        expr = re.compile('cpt\.([0-9]*)')
14611308Santhony.gutierrez@amd.com        cpts = []
14711308Santhony.gutierrez@amd.com        for dir in dirs:
14811308Santhony.gutierrez@amd.com            match = expr.match(dir)
14911308Santhony.gutierrez@amd.com            if match:
15011308Santhony.gutierrez@amd.com                cpts.append(match.group(1))
15111308Santhony.gutierrez@amd.com
15211308Santhony.gutierrez@amd.com        cpts.sort(lambda a,b: cmp(long(a), long(b)))
15311308Santhony.gutierrez@amd.com
15411308Santhony.gutierrez@amd.com        cpt_num = options.checkpoint_restore
15511308Santhony.gutierrez@amd.com        if cpt_num > len(cpts):
15611308Santhony.gutierrez@amd.com            fatal('Checkpoint %d not found', cpt_num)
15711308Santhony.gutierrez@amd.com
15811308Santhony.gutierrez@amd.com        maxtick = maxtick - int(cpts[cpt_num - 1])
15911308Santhony.gutierrez@amd.com        checkpoint_dir = joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1])
16011308Santhony.gutierrez@amd.com
16111308Santhony.gutierrez@amd.com    return maxtick, checkpoint_dir
16211308Santhony.gutierrez@amd.com
16311308Santhony.gutierrez@amd.comdef scriptCheckpoints(options, maxtick, cptdir):
16411308Santhony.gutierrez@amd.com    if options.at_instruction or options.simpoint:
16511308Santhony.gutierrez@amd.com        checkpoint_inst = int(options.take_checkpoints)
16611308Santhony.gutierrez@amd.com
16711308Santhony.gutierrez@amd.com        # maintain correct offset if we restored from some instruction
16811308Santhony.gutierrez@amd.com        if options.checkpoint_restore != None:
16913345Sgabeblack@google.com            checkpoint_inst += options.checkpoint_restore
17011308Santhony.gutierrez@amd.com
17111308Santhony.gutierrez@amd.com        print "Creating checkpoint at inst:%d" % (checkpoint_inst)
17213345Sgabeblack@google.com        exit_event = m5.simulate()
17311308Santhony.gutierrez@amd.com        exit_cause = exit_event.getCause()
17411308Santhony.gutierrez@amd.com        print "exit cause = %s" % exit_cause
17513345Sgabeblack@google.com
17611308Santhony.gutierrez@amd.com        # skip checkpoint instructions should they exist
17711308Santhony.gutierrez@amd.com        while exit_cause == "checkpoint":
17813345Sgabeblack@google.com            exit_event = m5.simulate()
17911308Santhony.gutierrez@amd.com            exit_cause = exit_event.getCause()
18011308Santhony.gutierrez@amd.com
18111308Santhony.gutierrez@amd.com        if exit_cause == "a thread reached the max instruction count":
18211308Santhony.gutierrez@amd.com            m5.checkpoint(joinpath(cptdir, "cpt.%s.%d" % \
18311308Santhony.gutierrez@amd.com                    (options.bench, checkpoint_inst)))
18411308Santhony.gutierrez@amd.com            print "Checkpoint written."
18511308Santhony.gutierrez@amd.com
18611308Santhony.gutierrez@amd.com    else:
18711308Santhony.gutierrez@amd.com        when, period = options.take_checkpoints.split(",", 1)
18811308Santhony.gutierrez@amd.com        when = int(when)
18911308Santhony.gutierrez@amd.com        period = int(period)
19011308Santhony.gutierrez@amd.com        num_checkpoints = 0
19111308Santhony.gutierrez@amd.com
19211308Santhony.gutierrez@amd.com        exit_event = m5.simulate(when - m5.curTick())
19311308Santhony.gutierrez@amd.com        exit_cause = exit_event.getCause()
19411308Santhony.gutierrez@amd.com        while exit_cause == "checkpoint":
19511308Santhony.gutierrez@amd.com            exit_event = m5.simulate(when - m5.curTick())
19611308Santhony.gutierrez@amd.com            exit_cause = exit_event.getCause()
19711308Santhony.gutierrez@amd.com
19811308Santhony.gutierrez@amd.com        if exit_cause == "simulate() limit reached":
19911308Santhony.gutierrez@amd.com            m5.checkpoint(joinpath(cptdir, "cpt.%d"))
20011308Santhony.gutierrez@amd.com            num_checkpoints += 1
20111308Santhony.gutierrez@amd.com
20211308Santhony.gutierrez@amd.com        sim_ticks = when
20311308Santhony.gutierrez@amd.com        max_checkpoints = options.max_checkpoints
20411308Santhony.gutierrez@amd.com
20511308Santhony.gutierrez@amd.com        while num_checkpoints < max_checkpoints and \
20611308Santhony.gutierrez@amd.com                exit_cause == "simulate() limit reached":
20711308Santhony.gutierrez@amd.com            if (sim_ticks + period) > maxtick:
20811308Santhony.gutierrez@amd.com                exit_event = m5.simulate(maxtick - sim_ticks)
20911308Santhony.gutierrez@amd.com                exit_cause = exit_event.getCause()
21011308Santhony.gutierrez@amd.com                break
21111308Santhony.gutierrez@amd.com            else:
21211308Santhony.gutierrez@amd.com                exit_event = m5.simulate(period)
21311308Santhony.gutierrez@amd.com                exit_cause = exit_event.getCause()
21411308Santhony.gutierrez@amd.com                sim_ticks += period
21511308Santhony.gutierrez@amd.com                while exit_event.getCause() == "checkpoint":
21611308Santhony.gutierrez@amd.com                    exit_event = m5.simulate(sim_ticks - m5.curTick())
21711308Santhony.gutierrez@amd.com                if exit_event.getCause() == "simulate() limit reached":
21811308Santhony.gutierrez@amd.com                    m5.checkpoint(joinpath(cptdir, "cpt.%d"))
21911308Santhony.gutierrez@amd.com                    num_checkpoints += 1
22011308Santhony.gutierrez@amd.com
22111308Santhony.gutierrez@amd.com    return exit_event
22211308Santhony.gutierrez@amd.com
22311308Santhony.gutierrez@amd.comdef benchCheckpoints(options, maxtick, cptdir):
22411308Santhony.gutierrez@amd.com    exit_event = m5.simulate(maxtick - m5.curTick())
22511308Santhony.gutierrez@amd.com    exit_cause = exit_event.getCause()
22611308Santhony.gutierrez@amd.com
22711308Santhony.gutierrez@amd.com    num_checkpoints = 0
22811308Santhony.gutierrez@amd.com    max_checkpoints = options.max_checkpoints
22911435Smitch.hayenga@arm.com
23011308Santhony.gutierrez@amd.com    while exit_cause == "checkpoint":
23111308Santhony.gutierrez@amd.com        m5.checkpoint(joinpath(cptdir, "cpt.%d"))
23211308Santhony.gutierrez@amd.com        num_checkpoints += 1
23311308Santhony.gutierrez@amd.com        if num_checkpoints == max_checkpoints:
23411308Santhony.gutierrez@amd.com            exit_cause = "maximum %d checkpoints dropped" % max_checkpoints
23511308Santhony.gutierrez@amd.com            break
23611308Santhony.gutierrez@amd.com
23711308Santhony.gutierrez@amd.com        exit_event = m5.simulate(maxtick - m5.curTick())
23811308Santhony.gutierrez@amd.com        exit_cause = exit_event.getCause()
23911308Santhony.gutierrez@amd.com
24011308Santhony.gutierrez@amd.com    return exit_event
24111308Santhony.gutierrez@amd.com
24211308Santhony.gutierrez@amd.comdef repeatSwitch(testsys, repeat_switch_cpu_list, maxtick, switch_freq):
24311308Santhony.gutierrez@amd.com    print "starting switch loop"
24411308Santhony.gutierrez@amd.com    while True:
24511308Santhony.gutierrez@amd.com        exit_event = m5.simulate(switch_freq)
24611308Santhony.gutierrez@amd.com        exit_cause = exit_event.getCause()
24711308Santhony.gutierrez@amd.com
24811308Santhony.gutierrez@amd.com        if exit_cause != "simulate() limit reached":
24911308Santhony.gutierrez@amd.com            return exit_event
25011308Santhony.gutierrez@amd.com
25111308Santhony.gutierrez@amd.com        m5.switchCpus(testsys, repeat_switch_cpu_list)
25211308Santhony.gutierrez@amd.com
25311308Santhony.gutierrez@amd.com        tmp_cpu_list = []
25411308Santhony.gutierrez@amd.com        for old_cpu, new_cpu in repeat_switch_cpu_list:
25511308Santhony.gutierrez@amd.com            tmp_cpu_list.append((new_cpu, old_cpu))
25611308Santhony.gutierrez@amd.com        repeat_switch_cpu_list = tmp_cpu_list
25711308Santhony.gutierrez@amd.com
25811308Santhony.gutierrez@amd.com        if (maxtick - m5.curTick()) <= switch_freq:
25911308Santhony.gutierrez@amd.com            exit_event = m5.simulate(maxtick - m5.curTick())
26011308Santhony.gutierrez@amd.com            return exit_event
26111308Santhony.gutierrez@amd.com
26211308Santhony.gutierrez@amd.comdef run(options, root, testsys, cpu_class):
26311308Santhony.gutierrez@amd.com    if options.maxtick:
26411308Santhony.gutierrez@amd.com        maxtick = options.maxtick
26511308Santhony.gutierrez@amd.com    elif options.maxtime:
26611308Santhony.gutierrez@amd.com        simtime = m5.ticks.seconds(simtime)
26711308Santhony.gutierrez@amd.com        print "simulating for: ", simtime
26811308Santhony.gutierrez@amd.com        maxtick = simtime
26911308Santhony.gutierrez@amd.com    else:
27011308Santhony.gutierrez@amd.com        maxtick = m5.MaxTick
27111308Santhony.gutierrez@amd.com
27211308Santhony.gutierrez@amd.com    if options.checkpoint_dir:
27311308Santhony.gutierrez@amd.com        cptdir = options.checkpoint_dir
27411308Santhony.gutierrez@amd.com    elif m5.options.outdir:
27511308Santhony.gutierrez@amd.com        cptdir = m5.options.outdir
27611308Santhony.gutierrez@amd.com    else:
27711308Santhony.gutierrez@amd.com        cptdir = getcwd()
27811308Santhony.gutierrez@amd.com
27911435Smitch.hayenga@arm.com    if options.fast_forward and options.checkpoint_restore != None:
28011308Santhony.gutierrez@amd.com        fatal("Can't specify both --fast-forward and --checkpoint-restore")
28111308Santhony.gutierrez@amd.com
28211308Santhony.gutierrez@amd.com    if options.standard_switch and not options.caches:
28311308Santhony.gutierrez@amd.com        fatal("Must specify --caches when using --standard-switch")
28411308Santhony.gutierrez@amd.com
28511308Santhony.gutierrez@amd.com    if options.standard_switch and options.repeat_switch:
28611308Santhony.gutierrez@amd.com        fatal("Can't specify both --standard-switch and --repeat-switch")
28711308Santhony.gutierrez@amd.com
28811308Santhony.gutierrez@amd.com    if options.repeat_switch and options.take_checkpoints:
28911308Santhony.gutierrez@amd.com        fatal("Can't specify both --repeat-switch and --take-checkpoints")
29011308Santhony.gutierrez@amd.com
29111308Santhony.gutierrez@amd.com    np = options.num_cpus
29211308Santhony.gutierrez@amd.com    switch_cpus = None
29311308Santhony.gutierrez@amd.com
29411308Santhony.gutierrez@amd.com    if options.prog_interval:
29511308Santhony.gutierrez@amd.com        for i in xrange(np):
29611308Santhony.gutierrez@amd.com            testsys.cpu[i].progress_interval = options.prog_interval
29711308Santhony.gutierrez@amd.com
29811308Santhony.gutierrez@amd.com    if options.maxinsts:
29911308Santhony.gutierrez@amd.com        for i in xrange(np):
30011308Santhony.gutierrez@amd.com            testsys.cpu[i].max_insts_any_thread = options.maxinsts
30111308Santhony.gutierrez@amd.com
30211308Santhony.gutierrez@amd.com    if cpu_class:
30311308Santhony.gutierrez@amd.com        switch_cpus = [cpu_class(switched_out=True, cpu_id=(i))
30411308Santhony.gutierrez@amd.com                       for i in xrange(np)]
30511308Santhony.gutierrez@amd.com
30611308Santhony.gutierrez@amd.com        for i in xrange(np):
30711308Santhony.gutierrez@amd.com            if options.fast_forward:
30811308Santhony.gutierrez@amd.com                testsys.cpu[i].max_insts_any_thread = int(options.fast_forward)
30911308Santhony.gutierrez@amd.com            switch_cpus[i].system =  testsys
31011308Santhony.gutierrez@amd.com            switch_cpus[i].workload = testsys.cpu[i].workload
31111308Santhony.gutierrez@amd.com            switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain
31211639Salexandru.dutu@amd.com            # simulation period
31311308Santhony.gutierrez@amd.com            if options.maxinsts:
31411308Santhony.gutierrez@amd.com                switch_cpus[i].max_insts_any_thread = options.maxinsts
31511308Santhony.gutierrez@amd.com            # Add checker cpu if selected
31611308Santhony.gutierrez@amd.com            if options.checker:
31711308Santhony.gutierrez@amd.com                switch_cpus[i].addCheckerCpu()
31811308Santhony.gutierrez@amd.com
31911308Santhony.gutierrez@amd.com        testsys.switch_cpus = switch_cpus
32011308Santhony.gutierrez@amd.com        switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
32111308Santhony.gutierrez@amd.com
32211308Santhony.gutierrez@amd.com    if options.repeat_switch:
32311308Santhony.gutierrez@amd.com        switch_class = getCPUClass(options.cpu_type)[0]
32411308Santhony.gutierrez@amd.com        if switch_class.require_caches() and \
32511308Santhony.gutierrez@amd.com                not options.caches:
32611308Santhony.gutierrez@amd.com            print "%s: Must be used with caches" % str(switch_class)
32711308Santhony.gutierrez@amd.com            sys.exit(1)
32811308Santhony.gutierrez@amd.com        if not switch_class.support_take_over():
32911308Santhony.gutierrez@amd.com            print "%s: CPU switching not supported" % str(switch_class)
33011308Santhony.gutierrez@amd.com            sys.exit(1)
33111308Santhony.gutierrez@amd.com
33211308Santhony.gutierrez@amd.com        repeat_switch_cpus = [switch_class(switched_out=True, \
33311308Santhony.gutierrez@amd.com                                               cpu_id=(i)) for i in xrange(np)]
33411308Santhony.gutierrez@amd.com
33511308Santhony.gutierrez@amd.com        for i in xrange(np):
33611308Santhony.gutierrez@amd.com            repeat_switch_cpus[i].system = testsys
33711308Santhony.gutierrez@amd.com            repeat_switch_cpus[i].workload = testsys.cpu[i].workload
33811308Santhony.gutierrez@amd.com            repeat_switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain
33911308Santhony.gutierrez@amd.com
34011308Santhony.gutierrez@amd.com            if options.maxinsts:
34111308Santhony.gutierrez@amd.com                repeat_switch_cpus[i].max_insts_any_thread = options.maxinsts
34211308Santhony.gutierrez@amd.com
34311308Santhony.gutierrez@amd.com            if options.checker:
34411308Santhony.gutierrez@amd.com                repeat_switch_cpus[i].addCheckerCpu()
34511308Santhony.gutierrez@amd.com
34611308Santhony.gutierrez@amd.com        testsys.repeat_switch_cpus = repeat_switch_cpus
34711308Santhony.gutierrez@amd.com
34811308Santhony.gutierrez@amd.com        if cpu_class:
34911308Santhony.gutierrez@amd.com            repeat_switch_cpu_list = [(switch_cpus[i], repeat_switch_cpus[i])
35011308Santhony.gutierrez@amd.com                                      for i in xrange(np)]
35111308Santhony.gutierrez@amd.com        else:
35211308Santhony.gutierrez@amd.com            repeat_switch_cpu_list = [(testsys.cpu[i], repeat_switch_cpus[i])
35311308Santhony.gutierrez@amd.com                                      for i in xrange(np)]
35411308Santhony.gutierrez@amd.com
35511308Santhony.gutierrez@amd.com    if options.standard_switch:
35611308Santhony.gutierrez@amd.com        switch_cpus = [TimingSimpleCPU(switched_out=True, cpu_id=(i))
35711308Santhony.gutierrez@amd.com                       for i in xrange(np)]
35811308Santhony.gutierrez@amd.com        switch_cpus_1 = [DerivO3CPU(switched_out=True, cpu_id=(i))
35911308Santhony.gutierrez@amd.com                        for i in xrange(np)]
36011308Santhony.gutierrez@amd.com
36111308Santhony.gutierrez@amd.com        for i in xrange(np):
36211308Santhony.gutierrez@amd.com            switch_cpus[i].system =  testsys
36311308Santhony.gutierrez@amd.com            switch_cpus_1[i].system =  testsys
36411308Santhony.gutierrez@amd.com            switch_cpus[i].workload = testsys.cpu[i].workload
36511308Santhony.gutierrez@amd.com            switch_cpus_1[i].workload = testsys.cpu[i].workload
36611308Santhony.gutierrez@amd.com            switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain
36711308Santhony.gutierrez@amd.com            switch_cpus_1[i].clk_domain = testsys.cpu[i].clk_domain
36811308Santhony.gutierrez@amd.com
36911308Santhony.gutierrez@amd.com            # if restoring, make atomic cpu simulate only a few instructions
37011308Santhony.gutierrez@amd.com            if options.checkpoint_restore != None:
37111308Santhony.gutierrez@amd.com                testsys.cpu[i].max_insts_any_thread = 1
37211308Santhony.gutierrez@amd.com            # Fast forward to specified location if we are not restoring
37311308Santhony.gutierrez@amd.com            elif options.fast_forward:
37411308Santhony.gutierrez@amd.com                testsys.cpu[i].max_insts_any_thread = int(options.fast_forward)
37511308Santhony.gutierrez@amd.com            # Fast forward to a simpoint (warning: time consuming)
37611308Santhony.gutierrez@amd.com            elif options.simpoint:
37711534Sjohn.kalamatianos@amd.com                if testsys.cpu[i].workload[0].simpoint == 0:
37811534Sjohn.kalamatianos@amd.com                    fatal('simpoint not found')
37911534Sjohn.kalamatianos@amd.com                testsys.cpu[i].max_insts_any_thread = \
38011534Sjohn.kalamatianos@amd.com                    testsys.cpu[i].workload[0].simpoint
38111534Sjohn.kalamatianos@amd.com            # No distance specified, just switch
38211534Sjohn.kalamatianos@amd.com            else:
38311308Santhony.gutierrez@amd.com                testsys.cpu[i].max_insts_any_thread = 1
38411308Santhony.gutierrez@amd.com
38511308Santhony.gutierrez@amd.com            # warmup period
38611308Santhony.gutierrez@amd.com            if options.warmup_insts:
38711308Santhony.gutierrez@amd.com                switch_cpus[i].max_insts_any_thread =  options.warmup_insts
38811640Salexandru.dutu@amd.com
38911640Salexandru.dutu@amd.com            # simulation period
39011646Santhony.gutierrez@amd.com            if options.maxinsts:
39111640Salexandru.dutu@amd.com                switch_cpus_1[i].max_insts_any_thread = options.maxinsts
39211640Salexandru.dutu@amd.com
39311640Salexandru.dutu@amd.com            # attach the checker cpu if selected
394            if options.checker:
395                switch_cpus[i].addCheckerCpu()
396                switch_cpus_1[i].addCheckerCpu()
397
398        testsys.switch_cpus = switch_cpus
399        testsys.switch_cpus_1 = switch_cpus_1
400        switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
401        switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)]
402
403    # set the checkpoint in the cpu before m5.instantiate is called
404    if options.take_checkpoints != None and \
405           (options.simpoint or options.at_instruction):
406        offset = int(options.take_checkpoints)
407        # Set an instruction break point
408        if options.simpoint:
409            for i in xrange(np):
410                if testsys.cpu[i].workload[0].simpoint == 0:
411                    fatal('no simpoint for testsys.cpu[%d].workload[0]', i)
412                checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset
413                testsys.cpu[i].max_insts_any_thread = checkpoint_inst
414                # used for output below
415                options.take_checkpoints = checkpoint_inst
416        else:
417            options.take_checkpoints = offset
418            # Set all test cpus with the right number of instructions
419            # for the upcoming simulation
420            for i in xrange(np):
421                testsys.cpu[i].max_insts_any_thread = offset
422
423    checkpoint_dir = None
424    if options.checkpoint_restore != None:
425        maxtick, checkpoint_dir = findCptDir(options, maxtick, cptdir, testsys)
426    m5.instantiate(checkpoint_dir)
427
428    if options.standard_switch or cpu_class:
429        if options.standard_switch:
430            print "Switch at instruction count:%s" % \
431                    str(testsys.cpu[0].max_insts_any_thread)
432            exit_event = m5.simulate()
433        elif cpu_class and options.fast_forward:
434            print "Switch at instruction count:%s" % \
435                    str(testsys.cpu[0].max_insts_any_thread)
436            exit_event = m5.simulate()
437        else:
438            print "Switch at curTick count:%s" % str(10000)
439            exit_event = m5.simulate(10000)
440        print "Switched CPUS @ tick %s" % (m5.curTick())
441
442        m5.switchCpus(testsys, switch_cpu_list)
443
444        if options.standard_switch:
445            print "Switch at instruction count:%d" % \
446                    (testsys.switch_cpus[0].max_insts_any_thread)
447
448            #warmup instruction count may have already been set
449            if options.warmup_insts:
450                exit_event = m5.simulate()
451            else:
452                exit_event = m5.simulate(options.standard_switch)
453            print "Switching CPUS @ tick %s" % (m5.curTick())
454            print "Simulation ends instruction count:%d" % \
455                    (testsys.switch_cpus_1[0].max_insts_any_thread)
456            m5.switchCpus(testsys, switch_cpu_list1)
457
458    # If we're taking and restoring checkpoints, use checkpoint_dir
459    # option only for finding the checkpoints to restore from.  This
460    # lets us test checkpointing by restoring from one set of
461    # checkpoints, generating a second set, and then comparing them.
462    if options.take_checkpoints and options.checkpoint_restore:
463        if m5.options.outdir:
464            cptdir = m5.options.outdir
465        else:
466            cptdir = getcwd()
467
468    if options.take_checkpoints != None :
469        # Checkpoints being taken via the command line at <when> and at
470        # subsequent periods of <period>.  Checkpoint instructions
471        # received from the benchmark running are ignored and skipped in
472        # favor of command line checkpoint instructions.
473        exit_event = scriptCheckpoints(options, maxtick, cptdir)
474    else:
475        if options.fast_forward:
476            m5.stats.reset()
477        print "**** REAL SIMULATION ****"
478
479        # If checkpoints are being taken, then the checkpoint instruction
480        # will occur in the benchmark code it self.
481        if options.repeat_switch and maxtick > options.repeat_switch:
482            exit_event = repeatSwitch(testsys, repeat_switch_cpu_list,
483                                      maxtick, options.repeat_switch)
484        else:
485            exit_event = benchCheckpoints(options, maxtick, cptdir)
486
487    print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_event.getCause())
488    if options.checkpoint_at_end:
489        m5.checkpoint(joinpath(cptdir, "cpt.%d"))
490
491    if not m5.options.interactive:
492        sys.exit(exit_event.getCode())
493