MOESI_AMD_Base.py revision 13885:d10ea5e56cb0
12810SN/A# Copyright (c) 2010-2015 Advanced Micro Devices, Inc. 213427Sodanrc@yahoo.com.br# All rights reserved. 310771Sstephan.diestelhorst@arm.com# 410028SGiacomo.Gabrielli@arm.com# For use for simulation and test purposes only 510028SGiacomo.Gabrielli@arm.com# 610028SGiacomo.Gabrielli@arm.com# Redistribution and use in source and binary forms, with or without 710028SGiacomo.Gabrielli@arm.com# modification, are permitted provided that the following conditions are met: 810028SGiacomo.Gabrielli@arm.com# 910028SGiacomo.Gabrielli@arm.com# 1. Redistributions of source code must retain the above copyright notice, 1010028SGiacomo.Gabrielli@arm.com# this list of conditions and the following disclaimer. 1110028SGiacomo.Gabrielli@arm.com# 1210028SGiacomo.Gabrielli@arm.com# 2. Redistributions in binary form must reproduce the above copyright notice, 1310028SGiacomo.Gabrielli@arm.com# this list of conditions and the following disclaimer in the documentation 1410028SGiacomo.Gabrielli@arm.com# and/or other materials provided with the distribution. 152810SN/A# 162810SN/A# 3. Neither the name of the copyright holder nor the names of its 172810SN/A# contributors may be used to endorse or promote products derived from this 182810SN/A# software without specific prior written permission. 192810SN/A# 202810SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 212810SN/A# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 222810SN/A# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 232810SN/A# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 242810SN/A# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 252810SN/A# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 262810SN/A# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 272810SN/A# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 282810SN/A# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 292810SN/A# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 302810SN/A# POSSIBILITY OF SUCH DAMAGE. 312810SN/A# 322810SN/A# Authors: Lisa Hsu 332810SN/A 342810SN/Aimport math 352810SN/Aimport m5 362810SN/Afrom m5.objects import * 372810SN/Afrom m5.defines import buildEnv 382810SN/Afrom m5.util import addToPath 392810SN/Afrom Ruby import create_topology 402810SN/Afrom Ruby import send_evicts 412810SN/Aimport FileSystemConfig 4213427Sodanrc@yahoo.com.br 432810SN/AaddToPath('../') 442810SN/A 452810SN/Afrom topologies.Cluster import Cluster 462810SN/Afrom topologies.Crossbar import Crossbar 473861SN/A 482810SN/Aclass CntrlBase: 492810SN/A _seqs = 0 5010623Smitch.hayenga@arm.com @classmethod 5110623Smitch.hayenga@arm.com def seqCount(cls): 522810SN/A # Use SeqCount not class since we need global count 5312727Snikos.nikoleris@arm.com CntrlBase._seqs += 1 5411168Sandreas.hansson@arm.com return CntrlBase._seqs - 1 5513424Sodanrc@yahoo.com.br 5611168Sandreas.hansson@arm.com _cntrls = 0 5712727Snikos.nikoleris@arm.com @classmethod 5810623Smitch.hayenga@arm.com def cntrlCount(cls): 5913427Sodanrc@yahoo.com.br # Use CntlCount not class since we need global count 6012727Snikos.nikoleris@arm.com CntrlBase._cntrls += 1 6112727Snikos.nikoleris@arm.com return CntrlBase._cntrls - 1 6213427Sodanrc@yahoo.com.br 6312727Snikos.nikoleris@arm.com _version = 0 642810SN/A @classmethod 6510623Smitch.hayenga@arm.com def versionCount(cls): 662810SN/A cls._version += 1 # Use count for this particular type 672810SN/A return cls._version - 1 6810623Smitch.hayenga@arm.com 6910623Smitch.hayenga@arm.comclass L1DCache(RubyCache): 7010623Smitch.hayenga@arm.com resourceStalls = False 7110623Smitch.hayenga@arm.com def create(self, options): 725875Ssteve.reinhardt@amd.com self.size = MemorySize(options.l1d_size) 7310623Smitch.hayenga@arm.com self.assoc = options.l1d_assoc 7410623Smitch.hayenga@arm.com self.replacement_policy = PseudoLRUReplacementPolicy() 755875Ssteve.reinhardt@amd.com 7610623Smitch.hayenga@arm.comclass L1ICache(RubyCache): 7710623Smitch.hayenga@arm.com resourceStalls = False 7810623Smitch.hayenga@arm.com def create(self, options): 7910623Smitch.hayenga@arm.com self.size = MemorySize(options.l1i_size) 8013427Sodanrc@yahoo.com.br self.assoc = options.l1i_assoc 8113427Sodanrc@yahoo.com.br self.replacement_policy = PseudoLRUReplacementPolicy() 8213427Sodanrc@yahoo.com.br 8313427Sodanrc@yahoo.com.brclass L2Cache(RubyCache): 842810SN/A resourceStalls = False 8513426Sodanrc@yahoo.com.br def create(self, options): 8613426Sodanrc@yahoo.com.br self.size = MemorySize(options.l2_size) 8713426Sodanrc@yahoo.com.br self.assoc = options.l2_assoc 8813426Sodanrc@yahoo.com.br self.replacement_policy = PseudoLRUReplacementPolicy() 8913426Sodanrc@yahoo.com.br 9010623Smitch.hayenga@arm.comclass CPCntrl(CorePair_Controller, CntrlBase): 915875Ssteve.reinhardt@amd.com 9210623Smitch.hayenga@arm.com def create(self, options, ruby_system, system): 9310028SGiacomo.Gabrielli@arm.com self.version = self.versionCount() 942810SN/A 955875Ssteve.reinhardt@amd.com self.L1Icache = L1ICache() 965875Ssteve.reinhardt@amd.com self.L1Icache.create(options) 972810SN/A self.L1D0cache = L1DCache() 9810771Sstephan.diestelhorst@arm.com self.L1D0cache.create(options) 9910771Sstephan.diestelhorst@arm.com self.L1D1cache = L1DCache() 10010771Sstephan.diestelhorst@arm.com self.L1D1cache.create(options) 10113425Sodanrc@yahoo.com.br self.L2cache = L2Cache() 10213425Sodanrc@yahoo.com.br self.L2cache.create(options) 10313425Sodanrc@yahoo.com.br 10413425Sodanrc@yahoo.com.br self.sequencer = RubySequencer() 10513425Sodanrc@yahoo.com.br self.sequencer.icache_hit_latency = 2 10613425Sodanrc@yahoo.com.br self.sequencer.dcache_hit_latency = 2 10713427Sodanrc@yahoo.com.br self.sequencer.version = self.seqCount() 10813425Sodanrc@yahoo.com.br self.sequencer.icache = self.L1Icache 10913427Sodanrc@yahoo.com.br self.sequencer.dcache = self.L1D0cache 11013427Sodanrc@yahoo.com.br self.sequencer.ruby_system = ruby_system 11113424Sodanrc@yahoo.com.br self.sequencer.coreid = 0 11213425Sodanrc@yahoo.com.br self.sequencer.is_cpu_sequencer = True 11313425Sodanrc@yahoo.com.br 11413425Sodanrc@yahoo.com.br self.sequencer1 = RubySequencer() 11513425Sodanrc@yahoo.com.br self.sequencer1.version = self.seqCount() 11610771Sstephan.diestelhorst@arm.com self.sequencer1.icache = self.L1Icache 11713425Sodanrc@yahoo.com.br self.sequencer1.dcache = self.L1D1cache 11813425Sodanrc@yahoo.com.br self.sequencer1.icache_hit_latency = 2 11913425Sodanrc@yahoo.com.br self.sequencer1.dcache_hit_latency = 2 12013425Sodanrc@yahoo.com.br self.sequencer1.ruby_system = ruby_system 12113425Sodanrc@yahoo.com.br self.sequencer1.coreid = 1 12213425Sodanrc@yahoo.com.br self.sequencer1.is_cpu_sequencer = True 12313425Sodanrc@yahoo.com.br 12413425Sodanrc@yahoo.com.br self.issue_latency = options.cpu_to_dir_latency 12510771Sstephan.diestelhorst@arm.com self.send_evictions = send_evicts(options) 12613425Sodanrc@yahoo.com.br 12713425Sodanrc@yahoo.com.br self.ruby_system = ruby_system 12813425Sodanrc@yahoo.com.br 12913425Sodanrc@yahoo.com.br if options.recycle_latency: 13013425Sodanrc@yahoo.com.br self.recycle_latency = options.recycle_latency 13113425Sodanrc@yahoo.com.br 13213425Sodanrc@yahoo.com.brclass L3Cache(RubyCache): 13313425Sodanrc@yahoo.com.br assoc = 8 13410771Sstephan.diestelhorst@arm.com dataArrayBanks = 256 13510771Sstephan.diestelhorst@arm.com tagArrayBanks = 256 13610771Sstephan.diestelhorst@arm.com 13710771Sstephan.diestelhorst@arm.com def create(self, options, ruby_system, system): 13813425Sodanrc@yahoo.com.br self.size = MemorySize(options.l3_size) 13910771Sstephan.diestelhorst@arm.com self.size.value /= options.num_dirs 14013425Sodanrc@yahoo.com.br self.dataArrayBanks /= options.num_dirs 14113427Sodanrc@yahoo.com.br self.tagArrayBanks /= options.num_dirs 14213427Sodanrc@yahoo.com.br self.dataArrayBanks /= options.num_dirs 14313427Sodanrc@yahoo.com.br self.tagArrayBanks /= options.num_dirs 14413427Sodanrc@yahoo.com.br self.dataAccessLatency = options.l3_data_latency 14513427Sodanrc@yahoo.com.br self.tagAccessLatency = options.l3_tag_latency 14613425Sodanrc@yahoo.com.br self.resourceStalls = options.no_resource_stalls 14713425Sodanrc@yahoo.com.br self.replacement_policy = PseudoLRUReplacementPolicy() 14813425Sodanrc@yahoo.com.br 14913425Sodanrc@yahoo.com.brclass L3Cntrl(L3Cache_Controller, CntrlBase): 15013425Sodanrc@yahoo.com.br def create(self, options, ruby_system, system): 15113425Sodanrc@yahoo.com.br self.version = self.versionCount() 15210771Sstephan.diestelhorst@arm.com self.L3cache = L3Cache() 15313425Sodanrc@yahoo.com.br self.L3cache.create(options, ruby_system, system) 1542810SN/A 15513423Sodanrc@yahoo.com.br self.l3_response_latency = max(self.L3cache.dataAccessLatency, 15613425Sodanrc@yahoo.com.br self.L3cache.tagAccessLatency) 15713425Sodanrc@yahoo.com.br self.ruby_system = ruby_system 15813423Sodanrc@yahoo.com.br 15913425Sodanrc@yahoo.com.br if options.recycle_latency: 16013425Sodanrc@yahoo.com.br self.recycle_latency = options.recycle_latency 16113423Sodanrc@yahoo.com.br 16213425Sodanrc@yahoo.com.br def connectWireBuffers(self, req_to_dir, resp_to_dir, l3_unblock_to_dir, 16313423Sodanrc@yahoo.com.br req_to_l3, probe_to_l3, resp_to_l3): 16413425Sodanrc@yahoo.com.br self.reqToDir = req_to_dir 16513425Sodanrc@yahoo.com.br self.respToDir = resp_to_dir 16613425Sodanrc@yahoo.com.br self.l3UnblockToDir = l3_unblock_to_dir 16713425Sodanrc@yahoo.com.br self.reqToL3 = req_to_l3 16813425Sodanrc@yahoo.com.br self.probeToL3 = probe_to_l3 16913425Sodanrc@yahoo.com.br self.respToL3 = resp_to_l3 17013425Sodanrc@yahoo.com.br 17110053Smitch.hayenga+gem5@gmail.comclass DirCntrl(Directory_Controller, CntrlBase): 1722810SN/A def create(self, options, dir_ranges, ruby_system, system): 17310623Smitch.hayenga@arm.com self.version = self.versionCount() 1742810SN/A 17513551Sjavier.bueno@metempsy.com self.response_latency = 30 17613422Sodanrc@yahoo.com.br 1772810SN/A self.addr_ranges = dir_ranges 1782810SN/A self.directory = RubyDirectoryMemory() 17910623Smitch.hayenga@arm.com 180 self.L3CacheMemory = L3Cache() 181 self.L3CacheMemory.create(options, ruby_system, system) 182 183 self.l3_hit_latency = max(self.L3CacheMemory.dataAccessLatency, 184 self.L3CacheMemory.tagAccessLatency) 185 186 self.number_of_TBEs = options.num_tbes 187 188 self.ruby_system = ruby_system 189 190 if options.recycle_latency: 191 self.recycle_latency = options.recycle_latency 192 193 self.CPUonly = True 194 195 def connectWireBuffers(self, req_to_dir, resp_to_dir, l3_unblock_to_dir, 196 req_to_l3, probe_to_l3, resp_to_l3): 197 self.reqToDir = req_to_dir 198 self.respToDir = resp_to_dir 199 self.l3UnblockToDir = l3_unblock_to_dir 200 self.reqToL3 = req_to_l3 201 self.probeToL3 = probe_to_l3 202 self.respToL3 = resp_to_l3 203 204def define_options(parser): 205 parser.add_option("--num-subcaches", type="int", default=4) 206 parser.add_option("--l3-data-latency", type="int", default=20) 207 parser.add_option("--l3-tag-latency", type="int", default=15) 208 parser.add_option("--cpu-to-dir-latency", type="int", default=15) 209 parser.add_option("--no-resource-stalls", action="store_false", 210 default=True) 211 parser.add_option("--num-tbes", type="int", default=256) 212 parser.add_option("--l2-latency", type="int", default=50) # load to use 213 214def create_system(options, full_system, system, dma_devices, bootmem, 215 ruby_system): 216 if buildEnv['PROTOCOL'] != 'MOESI_AMD_Base': 217 panic("This script requires the MOESI_AMD_Base protocol.") 218 219 cpu_sequencers = [] 220 221 # 222 # The ruby network creation expects the list of nodes in the system to 223 # be consistent with the NetDest list. Therefore the l1 controller 224 # nodes must be listed before the directory nodes and directory nodes 225 # before dma nodes, etc. 226 # 227 l1_cntrl_nodes = [] 228 l3_cntrl_nodes = [] 229 dir_cntrl_nodes = [] 230 231 control_count = 0 232 233 # 234 # Must create the individual controllers before the network to ensure 235 # the controller constructors are called before the network constructor 236 # 237 238 # This is the base crossbar that connects the L3s, Dirs, and cpu 239 # Cluster 240 mainCluster = Cluster(extBW = 512, intBW = 512) # 1 TB/s 241 242 if options.numa_high_bit: 243 numa_bit = options.numa_high_bit 244 else: 245 # if the numa_bit is not specified, set the directory bits as the 246 # lowest bits above the block offset bits, and the numa_bit as the 247 # highest of those directory bits 248 dir_bits = int(math.log(options.num_dirs, 2)) 249 block_size_bits = int(math.log(options.cacheline_size, 2)) 250 numa_bit = block_size_bits + dir_bits - 1 251 252 for i in range(options.num_dirs): 253 dir_ranges = [] 254 for r in system.mem_ranges: 255 addr_range = m5.objects.AddrRange(r.start, size = r.size(), 256 intlvHighBit = numa_bit, 257 intlvBits = dir_bits, 258 intlvMatch = i) 259 dir_ranges.append(addr_range) 260 261 262 dir_cntrl = DirCntrl(TCC_select_num_bits = 0) 263 dir_cntrl.create(options, dir_ranges, ruby_system, system) 264 265 # Connect the Directory controller to the ruby network 266 dir_cntrl.requestFromCores = MessageBuffer(ordered = True) 267 dir_cntrl.requestFromCores.slave = ruby_system.network.master 268 269 dir_cntrl.responseFromCores = MessageBuffer() 270 dir_cntrl.responseFromCores.slave = ruby_system.network.master 271 272 dir_cntrl.unblockFromCores = MessageBuffer() 273 dir_cntrl.unblockFromCores.slave = ruby_system.network.master 274 275 dir_cntrl.probeToCore = MessageBuffer() 276 dir_cntrl.probeToCore.master = ruby_system.network.slave 277 278 dir_cntrl.responseToCore = MessageBuffer() 279 dir_cntrl.responseToCore.master = ruby_system.network.slave 280 281 dir_cntrl.triggerQueue = MessageBuffer(ordered = True) 282 dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True) 283 dir_cntrl.responseFromMemory = MessageBuffer() 284 285 exec("system.dir_cntrl%d = dir_cntrl" % i) 286 dir_cntrl_nodes.append(dir_cntrl) 287 288 mainCluster.add(dir_cntrl) 289 290 # Technically this config can support an odd number of cpus, but the top 291 # level config files, such as the ruby_random_tester, will get confused if 292 # the number of cpus does not equal the number of sequencers. Thus make 293 # sure that an even number of cpus is specified. 294 assert((options.num_cpus % 2) == 0) 295 296 # For an odd number of CPUs, still create the right number of controllers 297 cpuCluster = Cluster(extBW = 512, intBW = 512) # 1 TB/s 298 for i in range((options.num_cpus + 1) // 2): 299 300 cp_cntrl = CPCntrl() 301 cp_cntrl.create(options, ruby_system, system) 302 303 exec("system.cp_cntrl%d = cp_cntrl" % i) 304 # 305 # Add controllers and sequencers to the appropriate lists 306 # 307 cpu_sequencers.extend([cp_cntrl.sequencer, cp_cntrl.sequencer1]) 308 309 # Connect the CP controllers and the network 310 cp_cntrl.requestFromCore = MessageBuffer() 311 cp_cntrl.requestFromCore.master = ruby_system.network.slave 312 313 cp_cntrl.responseFromCore = MessageBuffer() 314 cp_cntrl.responseFromCore.master = ruby_system.network.slave 315 316 cp_cntrl.unblockFromCore = MessageBuffer() 317 cp_cntrl.unblockFromCore.master = ruby_system.network.slave 318 319 cp_cntrl.probeToCore = MessageBuffer() 320 cp_cntrl.probeToCore.slave = ruby_system.network.master 321 322 cp_cntrl.responseToCore = MessageBuffer() 323 cp_cntrl.responseToCore.slave = ruby_system.network.master 324 325 cp_cntrl.mandatoryQueue = MessageBuffer() 326 cp_cntrl.triggerQueue = MessageBuffer(ordered = True) 327 328 cpuCluster.add(cp_cntrl) 329 330 # Register CPUs and caches for each CorePair and directory (SE mode only) 331 if not full_system: 332 FileSystemConfig.config_filesystem(options) 333 for i in xrange((options.num_cpus + 1) // 2): 334 FileSystemConfig.register_cpu(physical_package_id = 0, 335 core_siblings = 336 xrange(options.num_cpus), 337 core_id = i*2, 338 thread_siblings = []) 339 340 FileSystemConfig.register_cpu(physical_package_id = 0, 341 core_siblings = 342 xrange(options.num_cpus), 343 core_id = i*2+1, 344 thread_siblings = []) 345 346 FileSystemConfig.register_cache(level = 0, 347 idu_type = 'Instruction', 348 size = options.l1i_size, 349 line_size = options.cacheline_size, 350 assoc = options.l1i_assoc, 351 cpus = [i*2, i*2+1]) 352 353 FileSystemConfig.register_cache(level = 0, 354 idu_type = 'Data', 355 size = options.l1d_size, 356 line_size = options.cacheline_size, 357 assoc = options.l1d_assoc, 358 cpus = [i*2]) 359 360 FileSystemConfig.register_cache(level = 0, 361 idu_type = 'Data', 362 size = options.l1d_size, 363 line_size = options.cacheline_size, 364 assoc = options.l1d_assoc, 365 cpus = [i*2+1]) 366 367 FileSystemConfig.register_cache(level = 1, 368 idu_type = 'Unified', 369 size = options.l2_size, 370 line_size = options.cacheline_size, 371 assoc = options.l2_assoc, 372 cpus = [i*2, i*2+1]) 373 374 for i in range(options.num_dirs): 375 FileSystemConfig.register_cache(level = 2, 376 idu_type = 'Unified', 377 size = options.l3_size, 378 line_size = options.cacheline_size, 379 assoc = options.l3_assoc, 380 cpus = [n for n in 381 xrange(options.num_cpus)]) 382 383 # Assuming no DMA devices 384 assert(len(dma_devices) == 0) 385 386 # Add cpu/gpu clusters to main cluster 387 mainCluster.add(cpuCluster) 388 389 ruby_system.network.number_of_virtual_networks = 10 390 391 return (cpu_sequencers, dir_cntrl_nodes, mainCluster) 392