Simulation.py revision 5211:f7412cfae319
16019Shines@cs.fsu.edu# Copyright (c) 2006-2007 The Regents of The University of Michigan
26019Shines@cs.fsu.edu# All rights reserved.
313120SEdmund.Grimley-Evans@arm.com#
47178Sgblack@eecs.umich.edu# Redistribution and use in source and binary forms, with or without
57178Sgblack@eecs.umich.edu# modification, are permitted provided that the following conditions are
67178Sgblack@eecs.umich.edu# met: redistributions of source code must retain the above copyright
77178Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer;
87178Sgblack@eecs.umich.edu# redistributions in binary form must reproduce the above copyright
97178Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the
107178Sgblack@eecs.umich.edu# documentation and/or other materials provided with the distribution;
117178Sgblack@eecs.umich.edu# neither the name of the copyright holders nor the names of its
127178Sgblack@eecs.umich.edu# contributors may be used to endorse or promote products derived from
137178Sgblack@eecs.umich.edu# this software without specific prior written permission.
147178Sgblack@eecs.umich.edu#
156019Shines@cs.fsu.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
166019Shines@cs.fsu.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
176019Shines@cs.fsu.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
186019Shines@cs.fsu.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
196019Shines@cs.fsu.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
206019Shines@cs.fsu.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
216019Shines@cs.fsu.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
226019Shines@cs.fsu.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
236019Shines@cs.fsu.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
246019Shines@cs.fsu.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
256019Shines@cs.fsu.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
266019Shines@cs.fsu.edu#
276019Shines@cs.fsu.edu# Authors: Lisa Hsu
286019Shines@cs.fsu.edu
296019Shines@cs.fsu.edufrom os import getcwd
306019Shines@cs.fsu.edufrom os.path import join as joinpath
316019Shines@cs.fsu.eduimport m5
326019Shines@cs.fsu.edufrom m5.objects import *
336019Shines@cs.fsu.edum5.AddToPath('../common')
346019Shines@cs.fsu.edufrom Caches import L1Cache
356019Shines@cs.fsu.edu
366019Shines@cs.fsu.edudef setCPUClass(options):
376019Shines@cs.fsu.edu
386019Shines@cs.fsu.edu    atomic = False
396019Shines@cs.fsu.edu    if options.timing:
406019Shines@cs.fsu.edu        TmpClass = TimingSimpleCPU
416019Shines@cs.fsu.edu    elif options.detailed:
426019Shines@cs.fsu.edu        if not options.caches:
436019Shines@cs.fsu.edu            print "O3 CPU must be used with caches"
446019Shines@cs.fsu.edu            sys.exit(1)
456019Shines@cs.fsu.edu        TmpClass = DerivO3CPU
466019Shines@cs.fsu.edu    else:
476019Shines@cs.fsu.edu        TmpClass = AtomicSimpleCPU
487639Sgblack@eecs.umich.edu        atomic = True
497639Sgblack@eecs.umich.edu
507639Sgblack@eecs.umich.edu    CPUClass = None
517639Sgblack@eecs.umich.edu    test_mem_mode = 'atomic'
527639Sgblack@eecs.umich.edu
537639Sgblack@eecs.umich.edu    if not atomic:
547639Sgblack@eecs.umich.edu        if options.checkpoint_restore:
557639Sgblack@eecs.umich.edu            CPUClass = TmpClass
567639Sgblack@eecs.umich.edu            TmpClass = AtomicSimpleCPU
577639Sgblack@eecs.umich.edu        else:
587639Sgblack@eecs.umich.edu            test_mem_mode = 'timing'
597639Sgblack@eecs.umich.edu
607639Sgblack@eecs.umich.edu    return (TmpClass, test_mem_mode, CPUClass)
617639Sgblack@eecs.umich.edu
627639Sgblack@eecs.umich.edu
637639Sgblack@eecs.umich.edudef run(options, root, testsys, cpu_class):
647639Sgblack@eecs.umich.edu    if options.maxtick:
657639Sgblack@eecs.umich.edu        maxtick = options.maxtick
667639Sgblack@eecs.umich.edu    elif options.maxtime:
677639Sgblack@eecs.umich.edu        simtime = m5.ticks.seconds(simtime)
687639Sgblack@eecs.umich.edu        print "simulating for: ", simtime
697639Sgblack@eecs.umich.edu        maxtick = simtime
707639Sgblack@eecs.umich.edu    else:
717639Sgblack@eecs.umich.edu        maxtick = m5.MaxTick
727639Sgblack@eecs.umich.edu
737639Sgblack@eecs.umich.edu    if options.checkpoint_dir:
747639Sgblack@eecs.umich.edu        cptdir = options.checkpoint_dir
757639Sgblack@eecs.umich.edu    elif m5.options.outdir:
767639Sgblack@eecs.umich.edu        cptdir = m5.options.outdir
777639Sgblack@eecs.umich.edu    else:
787639Sgblack@eecs.umich.edu        cptdir = getcwd()
797639Sgblack@eecs.umich.edu
807639Sgblack@eecs.umich.edu    np = options.num_cpus
817639Sgblack@eecs.umich.edu    max_checkpoints = options.max_checkpoints
827639Sgblack@eecs.umich.edu    switch_cpus = None
837639Sgblack@eecs.umich.edu
847639Sgblack@eecs.umich.edu    if cpu_class:
857639Sgblack@eecs.umich.edu        switch_cpus = [cpu_class(defer_registration=True, cpu_id=(np+i))
867639Sgblack@eecs.umich.edu                       for i in xrange(np)]
877639Sgblack@eecs.umich.edu
887639Sgblack@eecs.umich.edu        for i in xrange(np):
897639Sgblack@eecs.umich.edu            switch_cpus[i].system =  testsys
907639Sgblack@eecs.umich.edu            if not m5.build_env['FULL_SYSTEM']:
917639Sgblack@eecs.umich.edu                switch_cpus[i].workload = testsys.cpu[i].workload
927639Sgblack@eecs.umich.edu            switch_cpus[i].clock = testsys.cpu[0].clock
937639Sgblack@eecs.umich.edu
947356Sgblack@eecs.umich.edu        root.switch_cpus = switch_cpus
957356Sgblack@eecs.umich.edu        switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
967356Sgblack@eecs.umich.edu
977435Sgblack@eecs.umich.edu    if options.standard_switch:
987435Sgblack@eecs.umich.edu        switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(np+i))
997435Sgblack@eecs.umich.edu                       for i in xrange(np)]
1007435Sgblack@eecs.umich.edu        switch_cpus_1 = [DerivO3CPU(defer_registration=True, cpu_id=(2*np+i))
1017435Sgblack@eecs.umich.edu                        for i in xrange(np)]
1027435Sgblack@eecs.umich.edu
1037435Sgblack@eecs.umich.edu        for i in xrange(np):
1047435Sgblack@eecs.umich.edu            switch_cpus[i].system =  testsys
1057435Sgblack@eecs.umich.edu            switch_cpus_1[i].system =  testsys
1067435Sgblack@eecs.umich.edu            if not m5.build_env['FULL_SYSTEM']:
1077435Sgblack@eecs.umich.edu                switch_cpus[i].workload = testsys.cpu[i].workload
1087639Sgblack@eecs.umich.edu                switch_cpus_1[i].workload = testsys.cpu[i].workload
1097639Sgblack@eecs.umich.edu            switch_cpus[i].clock = testsys.cpu[0].clock
1107639Sgblack@eecs.umich.edu            switch_cpus_1[i].clock = testsys.cpu[0].clock
1117435Sgblack@eecs.umich.edu
1127639Sgblack@eecs.umich.edu            if not options.caches:
1137639Sgblack@eecs.umich.edu                # O3 CPU must have a cache to work.
1147639Sgblack@eecs.umich.edu                switch_cpus_1[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'),
1157639Sgblack@eecs.umich.edu                                                         L1Cache(size = '64kB'))
1167639Sgblack@eecs.umich.edu                switch_cpus_1[i].connectMemPorts(testsys.membus)
1177639Sgblack@eecs.umich.edu
1187639Sgblack@eecs.umich.edu
1197639Sgblack@eecs.umich.edu            testsys.switch_cpus = switch_cpus
1207639Sgblack@eecs.umich.edu            testsys.switch_cpus_1 = switch_cpus_1
1217639Sgblack@eecs.umich.edu            switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
1227639Sgblack@eecs.umich.edu            switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)]
1237639Sgblack@eecs.umich.edu
1247639Sgblack@eecs.umich.edu    m5.instantiate(root)
1257639Sgblack@eecs.umich.edu
1267639Sgblack@eecs.umich.edu    if options.checkpoint_restore:
1277639Sgblack@eecs.umich.edu        from os.path import isdir
1287639Sgblack@eecs.umich.edu        from os import listdir
1297639Sgblack@eecs.umich.edu        import re
1307639Sgblack@eecs.umich.edu
1317639Sgblack@eecs.umich.edu        if not isdir(cptdir):
1327639Sgblack@eecs.umich.edu            m5.panic("checkpoint dir %s does not exist!" % cptdir)
13312595Ssiddhesh.poyarekar@gmail.com
1347639Sgblack@eecs.umich.edu        dirs = listdir(cptdir)
1357639Sgblack@eecs.umich.edu        expr = re.compile('cpt\.([0-9]*)')
1367639Sgblack@eecs.umich.edu        cpts = []
1377639Sgblack@eecs.umich.edu        for dir in dirs:
1387639Sgblack@eecs.umich.edu            match = expr.match(dir)
1397639Sgblack@eecs.umich.edu            if match:
1407639Sgblack@eecs.umich.edu                cpts.append(match.group(1))
1417639Sgblack@eecs.umich.edu
1427639Sgblack@eecs.umich.edu        cpts.sort(lambda a,b: cmp(long(a), long(b)))
1437639Sgblack@eecs.umich.edu
1447639Sgblack@eecs.umich.edu        cpt_num = options.checkpoint_restore
1457639Sgblack@eecs.umich.edu
1468144SAli.Saidi@ARM.com        if cpt_num > len(cpts):
1477639Sgblack@eecs.umich.edu            m5.panic('Checkpoint %d not found' % cpt_num)
1487639Sgblack@eecs.umich.edu
1497639Sgblack@eecs.umich.edu        ## Adjust max tick based on our starting tick
1507639Sgblack@eecs.umich.edu        maxtick = maxtick - int(cpts[cpt_num - 1])
1517639Sgblack@eecs.umich.edu
1527639Sgblack@eecs.umich.edu        ## Restore the checkpoint
1537639Sgblack@eecs.umich.edu        m5.restoreCheckpoint(root,
15410037SARM gem5 Developers                             joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1]))
1557639Sgblack@eecs.umich.edu
1567639Sgblack@eecs.umich.edu    if options.standard_switch or cpu_class:
1577639Sgblack@eecs.umich.edu        exit_event = m5.simulate(10000)
1587639Sgblack@eecs.umich.edu
1597639Sgblack@eecs.umich.edu        ## when you change to Timing (or Atomic), you halt the system given
1607639Sgblack@eecs.umich.edu        ## as argument.  When you are finished with the system changes
1617639Sgblack@eecs.umich.edu        ## (including switchCpus), you must resume the system manually.
1627639Sgblack@eecs.umich.edu        ## You DON'T need to resume after just switching CPUs if you haven't
1637639Sgblack@eecs.umich.edu        ## changed anything on the system level.
1647639Sgblack@eecs.umich.edu
1657639Sgblack@eecs.umich.edu        m5.changeToTiming(testsys)
16610037SARM gem5 Developers        m5.switchCpus(switch_cpu_list)
1677639Sgblack@eecs.umich.edu        m5.resume(testsys)
1687639Sgblack@eecs.umich.edu
1697639Sgblack@eecs.umich.edu        if options.standard_switch:
1707639Sgblack@eecs.umich.edu            exit_event = m5.simulate(options.warmup)
1717639Sgblack@eecs.umich.edu            m5.drain(testsys)
1727639Sgblack@eecs.umich.edu            m5.switchCpus(switch_cpu_list1)
1737639Sgblack@eecs.umich.edu            m5.resume(testsys)
1747639Sgblack@eecs.umich.edu
17510037SARM gem5 Developers    num_checkpoints = 0
1767639Sgblack@eecs.umich.edu    exit_cause = ''
1777639Sgblack@eecs.umich.edu
17810037SARM gem5 Developers    ## Checkpoints being taken via the command line at <when> and at subsequent
1797639Sgblack@eecs.umich.edu    ## periods of <period>.  Checkpoint instructions received from the benchmark running
1807639Sgblack@eecs.umich.edu    ## are ignored and skipped in favor of command line checkpoint instructions.
18110037SARM gem5 Developers    if options.take_checkpoints:
1827591SAli.Saidi@ARM.com        [when, period] = options.take_checkpoints.split(",", 1)
1837639Sgblack@eecs.umich.edu        when = int(when)
1847435Sgblack@eecs.umich.edu        period = int(period)
1857435Sgblack@eecs.umich.edu
1867639Sgblack@eecs.umich.edu        exit_event = m5.simulate(when)
18710037SARM gem5 Developers        while exit_event.getCause() == "checkpoint":
1887639Sgblack@eecs.umich.edu            exit_event = m5.simulate(when - m5.curTick())
1897639Sgblack@eecs.umich.edu
1907639Sgblack@eecs.umich.edu        if exit_event.getCause() == "simulate() limit reached":
1917639Sgblack@eecs.umich.edu            m5.checkpoint(root, joinpath(cptdir, "cpt.%d"))
1927639Sgblack@eecs.umich.edu            num_checkpoints += 1
1937639Sgblack@eecs.umich.edu
1947639Sgblack@eecs.umich.edu        sim_ticks = when
1957639Sgblack@eecs.umich.edu        exit_cause = "maximum %d checkpoints dropped" % max_checkpoints
1967639Sgblack@eecs.umich.edu        while num_checkpoints < max_checkpoints and \
1977639Sgblack@eecs.umich.edu                exit_event.getCause() == "simulate() limit reached":
1987639Sgblack@eecs.umich.edu            if (sim_ticks + period) > maxtick:
1997639Sgblack@eecs.umich.edu                exit_event = m5.simulate(maxtick - sim_ticks)
2007639Sgblack@eecs.umich.edu                exit_cause = exit_event.getCause()
2017639Sgblack@eecs.umich.edu                break
2027639Sgblack@eecs.umich.edu            else:
2037639Sgblack@eecs.umich.edu                exit_event = m5.simulate(period)
2047639Sgblack@eecs.umich.edu                sim_ticks += period
2057639Sgblack@eecs.umich.edu                while exit_event.getCause() == "checkpoint":
2067639Sgblack@eecs.umich.edu                    exit_event = m5.simulate(sim_ticks - m5.curTick())
2077639Sgblack@eecs.umich.edu                if exit_event.getCause() == "simulate() limit reached":
2087639Sgblack@eecs.umich.edu                    m5.checkpoint(root, joinpath(cptdir, "cpt.%d"))
2097639Sgblack@eecs.umich.edu                    num_checkpoints += 1
2107639Sgblack@eecs.umich.edu
2117639Sgblack@eecs.umich.edu        if exit_event.getCause() != "simulate() limit reached":
2127639Sgblack@eecs.umich.edu            exit_cause = exit_event.getCause();
2137639Sgblack@eecs.umich.edu
2147639Sgblack@eecs.umich.edu
2157639Sgblack@eecs.umich.edu    else: #no checkpoints being taken via this script
2167639Sgblack@eecs.umich.edu        exit_event = m5.simulate(maxtick)
2177639Sgblack@eecs.umich.edu
2187639Sgblack@eecs.umich.edu        while exit_event.getCause() == "checkpoint":
2197639Sgblack@eecs.umich.edu            m5.checkpoint(root, joinpath(cptdir, "cpt.%d"))
22010037SARM gem5 Developers            num_checkpoints += 1
2217591SAli.Saidi@ARM.com            if num_checkpoints == max_checkpoints:
2227591SAli.Saidi@ARM.com                exit_cause =  "maximum %d checkpoints dropped" % max_checkpoints
2237639Sgblack@eecs.umich.edu                break
2247639Sgblack@eecs.umich.edu
2257639Sgblack@eecs.umich.edu            exit_event = m5.simulate(maxtick - m5.curTick())
22610037SARM gem5 Developers            exit_cause = exit_event.getCause()
2277639Sgblack@eecs.umich.edu
2287639Sgblack@eecs.umich.edu    if exit_cause == '':
2297639Sgblack@eecs.umich.edu        exit_cause = exit_event.getCause()
2307639Sgblack@eecs.umich.edu    print 'Exiting @ cycle %i because %s' % (m5.curTick(), exit_cause)
2317639Sgblack@eecs.umich.edu
2327639Sgblack@eecs.umich.edu