Deleted Added
sdiff udiff text old ( 5353:487d6f3291d7 ) new ( 5361:e379019a1abd )
full compact
1# Copyright (c) 2006-2008 The Regents of The University of Michigan
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met: redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer;
8# redistributions in binary form must reproduce the above copyright
9# notice, this list of conditions and the following disclaimer in the
10# documentation and/or other materials provided with the distribution;
11# neither the name of the copyright holders nor the names of its
12# contributors may be used to endorse or promote products derived from
13# this software without specific prior written permission.
14#
15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26#
27# Authors: Lisa Hsu
28
29from os import getcwd
30from os.path import join as joinpath
31import m5
32from m5.objects import *
33m5.AddToPath('../common')
34from Caches import L1Cache
35
36def setCPUClass(options):
37
38 atomic = False
39 if options.timing:
40 class TmpClass(TimingSimpleCPU): pass
41 elif options.detailed:
42 if not options.caches:
43 print "O3 CPU must be used with caches"
44 sys.exit(1)
45 class TmpClass(DerivO3CPU): pass
46 else:
47 class TmpClass(AtomicSimpleCPU): pass
48 atomic = True
49
50 CPUClass = None
51 test_mem_mode = 'atomic'
52
53 if not atomic:
54 if options.checkpoint_restore:
55 CPUClass = TmpClass
56 class TmpClass(AtomicSimpleCPU): pass
57 else:
58 test_mem_mode = 'timing'
59
60 return (TmpClass, test_mem_mode, CPUClass)
61
62
63def run(options, root, testsys, cpu_class):
64 if options.maxtick:
65 maxtick = options.maxtick
66 elif options.maxtime:
67 simtime = m5.ticks.seconds(simtime)
68 print "simulating for: ", simtime
69 maxtick = simtime
70 else:
71 maxtick = m5.MaxTick
72
73 if options.checkpoint_dir:
74 cptdir = options.checkpoint_dir
75 elif m5.options.outdir:
76 cptdir = m5.options.outdir
77 else:
78 cptdir = getcwd()
79
80 np = options.num_cpus
81 max_checkpoints = options.max_checkpoints
82 switch_cpus = None
83
84 if cpu_class:
85 switch_cpus = [cpu_class(defer_registration=True, cpu_id=(np+i))
86 for i in xrange(np)]
87
88 for i in xrange(np):
89 switch_cpus[i].system = testsys
90 if not m5.build_env['FULL_SYSTEM']:
91 switch_cpus[i].workload = testsys.cpu[i].workload
92 switch_cpus[i].clock = testsys.cpu[0].clock
93
94 testsys.switch_cpus = switch_cpus
95 switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
96
97 if options.standard_switch:
98 if (options.fast_forward and options.warmup):
99 m5.panic("Must specify either warmup OR fast-forward with -s!")
100
101 switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(np+i))
102 for i in xrange(np)]
103 switch_cpus_1 = [DerivO3CPU(defer_registration=True, cpu_id=(2*np+i))
104 for i in xrange(np)]
105
106 for i in xrange(np):
107 switch_cpus[i].system = testsys
108 switch_cpus_1[i].system = testsys
109 if not m5.build_env['FULL_SYSTEM']:
110 switch_cpus[i].workload = testsys.cpu[i].workload
111 switch_cpus_1[i].workload = testsys.cpu[i].workload
112 switch_cpus[i].clock = testsys.cpu[0].clock
113 switch_cpus_1[i].clock = testsys.cpu[0].clock
114
115 if options.fast_forward:
116 switch_cpus[i].max_insts_any_thread = options.fast_forward
117 if options.max_inst:
118 switch_cpus_1[i].max_insts_any_thread = options.max_inst
119
120 if not options.caches:
121 # O3 CPU must have a cache to work.
122 switch_cpus_1[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'),
123 L1Cache(size = '64kB'))
124 switch_cpus_1[i].connectMemPorts(testsys.membus)
125
126
127 testsys.switch_cpus = switch_cpus
128 testsys.switch_cpus_1 = switch_cpus_1
129 switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
130 switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)]
131
132 elif options.fast_forward:
133 for i in xrange(np):
134 testsys.cpu[i].max_insts_any_thread = options.fast_forward
135
136 m5.instantiate(root)
137
138 if options.checkpoint_restore:
139 from os.path import isdir
140 from os import listdir
141 import re
142
143 if not isdir(cptdir):
144 m5.panic("checkpoint dir %s does not exist!" % cptdir)
145
146 dirs = listdir(cptdir)
147 expr = re.compile('cpt\.([0-9]*)')
148 cpts = []
149 for dir in dirs:
150 match = expr.match(dir)
151 if match:
152 cpts.append(match.group(1))
153
154 cpts.sort(lambda a,b: cmp(long(a), long(b)))
155
156 cpt_num = options.checkpoint_restore
157
158 if cpt_num > len(cpts):
159 m5.panic('Checkpoint %d not found' % cpt_num)
160
161 ## Adjust max tick based on our starting tick
162 maxtick = maxtick - int(cpts[cpt_num - 1])
163
164 ## Restore the checkpoint
165 m5.restoreCheckpoint(root,
166 joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1]))
167
168 if options.standard_switch or cpu_class:
169 exit_event = m5.simulate(10000)
170
171 ## when you change to Timing (or Atomic), you halt the system given
172 ## as argument. When you are finished with the system changes
173 ## (including switchCpus), you must resume the system manually.
174 ## You DON'T need to resume after just switching CPUs if you haven't
175 ## changed anything on the system level.
176
177 m5.changeToTiming(testsys)
178 m5.switchCpus(switch_cpu_list)
179 m5.resume(testsys)
180
181 if options.standard_switch:
182 if (options.warmup):
183 exit_event = m5.simulate(options.warmup)
184 if options.fast_forward:
185 exit_event = m5.simulate()
186 m5.drain(testsys)
187 m5.switchCpus(switch_cpu_list1)
188 m5.resume(testsys)
189
190 # This should *only* be used by itself to take a checkpoint!
191 # Otherwise, use standard_switch
192 elif options.fast_forward:
193 exit_event = m5.simulate()
194
195 while exit_event.getCause() != "a thread reached the max instruction count":
196 if exit_event.getCause() == "user interrupt received":
197 print "User interrupt! Switching to simulation mode"
198 break
199 else:
200 m5.simulate(True)
201
202 if exit_event.getCause() == "a thread reached the max instruction count":
203 print "Reached fast_forward count %d; starting simulation at cycle %d" % (options.fast_forward, m5.curTick())
204
205 m5.checkpoint(root, joinpath(cptdir, "cpt.%d"))
206 return
207
208 num_checkpoints = 0
209 exit_cause = ''
210
211 ## Checkpoints being taken via the command line at <when> and at subsequent
212 ## periods of <period>. Checkpoint instructions received from the benchmark running
213 ## are ignored and skipped in favor of command line checkpoint instructions.
214 if options.take_checkpoints:
215 [when, period] = options.take_checkpoints.split(",", 1)
216 when = int(when)
217 period = int(period)
218
219 exit_event = m5.simulate(when)
220 while exit_event.getCause() == "checkpoint":
221 exit_event = m5.simulate(when - m5.curTick())
222
223 if exit_event.getCause() == "simulate() limit reached":
224 m5.checkpoint(root, joinpath(cptdir, "cpt.%d"))
225 num_checkpoints += 1
226
227 sim_ticks = when
228 exit_cause = "maximum %d checkpoints dropped" % max_checkpoints
229 while num_checkpoints < max_checkpoints and \
230 exit_event.getCause() == "simulate() limit reached":
231 if (sim_ticks + period) > maxtick:
232 exit_event = m5.simulate(maxtick - sim_ticks)
233 exit_cause = exit_event.getCause()
234 break
235 else:
236 exit_event = m5.simulate(period)
237 sim_ticks += period
238 while exit_event.getCause() == "checkpoint":
239 exit_event = m5.simulate(sim_ticks - m5.curTick())
240 if exit_event.getCause() == "simulate() limit reached":
241 m5.checkpoint(root, joinpath(cptdir, "cpt.%d"))
242 num_checkpoints += 1
243
244 if exit_event.getCause() != "simulate() limit reached":
245 exit_cause = exit_event.getCause();
246
247
248 else: #no checkpoints being taken via this script
249 exit_event = m5.simulate(maxtick)
250
251 while exit_event.getCause() == "checkpoint":
252 m5.checkpoint(root, joinpath(cptdir, "cpt.%d"))
253 num_checkpoints += 1
254 if num_checkpoints == max_checkpoints:
255 exit_cause = "maximum %d checkpoints dropped" % max_checkpoints
256 break
257
258 exit_event = m5.simulate(maxtick - m5.curTick())
259 exit_cause = exit_event.getCause()
260
261 if exit_cause == '':
262 exit_cause = exit_event.getCause()
263 print 'Exiting @ cycle %i because %s' % (m5.curTick(), exit_cause)
264