MOESI_CMP_token.py revision 11065
19793Sakash.bagdia@arm.com# Copyright (c) 2006-2007 The Regents of The University of Michigan 28706Sandreas.hansson@arm.com# Copyright (c) 2009 Advanced Micro Devices, Inc. 38706Sandreas.hansson@arm.com# All rights reserved. 48706Sandreas.hansson@arm.com# 58706Sandreas.hansson@arm.com# Redistribution and use in source and binary forms, with or without 68706Sandreas.hansson@arm.com# modification, are permitted provided that the following conditions are 78706Sandreas.hansson@arm.com# met: redistributions of source code must retain the above copyright 88706Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer; 98706Sandreas.hansson@arm.com# redistributions in binary form must reproduce the above copyright 108706Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer in the 118706Sandreas.hansson@arm.com# documentation and/or other materials provided with the distribution; 128706Sandreas.hansson@arm.com# neither the name of the copyright holders nor the names of its 135369Ssaidi@eecs.umich.edu# contributors may be used to endorse or promote products derived from 143005Sstever@eecs.umich.edu# this software without specific prior written permission. 153005Sstever@eecs.umich.edu# 163005Sstever@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 173005Sstever@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 183005Sstever@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 193005Sstever@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 203005Sstever@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 213005Sstever@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 223005Sstever@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 233005Sstever@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 243005Sstever@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 253005Sstever@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 263005Sstever@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 273005Sstever@eecs.umich.edu# 283005Sstever@eecs.umich.edu# Authors: Brad Beckmann 293005Sstever@eecs.umich.edu 303005Sstever@eecs.umich.eduimport math 313005Sstever@eecs.umich.eduimport m5 323005Sstever@eecs.umich.edufrom m5.objects import * 333005Sstever@eecs.umich.edufrom m5.defines import buildEnv 343005Sstever@eecs.umich.edufrom Ruby import create_topology 353005Sstever@eecs.umich.edufrom Ruby import send_evicts 363005Sstever@eecs.umich.edu 373005Sstever@eecs.umich.edu# 383005Sstever@eecs.umich.edu# Declare caches used by the protocol 393005Sstever@eecs.umich.edu# 403005Sstever@eecs.umich.educlass L1Cache(RubyCache): pass 412710SN/Aclass L2Cache(RubyCache): pass 422710SN/A 433005Sstever@eecs.umich.edudef define_options(parser): 442889SN/A parser.add_option("--l1-retries", type="int", default=1, 456654Snate@binkert.org help="Token_CMP: # of l1 retries before going persistent") 466654Snate@binkert.org parser.add_option("--timeout-latency", type="int", default=300, 479907Snilay@cs.wisc.edu help="Token_CMP: cycles until issuing again"); 486654Snate@binkert.org parser.add_option("--disable-dyn-timeouts", action="store_true", 492667SN/A help="Token_CMP: disable dyanimc timeouts, use fixed latency instead") 506654Snate@binkert.org parser.add_option("--allow-atomic-migration", action="store_true", 516654Snate@binkert.org help="allow migratory sharing for atomic only accessed blocks") 526654Snate@binkert.org 535457Ssaidi@eecs.umich.edudef create_system(options, full_system, system, dma_ports, ruby_system): 546654Snate@binkert.org 558169SLisa.Hsu@amd.com if buildEnv['PROTOCOL'] != 'MOESI_CMP_token': 568169SLisa.Hsu@amd.com panic("This script requires the MOESI_CMP_token protocol to be built.") 578920Snilay@cs.wisc.edu 588169SLisa.Hsu@amd.com # 593395Shsul@eecs.umich.edu # number of tokens that the owner passes to requests so that shared blocks can 606981SLisa.Hsu@amd.com # respond to read requests 619836Sandreas.hansson@arm.com # 623448Shsul@eecs.umich.edu n_tokens = options.num_cpus + 1 635369Ssaidi@eecs.umich.edu 643394Shsul@eecs.umich.edu cpu_sequencers = [] 659197Snilay@cs.wisc.edu 669197Snilay@cs.wisc.edu # 679197Snilay@cs.wisc.edu # The ruby network creation expects the list of nodes in the system to be 689197Snilay@cs.wisc.edu # consistent with the NetDest list. Therefore the l1 controller nodes must be 699197Snilay@cs.wisc.edu # listed before the directory nodes and directory nodes before dma nodes, etc. 709197Snilay@cs.wisc.edu # 719197Snilay@cs.wisc.edu l1_cntrl_nodes = [] 729197Snilay@cs.wisc.edu l2_cntrl_nodes = [] 739197Snilay@cs.wisc.edu dir_cntrl_nodes = [] 749197Snilay@cs.wisc.edu dma_cntrl_nodes = [] 759197Snilay@cs.wisc.edu 769197Snilay@cs.wisc.edu # 779197Snilay@cs.wisc.edu # Must create the individual controllers before the network to ensure the 789197Snilay@cs.wisc.edu # controller constructors are called before the network constructor 799197Snilay@cs.wisc.edu # 809197Snilay@cs.wisc.edu l2_bits = int(math.log(options.num_l2caches, 2)) 819197Snilay@cs.wisc.edu block_size_bits = int(math.log(options.cacheline_size, 2)) 829197Snilay@cs.wisc.edu 839197Snilay@cs.wisc.edu for i in xrange(options.num_cpus): 849197Snilay@cs.wisc.edu # 859197Snilay@cs.wisc.edu # First create the Ruby objects associated with this cpu 869197Snilay@cs.wisc.edu # 879197Snilay@cs.wisc.edu l1i_cache = L1Cache(size = options.l1i_size, 889907Snilay@cs.wisc.edu assoc = options.l1i_assoc, 899197Snilay@cs.wisc.edu start_index_bit = block_size_bits) 909197Snilay@cs.wisc.edu l1d_cache = L1Cache(size = options.l1d_size, 919217Snilay@cs.wisc.edu assoc = options.l1d_assoc, 929197Snilay@cs.wisc.edu start_index_bit = block_size_bits) 939197Snilay@cs.wisc.edu 949197Snilay@cs.wisc.edu l1_cntrl = L1Cache_Controller(version = i, 959197Snilay@cs.wisc.edu L1Icache = l1i_cache, 969197Snilay@cs.wisc.edu L1Dcache = l1d_cache, 979197Snilay@cs.wisc.edu l2_select_num_bits = l2_bits, 989197Snilay@cs.wisc.edu N_tokens = n_tokens, 999197Snilay@cs.wisc.edu retry_threshold = \ 1009197Snilay@cs.wisc.edu options.l1_retries, 1019197Snilay@cs.wisc.edu fixed_timeout_latency = \ 1029197Snilay@cs.wisc.edu options.timeout_latency, 1039197Snilay@cs.wisc.edu dynamic_timeout_enabled = \ 1049197Snilay@cs.wisc.edu not options.disable_dyn_timeouts, 1059197Snilay@cs.wisc.edu no_mig_atomic = not \ 1069197Snilay@cs.wisc.edu options.allow_atomic_migration, 1079197Snilay@cs.wisc.edu send_evictions = send_evicts(options), 1089197Snilay@cs.wisc.edu transitions_per_cycle = options.ports, 1099197Snilay@cs.wisc.edu clk_domain=system.cpu[i].clk_domain, 1109197Snilay@cs.wisc.edu ruby_system = ruby_system) 1119197Snilay@cs.wisc.edu 1122957SN/A cpu_seq = RubySequencer(version = i, 1138920Snilay@cs.wisc.edu icache = l1i_cache, 1148920Snilay@cs.wisc.edu dcache = l1d_cache, 1152957SN/A clk_domain=system.cpu[i].clk_domain, 1168862Snilay@cs.wisc.edu ruby_system = ruby_system) 1178862Snilay@cs.wisc.edu 1188467Snilay@cs.wisc.edu l1_cntrl.sequencer = cpu_seq 1192957SN/A exec("ruby_system.l1_cntrl%d = l1_cntrl" % i) 1202957SN/A 1212957SN/A # Add controllers and sequencers to the appropriate lists 1222957SN/A cpu_sequencers.append(cpu_seq) 1232957SN/A l1_cntrl_nodes.append(l1_cntrl) 1242957SN/A 1258167SLisa.Hsu@amd.com # Connect the L1 controllers and the network 1269197Snilay@cs.wisc.edu l1_cntrl.requestFromL1Cache = MessageBuffer() 1278167SLisa.Hsu@amd.com l1_cntrl.requestFromL1Cache.master = ruby_system.network.slave 1285369Ssaidi@eecs.umich.edu l1_cntrl.responseFromL1Cache = MessageBuffer() 1298167SLisa.Hsu@amd.com l1_cntrl.responseFromL1Cache.master = ruby_system.network.slave 1308167SLisa.Hsu@amd.com l1_cntrl.persistentFromL1Cache = MessageBuffer(ordered = True) 1318167SLisa.Hsu@amd.com l1_cntrl.persistentFromL1Cache.master = ruby_system.network.slave 1328167SLisa.Hsu@amd.com 1338167SLisa.Hsu@amd.com l1_cntrl.mandatoryQueue = MessageBuffer() 1348167SLisa.Hsu@amd.com l1_cntrl.requestToL1Cache = MessageBuffer() 1358167SLisa.Hsu@amd.com l1_cntrl.requestToL1Cache.slave = ruby_system.network.master 1368168SLisa.Hsu@amd.com l1_cntrl.responseToL1Cache = MessageBuffer() 13710037SARM gem5 Developers l1_cntrl.responseToL1Cache.slave = ruby_system.network.master 13810037SARM gem5 Developers l1_cntrl.persistentToL1Cache = MessageBuffer(ordered = True) 13910037SARM gem5 Developers l1_cntrl.persistentToL1Cache.slave = ruby_system.network.master 14010037SARM gem5 Developers 14110037SARM gem5 Developers 1428168SLisa.Hsu@amd.com l2_index_start = block_size_bits + l2_bits 14310037SARM gem5 Developers 14410037SARM gem5 Developers for i in xrange(options.num_l2caches): 1458167SLisa.Hsu@amd.com # 1468167SLisa.Hsu@amd.com # First create the Ruby objects associated with this cpu 14710118Snilay@cs.wisc.edu # 14810118Snilay@cs.wisc.edu l2_cache = L2Cache(size = options.l2_size, 1495369Ssaidi@eecs.umich.edu assoc = options.l2_assoc, 1508920Snilay@cs.wisc.edu start_index_bit = l2_index_start) 1519197Snilay@cs.wisc.edu 1528920Snilay@cs.wisc.edu l2_cntrl = L2Cache_Controller(version = i, 1538920Snilay@cs.wisc.edu L2cache = l2_cache, 1548920Snilay@cs.wisc.edu N_tokens = n_tokens, 1555369Ssaidi@eecs.umich.edu transitions_per_cycle = options.ports, 1565369Ssaidi@eecs.umich.edu ruby_system = ruby_system) 1578718Snilay@cs.wisc.edu 1589197Snilay@cs.wisc.edu exec("ruby_system.l2_cntrl%d = l2_cntrl" % i) 1599197Snilay@cs.wisc.edu l2_cntrl_nodes.append(l2_cntrl) 1609197Snilay@cs.wisc.edu 1619197Snilay@cs.wisc.edu # Connect the L2 controllers and the network 1629197Snilay@cs.wisc.edu l2_cntrl.GlobalRequestFromL2Cache = MessageBuffer() 1633005Sstever@eecs.umich.edu l2_cntrl.GlobalRequestFromL2Cache.master = ruby_system.network.slave 1643395Shsul@eecs.umich.edu l2_cntrl.L1RequestFromL2Cache = MessageBuffer() 1653395Shsul@eecs.umich.edu l2_cntrl.L1RequestFromL2Cache.master = ruby_system.network.slave 1669793Sakash.bagdia@arm.com l2_cntrl.responseFromL2Cache = MessageBuffer() 1679836Sandreas.hansson@arm.com l2_cntrl.responseFromL2Cache.master = ruby_system.network.slave 1689815SAndreas Hansson <andreas.hansson> 1699793Sakash.bagdia@arm.com l2_cntrl.GlobalRequestToL2Cache = MessageBuffer() 1709827Sakash.bagdia@arm.com l2_cntrl.GlobalRequestToL2Cache.slave = ruby_system.network.master 1719827Sakash.bagdia@arm.com l2_cntrl.L1RequestToL2Cache = MessageBuffer() 1729827Sakash.bagdia@arm.com l2_cntrl.L1RequestToL2Cache.slave = ruby_system.network.master 1739827Sakash.bagdia@arm.com l2_cntrl.responseToL2Cache = MessageBuffer() 1749827Sakash.bagdia@arm.com l2_cntrl.responseToL2Cache.slave = ruby_system.network.master 1759827Sakash.bagdia@arm.com l2_cntrl.persistentToL2Cache = MessageBuffer(ordered = True) 1769827Sakash.bagdia@arm.com l2_cntrl.persistentToL2Cache.slave = ruby_system.network.master 1779827Sakash.bagdia@arm.com 1789827Sakash.bagdia@arm.com 1799827Sakash.bagdia@arm.com phys_mem_size = sum(map(lambda r: r.size(), system.mem_ranges)) 1809793Sakash.bagdia@arm.com assert(phys_mem_size % options.num_dirs == 0) 1819827Sakash.bagdia@arm.com mem_module_size = phys_mem_size / options.num_dirs 1829827Sakash.bagdia@arm.com 1839827Sakash.bagdia@arm.com # Run each of the ruby memory controllers at a ratio of the frequency of 1849793Sakash.bagdia@arm.com # the ruby system 1859793Sakash.bagdia@arm.com # clk_divider value is a fix to pass regression. 1869793Sakash.bagdia@arm.com ruby_system.memctrl_clk_domain = DerivedClockDomain( 1879793Sakash.bagdia@arm.com clk_domain=ruby_system.clk_domain, 1889793Sakash.bagdia@arm.com clk_divider=3) 1893395Shsul@eecs.umich.edu 1908926Sandreas.hansson@arm.com for i in xrange(options.num_dirs): 1919317Sandreas.hansson@arm.com dir_size = MemorySize('0B') 1929317Sandreas.hansson@arm.com dir_size.value = mem_module_size 1939317Sandreas.hansson@arm.com 1949317Sandreas.hansson@arm.com dir_cntrl = Directory_Controller(version = i, 1959317Sandreas.hansson@arm.com directory = RubyDirectoryMemory( 1968926Sandreas.hansson@arm.com version = i, size = dir_size), 1979647Sdam.sunwoo@arm.com l2_select_num_bits = l2_bits, 1989647Sdam.sunwoo@arm.com transitions_per_cycle = options.ports, 1999647Sdam.sunwoo@arm.com ruby_system = ruby_system) 2009647Sdam.sunwoo@arm.com 2019647Sdam.sunwoo@arm.com exec("ruby_system.dir_cntrl%d = dir_cntrl" % i) 2029647Sdam.sunwoo@arm.com dir_cntrl_nodes.append(dir_cntrl) 2039647Sdam.sunwoo@arm.com 2043395Shsul@eecs.umich.edu # Connect the directory controllers and the network 2059197Snilay@cs.wisc.edu dir_cntrl.requestToDir = MessageBuffer() 2069197Snilay@cs.wisc.edu dir_cntrl.requestToDir.slave = ruby_system.network.master 2079197Snilay@cs.wisc.edu dir_cntrl.responseToDir = MessageBuffer() 2088957Sjayneel@cs.wisc.edu dir_cntrl.responseToDir.slave = ruby_system.network.master 2098957Sjayneel@cs.wisc.edu dir_cntrl.persistentToDir = MessageBuffer(ordered = True) 2108957Sjayneel@cs.wisc.edu dir_cntrl.persistentToDir.slave = ruby_system.network.master 2113005Sstever@eecs.umich.edu dir_cntrl.dmaRequestToDir = MessageBuffer(ordered = True) 2124968Sacolyte@umich.edu dir_cntrl.dmaRequestToDir.slave = ruby_system.network.master 2139006Sandreas.hansson@arm.com 2144968Sacolyte@umich.edu dir_cntrl.requestFromDir = MessageBuffer() 2159647Sdam.sunwoo@arm.com dir_cntrl.requestFromDir.master = ruby_system.network.slave 2169647Sdam.sunwoo@arm.com dir_cntrl.responseFromDir = MessageBuffer() 2179647Sdam.sunwoo@arm.com dir_cntrl.responseFromDir.master = ruby_system.network.slave 2189647Sdam.sunwoo@arm.com dir_cntrl.persistentFromDir = MessageBuffer(ordered = True) 2198887Sgeoffrey.blake@arm.com dir_cntrl.persistentFromDir.master = ruby_system.network.slave 2208887Sgeoffrey.blake@arm.com dir_cntrl.dmaResponseFromDir = MessageBuffer(ordered = True) 2218887Sgeoffrey.blake@arm.com dir_cntrl.dmaResponseFromDir.master = ruby_system.network.slave 2229384SAndreas.Sandberg@arm.com dir_cntrl.responseFromMemory = MessageBuffer() 2239384SAndreas.Sandberg@arm.com 2248887Sgeoffrey.blake@arm.com 2258896Snilay@cs.wisc.edu for i, dma_port in enumerate(dma_ports): 2268896Snilay@cs.wisc.edu # 2278896Snilay@cs.wisc.edu # Create the Ruby objects associated with the dma controller 2288896Snilay@cs.wisc.edu # 22910150Snilay@cs.wisc.edu dma_seq = DMASequencer(version = i, 23010150Snilay@cs.wisc.edu ruby_system = ruby_system, 23110150Snilay@cs.wisc.edu slave = dma_port) 23210150Snilay@cs.wisc.edu 2339836Sandreas.hansson@arm.com dma_cntrl = DMA_Controller(version = i, 23410092Snilay@cs.wisc.edu dma_sequencer = dma_seq, 23510117Snilay@cs.wisc.edu transitions_per_cycle = options.ports, 23610120Snilay@cs.wisc.edu ruby_system = ruby_system) 2378896Snilay@cs.wisc.edu 2388896Snilay@cs.wisc.edu exec("ruby_system.dma_cntrl%d = dma_cntrl" % i) 23910120Snilay@cs.wisc.edu dma_cntrl_nodes.append(dma_cntrl) 2408896Snilay@cs.wisc.edu 2418896Snilay@cs.wisc.edu # Connect the dma controller to the network 2429268Smalek.musleh@gmail.com dma_cntrl.mandatoryQueue = MessageBuffer() 2439268Smalek.musleh@gmail.com dma_cntrl.responseFromDir = MessageBuffer(ordered = True) 2448896Snilay@cs.wisc.edu dma_cntrl.responseFromDir.slave = ruby_system.network.master 2458896Snilay@cs.wisc.edu dma_cntrl.reqToDirectory = MessageBuffer() 2468896Snilay@cs.wisc.edu dma_cntrl.reqToDirectory.master = ruby_system.network.slave 2478896Snilay@cs.wisc.edu 2488896Snilay@cs.wisc.edu all_cntrls = l1_cntrl_nodes + \ 2499222Shestness@cs.wisc.edu l2_cntrl_nodes + \ 2509268Smalek.musleh@gmail.com dir_cntrl_nodes + \ 2519268Smalek.musleh@gmail.com dma_cntrl_nodes 2529268Smalek.musleh@gmail.com 2539222Shestness@cs.wisc.edu # Create the io controller and the sequencer 2549222Shestness@cs.wisc.edu if full_system: 2558887Sgeoffrey.blake@arm.com io_seq = DMASequencer(version=len(dma_ports), ruby_system=ruby_system) 25610150Snilay@cs.wisc.edu ruby_system._io_port = io_seq 2579756Snilay@cs.wisc.edu io_controller = DMA_Controller(version = len(dma_ports), 2588887Sgeoffrey.blake@arm.com dma_sequencer = io_seq, 2598887Sgeoffrey.blake@arm.com ruby_system = ruby_system) 2609836Sandreas.hansson@arm.com ruby_system.io_controller = io_controller 2618887Sgeoffrey.blake@arm.com 2628801Sgblack@eecs.umich.edu # Connect the dma controller to the network 2633481Shsul@eecs.umich.edu io_controller.mandatoryQueue = MessageBuffer() 264 io_controller.responseFromDir = MessageBuffer(ordered = True) 265 io_controller.responseFromDir.slave = ruby_system.network.master 266 io_controller.reqToDirectory = MessageBuffer() 267 io_controller.reqToDirectory.master = ruby_system.network.slave 268 269 all_cntrls = all_cntrls + [io_controller] 270 271 272 ruby_system.network.number_of_virtual_networks = 6 273 topology = create_topology(all_cntrls, options) 274 return (cpu_sequencers, dir_cntrl_nodes, topology) 275