summaryrefslogtreecommitdiff
path: root/configs/example
diff options
context:
space:
mode:
Diffstat (limited to 'configs/example')
-rw-r--r--configs/example/memtest.py190
1 files changed, 123 insertions, 67 deletions
diff --git a/configs/example/memtest.py b/configs/example/memtest.py
index c28ffab10..5bb874e85 100644
--- a/configs/example/memtest.py
+++ b/configs/example/memtest.py
@@ -33,14 +33,55 @@ m5.AddToPath('../common')
parser = optparse.OptionParser()
-parser.add_option("--caches", action="store_true")
-parser.add_option("-t", "--timing", action="store_true")
-parser.add_option("-m", "--maxtick", type="int")
-parser.add_option("-l", "--maxloads", default = "1000000000000", type="int")
-parser.add_option("-n", "--numtesters", default = "8", type="int")
-parser.add_option("-p", "--protocol",
- default="moesi",
- help="The coherence protocol to use for the L1'a (i.e. MOESI, MOSI)")
+parser.add_option("-a", "--atomic", action="store_true",
+ help="Use atomic (non-timing) mode")
+parser.add_option("-b", "--blocking", action="store_true",
+ help="Use blocking caches")
+parser.add_option("-l", "--maxloads", metavar="N", default=0,
+ help="Stop after N loads")
+parser.add_option("-m", "--maxtick", type="int", default=m5.MaxTick,
+ metavar="T",
+ help="Stop after T ticks")
+
+#
+# The "tree" specification is a colon-separated list of one or more
+# integers. The first integer is the number of caches/testers
+# connected directly to main memory. The last integer in the list is
+# the number of testers associated with the uppermost level of memory
+# (L1 cache, if there are caches, or main memory if no caches). Thus
+# if there is only one integer, there are no caches, and the integer
+# specifies the number of testers connected directly to main memory.
+# The other integers (if any) specify the number of caches at each
+# level of the hierarchy between.
+#
+# Examples:
+#
+# "2:1" Two caches connected to memory with a single tester behind each
+# (single-level hierarchy, two testers total)
+#
+# "2:2:1" Two-level hierarchy, 2 L1s behind each of 2 L2s, 4 testers total
+#
+parser.add_option("-t", "--treespec", type="string", default="8:1",
+ help="Colon-separated multilevel tree specification, "
+ "see script comments for details "
+ "[default: %default]")
+
+parser.add_option("--force-bus", action="store_true",
+ help="Use bus between levels even with single cache")
+
+parser.add_option("-f", "--functional", type="int", default=0,
+ metavar="PCT",
+ help="Target percentage of functional accesses "
+ "[default: %default]")
+parser.add_option("-u", "--uncacheable", type="int", default=0,
+ metavar="PCT",
+ help="Target percentage of uncacheable accesses "
+ "[default: %default]")
+
+parser.add_option("--progress", type="int", default=1000,
+ metavar="NLOADS",
+ help="Progress message interval "
+ "[default: %default]")
(options, args) = parser.parse_args()
@@ -48,74 +89,92 @@ if args:
print "Error: script doesn't take any positional arguments"
sys.exit(1)
-# --------------------
-# Base L1 Cache
-# ====================
-
-class L1(BaseCache):
- latency = '1ns'
- block_size = 64
- mshrs = 12
- tgts_per_mshr = 8
- protocol = CoherenceProtocol(protocol=options.protocol)
-
-# ----------------------
-# Base L2 Cache
-# ----------------------
-
-class L2(BaseCache):
- block_size = 64
- latency = '10ns'
- mshrs = 92
- tgts_per_mshr = 16
- write_buffers = 8
-
-#MAX CORES IS 8 with the false sharing method
-if options.numtesters > 8:
- print "Error: NUmber of testers limited to 8 because of false sharing"
- sys,exit(1)
-
-cpus = [ MemTest(atomic=not options.timing, max_loads=options.maxloads,
- percent_functional=50, percent_uncacheable=10,
- progress_interval=1000)
- for i in xrange(options.numtesters) ]
+block_size = 64
-# system simulated
-system = System(cpu = cpus, funcmem = PhysicalMemory(),
- physmem = PhysicalMemory(latency = "50ns"), membus = Bus(clock="500MHz", width=16))
+try:
+ treespec = [int(x) for x in options.treespec.split(':')]
+ numtesters = reduce(lambda x,y: x*y, treespec)
+except:
+ print "Error parsing treespec option"
+ sys.exit(1)
-# l2cache & bus
-if options.caches:
- system.toL2Bus = Bus(clock="500MHz", width=16)
- system.l2c = L2(size='64kB', assoc=8)
- system.l2c.cpu_side = system.toL2Bus.port
+if numtesters > block_size:
+ print "Error: Number of testers limited to %s because of false sharing" \
+ % (block_size)
+ sys.exit(1)
- # connect l2c to membus
- system.l2c.mem_side = system.membus.port
+if len(treespec) < 1:
+ print "Error parsing treespec"
+ sys.exit(1)
-# add L1 caches
-for cpu in cpus:
- if options.caches:
- cpu.l1c = L1(size = '32kB', assoc = 4)
- cpu.test = cpu.l1c.cpu_side
- cpu.l1c.mem_side = system.toL2Bus.port
- else:
- cpu.test = system.membus.port
- system.funcmem.port = cpu.functional
+# define prototype L1 cache
+proto_l1 = BaseCache(size = '32kB', assoc = 4, block_size = block_size,
+ latency = '1ns', tgts_per_mshr = 8)
-# connect memory to membus
-system.physmem.port = system.membus.port
+if options.blocking:
+ proto_l1.mshrs = 1
+else:
+ proto_l1.mshrs = 8
+
+# build a list of prototypes, one for each level of treespec, starting
+# at the end (last entry is tester objects)
+prototypes = [ MemTest(atomic=options.atomic, max_loads=options.maxloads,
+ percent_functional=options.functional,
+ percent_uncacheable=options.uncacheable,
+ progress_interval=options.progress) ]
+
+# next comes L1 cache, if any
+if len(treespec) > 1:
+ prototypes.insert(0, proto_l1)
+
+# now add additional cache levels (if any) by scaling L1 params
+while len(prototypes) < len(treespec):
+ # clone previous level and update params
+ prev = prototypes[0]
+ next = prev()
+ next.size = prev.size * 4
+ next.latency = prev.latency * 10
+ next.assoc = prev.assoc * 2
+ prototypes.insert(0, next)
+# system simulated
+system = System(funcmem = PhysicalMemory(),
+ physmem = PhysicalMemory(latency = "100ns"))
+
+def make_level(spec, prototypes, attach_obj, attach_port):
+ fanout = spec[0]
+ parent = attach_obj # use attach obj as config parent too
+ if len(spec) > 1 and (fanout > 1 or options.force_bus):
+ new_bus = Bus(clock="500MHz", width=16)
+ new_bus.port = getattr(attach_obj, attach_port)
+ parent.cpu_side_bus = new_bus
+ attach_obj = new_bus
+ attach_port = "port"
+ objs = [prototypes[0]() for i in xrange(fanout)]
+ if len(spec) > 1:
+ # we just built caches, more levels to go
+ parent.cache = objs
+ for cache in objs:
+ cache.mem_side = getattr(attach_obj, attach_port)
+ make_level(spec[1:], prototypes[1:], cache, "cpu_side")
+ else:
+ # we just built the MemTest objects
+ parent.cpu = objs
+ for t in objs:
+ t.test = getattr(attach_obj, attach_port)
+ t.functional = system.funcmem.port
+
+make_level(treespec, prototypes, system.physmem, "port")
# -----------------------
# run simulation
# -----------------------
root = Root( system = system )
-if options.timing:
- root.system.mem_mode = 'timing'
-else:
+if options.atomic:
root.system.mem_mode = 'atomic'
+else:
+ root.system.mem_mode = 'timing'
# Not much point in this being higher than the L1 latency
m5.ticks.setGlobalFrequency('1ns')
@@ -124,9 +183,6 @@ m5.ticks.setGlobalFrequency('1ns')
m5.instantiate(root)
# simulate until program terminates
-if options.maxtick:
- exit_event = m5.simulate(options.maxtick)
-else:
- exit_event = m5.simulate(10000000000000)
+exit_event = m5.simulate(options.maxtick)
print 'Exiting @ tick', m5.curTick(), 'because', exit_event.getCause()