Mesh_westfirst.py revision 13731
12391SN/A# Copyright (c) 2010 Advanced Micro Devices, Inc.
28931Sandreas.hansson@arm.com#               2016 Georgia Institute of Technology
38931Sandreas.hansson@arm.com# All rights reserved.
48931Sandreas.hansson@arm.com#
58931Sandreas.hansson@arm.com# Redistribution and use in source and binary forms, with or without
68931Sandreas.hansson@arm.com# modification, are permitted provided that the following conditions are
78931Sandreas.hansson@arm.com# met: redistributions of source code must retain the above copyright
88931Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer;
98931Sandreas.hansson@arm.com# redistributions in binary form must reproduce the above copyright
108931Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer in the
118931Sandreas.hansson@arm.com# documentation and/or other materials provided with the distribution;
128931Sandreas.hansson@arm.com# neither the name of the copyright holders nor the names of its
138931Sandreas.hansson@arm.com# contributors may be used to endorse or promote products derived from
142391SN/A# this software without specific prior written permission.
152391SN/A#
162391SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172391SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182391SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192391SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202391SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212391SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222391SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232391SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242391SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252391SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262391SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272391SN/A#
282391SN/A# Authors: Brad Beckmann
292391SN/A#          Tushar Krishna
302391SN/A
312391SN/Afrom m5.params import *
322391SN/Afrom m5.objects import *
332391SN/A
342391SN/Afrom BaseTopology import SimpleTopology
352391SN/A
362391SN/A# Creates a generic Mesh assuming an equal number of cache
372391SN/A# and directory controllers.
382391SN/A# West-first routing is enforced (using link weights)
392665SN/A# to guarantee deadlock freedom.
402665SN/A# The network randomly chooses between links with the same
418931Sandreas.hansson@arm.com# weight for messages within unordered virtual networks.
422391SN/A# Within ordered virtual networks, a fixed link direction
432391SN/A# is always chosen based on which appears first inside the
448931Sandreas.hansson@arm.com# routing table.
458931Sandreas.hansson@arm.com
468931Sandreas.hansson@arm.comclass Mesh_westfirst(SimpleTopology):
472391SN/A    description='Mesh_westfirst'
482391SN/A
498931Sandreas.hansson@arm.com    def __init__(self, controllers):
508931Sandreas.hansson@arm.com        self.nodes = controllers
512391SN/A
522462SN/A    # Makes a generic mesh
538931Sandreas.hansson@arm.com    # assuming an equal number of cache and directory cntrls
548719SN/A
552462SN/A    def makeTopology(self, options, network, IntLink, ExtLink, Router):
569053Sdam.sunwoo@arm.com        nodes = self.nodes
579053Sdam.sunwoo@arm.com
589053Sdam.sunwoo@arm.com        num_routers = options.num_cpus
598931Sandreas.hansson@arm.com        num_rows = options.mesh_rows
609293Sandreas.hansson@arm.com
619293Sandreas.hansson@arm.com        # default values for link latency and router latency.
629293Sandreas.hansson@arm.com        # Can be over-ridden on a per link/router basis
639293Sandreas.hansson@arm.com        link_latency = options.link_latency # used by simple and garnet
649293Sandreas.hansson@arm.com        router_latency = options.router_latency # only used by garnet
659293Sandreas.hansson@arm.com
669293Sandreas.hansson@arm.com        # There must be an evenly divisible number of cntrls to routers
679293Sandreas.hansson@arm.com        # Also, obviously the number or rows must be <= the number of routers
689293Sandreas.hansson@arm.com        cntrls_per_router, remainder = divmod(len(nodes), num_routers)
699293Sandreas.hansson@arm.com        assert(num_rows > 0 and num_rows <= num_routers)
709293Sandreas.hansson@arm.com        num_columns = int(num_routers / num_rows)
719293Sandreas.hansson@arm.com        assert(num_columns * num_rows == num_routers)
729293Sandreas.hansson@arm.com
739293Sandreas.hansson@arm.com        # Create the routers in the mesh
749293Sandreas.hansson@arm.com        routers = [Router(router_id=i, latency=router_latency) \
759293Sandreas.hansson@arm.com            for i in range(num_routers)]
769293Sandreas.hansson@arm.com        network.routers = routers
7711005Sandreas.sandberg@arm.com
789293Sandreas.hansson@arm.com        # link counter to set unique link ids
799293Sandreas.hansson@arm.com        link_count = 0
809293Sandreas.hansson@arm.com
819293Sandreas.hansson@arm.com        # Add all but the remainder nodes to the list of nodes to be uniformly
829293Sandreas.hansson@arm.com        # distributed across the network.
839293Sandreas.hansson@arm.com        network_nodes = []
849293Sandreas.hansson@arm.com        remainder_nodes = []
859293Sandreas.hansson@arm.com        for node_index in range(len(nodes)):
869293Sandreas.hansson@arm.com            if node_index < (len(nodes) - remainder):
879293Sandreas.hansson@arm.com                network_nodes.append(nodes[node_index])
889293Sandreas.hansson@arm.com            else:
899293Sandreas.hansson@arm.com                remainder_nodes.append(nodes[node_index])
909293Sandreas.hansson@arm.com
919293Sandreas.hansson@arm.com        # Connect each node to the appropriate router
929293Sandreas.hansson@arm.com        ext_links = []
939293Sandreas.hansson@arm.com        for (i, n) in enumerate(network_nodes):
949293Sandreas.hansson@arm.com            cntrl_level, router_id = divmod(i, num_routers)
959293Sandreas.hansson@arm.com            assert(cntrl_level < cntrls_per_router)
969293Sandreas.hansson@arm.com            ext_links.append(ExtLink(link_id=link_count, ext_node=n,
978931Sandreas.hansson@arm.com                                    int_node=routers[router_id],
988931Sandreas.hansson@arm.com                                    latency = link_latency))
998931Sandreas.hansson@arm.com            link_count += 1
1008931Sandreas.hansson@arm.com
1018931Sandreas.hansson@arm.com        # Connect the remainding nodes to router 0.  These should only be
1028931Sandreas.hansson@arm.com        # DMA nodes.
1038931Sandreas.hansson@arm.com        for (i, node) in enumerate(remainder_nodes):
1042391SN/A            assert(node.type == 'DMA_Controller')
1056107SN/A            assert(i < remainder)
1066107SN/A            ext_links.append(ExtLink(link_id=link_count, ext_node=node,
1078931Sandreas.hansson@arm.com                                    int_node=routers[0],
1089235Sandreas.hansson@arm.com                                    latency = link_latency))
1092413SN/A            link_count += 1
1108931Sandreas.hansson@arm.com
1118931Sandreas.hansson@arm.com        network.ext_links = ext_links
1122413SN/A
1138931Sandreas.hansson@arm.com        # Create the mesh links.
1148931Sandreas.hansson@arm.com        int_links = []
1152413SN/A
1168931Sandreas.hansson@arm.com        # East output to West input links (weight = 2)
1178931Sandreas.hansson@arm.com        for row in range(num_rows):
1183170SN/A            for col in range(num_columns):
1193170SN/A                if (col + 1 < num_columns):
1203170SN/A                    east_out = col + (row * num_columns)
1213170SN/A                    west_in = (col + 1) + (row * num_columns)
1223170SN/A                    int_links.append(IntLink(link_id=link_count,
1233170SN/A                                             src_node=routers[east_out],
1243170SN/A                                             dst_node=routers[west_in],
1254626SN/A                                             latency = link_latency,
1263170SN/A                                             weight=2))
1273170SN/A                    link_count += 1
1283170SN/A
1293170SN/A        # West output to East input links (weight = 1)
1304626SN/A        for row in range(num_rows):
1313170SN/A            for col in range(num_columns):
1323170SN/A                if (col + 1 < num_columns):
1333170SN/A                    east_in = col + (row * num_columns)
1343170SN/A                    west_out = (col + 1) + (row * num_columns)
1353170SN/A                    int_links.append(IntLink(link_id=link_count,
1363170SN/A                                             src_node=routers[west_out],
1373170SN/A                                             dst_node=routers[east_in],
1383170SN/A                                             latency = link_latency,
1394626SN/A                                             weight=1))
1404626SN/A                    link_count += 1
1413170SN/A
1423170SN/A
1436102SN/A        # North output to South input links (weight = 2)
1446102SN/A        for col in range(num_columns):
1454040SN/A            for row in range(num_rows):
1463170SN/A                if (row + 1 < num_rows):
1476102SN/A                    north_out = col + (row * num_columns)
1483170SN/A                    south_in = col + ((row + 1) * num_columns)
1493170SN/A                    int_links.append(IntLink(link_id=link_count,
1504626SN/A                                             src_node=routers[north_out],
1513170SN/A                                             dst_node=routers[south_in],
1523170SN/A                                             latency = link_latency,
1533170SN/A                                             weight=2))
1548719SN/A                    link_count += 1
1559053Sdam.sunwoo@arm.com
1568719SN/A        # South output to North input links (weight = 2)
1579053Sdam.sunwoo@arm.com        for col in range(num_columns):
1588719SN/A            for row in range(num_rows):
1599053Sdam.sunwoo@arm.com                if (row + 1 < num_rows):
1608719SN/A                    north_in = col + (row * num_columns)
1619053Sdam.sunwoo@arm.com                    south_out = col + ((row + 1) * num_columns)
1628719SN/A                    int_links.append(IntLink(link_id=link_count,
1639053Sdam.sunwoo@arm.com                                             src_node=routers[south_out],
1648719SN/A                                             dst_node=routers[north_in],
1659053Sdam.sunwoo@arm.com                                             latency = link_latency,
1668719SN/A                                             weight=2))
1678719SN/A                    link_count += 1
1688719SN/A
1698719SN/A
1708719SN/A        network.int_links = int_links
1718719SN/A