# Copyright (c) 2011-2015 Advanced Micro Devices, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. 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.
#
# 3. Neither the name of the copyright holder 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 HOLDER 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.

# Configure the TLB hierarchy
# Places which would probably need to be modified if you
# want a different hierarchy are specified by a <Modify here .. >'
# comment
import m5
from m5.objects import *


def TLB_constructor(options, level, gpu_ctrl=None, full_system=False):

    if full_system:
        constructor_call = (
            "VegaGPUTLB(\
                gpu_device = gpu_ctrl, \
                size = options.L%(level)dTLBentries, \
                assoc = options.L%(level)dTLBassoc, \
                hitLatency = options.L%(level)dAccessLatency,\
                missLatency1 = options.L%(level)dMissLatency,\
                missLatency2 = options.L%(level)dMissLatency,\
                maxOutstandingReqs = options.L%(level)dMaxOutstandingReqs,\
                clk_domain = SrcClockDomain(\
                    clock = options.gpu_clock,\
                    voltage_domain = VoltageDomain(\
                        voltage = options.gpu_voltage)))"
            % locals()
        )
    else:
        constructor_call = (
            "X86GPUTLB(size = options.L%(level)dTLBentries, \
                assoc = options.L%(level)dTLBassoc, \
                hitLatency = options.L%(level)dAccessLatency,\
                missLatency2 = options.L%(level)dMissLatency,\
                maxOutstandingReqs = options.L%(level)dMaxOutstandingReqs,\
                accessDistance = options.L%(level)dAccessDistanceStat,\
                clk_domain = SrcClockDomain(\
                    clock = options.gpu_clock,\
                    voltage_domain = VoltageDomain(\
                        voltage = options.gpu_voltage)))"
            % locals()
        )
    return constructor_call


def Coalescer_constructor(options, level, full_system):

    if full_system:
        constructor_call = (
            "VegaTLBCoalescer(probesPerCycle = \
            options.L%(level)dProbesPerCycle, \
            tlb_level  = %(level)d ,\
            coalescingWindow = options.L%(level)dCoalescingWindow,\
            disableCoalescing = options.L%(level)dDisableCoalescing,\
            clk_domain = SrcClockDomain(\
                clock = options.gpu_clock,\
                voltage_domain = VoltageDomain(\
                    voltage = options.gpu_voltage)))"
            % locals()
        )
    else:
        constructor_call = (
            "TLBCoalescer(probesPerCycle = \
            options.L%(level)dProbesPerCycle, \
            coalescingWindow = options.L%(level)dCoalescingWindow,\
            disableCoalescing = options.L%(level)dDisableCoalescing,\
            clk_domain = SrcClockDomain(\
                clock = options.gpu_clock,\
                voltage_domain = VoltageDomain(\
                    voltage = options.gpu_voltage)))"
            % locals()
        )
    return constructor_call


def create_TLB_Coalescer(
    options,
    my_level,
    my_index,
    tlb_name,
    coalescer_name,
    gpu_ctrl=None,
    full_system=False,
):
    # arguments: options, TLB level, number of private structures for this
    # Level, TLB name and  Coalescer name
    for i in range(my_index):
        tlb_name.append(
            eval(TLB_constructor(options, my_level, gpu_ctrl, full_system))
        )
        coalescer_name.append(
            eval(Coalescer_constructor(options, my_level, full_system))
        )


def config_tlb_hierarchy(
    options, system, shader_idx, gpu_ctrl=None, full_system=False
):
    n_cu = options.num_compute_units

    if options.TLB_config == "perLane":
        num_TLBs = 64 * n_cu
    elif options.TLB_config == "mono":
        num_TLBs = 1
    elif options.TLB_config == "perCU":
        num_TLBs = n_cu
    elif options.TLB_config == "2CU":
        num_TLBs = n_cu >> 1
    else:
        print("Bad option for TLB Configuration.")
        sys.exit(1)

    # -------------------------------------------------------------------------
    # A visual representation of the TLB hierarchy
    # for ease of configuration
    # < Modify here the width and the number of levels if you want a different
    # configuration >
    # width is the number of TLBs of the given type (i.e., D-TLB, I-TLB etc)
    # for this level
    L1 = [
        {
            "name": "sqc",
            "width": options.num_sqc,
            "TLBarray": [],
            "CoalescerArray": [],
        },
        {
            "name": "scalar",
            "width": options.num_scalar_cache,
            "TLBarray": [],
            "CoalescerArray": [],
        },
        {
            "name": "l1",
            "width": num_TLBs,
            "TLBarray": [],
            "CoalescerArray": [],
        },
    ]

    L2 = [{"name": "l2", "width": 1, "TLBarray": [], "CoalescerArray": []}]
    L3 = [{"name": "l3", "width": 1, "TLBarray": [], "CoalescerArray": []}]

    TLB_hierarchy = [L1, L2, L3]

    # -------------------------------------------------------------------------
    # Create the hiearchy
    # Call the appropriate constructors and add objects to the system

    for i in range(len(TLB_hierarchy)):
        hierarchy_level = TLB_hierarchy[i]
        level = i + 1
        for TLB_type in hierarchy_level:
            TLB_index = TLB_type["width"]
            TLB_array = TLB_type["TLBarray"]
            Coalescer_array = TLB_type["CoalescerArray"]
            # If the sim calls for a fixed L1 TLB size across CUs,
            # override the TLB entries option
            if options.tot_L1TLB_size:
                options.L1TLBentries = options.tot_L1TLB_size / num_TLBs
                if options.L1TLBassoc > options.L1TLBentries:
                    options.L1TLBassoc = options.L1TLBentries
            # call the constructors for the TLB and the Coalescer
            create_TLB_Coalescer(
                options,
                level,
                TLB_index,
                TLB_array,
                Coalescer_array,
                gpu_ctrl,
                full_system,
            )

            system_TLB_name = TLB_type["name"] + "_tlb"
            system_Coalescer_name = TLB_type["name"] + "_coalescer"

            # add the different TLB levels to the system
            # Modify here if you want to make the TLB hierarchy a child of
            # the shader.
            exec("system.%s = TLB_array" % system_TLB_name)
            exec("system.%s = Coalescer_array" % system_Coalescer_name)

    # ===========================================================
    # Specify the TLB hierarchy (i.e., port connections)
    # All TLBs but the last level TLB need to have a memSidePort
    # ===========================================================

    # Each TLB is connected with its Coalescer through a single port.
    # There is a one-to-one mapping of TLBs to Coalescers at a given level
    # This won't be modified no matter what the hierarchy looks like.
    for i in range(len(TLB_hierarchy)):
        hierarchy_level = TLB_hierarchy[i]
        level = i + 1
        for TLB_type in hierarchy_level:
            name = TLB_type["name"]
            for index in range(TLB_type["width"]):
                exec(
                    "system.%s_coalescer[%d].mem_side_ports[0] = \
                        system.%s_tlb[%d].cpu_side_ports[0]"
                    % (name, index, name, index)
                )

    # Connect the cpuSidePort of all the coalescers in level 1
    # < Modify here if you want a different configuration >
    for TLB_type in L1:
        name = TLB_type["name"]
        num_TLBs = TLB_type["width"]
        if name == "l1":  # L1 D-TLBs
            tlb_per_cu = num_TLBs // n_cu
            for cu_idx in range(n_cu):
                if tlb_per_cu:
                    for tlb in range(tlb_per_cu):
                        exec(
                            "system.cpu[%d].CUs[%d].translation_port[%d] = \
                                system.l1_coalescer[%d].cpu_side_ports[%d]"
                            % (
                                shader_idx,
                                cu_idx,
                                tlb,
                                cu_idx * tlb_per_cu + tlb,
                                0,
                            )
                        )
                else:
                    exec(
                        "system.cpu[%d].CUs[%d].translation_port[%d] = \
                            system.l1_coalescer[%d].cpu_side_ports[%d]"
                        % (
                            shader_idx,
                            cu_idx,
                            tlb_per_cu,
                            cu_idx / (n_cu / num_TLBs),
                            cu_idx % (n_cu / num_TLBs),
                        )
                    )
        elif name == "sqc":  # I-TLB
            for index in range(n_cu):
                sqc_tlb_index = index / options.cu_per_sqc
                sqc_tlb_port_id = index % options.cu_per_sqc
                exec(
                    "system.cpu[%d].CUs[%d].sqc_tlb_port = \
                        system.sqc_coalescer[%d].cpu_side_ports[%d]"
                    % (shader_idx, index, sqc_tlb_index, sqc_tlb_port_id)
                )
        elif name == "scalar":  # Scalar D-TLB
            for index in range(n_cu):
                scalar_tlb_index = index / options.cu_per_scalar_cache
                scalar_tlb_port_id = index % options.cu_per_scalar_cache
                exec(
                    "system.cpu[%d].CUs[%d].scalar_tlb_port = \
                        system.scalar_coalescer[%d].cpu_side_ports[%d]"
                    % (shader_idx, index, scalar_tlb_index, scalar_tlb_port_id)
                )

    # Connect the memSidePorts of all the TLBs with the
    # cpuSidePorts of the Coalescers of the next level
    # < Modify here if you want a different configuration >
    # L1 <-> L2
    l2_coalescer_index = 0
    for TLB_type in L1:
        name = TLB_type["name"]
        for index in range(TLB_type["width"]):
            exec(
                "system.%s_tlb[%d].mem_side_ports[0] = \
                    system.l2_coalescer[0].cpu_side_ports[%d]"
                % (name, index, l2_coalescer_index)
            )
            l2_coalescer_index += 1

    # L2 <-> L3
    system.l2_tlb[0].mem_side_ports[0] = system.l3_coalescer[0].cpu_side_ports[
        0
    ]

    # L3 TLB Vega page table walker to memory for full system only
    if full_system:
        for TLB_type in L3:
            name = TLB_type["name"]
            for index in range(TLB_type["width"]):
                exec(
                    "system._dma_ports.append(system.%s_tlb[%d].walker)"
                    % (name, index)
                )

    return system
