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