1# Copyright (c) 2011-2015 Advanced Micro Devices, Inc. 2# All rights reserved. 3# 4# For use for simulation and test purposes only 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are met: 8# 9# 1. Redistributions of source code must retain the above copyright notice, 10# this list of conditions and the following disclaimer. 11# 12# 2. Redistributions in binary form must reproduce the above copyright notice, 13# this list of conditions and the following disclaimer in the documentation 14# and/or other materials provided with the distribution. 15# 16# 3. Neither the name of the copyright holder nor the names of its 17# contributors may be used to endorse or promote products derived from this 18# software without specific prior written permission. 19# 20# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30# POSSIBILITY OF SUCH DAMAGE. 31# 32# Authors: Lisa Hsu 33 34from __future__ import print_function 35from __future__ import absolute_import 36 37# Configure the TLB hierarchy 38# Places which would probably need to be modified if you 39# want a different hierarchy are specified by a <Modify here .. >' 40# comment 41import m5 42from m5.objects import * 43 44def TLB_constructor(level): 45 46 constructor_call = "X86GPUTLB(size = options.L%(level)dTLBentries, \ 47 assoc = options.L%(level)dTLBassoc, \ 48 hitLatency = options.L%(level)dAccessLatency,\ 49 missLatency2 = options.L%(level)dMissLatency,\ 50 maxOutstandingReqs = options.L%(level)dMaxOutstandingReqs,\ 51 accessDistance = options.L%(level)dAccessDistanceStat,\ 52 clk_domain = SrcClockDomain(\ 53 clock = options.GPUClock,\ 54 voltage_domain = VoltageDomain(\ 55 voltage = options.gpu_voltage)))" % locals() 56 return constructor_call 57 58def Coalescer_constructor(level): 59 60 constructor_call = "TLBCoalescer(probesPerCycle = \ 61 options.L%(level)dProbesPerCycle, \ 62 coalescingWindow = options.L%(level)dCoalescingWindow,\ 63 disableCoalescing = options.L%(level)dDisableCoalescing,\ 64 clk_domain = SrcClockDomain(\ 65 clock = options.GPUClock,\ 66 voltage_domain = VoltageDomain(\ 67 voltage = options.gpu_voltage)))" % locals() 68 return constructor_call 69 70def create_TLB_Coalescer(options, my_level, my_index, TLB_name, Coalescer_name): 71 # arguments: options, TLB level, number of private structures for this Level, 72 # TLB name and Coalescer name 73 for i in range(my_index): 74 TLB_name.append(eval(TLB_constructor(my_level))) 75 Coalescer_name.append(eval(Coalescer_constructor(my_level))) 76 77def config_tlb_hierarchy(options, system, shader_idx): 78 n_cu = options.num_compute_units 79 # Make this configurable now, instead of the hard coded val. The dispatcher 80 # is always the last item in the system.cpu list. 81 dispatcher_idx = len(system.cpu) - 1 82 83 if options.TLB_config == "perLane": 84 num_TLBs = 64 * n_cu 85 elif options.TLB_config == "mono": 86 num_TLBs = 1 87 elif options.TLB_config == "perCU": 88 num_TLBs = n_cu 89 elif options.TLB_config == "2CU": 90 num_TLBs = n_cu >> 1 91 else: 92 print("Bad option for TLB Configuration.") 93 sys.exit(1) 94 95 #---------------------------------------------------------------------------------------- 96 # A visual representation of the TLB hierarchy 97 # for ease of configuration 98 # < Modify here the width and the number of levels if you want a different configuration > 99 # width is the number of TLBs of the given type (i.e., D-TLB, I-TLB etc) for this level 100 L1 = [{'name': 'sqc', 'width': options.num_sqc, 'TLBarray': [], 'CoalescerArray': []}, 101 {'name': 'dispatcher', 'width': 1, 'TLBarray': [], 'CoalescerArray': []}, 102 {'name': 'l1', 'width': num_TLBs, 'TLBarray': [], 'CoalescerArray': []}] 103 104 L2 = [{'name': 'l2', 'width': 1, 'TLBarray': [], 'CoalescerArray': []}] 105 L3 = [{'name': 'l3', 'width': 1, 'TLBarray': [], 'CoalescerArray': []}] 106 107 TLB_hierarchy = [L1, L2, L3] 108 109 #---------------------------------------------------------------------------------------- 110 # Create the hiearchy 111 # Call the appropriate constructors and add objects to the system 112 113 for i in range(len(TLB_hierarchy)): 114 hierarchy_level = TLB_hierarchy[i] 115 level = i+1 116 for TLB_type in hierarchy_level: 117 TLB_index = TLB_type['width'] 118 TLB_array = TLB_type['TLBarray'] 119 Coalescer_array = TLB_type['CoalescerArray'] 120 # If the sim calls for a fixed L1 TLB size across CUs, 121 # override the TLB entries option 122 if options.tot_L1TLB_size: 123 options.L1TLBentries = options.tot_L1TLB_size / num_TLBs 124 if options.L1TLBassoc > options.L1TLBentries: 125 options.L1TLBassoc = options.L1TLBentries 126 # call the constructors for the TLB and the Coalescer 127 create_TLB_Coalescer(options, level, TLB_index,\ 128 TLB_array, Coalescer_array) 129 130 system_TLB_name = TLB_type['name'] + '_tlb' 131 system_Coalescer_name = TLB_type['name'] + '_coalescer' 132 133 # add the different TLB levels to the system 134 # Modify here if you want to make the TLB hierarchy a child of 135 # the shader. 136 exec('system.%s = TLB_array' % system_TLB_name) 137 exec('system.%s = Coalescer_array' % system_Coalescer_name) 138 139 #=========================================================== 140 # Specify the TLB hierarchy (i.e., port connections) 141 # All TLBs but the last level TLB need to have a memSidePort (master) 142 #=========================================================== 143 144 # Each TLB is connected with its Coalescer through a single port. 145 # There is a one-to-one mapping of TLBs to Coalescers at a given level 146 # This won't be modified no matter what the hierarchy looks like. 147 for i in range(len(TLB_hierarchy)): 148 hierarchy_level = TLB_hierarchy[i] 149 level = i+1 150 for TLB_type in hierarchy_level: 151 name = TLB_type['name'] 152 for index in range(TLB_type['width']): 153 exec('system.%s_coalescer[%d].master[0] = \ 154 system.%s_tlb[%d].slave[0]' % \ 155 (name, index, name, index)) 156 157 # Connect the cpuSidePort (slave) of all the coalescers in level 1 158 # < Modify here if you want a different configuration > 159 for TLB_type in L1: 160 name = TLB_type['name'] 161 num_TLBs = TLB_type['width'] 162 if name == 'l1': # L1 D-TLBs 163 tlb_per_cu = num_TLBs // n_cu 164 for cu_idx in range(n_cu): 165 if tlb_per_cu: 166 for tlb in range(tlb_per_cu): 167 exec('system.cpu[%d].CUs[%d].translation_port[%d] = \ 168 system.l1_coalescer[%d].slave[%d]' % \ 169 (shader_idx, cu_idx, tlb, cu_idx*tlb_per_cu+tlb, 0)) 170 else: 171 exec('system.cpu[%d].CUs[%d].translation_port[%d] = \ 172 system.l1_coalescer[%d].slave[%d]' % \ 173 (shader_idx, cu_idx, tlb_per_cu, cu_idx / (n_cu / num_TLBs), cu_idx % (n_cu / num_TLBs))) 174 175 elif name == 'dispatcher': # Dispatcher TLB 176 for index in range(TLB_type['width']): 177 exec('system.cpu[%d].translation_port = \ 178 system.dispatcher_coalescer[%d].slave[0]' % \ 179 (dispatcher_idx, index)) 180 elif name == 'sqc': # I-TLB 181 for index in range(n_cu): 182 sqc_tlb_index = index / options.cu_per_sqc 183 sqc_tlb_port_id = index % options.cu_per_sqc 184 exec('system.cpu[%d].CUs[%d].sqc_tlb_port = \ 185 system.sqc_coalescer[%d].slave[%d]' % \ 186 (shader_idx, index, sqc_tlb_index, sqc_tlb_port_id)) 187 188 189 # Connect the memSidePorts (masters) of all the TLBs with the 190 # cpuSidePorts (slaves) of the Coalescers of the next level 191 # < Modify here if you want a different configuration > 192 # L1 <-> L2 193 l2_coalescer_index = 0 194 for TLB_type in L1: 195 name = TLB_type['name'] 196 for index in range(TLB_type['width']): 197 exec('system.%s_tlb[%d].master[0] = \ 198 system.l2_coalescer[0].slave[%d]' % \ 199 (name, index, l2_coalescer_index)) 200 l2_coalescer_index += 1 201 # L2 <-> L3 202 system.l2_tlb[0].master[0] = system.l3_coalescer[0].slave[0] 203 204 return system 205