MOESI_CMP_token.py revision 10519
12810SN/A# Copyright (c) 2006-2007 The Regents of The University of Michigan
28856Sandreas.hansson@arm.com# Copyright (c) 2009 Advanced Micro Devices, Inc.
38856Sandreas.hansson@arm.com# All rights reserved.
48856Sandreas.hansson@arm.com#
58856Sandreas.hansson@arm.com# Redistribution and use in source and binary forms, with or without
68856Sandreas.hansson@arm.com# modification, are permitted provided that the following conditions are
78856Sandreas.hansson@arm.com# met: redistributions of source code must retain the above copyright
88856Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer;
98856Sandreas.hansson@arm.com# redistributions in binary form must reproduce the above copyright
108856Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer in the
118856Sandreas.hansson@arm.com# documentation and/or other materials provided with the distribution;
128856Sandreas.hansson@arm.com# neither the name of the copyright holders nor the names of its
138856Sandreas.hansson@arm.com# contributors may be used to endorse or promote products derived from
142810SN/A# this software without specific prior written permission.
152810SN/A#
162810SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172810SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182810SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192810SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202810SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212810SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222810SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232810SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242810SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252810SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262810SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272810SN/A#
282810SN/A# Authors: Brad Beckmann
292810SN/A
302810SN/Aimport math
312810SN/Aimport m5
322810SN/Afrom m5.objects import *
332810SN/Afrom m5.defines import buildEnv
342810SN/Afrom Ruby import create_topology
352810SN/A
362810SN/A#
372810SN/A# Note: the L1 Cache latency is only used by the sequencer on fast path hits
382810SN/A#
392810SN/Aclass L1Cache(RubyCache):
402810SN/A    latency = 2
412810SN/A
422810SN/A#
432810SN/A# Note: the L2 Cache latency is not currently used
442810SN/A#
452810SN/Aclass L2Cache(RubyCache):
462810SN/A    latency = 10
472810SN/A
483348SN/Adef define_options(parser):
493348SN/A    parser.add_option("--l1-retries", type="int", default=1,
508232Snate@binkert.org                      help="Token_CMP: # of l1 retries before going persistent")
515338Sstever@gmail.com    parser.add_option("--timeout-latency", type="int", default=300,
525338Sstever@gmail.com                      help="Token_CMP: cycles until issuing again");
538786Sgblack@eecs.umich.edu    parser.add_option("--disable-dyn-timeouts", action="store_true",
542810SN/A          help="Token_CMP: disable dyanimc timeouts, use fixed latency instead")
552810SN/A    parser.add_option("--allow-atomic-migration", action="store_true",
562810SN/A          help="allow migratory sharing for atomic only accessed blocks")
578856Sandreas.hansson@arm.com
588856Sandreas.hansson@arm.comdef create_system(options, full_system, system, dma_ports, ruby_system):
598856Sandreas.hansson@arm.com
608914Sandreas.hansson@arm.com    if buildEnv['PROTOCOL'] != 'MOESI_CMP_token':
618914Sandreas.hansson@arm.com        panic("This script requires the MOESI_CMP_token protocol to be built.")
628856Sandreas.hansson@arm.com
638856Sandreas.hansson@arm.com    #
644475SN/A    # number of tokens that the owner passes to requests so that shared blocks can
655034SN/A    # respond to read requests
665034SN/A    #
675314SN/A    n_tokens = options.num_cpus + 1
685314SN/A
694628SN/A    cpu_sequencers = []
705034SN/A
715034SN/A    #
725034SN/A    # The ruby network creation expects the list of nodes in the system to be
736122SSteve.Reinhardt@amd.com    # consistent with the NetDest list.  Therefore the l1 controller nodes must be
748134SAli.Saidi@ARM.com    # listed before the directory nodes and directory nodes before dma nodes, etc.
754626SN/A    #
764626SN/A    l1_cntrl_nodes = []
775034SN/A    l2_cntrl_nodes = []
786122SSteve.Reinhardt@amd.com    dir_cntrl_nodes = []
798883SAli.Saidi@ARM.com    dma_cntrl_nodes = []
808833Sdam.sunwoo@arm.com
814458SN/A    #
822810SN/A    # Must create the individual controllers before the network to ensure the
832810SN/A    # controller constructors are called before the network constructor
843013SN/A    #
858856Sandreas.hansson@arm.com    l2_bits = int(math.log(options.num_l2caches, 2))
862810SN/A    block_size_bits = int(math.log(options.cacheline_size, 2))
873013SN/A
888856Sandreas.hansson@arm.com    for i in xrange(options.num_cpus):
892810SN/A        #
902810SN/A        # First create the Ruby objects associated with this cpu
912810SN/A        #
922810SN/A        l1i_cache = L1Cache(size = options.l1i_size,
938856Sandreas.hansson@arm.com                            assoc = options.l1i_assoc,
942810SN/A                            start_index_bit = block_size_bits)
953013SN/A        l1d_cache = L1Cache(size = options.l1d_size,
968856Sandreas.hansson@arm.com                            assoc = options.l1d_assoc,
973013SN/A                            start_index_bit = block_size_bits)
988856Sandreas.hansson@arm.com
998856Sandreas.hansson@arm.com        l1_cntrl = L1Cache_Controller(version = i,
1002897SN/A                                      L1Icache = l1i_cache,
1014666SN/A                                      L1Dcache = l1d_cache,
1028856Sandreas.hansson@arm.com                                      l2_select_num_bits = l2_bits,
1032897SN/A                                      N_tokens = n_tokens,
1042810SN/A                                      retry_threshold = \
1052810SN/A                                        options.l1_retries,
1062844SN/A                                      fixed_timeout_latency = \
1072810SN/A                                        options.timeout_latency,
1082858SN/A                                      dynamic_timeout_enabled = \
1092858SN/A                                        not options.disable_dyn_timeouts,
1108856Sandreas.hansson@arm.com                                      no_mig_atomic = not \
1118856Sandreas.hansson@arm.com                                        options.allow_atomic_migration,
1128711Sandreas.hansson@arm.com                                      send_evictions = (
1132858SN/A                                          options.cpu_type == "detailed"),
1142858SN/A                                      transitions_per_cycle = options.ports,
1154628SN/A                                      clk_domain=system.cpu[i].clk_domain,
1162858SN/A                                      ruby_system = ruby_system)
1172810SN/A
1182810SN/A        cpu_seq = RubySequencer(version = i,
1192810SN/A                                icache = l1i_cache,
1202810SN/A                                dcache = l1d_cache,
1212810SN/A                                clk_domain=system.cpu[i].clk_domain,
1224022SN/A                                ruby_system = ruby_system)
1234022SN/A
1244022SN/A        l1_cntrl.sequencer = cpu_seq
1252810SN/A        exec("ruby_system.l1_cntrl%d = l1_cntrl" % i)
1262810SN/A
1278833Sdam.sunwoo@arm.com        # Add controllers and sequencers to the appropriate lists
1282810SN/A        cpu_sequencers.append(cpu_seq)
1292810SN/A        l1_cntrl_nodes.append(l1_cntrl)
1302810SN/A
1312810SN/A        # Connect the L1 controllers and the network
1328833Sdam.sunwoo@arm.com        l1_cntrl.requestFromL1Cache =  ruby_system.network.slave
1338833Sdam.sunwoo@arm.com        l1_cntrl.responseFromL1Cache =  ruby_system.network.slave
1348833Sdam.sunwoo@arm.com        l1_cntrl.persistentFromL1Cache =  ruby_system.network.slave
1352810SN/A
1362810SN/A        l1_cntrl.requestToL1Cache =  ruby_system.network.master
1374871SN/A        l1_cntrl.responseToL1Cache =  ruby_system.network.master
1384871SN/A        l1_cntrl.persistentToL1Cache =  ruby_system.network.master
1394871SN/A
1404871SN/A
1414871SN/A    l2_index_start = block_size_bits + l2_bits
1424871SN/A
1434871SN/A    for i in xrange(options.num_l2caches):
1444871SN/A        #
1454871SN/A        # First create the Ruby objects associated with this cpu
1464871SN/A        #
1472810SN/A        l2_cache = L2Cache(size = options.l2_size,
1482810SN/A                           assoc = options.l2_assoc,
1492810SN/A                           start_index_bit = l2_index_start)
1508833Sdam.sunwoo@arm.com
1512810SN/A        l2_cntrl = L2Cache_Controller(version = i,
1524871SN/A                                      L2cache = l2_cache,
1538833Sdam.sunwoo@arm.com                                      N_tokens = n_tokens,
1548833Sdam.sunwoo@arm.com                                      transitions_per_cycle = options.ports,
1558833Sdam.sunwoo@arm.com                                      ruby_system = ruby_system)
1562810SN/A
1572810SN/A        exec("ruby_system.l2_cntrl%d = l2_cntrl" % i)
1582810SN/A        l2_cntrl_nodes.append(l2_cntrl)
1592810SN/A
1608833Sdam.sunwoo@arm.com        # Connect the L2 controllers and the network
1612810SN/A        l2_cntrl.GlobalRequestFromL2Cache = ruby_system.network.slave
1624871SN/A        l2_cntrl.L1RequestFromL2Cache = ruby_system.network.slave
1638833Sdam.sunwoo@arm.com        l2_cntrl.responseFromL2Cache = ruby_system.network.slave
1648833Sdam.sunwoo@arm.com
1658833Sdam.sunwoo@arm.com        l2_cntrl.GlobalRequestToL2Cache = ruby_system.network.master
1662810SN/A        l2_cntrl.L1RequestToL2Cache = ruby_system.network.master
1672810SN/A        l2_cntrl.responseToL2Cache = ruby_system.network.master
1684022SN/A        l2_cntrl.persistentToL2Cache = ruby_system.network.master
1694022SN/A
1704022SN/A
1712810SN/A    phys_mem_size = sum(map(lambda r: r.size(), system.mem_ranges))
1722810SN/A    assert(phys_mem_size % options.num_dirs == 0)
1738833Sdam.sunwoo@arm.com    mem_module_size = phys_mem_size / options.num_dirs
1742810SN/A
1752810SN/A    # Run each of the ruby memory controllers at a ratio of the frequency of
1762810SN/A    # the ruby system
1772810SN/A    # clk_divider value is a fix to pass regression.
1788833Sdam.sunwoo@arm.com    ruby_system.memctrl_clk_domain = DerivedClockDomain(
1798833Sdam.sunwoo@arm.com                                          clk_domain=ruby_system.clk_domain,
1808833Sdam.sunwoo@arm.com                                          clk_divider=3)
1812810SN/A
1822810SN/A    for i in xrange(options.num_dirs):
1832810SN/A        #
1842810SN/A        # Create the Ruby objects associated with the directory controller
1852810SN/A        #
1868833Sdam.sunwoo@arm.com
1872810SN/A        mem_cntrl = RubyMemoryControl(
1884871SN/A                              clk_domain = ruby_system.memctrl_clk_domain,
1898833Sdam.sunwoo@arm.com                              version = i,
1908833Sdam.sunwoo@arm.com                              ruby_system = ruby_system)
1918833Sdam.sunwoo@arm.com
1922810SN/A        dir_size = MemorySize('0B')
1932810SN/A        dir_size.value = mem_module_size
1942810SN/A
1952810SN/A        dir_cntrl = Directory_Controller(version = i,
1968833Sdam.sunwoo@arm.com                                         directory = \
1972810SN/A                                         RubyDirectoryMemory(version = i,
1984871SN/A                                             use_map = options.use_map,
1998833Sdam.sunwoo@arm.com                                             size = dir_size),
2008833Sdam.sunwoo@arm.com                                         memBuffer = mem_cntrl,
2018833Sdam.sunwoo@arm.com                                         l2_select_num_bits = l2_bits,
2022810SN/A                                         transitions_per_cycle = options.ports,
2032810SN/A                                         ruby_system = ruby_system)
2044022SN/A
2054022SN/A        exec("ruby_system.dir_cntrl%d = dir_cntrl" % i)
2064022SN/A        dir_cntrl_nodes.append(dir_cntrl)
2072810SN/A
2082810SN/A        # Connect the directory controllers and the network
2098833Sdam.sunwoo@arm.com        dir_cntrl.requestToDir = ruby_system.network.master
2102810SN/A        dir_cntrl.responseToDir = ruby_system.network.master
2112810SN/A        dir_cntrl.persistentToDir = ruby_system.network.master
2122810SN/A        dir_cntrl.dmaRequestToDir = ruby_system.network.master
2132810SN/A
2148833Sdam.sunwoo@arm.com        dir_cntrl.requestFromDir = ruby_system.network.slave
2158833Sdam.sunwoo@arm.com        dir_cntrl.responseFromDir = ruby_system.network.slave
2168833Sdam.sunwoo@arm.com        dir_cntrl.persistentFromDir = ruby_system.network.slave
2172810SN/A        dir_cntrl.dmaResponseFromDir = ruby_system.network.slave
2182810SN/A
2192810SN/A
2202810SN/A    for i, dma_port in enumerate(dma_ports):
2212810SN/A        #
2228833Sdam.sunwoo@arm.com        # Create the Ruby objects associated with the dma controller
2232810SN/A        #
2244871SN/A        dma_seq = DMASequencer(version = i,
2258833Sdam.sunwoo@arm.com                               ruby_system = ruby_system,
2268833Sdam.sunwoo@arm.com                               slave = dma_port)
2278833Sdam.sunwoo@arm.com
2282810SN/A        dma_cntrl = DMA_Controller(version = i,
2292810SN/A                                   dma_sequencer = dma_seq,
2302810SN/A                                   transitions_per_cycle = options.ports,
2312810SN/A                                   ruby_system = ruby_system)
2328833Sdam.sunwoo@arm.com
2332810SN/A        exec("ruby_system.dma_cntrl%d = dma_cntrl" % i)
2344871SN/A        dma_cntrl_nodes.append(dma_cntrl)
2358833Sdam.sunwoo@arm.com
2368833Sdam.sunwoo@arm.com        # Connect the dma controller to the network
2378833Sdam.sunwoo@arm.com        dma_cntrl.responseFromDir = ruby_system.network.master
2382810SN/A        dma_cntrl.reqToDirectory = ruby_system.network.slave
2392810SN/A
2404022SN/A    all_cntrls = l1_cntrl_nodes + \
2414022SN/A                 l2_cntrl_nodes + \
2424022SN/A                 dir_cntrl_nodes + \
2432810SN/A                 dma_cntrl_nodes
2442810SN/A
2452810SN/A    # Create the io controller and the sequencer
2462810SN/A    if full_system:
2472810SN/A        io_seq = DMASequencer(version=len(dma_ports), ruby_system=ruby_system)
2482810SN/A        ruby_system._io_port = io_seq
2498833Sdam.sunwoo@arm.com        io_controller = DMA_Controller(version = len(dma_ports),
2502810SN/A                                       dma_sequencer = io_seq,
2518833Sdam.sunwoo@arm.com                                       ruby_system = ruby_system)
2528833Sdam.sunwoo@arm.com        ruby_system.io_controller = io_controller
2538833Sdam.sunwoo@arm.com
2542810SN/A        # Connect the dma controller to the network
2552810SN/A        io_controller.responseFromDir = ruby_system.network.master
2562810SN/A        io_controller.reqToDirectory = ruby_system.network.slave
2572810SN/A
2582810SN/A        all_cntrls = all_cntrls + [io_controller]
2598833Sdam.sunwoo@arm.com
2602810SN/A
2612810SN/A    topology = create_topology(all_cntrls, options)
2628833Sdam.sunwoo@arm.com    return (cpu_sequencers, dir_cntrl_nodes, topology)
2638833Sdam.sunwoo@arm.com