# Copyright (c) 2006-2007 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Ron Dreslinski

import optparse
import sys

import m5
from m5.objects import *

parser = optparse.OptionParser()

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()

if args:
     print "Error: script doesn't take any positional arguments"
     sys.exit(1)

block_size = 64

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)

if numtesters > block_size:
     print "Error: Number of testers limited to %s because of false sharing" \
           % (block_size)
     sys.exit(1)

if len(treespec) < 1:
     print "Error parsing treespec"
     sys.exit(1)

# define prototype L1 cache
proto_l1 = BaseCache(size = '32kB', assoc = 4, block_size = block_size,
                     hit_latency = '1ns', response_latency = '1ns',
                     tgts_per_mshr = 8)

if options.blocking:
     proto_l1.mshrs = 1
else:
     proto_l1.mshrs = 4

# 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
for scale in treespec[:-2]:
     # clone previous level and update params
     prev = prototypes[0]
     next = prev()
     next.size = prev.size * scale
     next.latency = prev.latency * 10
     next.assoc = prev.assoc * scale
     next.mshrs = prev.mshrs * scale
     prototypes.insert(0, next)

# system simulated
system = System(funcmem = SimpleMemory(in_addr_map = False),
                funcbus = NoncoherentBus(),
                physmem = SimpleMemory(latency = "100ns"))
system.clk_domain = SrcClockDomain(clock =  options.sys_clock)

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):
          port = getattr(attach_obj, attach_port)
          new_bus = CoherentBus(width=16)
          if (port.role == 'MASTER'):
               new_bus.slave = port
               attach_port = "master"
          else:
               new_bus.master = port
               attach_port = "slave"
          parent.cpu_side_bus = new_bus
          attach_obj = new_bus
     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.funcbus.slave

make_level(treespec, prototypes, system.physmem, "port")

# connect reference memory to funcbus
system.funcbus.master = system.funcmem.port

# -----------------------
# run simulation
# -----------------------

root = Root( full_system = False, system = system )
if options.atomic:
    root.system.mem_mode = 'atomic'
else:
    root.system.mem_mode = 'timing'

# The system port is never used in the tester so merely connect it
# to avoid problems
root.system.system_port = root.system.funcbus.slave

# Not much point in this being higher than the L1 latency
m5.ticks.setGlobalFrequency('1ns')

# instantiate configuration
m5.instantiate()

# simulate until program terminates
exit_event = m5.simulate(options.maxtick)

print 'Exiting @ tick', m5.curTick(), 'because', exit_event.getCause()
