import sys
import argparse
import subprocess
from pprint import pprint

import m5
from m5.objects import *
from m5.util import *

addToPath("../")

from common import MemConfig
from common import HMC


def add_options(parser):
    parser.add_argument(
        "--external-memory-system",
        default=0,
        action="store",
        type=int,
        help="External memory system",
    )
    # TLM related options, currently optional in configs/common/MemConfig.py
    parser.add_argument(
        "--tlm-memory",
        action="store_true",
        help="use\
                        external port for SystemC TLM co-simulation. Default:\
                        no",
    )
    # Elastic traces related options, currently optional in
    # configs/common/MemConfig.py
    parser.add_argument(
        "--elastic-trace-en",
        action="store_true",
        help="enable capture of data dependency and\
                        instruction fetch traces using elastic trace\
                        probe.\nDefault: no",
    )
    # Options related to traffic generation
    parser.add_argument(
        "--num-tgen",
        default=4,
        action="store",
        type=int,
        choices=[4],
        help="number of traffic generators.\
                        Right now this script supports only 4.\nDefault: 4",
    )
    parser.add_argument(
        "--tgen-cfg-file",
        default="./configs/example/hmc_tgen.cfg",
        type=str,
        help="Traffic generator(s) configuration\
                        file. Note: this script uses the same configuration\
                        file for all traffic generators",
    )


# considering 4GB HMC device with following parameters
# hmc_device_size = '4GB'
# hmc_vault_size = '256MB'
# hmc_stack_size = 8
# hmc_bank_in_stack = 2
# hmc_bank_size = '16MB'
# hmc_bank_in_vault = 16
def build_system(options):
    # create the system we are going to simulate
    system = System()
    # use timing mode for the interaction between requestor-responder ports
    system.mem_mode = "timing"
    # set the clock frequency of the system
    clk = "100GHz"
    vd = VoltageDomain(voltage="1V")
    system.clk_domain = SrcClockDomain(clock=clk, voltage_domain=vd)
    # add traffic generators to the system
    system.tgen = [
        TrafficGen(config_file=options.tgen_cfg_file)
        for i in range(options.num_tgen)
    ]
    # Config memory system with given HMC arch
    MemConfig.config_mem(options, system)
    # Connect the traffic generatiors
    if options.arch == "distributed":
        for i in range(options.num_tgen):
            system.tgen[i].port = system.membus.cpu_side_ports
        # connect the system port even if it is not used in this example
        system.system_port = system.membus.cpu_side_ports
    if options.arch == "mixed":
        for i in range(int(options.num_tgen / 2)):
            system.tgen[i].port = system.membus.cpu_side_ports
        hh = system.hmc_host
        if options.enable_global_monitor:
            system.tgen[2].port = hh.lmonitor[2].cpu_side_port
            hh.lmonitor[2].mem_side_port = hh.seriallink[2].cpu_side_port
            system.tgen[3].port = hh.lmonitor[3].cpu_side_port
            hh.lmonitor[3].mem_side_port = hh.seriallink[3].cpu_side_port
        else:
            system.tgen[2].port = hh.seriallink[2].cpu_side_port
            system.tgen[3].port = hh.seriallink[3].cpu_side_port
        # connect the system port even if it is not used in this example
        system.system_port = system.membus.cpu_side_ports
    if options.arch == "same":
        hh = system.hmc_host
        for i in range(options.num_links_controllers):
            if options.enable_global_monitor:
                system.tgen[i].port = hh.lmonitor[i].cpu_side_port
            else:
                system.tgen[i].port = hh.seriallink[i].cpu_side_port
    # set up the root SimObject
    root = Root(full_system=False, system=system)
    return root


def main():
    parser = argparse.ArgumentParser(
        description="Simple system using HMC as\
                                     main memory"
    )
    HMC.add_options(parser)
    add_options(parser)
    options = parser.parse_args()
    # build the system
    root = build_system(options)
    # instantiate all of the objects we've created so far
    m5.instantiate()
    print("Beginning simulation!")
    event = m5.simulate(10000000000)
    m5.stats.dump()
    print(
        "Exiting @ tick %i because %s (exit code is %i)"
        % (m5.curTick(), event.getCause(), event.getCode())
    )
    print("Done")


if __name__ == "__m5_main__":
    main()
