Simulation.py revision 3509:ff94a3eda992
14403Srdreslin@umich.edu# Copyright (c) 2006 The Regents of The University of Michigan
21693Sstever@eecs.umich.edu# All rights reserved.
31693Sstever@eecs.umich.edu#
41693Sstever@eecs.umich.edu# Redistribution and use in source and binary forms, with or without
51693Sstever@eecs.umich.edu# modification, are permitted provided that the following conditions are
61693Sstever@eecs.umich.edu# met: redistributions of source code must retain the above copyright
71693Sstever@eecs.umich.edu# notice, this list of conditions and the following disclaimer;
81693Sstever@eecs.umich.edu# redistributions in binary form must reproduce the above copyright
91693Sstever@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the
101693Sstever@eecs.umich.edu# documentation and/or other materials provided with the distribution;
111693Sstever@eecs.umich.edu# neither the name of the copyright holders nor the names of its
121693Sstever@eecs.umich.edu# contributors may be used to endorse or promote products derived from
131693Sstever@eecs.umich.edu# this software without specific prior written permission.
141693Sstever@eecs.umich.edu#
151693Sstever@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
161693Sstever@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
171693Sstever@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
181693Sstever@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
191693Sstever@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
201693Sstever@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
211693Sstever@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
221693Sstever@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
231693Sstever@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
241693Sstever@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
251693Sstever@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
261693Sstever@eecs.umich.edu#
271693Sstever@eecs.umich.edu# Authors: Lisa Hsu
281693Sstever@eecs.umich.edu
293358Srdreslin@umich.edufrom os import getcwd
303358Srdreslin@umich.edufrom os.path import join as joinpath
311516SN/Aimport m5
326654Snate@binkert.orgfrom m5.objects import *
336654Snate@binkert.orgm5.AddToPath('../common')
346654Snate@binkert.orgfrom Caches import L1Cache
356654Snate@binkert.org
363358Srdreslin@umich.edudef setCPUClass(options):
373358Srdreslin@umich.edu
386654Snate@binkert.org    atomic = False
396654Snate@binkert.org    if options.timing:
401516SN/A        TmpClass = TimingSimpleCPU
413358Srdreslin@umich.edu    elif options.detailed:
423358Srdreslin@umich.edu        TmpClass = DerivO3CPU
433358Srdreslin@umich.edu    else:
443358Srdreslin@umich.edu        TmpClass = AtomicSimpleCPU
453358Srdreslin@umich.edu        atomic = True
463358Srdreslin@umich.edu
473358Srdreslin@umich.edu    CPUClass = None
483358Srdreslin@umich.edu    test_mem_mode = 'atomic'
493358Srdreslin@umich.edu
503358Srdreslin@umich.edu    if not atomic:
513358Srdreslin@umich.edu        if options.checkpoint_restore:
523358Srdreslin@umich.edu            CPUClass = TmpClass
533360Srdreslin@umich.edu            TmpClass = AtomicSimpleCPU
543358Srdreslin@umich.edu        else:
553360Srdreslin@umich.edu            test_mem_mode = 'timing'
563360Srdreslin@umich.edu
573360Srdreslin@umich.edu    return (TmpClass, test_mem_mode, CPUClass)
585255Ssaidi@eecs.umich.edu
593360Srdreslin@umich.edu
603360Srdreslin@umich.edudef run(options, root, testsys, cpu_class):
613360Srdreslin@umich.edu    if options.maxtick:
625255Ssaidi@eecs.umich.edu        maxtick = options.maxtick
633358Srdreslin@umich.edu    elif options.maxtime:
644403Srdreslin@umich.edu        simtime = int(options.maxtime * root.clock.value)
653360Srdreslin@umich.edu        print "simulating for: ", simtime
663358Srdreslin@umich.edu        maxtick = simtime
673358Srdreslin@umich.edu    else:
683358Srdreslin@umich.edu        maxtick = -1
693358Srdreslin@umich.edu
703358Srdreslin@umich.edu    if options.checkpoint_dir:
713358Srdreslin@umich.edu        cptdir = options.checkpoint_dir
723358Srdreslin@umich.edu    else:
733358Srdreslin@umich.edu        cptdir = getcwd()
743358Srdreslin@umich.edu
753360Srdreslin@umich.edu    np = options.num_cpus
763360Srdreslin@umich.edu    max_checkpoints = options.max_checkpoints
773360Srdreslin@umich.edu    switch_cpus = None
783360Srdreslin@umich.edu
793358Srdreslin@umich.edu    if cpu_class:
803358Srdreslin@umich.edu        switch_cpus = [cpu_class(defer_registration=True, cpu_id=(np+i))
813358Srdreslin@umich.edu                       for i in xrange(np)]
823358Srdreslin@umich.edu
834403Srdreslin@umich.edu        for i in xrange(np):
844403Srdreslin@umich.edu            switch_cpus[i].system =  testsys
855256Ssaidi@eecs.umich.edu            if not m5.build_env['FULL_SYSTEM']:
865255Ssaidi@eecs.umich.edu                switch_cpus[i].workload = testsys.cpu[i].workload
873358Srdreslin@umich.edu            switch_cpus[i].clock = testsys.cpu[0].clock
883358Srdreslin@umich.edu            if options.caches:
894403Srdreslin@umich.edu                switch_cpus[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'),
904403Srdreslin@umich.edu                                                       L1Cache(size = '64kB'))
915255Ssaidi@eecs.umich.edu                switch_cpus[i].connectMemPorts(testsys.membus)
923358Srdreslin@umich.edu
933358Srdreslin@umich.edu        root.switch_cpus = switch_cpus
944403Srdreslin@umich.edu        switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
955255Ssaidi@eecs.umich.edu
964403Srdreslin@umich.edu    if options.standard_switch:
973358Srdreslin@umich.edu        switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(np+i))
983358Srdreslin@umich.edu                       for i in xrange(np)]
994403Srdreslin@umich.edu        switch_cpus_1 = [DerivO3CPU(defer_registration=True, cpu_id=(2*np+i))
1005255Ssaidi@eecs.umich.edu                        for i in xrange(np)]
1014403Srdreslin@umich.edu
1023358Srdreslin@umich.edu        for i in xrange(np):
1033358Srdreslin@umich.edu            switch_cpus[i].system =  testsys
1044403Srdreslin@umich.edu            switch_cpus_1[i].system =  testsys
1055255Ssaidi@eecs.umich.edu            if not m5.build_env['FULL_SYSTEM']:
1064403Srdreslin@umich.edu                switch_cpus[i].workload = testsys.cpu[i].workload
1073358Srdreslin@umich.edu                switch_cpus_1[i].workload = testsys.cpu[i].workload
1083358Srdreslin@umich.edu            switch_cpus[i].clock = testsys.cpu[0].clock
1094403Srdreslin@umich.edu            switch_cpus_1[i].clock = testsys.cpu[0].clock
1105255Ssaidi@eecs.umich.edu
1114403Srdreslin@umich.edu            if options.caches:
1124403Srdreslin@umich.edu                switch_cpus[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'),
1133358Srdreslin@umich.edu                                                       L1Cache(size = '64kB'))
1143358Srdreslin@umich.edu                switch_cpus[i].connectMemPorts(testsys.membus)
1154403Srdreslin@umich.edu            else:
1165255Ssaidi@eecs.umich.edu                # O3 CPU must have a cache to work.
1174403Srdreslin@umich.edu                switch_cpus_1[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'),
1184403Srdreslin@umich.edu                                                         L1Cache(size = '64kB'))
1194403Srdreslin@umich.edu                switch_cpus_1[i].connectMemPorts(testsys.membus)
1203360Srdreslin@umich.edu
1214403Srdreslin@umich.edu
1223358Srdreslin@umich.edu            root.switch_cpus = switch_cpus
1233358Srdreslin@umich.edu            root.switch_cpus_1 = switch_cpus_1
1244403Srdreslin@umich.edu            switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
1255255Ssaidi@eecs.umich.edu            switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)]
1264403Srdreslin@umich.edu
1273358Srdreslin@umich.edu    m5.instantiate(root)
1283358Srdreslin@umich.edu
1294403Srdreslin@umich.edu    if options.checkpoint_restore:
1305255Ssaidi@eecs.umich.edu        from os.path import isdir
1314403Srdreslin@umich.edu        from os import listdir
1323358Srdreslin@umich.edu        import re
1333358Srdreslin@umich.edu
1344403Srdreslin@umich.edu        if not isdir(cptdir):
1355256Ssaidi@eecs.umich.edu            m5.panic("checkpoint dir %s does not exist!" % cptdir)
1365255Ssaidi@eecs.umich.edu
1374403Srdreslin@umich.edu        dirs = listdir(cptdir)
1383358Srdreslin@umich.edu        expr = re.compile('cpt.([0-9]*)')
1393358Srdreslin@umich.edu        cpts = []
1404403Srdreslin@umich.edu        for dir in dirs:
1415255Ssaidi@eecs.umich.edu            match = expr.match(dir)
1424403Srdreslin@umich.edu            if match:
1434403Srdreslin@umich.edu                cpts.append(match.group(1))
1444403Srdreslin@umich.edu
1453360Srdreslin@umich.edu        cpts.sort(lambda a,b: cmp(long(a), long(b)))
1464403Srdreslin@umich.edu
1473358Srdreslin@umich.edu        cpt_num = options.checkpoint_restore
1483358Srdreslin@umich.edu
1494403Srdreslin@umich.edu        if cpt_num > len(cpts):
1505255Ssaidi@eecs.umich.edu            m5.panic('Checkpoint %d not found' % cpt_num)
1514403Srdreslin@umich.edu
1524403Srdreslin@umich.edu        m5.restoreCheckpoint(root,
1534403Srdreslin@umich.edu                             joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1]))
1543360Srdreslin@umich.edu
1554403Srdreslin@umich.edu    if options.standard_switch or cpu_class:
1563358Srdreslin@umich.edu        exit_event = m5.simulate(10000)
1573358Srdreslin@umich.edu
1583358Srdreslin@umich.edu        ## when you change to Timing (or Atomic), you halt the system given
1593358Srdreslin@umich.edu        ## as argument.  When you are finished with the system changes
1603358Srdreslin@umich.edu        ## (including switchCpus), you must resume the system manually.
1613358Srdreslin@umich.edu        ## You DON'T need to resume after just switching CPUs if you haven't
1623358Srdreslin@umich.edu        ## changed anything on the system level.
1633358Srdreslin@umich.edu
1643358Srdreslin@umich.edu        m5.changeToTiming(testsys)
1653358Srdreslin@umich.edu        m5.switchCpus(switch_cpu_list)
1663358Srdreslin@umich.edu        m5.resume(testsys)
1673358Srdreslin@umich.edu
1683358Srdreslin@umich.edu        if options.standard_switch:
1693358Srdreslin@umich.edu            exit_event = m5.simulate(options.warmup)
1703358Srdreslin@umich.edu            m5.switchCpus(switch_cpu_list1)
1713358Srdreslin@umich.edu
1723358Srdreslin@umich.edu    num_checkpoints = 0
1733358Srdreslin@umich.edu    exit_cause = ''
1743358Srdreslin@umich.edu
1753358Srdreslin@umich.edu    ## Checkpoints being taken via the command line at <when> and at subsequent
1763358Srdreslin@umich.edu    ## periods of <period>.  Checkpoint instructions received from the benchmark running
1773358Srdreslin@umich.edu    ## are ignored and skipped in favor of command line checkpoint instructions.
1783358Srdreslin@umich.edu    if options.take_checkpoints:
1793358Srdreslin@umich.edu        [when, period] = options.take_checkpoints.split(",", 1)
1803358Srdreslin@umich.edu        when = int(when)
1813358Srdreslin@umich.edu        period = int(period)
1823358Srdreslin@umich.edu
1833358Srdreslin@umich.edu        exit_event = m5.simulate(when)
1843358Srdreslin@umich.edu        while exit_event.getCause() == "checkpoint":
1853358Srdreslin@umich.edu            exit_event = m5.simulate(when - m5.curTick())
1863358Srdreslin@umich.edu
1873358Srdreslin@umich.edu        if exit_event.getCause() == "simulate() limit reached":
1883358Srdreslin@umich.edu            m5.checkpoint(root, joinpath(cptdir, "cpt.%d"))
1893358Srdreslin@umich.edu            num_checkpoints += 1
1903358Srdreslin@umich.edu
1913358Srdreslin@umich.edu        sim_ticks = when
1921516SN/A        exit_cause = "maximum %d checkpoints dropped" % max_checkpoints
1933358Srdreslin@umich.edu        while num_checkpoints < max_checkpoints:
1943358Srdreslin@umich.edu            if (sim_ticks + period) > maxtick and maxtick != -1:
1953358Srdreslin@umich.edu                exit_event = m5.simulate(maxtick - sim_ticks)
1961516SN/A                exit_cause = exit_event.getCause()
1973358Srdreslin@umich.edu                break
1983358Srdreslin@umich.edu            else:
1993358Srdreslin@umich.edu                exit_event = m5.simulate(period)
2003358Srdreslin@umich.edu                sim_ticks += period
2013358Srdreslin@umich.edu                while exit_event.getCause() == "checkpoint":
2021516SN/A                    exit_event = m5.simulate(sim_ticks - m5.curTick())
2033358Srdreslin@umich.edu                if exit_event.getCause() == "simulate() limit reached":
2043358Srdreslin@umich.edu                    m5.checkpoint(root, joinpath(cptdir, "cpt.%d"))
2053358Srdreslin@umich.edu                    num_checkpoints += 1
2063358Srdreslin@umich.edu
2073358Srdreslin@umich.edu    else: #no checkpoints being taken via this script
2083358Srdreslin@umich.edu        exit_event = m5.simulate(maxtick)
2093358Srdreslin@umich.edu
2103358Srdreslin@umich.edu        while exit_event.getCause() == "checkpoint":
2113358Srdreslin@umich.edu            m5.checkpoint(root, joinpath(cptdir, "cpt.%d"))
2123358Srdreslin@umich.edu            num_checkpoints += 1
2133358Srdreslin@umich.edu            if num_checkpoints == max_checkpoints:
2143358Srdreslin@umich.edu                exit_cause =  "maximum %d checkpoints dropped" % max_checkpoints
2153358Srdreslin@umich.edu                break
2163358Srdreslin@umich.edu
2173358Srdreslin@umich.edu            if maxtick == -1:
2183358Srdreslin@umich.edu                exit_event = m5.simulate(maxtick)
2193358Srdreslin@umich.edu            else:
2203358Srdreslin@umich.edu                exit_event = m5.simulate(maxtick - m5.curTick())
2213358Srdreslin@umich.edu
2223358Srdreslin@umich.edu            exit_cause = exit_event.getCause()
2233358Srdreslin@umich.edu
2243358Srdreslin@umich.edu    if exit_cause == '':
2253358Srdreslin@umich.edu        exit_cause = exit_event.getCause()
2263358Srdreslin@umich.edu    print 'Exiting @ cycle', m5.curTick(), 'because ', exit_cause
2273358Srdreslin@umich.edu
2283358Srdreslin@umich.edu