Simulation.py revision 3514:b166ee5dce91
12292SN/A# Copyright (c) 2006 The Regents of The University of Michigan
27597Sminkyu.jeong@arm.com# All rights reserved.
37597Sminkyu.jeong@arm.com#
47597Sminkyu.jeong@arm.com# Redistribution and use in source and binary forms, with or without
57597Sminkyu.jeong@arm.com# modification, are permitted provided that the following conditions are
67597Sminkyu.jeong@arm.com# met: redistributions of source code must retain the above copyright
77597Sminkyu.jeong@arm.com# notice, this list of conditions and the following disclaimer;
87597Sminkyu.jeong@arm.com# redistributions in binary form must reproduce the above copyright
97597Sminkyu.jeong@arm.com# notice, this list of conditions and the following disclaimer in the
107597Sminkyu.jeong@arm.com# documentation and/or other materials provided with the distribution;
117597Sminkyu.jeong@arm.com# neither the name of the copyright holders nor the names of its
127597Sminkyu.jeong@arm.com# contributors may be used to endorse or promote products derived from
137597Sminkyu.jeong@arm.com# this software without specific prior written permission.
142292SN/A#
152292SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
162292SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
172292SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
182292SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
192292SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
202292SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
212292SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
222292SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
232292SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
242292SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
252292SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
262292SN/A#
272292SN/A# Authors: Lisa Hsu
282292SN/A
292292SN/Afrom os import getcwd
302292SN/Aimport m5
312292SN/Afrom m5.objects import *
322292SN/Am5.AddToPath('../common')
332292SN/Afrom Caches import L1Cache
342292SN/A
352292SN/Adef setCPUClass(options):
362292SN/A
372292SN/A    atomic = False
382292SN/A    if options.timing:
392689Sktlim@umich.edu        TmpClass = TimingSimpleCPU
402689Sktlim@umich.edu    elif options.detailed:
412689Sktlim@umich.edu        TmpClass = DerivO3CPU
422292SN/A    else:
432292SN/A        TmpClass = AtomicSimpleCPU
443326Sktlim@umich.edu        atomic = True
456658Snate@binkert.org
462733Sktlim@umich.edu    CPUClass = None
472907Sktlim@umich.edu    test_mem_mode = 'atomic'
482292SN/A
492292SN/A    if not atomic:
502722Sktlim@umich.edu        if options.checkpoint_restore:
512669Sktlim@umich.edu            CPUClass = TmpClass
522292SN/A            TmpClass = AtomicSimpleCPU
532790Sktlim@umich.edu        else:
542790Sktlim@umich.edu            test_mem_mode = 'timing'
552790Sktlim@umich.edu
562790Sktlim@umich.edu    return (TmpClass, test_mem_mode, CPUClass)
572669Sktlim@umich.edu
582678Sktlim@umich.edu
592678Sktlim@umich.edudef run(options, root, testsys, cpu_class):
605606Snate@binkert.org    if options.maxtick:
612292SN/A        maxtick = options.maxtick
622678Sktlim@umich.edu    elif options.maxtime:
632292SN/A        simtime = int(options.maxtime * root.clock.value)
642292SN/A        print "simulating for: ", simtime
652669Sktlim@umich.edu        maxtick = simtime
662292SN/A    else:
672678Sktlim@umich.edu        maxtick = -1
682292SN/A
692678Sktlim@umich.edu    if options.checkpoint_dir:
702678Sktlim@umich.edu        cptdir = options.checkpoint_dir
712678Sktlim@umich.edu    else:
724319Sktlim@umich.edu        cptdir = getcwd()
734319Sktlim@umich.edu
744319Sktlim@umich.edu    np = options.num_cpus
754319Sktlim@umich.edu    max_checkpoints = options.max_checkpoints
764319Sktlim@umich.edu    switch_cpus = None
772678Sktlim@umich.edu
782678Sktlim@umich.edu    if cpu_class:
792292SN/A        switch_cpus = [cpu_class(defer_registration=True, cpu_id=(np+i))
802678Sktlim@umich.edu                       for i in xrange(np)]
812678Sktlim@umich.edu
825336Shines@cs.fsu.edu        for i in xrange(np):
832678Sktlim@umich.edu            switch_cpus[i].system =  testsys
844873Sstever@eecs.umich.edu            if not m5.build_env['FULL_SYSTEM']:
852678Sktlim@umich.edu                switch_cpus[i].workload = testsys.cpu[i].workload
862292SN/A            switch_cpus[i].clock = testsys.cpu[0].clock
872678Sktlim@umich.edu
882678Sktlim@umich.edu        root.switch_cpus = switch_cpus
892678Sktlim@umich.edu        switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
902678Sktlim@umich.edu
912678Sktlim@umich.edu    if options.standard_switch:
922678Sktlim@umich.edu        switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(np+i))
932678Sktlim@umich.edu                       for i in xrange(np)]
942698Sktlim@umich.edu        switch_cpus_1 = [DerivO3CPU(defer_registration=True, cpu_id=(2*np+i))
952344SN/A                        for i in xrange(np)]
962678Sktlim@umich.edu
972678Sktlim@umich.edu        for i in xrange(np):
984986Ssaidi@eecs.umich.edu            switch_cpus[i].system =  testsys
994986Ssaidi@eecs.umich.edu            switch_cpus_1[i].system =  testsys
1006974Stjones1@inf.ed.ac.uk            if not m5.build_env['FULL_SYSTEM']:
1016974Stjones1@inf.ed.ac.uk                switch_cpus[i].workload = testsys.cpu[i].workload
1026974Stjones1@inf.ed.ac.uk                switch_cpus_1[i].workload = testsys.cpu[i].workload
1036974Stjones1@inf.ed.ac.uk            switch_cpus[i].clock = testsys.cpu[0].clock
1046974Stjones1@inf.ed.ac.uk            switch_cpus_1[i].clock = testsys.cpu[0].clock
1056974Stjones1@inf.ed.ac.uk
1066974Stjones1@inf.ed.ac.uk            if not options.caches:
1072678Sktlim@umich.edu                # O3 CPU must have a cache to work.
1082820Sktlim@umich.edu                switch_cpus_1[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'),
1092678Sktlim@umich.edu                                                         L1Cache(size = '64kB'))
1102678Sktlim@umich.edu                switch_cpus_1[i].connectMemPorts(testsys.membus)
1116974Stjones1@inf.ed.ac.uk
1126974Stjones1@inf.ed.ac.uk
1136974Stjones1@inf.ed.ac.uk            testsys.switch_cpus = switch_cpus
1146974Stjones1@inf.ed.ac.uk            testsys.switch_cpus_1 = switch_cpus_1
1156974Stjones1@inf.ed.ac.uk            switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
1166974Stjones1@inf.ed.ac.uk            switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)]
1172678Sktlim@umich.edu
1182678Sktlim@umich.edu    m5.instantiate(root)
1192678Sktlim@umich.edu
1202678Sktlim@umich.edu    if options.checkpoint_restore:
1212678Sktlim@umich.edu        from os.path import isdir
1222344SN/A        from os import listdir
1232307SN/A        import re
1246974Stjones1@inf.ed.ac.uk
1256974Stjones1@inf.ed.ac.uk        if not isdir(cptdir):
1266974Stjones1@inf.ed.ac.uk            m5.panic("checkpoint dir %s does not exist!" % cptdir)
1276974Stjones1@inf.ed.ac.uk
1282678Sktlim@umich.edu        dirs = listdir(cptdir)
1294032Sktlim@umich.edu        expr = re.compile('cpt.([0-9]*)')
1302678Sktlim@umich.edu        cpts = []
1312292SN/A        for dir in dirs:
1322292SN/A            match = expr.match(dir)
1332292SN/A            if match:
1342292SN/A                cpts.append(match.group(1))
1352678Sktlim@umich.edu
1362678Sktlim@umich.edu        cpts.sort(lambda a,b: cmp(long(a), long(b)))
1376974Stjones1@inf.ed.ac.uk
1382292SN/A        cpt_num = options.checkpoint_restore
1392292SN/A
1402292SN/A        if cpt_num > len(cpts):
1412292SN/A            m5.panic('Checkpoint %d not found' % cpt_num)
1422292SN/A
1435529Snate@binkert.org        m5.restoreCheckpoint(root,
1445529Snate@binkert.org                             "/".join([cptdir, "cpt.%s" % cpts[cpt_num - 1]]))
1455529Snate@binkert.org
1462292SN/A    if options.standard_switch or cpu_class:
1474329Sktlim@umich.edu        exit_event = m5.simulate(10000)
1484329Sktlim@umich.edu
1494329Sktlim@umich.edu        ## when you change to Timing (or Atomic), you halt the system given
1504329Sktlim@umich.edu        ## as argument.  When you are finished with the system changes
1512292SN/A        ## (including switchCpus), you must resume the system manually.
1522307SN/A        ## You DON'T need to resume after just switching CPUs if you haven't
1532307SN/A        ## changed anything on the system level.
1542907Sktlim@umich.edu
1552907Sktlim@umich.edu        m5.changeToTiming(testsys)
1562292SN/A        m5.switchCpus(switch_cpu_list)
1572292SN/A        m5.resume(testsys)
1582329SN/A
1592329SN/A        if options.standard_switch:
1602329SN/A            exit_event = m5.simulate(options.warmup)
1612292SN/A            m5.switchCpus(switch_cpu_list1)
1622292SN/A
1632292SN/A    num_checkpoints = 0
1642292SN/A    exit_cause = ''
1652292SN/A
1662292SN/A    ## Checkpoints being taken via the command line at <when> and at subsequent
1672292SN/A    ## periods of <period>.  Checkpoint instructions received from the benchmark running
1682292SN/A    ## are ignored and skipped in favor of command line checkpoint instructions.
1692292SN/A    if options.take_checkpoints:
1702292SN/A        [when, period] = options.take_checkpoints.split(",", 1)
1712292SN/A        when = int(when)
1723492Sktlim@umich.edu        period = int(period)
1732329SN/A
1742292SN/A        exit_event = m5.simulate(when)
1752292SN/A        while exit_event.getCause() == "checkpoint":
1762292SN/A            exit_event = m5.simulate(when - m5.curTick())
1772292SN/A
1782292SN/A        if exit_event.getCause() == "simulate() limit reached":
1792292SN/A            m5.checkpoint(root, "/".join([cptdir,"cpt.%d"]))
1802292SN/A            num_checkpoints += 1
1812292SN/A
1822292SN/A        sim_ticks = when
1832292SN/A        exit_cause = "maximum %d checkpoints dropped" % max_checkpoints
1842292SN/A        while num_checkpoints < max_checkpoints:
1852292SN/A            if (sim_ticks + period) > maxtick and maxtick != -1:
1862292SN/A                exit_event = m5.simulate(maxtick - sim_ticks)
1872292SN/A                exit_cause = exit_event.getCause()
1882292SN/A                break
1892292SN/A            else:
1902292SN/A                exit_event = m5.simulate(period)
1912727Sktlim@umich.edu                sim_ticks += period
1922727Sktlim@umich.edu                while exit_event.getCause() == "checkpoint":
1932727Sktlim@umich.edu                    exit_event = m5.simulate(sim_ticks - m5.curTick())
1942727Sktlim@umich.edu                if exit_event.getCause() == "simulate() limit reached":
1952727Sktlim@umich.edu                    m5.checkpoint(root, "/".join([cptdir,"cpt.%d"]))
1962727Sktlim@umich.edu                    num_checkpoints += 1
1972727Sktlim@umich.edu
1982727Sktlim@umich.edu    else: #no checkpoints being taken via this script
1992727Sktlim@umich.edu        exit_event = m5.simulate(maxtick)
2002727Sktlim@umich.edu
2012727Sktlim@umich.edu        while exit_event.getCause() == "checkpoint":
2022727Sktlim@umich.edu            m5.checkpoint(root, "/".join([cptdir,"cpt.%d"]))
2032727Sktlim@umich.edu            num_checkpoints += 1
2042727Sktlim@umich.edu            if num_checkpoints == max_checkpoints:
2052727Sktlim@umich.edu                exit_cause =  "maximum %d checkpoints dropped" % max_checkpoints
2062727Sktlim@umich.edu                break
2072727Sktlim@umich.edu
2082727Sktlim@umich.edu            if maxtick == -1:
2092361SN/A                exit_event = m5.simulate(maxtick)
2102361SN/A            else:
2112361SN/A                exit_event = m5.simulate(maxtick - m5.curTick())
2122361SN/A
2132727Sktlim@umich.edu            exit_cause = exit_event.getCause()
2142727Sktlim@umich.edu
2152727Sktlim@umich.edu    if exit_cause == '':
2162727Sktlim@umich.edu        exit_cause = exit_event.getCause()
2172727Sktlim@umich.edu    print 'Exiting @ cycle %i because %s' % (m5.curTick(), exit_cause)
2182727Sktlim@umich.edu
2192727Sktlim@umich.edu