# 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
