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