Mesh_XY.py revision 13774:a1be2a0c55f2
110995Sandreas.sandberg@arm.com# Copyright (c) 2010 Advanced Micro Devices, Inc. 210995Sandreas.sandberg@arm.com# 2016 Georgia Institute of Technology 310995Sandreas.sandberg@arm.com# All rights reserved. 410995Sandreas.sandberg@arm.com# 510995Sandreas.sandberg@arm.com# Redistribution and use in source and binary forms, with or without 610995Sandreas.sandberg@arm.com# modification, are permitted provided that the following conditions are 710995Sandreas.sandberg@arm.com# met: redistributions of source code must retain the above copyright 810995Sandreas.sandberg@arm.com# notice, this list of conditions and the following disclaimer; 910995Sandreas.sandberg@arm.com# redistributions in binary form must reproduce the above copyright 1010995Sandreas.sandberg@arm.com# notice, this list of conditions and the following disclaimer in the 1110995Sandreas.sandberg@arm.com# documentation and/or other materials provided with the distribution; 1210995Sandreas.sandberg@arm.com# neither the name of the copyright holders nor the names of its 1310995Sandreas.sandberg@arm.com# contributors may be used to endorse or promote products derived from 1410995Sandreas.sandberg@arm.com# this software without specific prior written permission. 1510995Sandreas.sandberg@arm.com# 1610995Sandreas.sandberg@arm.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1710995Sandreas.sandberg@arm.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1810995Sandreas.sandberg@arm.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1910995Sandreas.sandberg@arm.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2010995Sandreas.sandberg@arm.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2110995Sandreas.sandberg@arm.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2210995Sandreas.sandberg@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2310995Sandreas.sandberg@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2410995Sandreas.sandberg@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2510995Sandreas.sandberg@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2610995Sandreas.sandberg@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2710995Sandreas.sandberg@arm.com# 2810995Sandreas.sandberg@arm.com# Authors: Brad Beckmann 2910995Sandreas.sandberg@arm.com# Tushar Krishna 3010995Sandreas.sandberg@arm.com 3110995Sandreas.sandberg@arm.comfrom __future__ import print_function 3210995Sandreas.sandberg@arm.comfrom __future__ import absolute_import 3310995Sandreas.sandberg@arm.com 3410995Sandreas.sandberg@arm.comfrom m5.params import * 3510995Sandreas.sandberg@arm.comfrom m5.objects import * 3610995Sandreas.sandberg@arm.com 3710995Sandreas.sandberg@arm.comfrom .BaseTopology import SimpleTopology 3810995Sandreas.sandberg@arm.com 3910995Sandreas.sandberg@arm.com# Creates a generic Mesh assuming an equal number of cache 4010995Sandreas.sandberg@arm.com# and directory controllers. 4110995Sandreas.sandberg@arm.com# XY routing is enforced (using link weights) 4210995Sandreas.sandberg@arm.com# to guarantee deadlock freedom. 4310995Sandreas.sandberg@arm.com 4410995Sandreas.sandberg@arm.comclass Mesh_XY(SimpleTopology): 4510995Sandreas.sandberg@arm.com description='Mesh_XY' 4610995Sandreas.sandberg@arm.com 4710995Sandreas.sandberg@arm.com def __init__(self, controllers): 4810995Sandreas.sandberg@arm.com self.nodes = controllers 4910995Sandreas.sandberg@arm.com 5010995Sandreas.sandberg@arm.com # Makes a generic mesh 5110995Sandreas.sandberg@arm.com # assuming an equal number of cache and directory cntrls 5210995Sandreas.sandberg@arm.com 5310995Sandreas.sandberg@arm.com def makeTopology(self, options, network, IntLink, ExtLink, Router): 5410995Sandreas.sandberg@arm.com nodes = self.nodes 5510995Sandreas.sandberg@arm.com 5610995Sandreas.sandberg@arm.com num_routers = options.num_cpus 5710995Sandreas.sandberg@arm.com num_rows = options.mesh_rows 5810995Sandreas.sandberg@arm.com 5910995Sandreas.sandberg@arm.com # default values for link latency and router latency. 6010995Sandreas.sandberg@arm.com # Can be over-ridden on a per link/router basis 6110995Sandreas.sandberg@arm.com link_latency = options.link_latency # used by simple and garnet 6210995Sandreas.sandberg@arm.com router_latency = options.router_latency # only used by garnet 6310995Sandreas.sandberg@arm.com 6410995Sandreas.sandberg@arm.com 6510995Sandreas.sandberg@arm.com # There must be an evenly divisible number of cntrls to routers 6610995Sandreas.sandberg@arm.com # Also, obviously the number or rows must be <= the number of routers 6710995Sandreas.sandberg@arm.com cntrls_per_router, remainder = divmod(len(nodes), num_routers) 6810995Sandreas.sandberg@arm.com assert(num_rows > 0 and num_rows <= num_routers) 6910995Sandreas.sandberg@arm.com num_columns = int(num_routers / num_rows) 7010995Sandreas.sandberg@arm.com assert(num_columns * num_rows == num_routers) 7110995Sandreas.sandberg@arm.com 7210995Sandreas.sandberg@arm.com # Create the routers in the mesh 7310995Sandreas.sandberg@arm.com routers = [Router(router_id=i, latency = router_latency) \ 7410995Sandreas.sandberg@arm.com for i in range(num_routers)] 7510995Sandreas.sandberg@arm.com network.routers = routers 7610995Sandreas.sandberg@arm.com 7710995Sandreas.sandberg@arm.com # link counter to set unique link ids 7810995Sandreas.sandberg@arm.com link_count = 0 7910995Sandreas.sandberg@arm.com 8010995Sandreas.sandberg@arm.com # Add all but the remainder nodes to the list of nodes to be uniformly 8110995Sandreas.sandberg@arm.com # distributed across the network. 8210995Sandreas.sandberg@arm.com network_nodes = [] 8310995Sandreas.sandberg@arm.com remainder_nodes = [] 8410995Sandreas.sandberg@arm.com for node_index in range(len(nodes)): 8510995Sandreas.sandberg@arm.com if node_index < (len(nodes) - remainder): 8610995Sandreas.sandberg@arm.com network_nodes.append(nodes[node_index]) 8710995Sandreas.sandberg@arm.com else: 8810995Sandreas.sandberg@arm.com remainder_nodes.append(nodes[node_index]) 8910995Sandreas.sandberg@arm.com 9010995Sandreas.sandberg@arm.com # Connect each node to the appropriate router 9110995Sandreas.sandberg@arm.com ext_links = [] 9210995Sandreas.sandberg@arm.com for (i, n) in enumerate(network_nodes): 9310995Sandreas.sandberg@arm.com cntrl_level, router_id = divmod(i, num_routers) 9410995Sandreas.sandberg@arm.com assert(cntrl_level < cntrls_per_router) 9510995Sandreas.sandberg@arm.com ext_links.append(ExtLink(link_id=link_count, ext_node=n, 9610995Sandreas.sandberg@arm.com int_node=routers[router_id], 9710995Sandreas.sandberg@arm.com latency = link_latency)) 9810995Sandreas.sandberg@arm.com link_count += 1 9910995Sandreas.sandberg@arm.com 10010995Sandreas.sandberg@arm.com # Connect the remainding nodes to router 0. These should only be 10110995Sandreas.sandberg@arm.com # DMA nodes. 10210995Sandreas.sandberg@arm.com for (i, node) in enumerate(remainder_nodes): 10310995Sandreas.sandberg@arm.com assert(node.type == 'DMA_Controller') 10410995Sandreas.sandberg@arm.com assert(i < remainder) 10510995Sandreas.sandberg@arm.com ext_links.append(ExtLink(link_id=link_count, ext_node=node, 10610995Sandreas.sandberg@arm.com int_node=routers[0], 10710995Sandreas.sandberg@arm.com latency = link_latency)) 10810995Sandreas.sandberg@arm.com link_count += 1 10910995Sandreas.sandberg@arm.com 11010995Sandreas.sandberg@arm.com network.ext_links = ext_links 11110995Sandreas.sandberg@arm.com 11210995Sandreas.sandberg@arm.com # Create the mesh links. 11310995Sandreas.sandberg@arm.com int_links = [] 11410995Sandreas.sandberg@arm.com 11510995Sandreas.sandberg@arm.com # East output to West input links (weight = 1) 11610995Sandreas.sandberg@arm.com for row in range(num_rows): 11710995Sandreas.sandberg@arm.com for col in range(num_columns): 11810995Sandreas.sandberg@arm.com if (col + 1 < num_columns): 11910995Sandreas.sandberg@arm.com east_out = col + (row * num_columns) 12010995Sandreas.sandberg@arm.com west_in = (col + 1) + (row * num_columns) 12110995Sandreas.sandberg@arm.com int_links.append(IntLink(link_id=link_count, 12210995Sandreas.sandberg@arm.com src_node=routers[east_out], 12310995Sandreas.sandberg@arm.com dst_node=routers[west_in], 12410995Sandreas.sandberg@arm.com src_outport="East", 12510995Sandreas.sandberg@arm.com dst_inport="West", 12610995Sandreas.sandberg@arm.com latency = link_latency, 12710995Sandreas.sandberg@arm.com weight=1)) 12810995Sandreas.sandberg@arm.com link_count += 1 12910995Sandreas.sandberg@arm.com 13010995Sandreas.sandberg@arm.com # West output to East input links (weight = 1) 13110995Sandreas.sandberg@arm.com for row in range(num_rows): 13210995Sandreas.sandberg@arm.com for col in range(num_columns): 13310995Sandreas.sandberg@arm.com if (col + 1 < num_columns): 13410995Sandreas.sandberg@arm.com east_in = col + (row * num_columns) 13510995Sandreas.sandberg@arm.com west_out = (col + 1) + (row * num_columns) 13610995Sandreas.sandberg@arm.com int_links.append(IntLink(link_id=link_count, 13710995Sandreas.sandberg@arm.com src_node=routers[west_out], 13810995Sandreas.sandberg@arm.com dst_node=routers[east_in], 139 src_outport="West", 140 dst_inport="East", 141 latency = link_latency, 142 weight=1)) 143 link_count += 1 144 145 # North output to South input links (weight = 2) 146 for col in range(num_columns): 147 for row in range(num_rows): 148 if (row + 1 < num_rows): 149 north_out = col + (row * num_columns) 150 south_in = col + ((row + 1) * num_columns) 151 int_links.append(IntLink(link_id=link_count, 152 src_node=routers[north_out], 153 dst_node=routers[south_in], 154 src_outport="North", 155 dst_inport="South", 156 latency = link_latency, 157 weight=2)) 158 link_count += 1 159 160 # South output to North input links (weight = 2) 161 for col in range(num_columns): 162 for row in range(num_rows): 163 if (row + 1 < num_rows): 164 north_in = col + (row * num_columns) 165 south_out = col + ((row + 1) * num_columns) 166 int_links.append(IntLink(link_id=link_count, 167 src_node=routers[south_out], 168 dst_node=routers[north_in], 169 src_outport="South", 170 dst_inport="North", 171 latency = link_latency, 172 weight=2)) 173 link_count += 1 174 175 176 network.int_links = int_links 177