#cmp.py
# Simple configuration script

import os, optparse, sys

import m5
from m5.defines import buildEnv
from m5.objects import *
from m5.util import addToPath, fatal

addToPath('../common')
addToPath('../ruby')
addToPath('../topologies')


import Options
import Ruby
import Simulation
import MemConfig_32
from Caches import *
import CacheConfig
import cpu2006

# Get paths we might need.  It's expected this file is in m5/configs/example.
config_path = os.path.dirname(os.path.abspath(__file__))
print config_path   # 'configs/cpu2006'
config_root = os.path.dirname(config_path)
print config_root
m5_root = os.path.dirname(config_root)
print m5_root

parser = optparse.OptionParser()
Options.addCommonOptions(parser)
Options.addSEOptions(parser)

if '--ruby' in sys.argv:
    Ruby.define_options(parser)

(options, args) = parser.parse_args()

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

multiprocesses = []
if options.cmd:
    workloads = options.cmd.split(';')
    for wrkld in workloads:
		process = LiveProcess()
		if wrkld == 'perlbench':
		   process = cpu2006.perlbench
		elif wrkld == 'bzip2':
		   process = cpu2006.bzip2
		elif wrkld == 'gcc':
		   process = cpu2006.gcc
		elif wrkld == 'bwaves':
		   process = cpu2006.bwaves
		elif wrkld == 'gamess':
		   process = cpu2006.gamess
		elif wrkld == 'mcf':
		   process = cpu2006.mcf
		elif wrkld == 'milc':
		   process = cpu2006.milc
		elif wrkld == 'zeusmp':
		   process = cpu2006.zeusmp
		elif wrkld == 'gromacs':
		   process = cpu2006.gromacs
		elif wrkld == 'cactusADM':
		   process = cpu2006.cactusADM
		elif wrkld == 'leslie3d':
		   process = cpu2006.leslie3d
		elif wrkld == 'namd':
		   process = cpu2006.namd
		elif wrkld == 'gobmk':
		   process = cpu2006.gobmk;
		elif wrkld == 'dealII':
		   process = cpu2006.dealII
		elif wrkld == 'soplex':
		   process = cpu2006.soplex
		elif wrkld == 'povray':
		   process = cpu2006.povray
		elif wrkld == 'calculix':
		   process = cpu2006.calculix
		elif wrkld == 'hmmer':
		   process = cpu2006.hmmer
		elif wrkld == 'sjeng':
		   process = cpu2006.sjeng
		elif wrkld == 'GemsFDTD':
		   process = cpu2006.GemsFDTD
		elif wrkld == 'libquantum':
		   process = cpu2006.libquantum
		elif wrkld == 'h264ref':
		   process = cpu2006.h264ref
		elif wrkld == 'tonto':
		   process = cpu2006.tonto
		elif wrkld == 'lbm':
		   process = cpu2006.lbm
		elif wrkld == 'omnetpp':
		   process = cpu2006.omnetpp
		elif wrkld == 'astar':
		   process = cpu2006.astar
		elif wrkld == 'wrf':
		   process = cpu2006.wrf
		elif wrkld == 'sphinx3':
		   process = cpu2006.sphinx3
		elif wrkld == 'xalancbmk':
		   process = cpu2006.xalancbmk
		elif wrkld == 'specrand_i':
		   process = cpu2006.specrand_i
		elif wrkld == 'specrand_f':
		   process = cpu2006.specrand_f
		multiprocesses.append(process)

(CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options)
CPUClass.numThreads = 1

MemClass = Simulation.setMemClass(options)

# Check -- do not allow SMT with multiple CPUs
if options.smt and options.num_cpus > 1:
    fatal("You cannot use SMT with multiple CPUs!")

np = options.num_cpus
system = System(cpu = [CPUClass(cpu_id=i) for i in xrange(np)],
                mem_mode = test_mem_mode,
                mem_ranges = [AddrRange(options.mem_size)],
                cache_line_size = options.cacheline_size)

# Create a top-level voltage domain
system.voltage_domain = VoltageDomain(voltage = options.sys_voltage)

# Create a source clock for the system and set the clock period
system.clk_domain = SrcClockDomain(clock =  options.sys_clock,
                                   voltage_domain = system.voltage_domain)

# Create a CPU voltage domain
system.cpu_voltage_domain = VoltageDomain()

# Create a separate clock domain for the CPUs
system.cpu_clk_domain = SrcClockDomain(clock = options.cpu_clock,
                                       voltage_domain =
                                       system.cpu_voltage_domain)

# All cpus belong to a common cpu_clk_domain, therefore running at a common
# frequency.
for cpu in system.cpu:
    cpu.clk_domain = system.cpu_clk_domain

# Sanity check
if options.fastmem:
    if CPUClass != AtomicSimpleCPU:
        fatal("Fastmem can only be used with atomic CPU!")
    if (options.caches or options.l2cache):
        fatal("You cannot use fastmem in combination with caches!")
if options.simpoint_profile:
    if not options.fastmem:
        # Atomic CPU checked with fastmem option already
        fatal("SimPoint generation should be done with atomic cpu and fastmem")
    if np > 1:
        fatal("SimPoint generation not supported with more than one CPUs")

for i in xrange(np):
    if options.smt:
        system.cpu[i].workload = multiprocesses
    elif len(multiprocesses) == 1:
        system.cpu[i].workload = multiprocesses[0]
    else:
        system.cpu[i].workload = multiprocesses[i]
    if options.fastmem:
        system.cpu[i].fastmem = True

    if options.simpoint_profile:
        system.cpu[i].simpoint_profile = True
        system.cpu[i].simpoint_interval = options.simpoint_interval

    if options.checker:
        system.cpu[i].addCheckerCpu()

    system.cpu[i].createThreads()

if options.ruby:
    if not (options.cpu_type == "detailed" or options.cpu_type == "timing"):
        print >> sys.stderr, "Ruby requires TimingSimpleCPU or O3CPU!!"
        sys.exit(1)

    # Set the option for physmem so that it is not allocated any space
    system.physmem = MemClass(range=AddrRange(options.mem_size),
                              null = True)

    options.use_map = True
    Ruby.create_system(options, system)
    assert(options.num_cpus == len(system.ruby._cpu_ruby_ports))

    for i in xrange(np):
        ruby_port = system.ruby._cpu_ruby_ports[i]

        # Create the interrupt controller and connect its ports to Ruby
        # Note that the interrupt controller is always present but only
        # in x86 does it have message ports that need to be connected
        system.cpu[i].createInterruptController()

        # Connect the cpu's cache ports to Ruby
        system.cpu[i].icache_port = ruby_port.slave
        system.cpu[i].dcache_port = ruby_port.slave
        if buildEnv['TARGET_ISA'] == 'x86':
            system.cpu[i].interrupts.pio = ruby_port.master
            system.cpu[i].interrupts.int_master = ruby_port.slave
            system.cpu[i].interrupts.int_slave = ruby_port.master
            system.cpu[i].itb.walker.port = ruby_port.slave
            system.cpu[i].dtb.walker.port = ruby_port.slave
else:
    system.membus = CoherentBus()
    system.system_port = system.membus.slave
    CacheConfig.config_cache(options, system)
    MemConfig_32.config_mem(options, system)

root = Root(full_system = False, system = system)
Simulation.run(options, root, system, FutureClass)


