Mesh_XY.py revision 13731
112334Sgabeblack@google.com# Copyright (c) 2010 Advanced Micro Devices, Inc.
212334Sgabeblack@google.com#               2016 Georgia Institute of Technology
312334Sgabeblack@google.com# All rights reserved.
412334Sgabeblack@google.com#
512334Sgabeblack@google.com# Redistribution and use in source and binary forms, with or without
612334Sgabeblack@google.com# modification, are permitted provided that the following conditions are
712334Sgabeblack@google.com# met: redistributions of source code must retain the above copyright
812334Sgabeblack@google.com# notice, this list of conditions and the following disclaimer;
912334Sgabeblack@google.com# redistributions in binary form must reproduce the above copyright
1012334Sgabeblack@google.com# notice, this list of conditions and the following disclaimer in the
1112334Sgabeblack@google.com# documentation and/or other materials provided with the distribution;
1212334Sgabeblack@google.com# neither the name of the copyright holders nor the names of its
1312334Sgabeblack@google.com# contributors may be used to endorse or promote products derived from
1412334Sgabeblack@google.com# this software without specific prior written permission.
1512334Sgabeblack@google.com#
1612334Sgabeblack@google.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712334Sgabeblack@google.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812334Sgabeblack@google.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912334Sgabeblack@google.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012334Sgabeblack@google.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112334Sgabeblack@google.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212334Sgabeblack@google.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312334Sgabeblack@google.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412334Sgabeblack@google.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512334Sgabeblack@google.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612334Sgabeblack@google.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712334Sgabeblack@google.com#
2812334Sgabeblack@google.com# Authors: Brad Beckmann
2912334Sgabeblack@google.com#          Tushar Krishna
3012334Sgabeblack@google.com
3112334Sgabeblack@google.comfrom m5.params import *
3212334Sgabeblack@google.comfrom m5.objects import *
3312334Sgabeblack@google.com
3412334Sgabeblack@google.comfrom BaseTopology import SimpleTopology
3512334Sgabeblack@google.com
3612334Sgabeblack@google.com# Creates a generic Mesh assuming an equal number of cache
3712334Sgabeblack@google.com# and directory controllers.
3812334Sgabeblack@google.com# XY routing is enforced (using link weights)
3912334Sgabeblack@google.com# to guarantee deadlock freedom.
4012334Sgabeblack@google.com
4112334Sgabeblack@google.comclass Mesh_XY(SimpleTopology):
4212334Sgabeblack@google.com    description='Mesh_XY'
4312334Sgabeblack@google.com
4412334Sgabeblack@google.com    def __init__(self, controllers):
4512334Sgabeblack@google.com        self.nodes = controllers
4612334Sgabeblack@google.com
4712334Sgabeblack@google.com    # Makes a generic mesh
4812334Sgabeblack@google.com    # assuming an equal number of cache and directory cntrls
4912375Sgabeblack@google.com
5012334Sgabeblack@google.com    def makeTopology(self, options, network, IntLink, ExtLink, Router):
5112334Sgabeblack@google.com        nodes = self.nodes
5212334Sgabeblack@google.com
5312334Sgabeblack@google.com        num_routers = options.num_cpus
5412334Sgabeblack@google.com        num_rows = options.mesh_rows
5512334Sgabeblack@google.com
5612334Sgabeblack@google.com        # default values for link latency and router latency.
5712334Sgabeblack@google.com        # Can be over-ridden on a per link/router basis
5812375Sgabeblack@google.com        link_latency = options.link_latency # used by simple and garnet
5912375Sgabeblack@google.com        router_latency = options.router_latency # only used by garnet
6012375Sgabeblack@google.com
6112375Sgabeblack@google.com
6212375Sgabeblack@google.com        # There must be an evenly divisible number of cntrls to routers
6312375Sgabeblack@google.com        # Also, obviously the number or rows must be <= the number of routers
6412375Sgabeblack@google.com        cntrls_per_router, remainder = divmod(len(nodes), num_routers)
6512375Sgabeblack@google.com        assert(num_rows > 0 and num_rows <= num_routers)
6612334Sgabeblack@google.com        num_columns = int(num_routers / num_rows)
6712375Sgabeblack@google.com        assert(num_columns * num_rows == num_routers)
6812334Sgabeblack@google.com
6912334Sgabeblack@google.com        # Create the routers in the mesh
7012334Sgabeblack@google.com        routers = [Router(router_id=i, latency = router_latency) \
7112375Sgabeblack@google.com            for i in range(num_routers)]
7212375Sgabeblack@google.com        network.routers = routers
7312375Sgabeblack@google.com
7412375Sgabeblack@google.com        # link counter to set unique link ids
7512375Sgabeblack@google.com        link_count = 0
7612375Sgabeblack@google.com
7712375Sgabeblack@google.com        # Add all but the remainder nodes to the list of nodes to be uniformly
7812375Sgabeblack@google.com        # distributed across the network.
7912375Sgabeblack@google.com        network_nodes = []
8012334Sgabeblack@google.com        remainder_nodes = []
8112375Sgabeblack@google.com        for node_index in range(len(nodes)):
8212375Sgabeblack@google.com            if node_index < (len(nodes) - remainder):
8312375Sgabeblack@google.com                network_nodes.append(nodes[node_index])
8412375Sgabeblack@google.com            else:
8512375Sgabeblack@google.com                remainder_nodes.append(nodes[node_index])
8612375Sgabeblack@google.com
8712334Sgabeblack@google.com        # Connect each node to the appropriate router
8812375Sgabeblack@google.com        ext_links = []
8912375Sgabeblack@google.com        for (i, n) in enumerate(network_nodes):
9012375Sgabeblack@google.com            cntrl_level, router_id = divmod(i, num_routers)
9112375Sgabeblack@google.com            assert(cntrl_level < cntrls_per_router)
9212375Sgabeblack@google.com            ext_links.append(ExtLink(link_id=link_count, ext_node=n,
9312334Sgabeblack@google.com                                    int_node=routers[router_id],
9412334Sgabeblack@google.com                                    latency = link_latency))
9512375Sgabeblack@google.com            link_count += 1
9612375Sgabeblack@google.com
9712334Sgabeblack@google.com        # Connect the remainding nodes to router 0.  These should only be
9812375Sgabeblack@google.com        # DMA nodes.
9912375Sgabeblack@google.com        for (i, node) in enumerate(remainder_nodes):
10012375Sgabeblack@google.com            assert(node.type == 'DMA_Controller')
10112375Sgabeblack@google.com            assert(i < remainder)
10212334Sgabeblack@google.com            ext_links.append(ExtLink(link_id=link_count, ext_node=node,
10312334Sgabeblack@google.com                                    int_node=routers[0],
10412375Sgabeblack@google.com                                    latency = link_latency))
10512334Sgabeblack@google.com            link_count += 1
10612334Sgabeblack@google.com
10712334Sgabeblack@google.com        network.ext_links = ext_links
10812375Sgabeblack@google.com
10912334Sgabeblack@google.com        # Create the mesh links.
11012375Sgabeblack@google.com        int_links = []
11112375Sgabeblack@google.com
11212375Sgabeblack@google.com        # East output to West input links (weight = 1)
11312334Sgabeblack@google.com        for row in range(num_rows):
11412334Sgabeblack@google.com            for col in range(num_columns):
11512375Sgabeblack@google.com                if (col + 1 < num_columns):
11612375Sgabeblack@google.com                    east_out = col + (row * num_columns)
11712375Sgabeblack@google.com                    west_in = (col + 1) + (row * num_columns)
11812375Sgabeblack@google.com                    int_links.append(IntLink(link_id=link_count,
11912375Sgabeblack@google.com                                             src_node=routers[east_out],
12012334Sgabeblack@google.com                                             dst_node=routers[west_in],
12112375Sgabeblack@google.com                                             src_outport="East",
12212375Sgabeblack@google.com                                             dst_inport="West",
12312375Sgabeblack@google.com                                             latency = link_latency,
12412375Sgabeblack@google.com                                             weight=1))
12512334Sgabeblack@google.com                    link_count += 1
12612334Sgabeblack@google.com
12712375Sgabeblack@google.com        # West output to East input links (weight = 1)
12812375Sgabeblack@google.com        for row in range(num_rows):
12912375Sgabeblack@google.com            for col in range(num_columns):
13012375Sgabeblack@google.com                if (col + 1 < num_columns):
13112375Sgabeblack@google.com                    east_in = col + (row * num_columns)
13212334Sgabeblack@google.com                    west_out = (col + 1) + (row * num_columns)
13312334Sgabeblack@google.com                    int_links.append(IntLink(link_id=link_count,
13412334Sgabeblack@google.com                                             src_node=routers[west_out],
13512375Sgabeblack@google.com                                             dst_node=routers[east_in],
13612375Sgabeblack@google.com                                             src_outport="West",
13712375Sgabeblack@google.com                                             dst_inport="East",
13812375Sgabeblack@google.com                                             latency = link_latency,
13912375Sgabeblack@google.com                                             weight=1))
14012375Sgabeblack@google.com                    link_count += 1
14112375Sgabeblack@google.com
14212375Sgabeblack@google.com        # North output to South input links (weight = 2)
14312375Sgabeblack@google.com        for col in range(num_columns):
14412375Sgabeblack@google.com            for row in range(num_rows):
14512375Sgabeblack@google.com                if (row + 1 < num_rows):
14612375Sgabeblack@google.com                    north_out = col + (row * num_columns)
14712375Sgabeblack@google.com                    south_in = col + ((row + 1) * num_columns)
14812375Sgabeblack@google.com                    int_links.append(IntLink(link_id=link_count,
14912375Sgabeblack@google.com                                             src_node=routers[north_out],
15012375Sgabeblack@google.com                                             dst_node=routers[south_in],
15112375Sgabeblack@google.com                                             src_outport="North",
15212375Sgabeblack@google.com                                             dst_inport="South",
15312334Sgabeblack@google.com                                             latency = link_latency,
15412334Sgabeblack@google.com                                             weight=2))
15512375Sgabeblack@google.com                    link_count += 1
15612375Sgabeblack@google.com
15712375Sgabeblack@google.com        # South output to North input links (weight = 2)
15812375Sgabeblack@google.com        for col in range(num_columns):
15912375Sgabeblack@google.com            for row in range(num_rows):
16012334Sgabeblack@google.com                if (row + 1 < num_rows):
16112375Sgabeblack@google.com                    north_in = col + (row * num_columns)
16212375Sgabeblack@google.com                    south_out = col + ((row + 1) * num_columns)
16312375Sgabeblack@google.com                    int_links.append(IntLink(link_id=link_count,
16412375Sgabeblack@google.com                                             src_node=routers[south_out],
16512375Sgabeblack@google.com                                             dst_node=routers[north_in],
16612375Sgabeblack@google.com                                             src_outport="South",
16712375Sgabeblack@google.com                                             dst_inport="North",
16812375Sgabeblack@google.com                                             latency = link_latency,
16912375Sgabeblack@google.com                                             weight=2))
17012375Sgabeblack@google.com                    link_count += 1
17112375Sgabeblack@google.com
17212375Sgabeblack@google.com
17312375Sgabeblack@google.com        network.int_links = int_links
17412375Sgabeblack@google.com