X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=configs%2Fcommon%2FSimulation.py;h=e53c755c6c09e1e5528158eaa29966641cd1a8bc;hb=e53de444f665fcb406c75648674ddc4224127515;hp=f6273a6f06ce8c8dae1b1a89bb5b11ba319631a2;hpb=7e25052feebcc69592e8d40aa085e386ad23b173;p=gem5.git diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py index f6273a6f0..e53c755c6 100644 --- a/configs/common/Simulation.py +++ b/configs/common/Simulation.py @@ -1,3 +1,15 @@ +# Copyright (c) 2012-2013 ARM Limited +# All rights reserved +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# # Copyright (c) 2006-2008 The Regents of The University of Michigan # Copyright (c) 2010 Advanced Micro Devices, Inc. # All rights reserved. @@ -24,34 +36,32 @@ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Authors: Lisa Hsu +from __future__ import print_function +from __future__ import absolute_import + +import six +import sys from os import getcwd from os.path import join as joinpath +from common import CpuConfig +from common import ObjectList + import m5 from m5.defines import buildEnv from m5.objects import * from m5.util import * -from O3_ARM_v7a import * + +if six.PY3: + long = int addToPath('../common') def getCPUClass(cpu_type): - """Returns the required cpu class and the mode of operation. - """ - - if cpu_type == "timing": - return TimingSimpleCPU, 'timing' - elif cpu_type == "detailed": - return DerivO3CPU, 'timing' - elif cpu_type == "arm_detailed": - return O3_ARM_v7a_3, 'timing' - elif cpu_type == "inorder": - return InOrderCPU, 'timing' - else: - return AtomicSimpleCPU, 'atomic' + """Returns the required cpu class and the mode of operation.""" + cls = ObjectList.cpu_list.get(cpu_type) + return cls, cls.memory_mode() def setCPUClass(options): """Returns two cpu classes and the initial mode of operation. @@ -63,14 +73,11 @@ def setCPUClass(options): depending on the options provided. """ - if options.cpu_type == "detailed" or \ - options.cpu_type == "arm_detailed" or \ - options.cpu_type == "inorder" : - if not options.caches and not options.ruby: - fatal("O3/Inorder CPU must be used with caches") - TmpClass, test_mem_mode = getCPUClass(options.cpu_type) CPUClass = None + if TmpClass.require_caches() and \ + not options.caches and not options.ruby: + fatal("%s must be used with caches" % options.cpu_type) if options.checkpoint_restore != None: if options.restore_with_cpu != options.cpu_type: @@ -81,11 +88,23 @@ def setCPUClass(options): TmpClass = AtomicSimpleCPU test_mem_mode = 'atomic' + # Ruby only supports atomic accesses in noncaching mode + if test_mem_mode == 'atomic' and options.ruby: + warn("Memory mode will be changed to atomic_noncaching") + test_mem_mode = 'atomic_noncaching' + return (TmpClass, test_mem_mode, CPUClass) +def setMemClass(options): + """Returns a memory controller class.""" + + return ObjectList.mem_list.get(options.mem_type) + def setWorkCountOptions(system, options): if options.work_item_id != None: system.work_item_id = options.work_item_id + if options.num_work_ids != None: + system.num_work_ids = options.num_work_ids if options.work_begin_cpu_id_exit != None: system.work_begin_cpu_id_exit = options.work_begin_cpu_id_exit if options.work_end_exit_count != None: @@ -99,7 +118,7 @@ def setWorkCountOptions(system, options): if options.work_cpus_checkpoint_count != None: system.work_cpus_ckpt_count = options.work_cpus_checkpoint_count -def findCptDir(options, maxtick, cptdir, testsys): +def findCptDir(options, cptdir, testsys): """Figures out the directory from which the checkpointed state is read. There are two different ways in which the directories holding checkpoints @@ -110,9 +129,6 @@ def findCptDir(options, maxtick, cptdir, testsys): This function parses through the options to figure out which one of the above should be used for selecting the checkpoint, and then figures out the appropriate directory. - - It also sets the value of the maximum tick value till which the simulation - will run. """ from os.path import isdir, exists @@ -122,6 +138,7 @@ def findCptDir(options, maxtick, cptdir, testsys): if not isdir(cptdir): fatal("checkpoint dir %s does not exist!", cptdir) + cpt_starttick = 0 if options.at_instruction or options.simpoint: inst = options.checkpoint_restore if options.simpoint: @@ -133,9 +150,46 @@ def findCptDir(options, maxtick, cptdir, testsys): checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % (options.bench, inst)) if not exists(checkpoint_dir): fatal("Unable to find checkpoint directory %s", checkpoint_dir) + + elif options.restore_simpoint_checkpoint: + # Restore from SimPoint checkpoints + # Assumes that the checkpoint dir names are formatted as follows: + dirs = listdir(cptdir) + expr = re.compile('cpt\.simpoint_(\d+)_inst_(\d+)' + + '_weight_([\d\.e\-]+)_interval_(\d+)_warmup_(\d+)') + cpts = [] + for dir in dirs: + match = expr.match(dir) + if match: + cpts.append(dir) + cpts.sort() + + cpt_num = options.checkpoint_restore + if cpt_num > len(cpts): + fatal('Checkpoint %d not found', cpt_num) + checkpoint_dir = joinpath(cptdir, cpts[cpt_num - 1]) + match = expr.match(cpts[cpt_num - 1]) + if match: + index = int(match.group(1)) + start_inst = int(match.group(2)) + weight_inst = float(match.group(3)) + interval_length = int(match.group(4)) + warmup_length = int(match.group(5)) + print("Resuming from", checkpoint_dir) + simpoint_start_insts = [] + simpoint_start_insts.append(warmup_length) + simpoint_start_insts.append(warmup_length + interval_length) + testsys.cpu[0].simpoint_start_insts = simpoint_start_insts + if testsys.switch_cpus != None: + testsys.switch_cpus[0].simpoint_start_insts = simpoint_start_insts + + print("Resuming from SimPoint", end=' ') + print("#%d, start_inst:%d, weight:%f, interval:%d, warmup:%d" % + (index, start_inst, weight_inst, interval_length, warmup_length)) + else: dirs = listdir(cptdir) - expr = re.compile('cpt\.([0-9]*)') + expr = re.compile('cpt\.([0-9]+)') cpts = [] for dir in dirs: match = expr.match(dir) @@ -148,10 +202,10 @@ def findCptDir(options, maxtick, cptdir, testsys): if cpt_num > len(cpts): fatal('Checkpoint %d not found', cpt_num) - maxtick = maxtick - int(cpts[cpt_num - 1]) + cpt_starttick = int(cpts[cpt_num - 1]) checkpoint_dir = joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1]) - return maxtick, checkpoint_dir + return cpt_starttick, checkpoint_dir def scriptCheckpoints(options, maxtick, cptdir): if options.at_instruction or options.simpoint: @@ -161,10 +215,10 @@ def scriptCheckpoints(options, maxtick, cptdir): if options.checkpoint_restore != None: checkpoint_inst += options.checkpoint_restore - print "Creating checkpoint at inst:%d" % (checkpoint_inst) + print("Creating checkpoint at inst:%d" % (checkpoint_inst)) exit_event = m5.simulate() exit_cause = exit_event.getCause() - print "exit cause = %s" % exit_cause + print("exit cause = %s" % exit_cause) # skip checkpoint instructions should they exist while exit_cause == "checkpoint": @@ -174,7 +228,7 @@ def scriptCheckpoints(options, maxtick, cptdir): if exit_cause == "a thread reached the max instruction count": m5.checkpoint(joinpath(cptdir, "cpt.%s.%d" % \ (options.bench, checkpoint_inst))) - print "Checkpoint written." + print("Checkpoint written.") else: when, period = options.take_checkpoints.split(",", 1) @@ -182,7 +236,7 @@ def scriptCheckpoints(options, maxtick, cptdir): period = int(period) num_checkpoints = 0 - exit_event = m5.simulate(when) + exit_event = m5.simulate(when - m5.curTick()) exit_cause = exit_event.getCause() while exit_cause == "checkpoint": exit_event = m5.simulate(when - m5.curTick()) @@ -211,10 +265,10 @@ def scriptCheckpoints(options, maxtick, cptdir): m5.checkpoint(joinpath(cptdir, "cpt.%d")) num_checkpoints += 1 - return exit_cause + return exit_event def benchCheckpoints(options, maxtick, cptdir): - exit_event = m5.simulate(maxtick) + exit_event = m5.simulate(maxtick - m5.curTick()) exit_cause = exit_event.getCause() num_checkpoints = 0 @@ -230,21 +284,143 @@ def benchCheckpoints(options, maxtick, cptdir): exit_event = m5.simulate(maxtick - m5.curTick()) exit_cause = exit_event.getCause() - return exit_cause + return exit_event + +# Set up environment for taking SimPoint checkpoints +# Expecting SimPoint files generated by SimPoint 3.2 +def parseSimpointAnalysisFile(options, testsys): + import re + + simpoint_filename, weight_filename, interval_length, warmup_length = \ + options.take_simpoint_checkpoints.split(",", 3) + print("simpoint analysis file:", simpoint_filename) + print("simpoint weight file:", weight_filename) + print("interval length:", interval_length) + print("warmup length:", warmup_length) + + interval_length = int(interval_length) + warmup_length = int(warmup_length) + + # Simpoint analysis output starts interval counts with 0. + simpoints = [] + simpoint_start_insts = [] + + # Read in SimPoint analysis files + simpoint_file = open(simpoint_filename) + weight_file = open(weight_filename) + while True: + line = simpoint_file.readline() + if not line: + break + m = re.match("(\d+)\s+(\d+)", line) + if m: + interval = int(m.group(1)) + else: + fatal('unrecognized line in simpoint file!') + + line = weight_file.readline() + if not line: + fatal('not enough lines in simpoint weight file!') + m = re.match("([0-9\.e\-]+)\s+(\d+)", line) + if m: + weight = float(m.group(1)) + else: + fatal('unrecognized line in simpoint weight file!') + + if (interval * interval_length - warmup_length > 0): + starting_inst_count = \ + interval * interval_length - warmup_length + actual_warmup_length = warmup_length + else: + # Not enough room for proper warmup + # Just starting from the beginning + starting_inst_count = 0 + actual_warmup_length = interval * interval_length + + simpoints.append((interval, weight, starting_inst_count, + actual_warmup_length)) + + # Sort SimPoints by starting inst count + simpoints.sort(key=lambda obj: obj[2]) + for s in simpoints: + interval, weight, starting_inst_count, actual_warmup_length = s + print(str(interval), str(weight), starting_inst_count, + actual_warmup_length) + simpoint_start_insts.append(starting_inst_count) + + print("Total # of simpoints:", len(simpoints)) + testsys.cpu[0].simpoint_start_insts = simpoint_start_insts + + return (simpoints, interval_length) + +def takeSimpointCheckpoints(simpoints, interval_length, cptdir): + num_checkpoints = 0 + index = 0 + last_chkpnt_inst_count = -1 + for simpoint in simpoints: + interval, weight, starting_inst_count, actual_warmup_length = simpoint + if starting_inst_count == last_chkpnt_inst_count: + # checkpoint starting point same as last time + # (when warmup period longer than starting point) + exit_cause = "simpoint starting point found" + code = 0 + else: + exit_event = m5.simulate() + + # skip checkpoint instructions should they exist + while exit_event.getCause() == "checkpoint": + print("Found 'checkpoint' exit event...ignoring...") + exit_event = m5.simulate() + + exit_cause = exit_event.getCause() + code = exit_event.getCode() + + if exit_cause == "simpoint starting point found": + m5.checkpoint(joinpath(cptdir, + "cpt.simpoint_%02d_inst_%d_weight_%f_interval_%d_warmup_%d" + % (index, starting_inst_count, weight, interval_length, + actual_warmup_length))) + print("Checkpoint #%d written. start inst:%d weight:%f" % + (num_checkpoints, starting_inst_count, weight)) + num_checkpoints += 1 + last_chkpnt_inst_count = starting_inst_count + else: + break + index += 1 + + print('Exiting @ tick %i because %s' % (m5.curTick(), exit_cause)) + print("%d checkpoints taken" % num_checkpoints) + sys.exit(code) + +def restoreSimpointCheckpoint(): + exit_event = m5.simulate() + exit_cause = exit_event.getCause() + + if exit_cause == "simpoint starting point found": + print("Warmed up! Dumping and resetting stats!") + m5.stats.dump() + m5.stats.reset() + + exit_event = m5.simulate() + exit_cause = exit_event.getCause() + + if exit_cause == "simpoint starting point found": + print("Done running SimPoint!") + sys.exit(exit_event.getCode()) + + print('Exiting @ tick %i because %s' % (m5.curTick(), exit_cause)) + sys.exit(exit_event.getCode()) def repeatSwitch(testsys, repeat_switch_cpu_list, maxtick, switch_freq): - print "starting switch loop" + print("starting switch loop") while True: exit_event = m5.simulate(switch_freq) exit_cause = exit_event.getCause() if exit_cause != "simulate() limit reached": - return exit_cause + return exit_event - print "draining the system" - m5.doDrain(testsys) - m5.switchCpus(repeat_switch_cpu_list) - m5.resume(testsys) + m5.switchCpus(testsys, repeat_switch_cpu_list) tmp_cpu_list = [] for old_cpu, new_cpu in repeat_switch_cpu_list: @@ -253,18 +429,9 @@ def repeatSwitch(testsys, repeat_switch_cpu_list, maxtick, switch_freq): if (maxtick - m5.curTick()) <= switch_freq: exit_event = m5.simulate(maxtick - m5.curTick()) - return exit_event.getCause() + return exit_event def run(options, root, testsys, cpu_class): - if options.maxtick: - maxtick = options.maxtick - elif options.maxtime: - simtime = m5.ticks.seconds(simtime) - print "simulating for: ", simtime - maxtick = simtime - else: - maxtick = m5.MaxTick - if options.checkpoint_dir: cptdir = options.checkpoint_dir elif m5.options.outdir: @@ -288,62 +455,67 @@ def run(options, root, testsys, cpu_class): switch_cpus = None if options.prog_interval: - for i in xrange(np): + for i in range(np): testsys.cpu[i].progress_interval = options.prog_interval if options.maxinsts: - for i in xrange(np): + for i in range(np): testsys.cpu[i].max_insts_any_thread = options.maxinsts if cpu_class: - switch_cpus = [cpu_class(defer_registration=True, cpu_id=(i)) - for i in xrange(np)] + switch_cpus = [cpu_class(switched_out=True, cpu_id=(i)) + for i in range(np)] - for i in xrange(np): + for i in range(np): if options.fast_forward: testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) - switch_cpus[i].system = testsys + switch_cpus[i].system = testsys switch_cpus[i].workload = testsys.cpu[i].workload - switch_cpus[i].clock = testsys.cpu[i].clock + switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain + switch_cpus[i].progress_interval = \ + testsys.cpu[i].progress_interval + switch_cpus[i].isa = testsys.cpu[i].isa # simulation period if options.maxinsts: switch_cpus[i].max_insts_any_thread = options.maxinsts # Add checker cpu if selected if options.checker: switch_cpus[i].addCheckerCpu() + if options.bp_type: + bpClass = ObjectList.bp_list.get(options.bp_type) + switch_cpus[i].branchPred = bpClass() + if options.indirect_bp_type: + IndirectBPClass = ObjectList.indirect_bp_list.get( + options.indirect_bp_type) + switch_cpus[i].branchPred.indirectBranchPred = \ + IndirectBPClass() + + # If elastic tracing is enabled attach the elastic trace probe + # to the switch CPUs + if options.elastic_trace_en: + CpuConfig.config_etrace(cpu_class, switch_cpus, options) testsys.switch_cpus = switch_cpus - switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] + switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in range(np)] if options.repeat_switch: - if options.cpu_type == "arm_detailed": - if not options.caches: - print "O3 CPU must be used with caches" - sys.exit(1) - - repeat_switch_cpus = [O3_ARM_v7a_3(defer_registration=True, \ - cpu_id=(i)) for i in xrange(np)] - elif options.cpu_type == "detailed": - if not options.caches: - print "O3 CPU must be used with caches" - sys.exit(1) - - repeat_switch_cpus = [DerivO3CPU(defer_registration=True, \ - cpu_id=(i)) for i in xrange(np)] - elif options.cpu_type == "inorder": - print "inorder CPU switching not supported" + switch_class = getCPUClass(options.cpu_type)[0] + if switch_class.require_caches() and \ + not options.caches: + print("%s: Must be used with caches" % str(switch_class)) sys.exit(1) - elif options.cpu_type == "timing": - repeat_switch_cpus = [TimingSimpleCPU(defer_registration=True, \ - cpu_id=(i)) for i in xrange(np)] - else: - repeat_switch_cpus = [AtomicSimpleCPU(defer_registration=True, \ - cpu_id=(i)) for i in xrange(np)] + if not switch_class.support_take_over(): + print("%s: CPU switching not supported" % str(switch_class)) + sys.exit(1) + + repeat_switch_cpus = [switch_class(switched_out=True, \ + cpu_id=(i)) for i in range(np)] - for i in xrange(np): + for i in range(np): repeat_switch_cpus[i].system = testsys repeat_switch_cpus[i].workload = testsys.cpu[i].workload - repeat_switch_cpus[i].clock = testsys.cpu[i].clock + repeat_switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain + repeat_switch_cpus[i].isa = testsys.cpu[i].isa if options.maxinsts: repeat_switch_cpus[i].max_insts_any_thread = options.maxinsts @@ -355,24 +527,26 @@ def run(options, root, testsys, cpu_class): if cpu_class: repeat_switch_cpu_list = [(switch_cpus[i], repeat_switch_cpus[i]) - for i in xrange(np)] + for i in range(np)] else: repeat_switch_cpu_list = [(testsys.cpu[i], repeat_switch_cpus[i]) - for i in xrange(np)] + for i in range(np)] if options.standard_switch: - switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(i)) - for i in xrange(np)] - switch_cpus_1 = [DerivO3CPU(defer_registration=True, cpu_id=(i)) - for i in xrange(np)] + switch_cpus = [TimingSimpleCPU(switched_out=True, cpu_id=(i)) + for i in range(np)] + switch_cpus_1 = [DerivO3CPU(switched_out=True, cpu_id=(i)) + for i in range(np)] - for i in xrange(np): + for i in range(np): switch_cpus[i].system = testsys switch_cpus_1[i].system = testsys switch_cpus[i].workload = testsys.cpu[i].workload switch_cpus_1[i].workload = testsys.cpu[i].workload - switch_cpus[i].clock = testsys.cpu[i].clock - switch_cpus_1[i].clock = testsys.cpu[i].clock + switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain + switch_cpus_1[i].clk_domain = testsys.cpu[i].clk_domain + switch_cpus[i].isa = testsys.cpu[i].isa + switch_cpus_1[i].isa = testsys.cpu[i].isa # if restoring, make atomic cpu simulate only a few instructions if options.checkpoint_restore != None: @@ -405,8 +579,12 @@ def run(options, root, testsys, cpu_class): testsys.switch_cpus = switch_cpus testsys.switch_cpus_1 = switch_cpus_1 - switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] - switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)] + switch_cpu_list = [ + (testsys.cpu[i], switch_cpus[i]) for i in range(np) + ] + switch_cpu_list1 = [ + (switch_cpus[i], switch_cpus_1[i]) for i in range(np) + ] # set the checkpoint in the cpu before m5.instantiate is called if options.take_checkpoints != None and \ @@ -414,7 +592,7 @@ def run(options, root, testsys, cpu_class): offset = int(options.take_checkpoints) # Set an instruction break point if options.simpoint: - for i in xrange(np): + for i in range(np): if testsys.cpu[i].workload[0].simpoint == 0: fatal('no simpoint for testsys.cpu[%d].workload[0]', i) checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset @@ -425,59 +603,97 @@ def run(options, root, testsys, cpu_class): options.take_checkpoints = offset # Set all test cpus with the right number of instructions # for the upcoming simulation - for i in xrange(np): + for i in range(np): testsys.cpu[i].max_insts_any_thread = offset + if options.take_simpoint_checkpoints != None: + simpoints, interval_length = parseSimpointAnalysisFile(options, testsys) + checkpoint_dir = None - if options.checkpoint_restore != None: - maxtick, checkpoint_dir = findCptDir(options, maxtick, cptdir, testsys) + if options.checkpoint_restore: + cpt_starttick, checkpoint_dir = findCptDir(options, cptdir, testsys) + root.apply_config(options.param) m5.instantiate(checkpoint_dir) + # Initialization is complete. If we're not in control of simulation + # (that is, if we're a slave simulator acting as a component in another + # 'master' simulator) then we're done here. The other simulator will + # call simulate() directly. --initialize-only is used to indicate this. + if options.initialize_only: + return + + # Handle the max tick settings now that tick frequency was resolved + # during system instantiation + # NOTE: the maxtick variable here is in absolute ticks, so it must + # include any simulated ticks before a checkpoint + explicit_maxticks = 0 + maxtick_from_abs = m5.MaxTick + maxtick_from_rel = m5.MaxTick + maxtick_from_maxtime = m5.MaxTick + if options.abs_max_tick: + maxtick_from_abs = options.abs_max_tick + explicit_maxticks += 1 + if options.rel_max_tick: + maxtick_from_rel = options.rel_max_tick + if options.checkpoint_restore: + # NOTE: this may need to be updated if checkpoints ever store + # the ticks per simulated second + maxtick_from_rel += cpt_starttick + if options.at_instruction or options.simpoint: + warn("Relative max tick specified with --at-instruction or" \ + " --simpoint\n These options don't specify the " \ + "checkpoint start tick, so assuming\n you mean " \ + "absolute max tick") + explicit_maxticks += 1 + if options.maxtime: + maxtick_from_maxtime = m5.ticks.fromSeconds(options.maxtime) + explicit_maxticks += 1 + if explicit_maxticks > 1: + warn("Specified multiple of --abs-max-tick, --rel-max-tick, --maxtime."\ + " Using least") + maxtick = min([maxtick_from_abs, maxtick_from_rel, maxtick_from_maxtime]) + + if options.checkpoint_restore != None and maxtick < cpt_starttick: + fatal("Bad maxtick (%d) specified: " \ + "Checkpoint starts starts from tick: %d", maxtick, cpt_starttick) + if options.standard_switch or cpu_class: if options.standard_switch: - print "Switch at instruction count:%s" % \ - str(testsys.cpu[0].max_insts_any_thread) + print("Switch at instruction count:%s" % + str(testsys.cpu[0].max_insts_any_thread)) exit_event = m5.simulate() elif cpu_class and options.fast_forward: - print "Switch at instruction count:%s" % \ - str(testsys.cpu[0].max_insts_any_thread) + print("Switch at instruction count:%s" % + str(testsys.cpu[0].max_insts_any_thread)) exit_event = m5.simulate() else: - print "Switch at curTick count:%s" % str(10000) + print("Switch at curTick count:%s" % str(10000)) exit_event = m5.simulate(10000) - print "Switched CPUS @ tick %s" % (m5.curTick()) + print("Switched CPUS @ tick %s" % (m5.curTick())) - # when you change to Timing (or Atomic), you halt the system - # given as argument. When you are finished with the system - # changes (including switchCpus), you must resume the system - # manually. You DON'T need to resume after just switching - # CPUs if you haven't changed anything on the system level. - - m5.changeToTiming(testsys) - m5.switchCpus(switch_cpu_list) - m5.resume(testsys) + m5.switchCpus(testsys, switch_cpu_list) if options.standard_switch: - print "Switch at instruction count:%d" % \ - (testsys.switch_cpus[0].max_insts_any_thread) + print("Switch at instruction count:%d" % + (testsys.switch_cpus[0].max_insts_any_thread)) #warmup instruction count may have already been set if options.warmup_insts: exit_event = m5.simulate() else: exit_event = m5.simulate(options.standard_switch) - print "Switching CPUS @ tick %s" % (m5.curTick()) - print "Simulation ends instruction count:%d" % \ - (testsys.switch_cpus_1[0].max_insts_any_thread) - m5.doDrain(testsys) - m5.switchCpus(switch_cpu_list1) - m5.resume(testsys) + print("Switching CPUS @ tick %s" % (m5.curTick())) + print("Simulation ends instruction count:%d" % + (testsys.switch_cpus_1[0].max_insts_any_thread)) + m5.switchCpus(testsys, switch_cpu_list1) # If we're taking and restoring checkpoints, use checkpoint_dir # option only for finding the checkpoints to restore from. This # lets us test checkpointing by restoring from one set of # checkpoints, generating a second set, and then comparing them. - if options.take_checkpoints and options.checkpoint_restore: + if (options.take_checkpoints or options.take_simpoint_checkpoints) \ + and options.checkpoint_restore: + if m5.options.outdir: cptdir = m5.options.outdir else: @@ -488,20 +704,33 @@ def run(options, root, testsys, cpu_class): # subsequent periods of . Checkpoint instructions # received from the benchmark running are ignored and skipped in # favor of command line checkpoint instructions. - exit_cause = scriptCheckpoints(options, maxtick, cptdir) + exit_event = scriptCheckpoints(options, maxtick, cptdir) + + # Take SimPoint checkpoints + elif options.take_simpoint_checkpoints != None: + takeSimpointCheckpoints(simpoints, interval_length, cptdir) + + # Restore from SimPoint checkpoints + elif options.restore_simpoint_checkpoint != None: + restoreSimpointCheckpoint() + else: if options.fast_forward: m5.stats.reset() - print "**** REAL SIMULATION ****" + print("**** REAL SIMULATION ****") # If checkpoints are being taken, then the checkpoint instruction # will occur in the benchmark code it self. if options.repeat_switch and maxtick > options.repeat_switch: - exit_cause = repeatSwitch(testsys, repeat_switch_cpu_list, + exit_event = repeatSwitch(testsys, repeat_switch_cpu_list, maxtick, options.repeat_switch) else: - exit_cause = benchCheckpoints(options, maxtick, cptdir) + exit_event = benchCheckpoints(options, maxtick, cptdir) - print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_cause) + print('Exiting @ tick %i because %s' % + (m5.curTick(), exit_event.getCause())) if options.checkpoint_at_end: m5.checkpoint(joinpath(cptdir, "cpt.%d")) + + if exit_event.getCode() != 0: + print("Simulated exit code not 0! Exit code is", exit_event.getCode())