64a8506160e11028c4854b6478f8797c2947a6aa
[gem5.git] / configs / topologies / Mesh_XY.py
1 # Copyright (c) 2010 Advanced Micro Devices, Inc.
2 # 2016 Georgia Institute of Technology
3 # All rights reserved.
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
7 # met: redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer;
9 # redistributions in binary form must reproduce the above copyright
10 # notice, this list of conditions and the following disclaimer in the
11 # documentation and/or other materials provided with the distribution;
12 # neither the name of the copyright holders nor the names of its
13 # contributors may be used to endorse or promote products derived from
14 # this software without specific prior written permission.
15 #
16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 from __future__ import print_function
29 from __future__ import absolute_import
30
31 from m5.params import *
32 from m5.objects import *
33
34 from common import FileSystemConfig
35
36 from topologies.BaseTopology import SimpleTopology
37
38 # Creates a generic Mesh assuming an equal number of cache
39 # and directory controllers.
40 # XY routing is enforced (using link weights)
41 # to guarantee deadlock freedom.
42
43 class Mesh_XY(SimpleTopology):
44 description='Mesh_XY'
45
46 def __init__(self, controllers):
47 self.nodes = controllers
48
49 # Makes a generic mesh
50 # assuming an equal number of cache and directory cntrls
51
52 def makeTopology(self, options, network, IntLink, ExtLink, Router):
53 nodes = self.nodes
54
55 num_routers = options.num_cpus
56 num_rows = options.mesh_rows
57
58 # default values for link latency and router latency.
59 # Can be over-ridden on a per link/router basis
60 link_latency = options.link_latency # used by simple and garnet
61 router_latency = options.router_latency # only used by garnet
62
63
64 # There must be an evenly divisible number of cntrls to routers
65 # Also, obviously the number or rows must be <= the number of routers
66 cntrls_per_router, remainder = divmod(len(nodes), num_routers)
67 assert(num_rows > 0 and num_rows <= num_routers)
68 num_columns = int(num_routers / num_rows)
69 assert(num_columns * num_rows == num_routers)
70
71 # Create the routers in the mesh
72 routers = [Router(router_id=i, latency = router_latency) \
73 for i in range(num_routers)]
74 network.routers = routers
75
76 # link counter to set unique link ids
77 link_count = 0
78
79 # Add all but the remainder nodes to the list of nodes to be uniformly
80 # distributed across the network.
81 network_nodes = []
82 remainder_nodes = []
83 for node_index in range(len(nodes)):
84 if node_index < (len(nodes) - remainder):
85 network_nodes.append(nodes[node_index])
86 else:
87 remainder_nodes.append(nodes[node_index])
88
89 # Connect each node to the appropriate router
90 ext_links = []
91 for (i, n) in enumerate(network_nodes):
92 cntrl_level, router_id = divmod(i, num_routers)
93 assert(cntrl_level < cntrls_per_router)
94 ext_links.append(ExtLink(link_id=link_count, ext_node=n,
95 int_node=routers[router_id],
96 latency = link_latency))
97 link_count += 1
98
99 # Connect the remainding nodes to router 0. These should only be
100 # DMA nodes.
101 for (i, node) in enumerate(remainder_nodes):
102 assert(node.type == 'DMA_Controller')
103 assert(i < remainder)
104 ext_links.append(ExtLink(link_id=link_count, ext_node=node,
105 int_node=routers[0],
106 latency = link_latency))
107 link_count += 1
108
109 network.ext_links = ext_links
110
111 # Create the mesh links.
112 int_links = []
113
114 # East output to West input links (weight = 1)
115 for row in range(num_rows):
116 for col in range(num_columns):
117 if (col + 1 < num_columns):
118 east_out = col + (row * num_columns)
119 west_in = (col + 1) + (row * num_columns)
120 int_links.append(IntLink(link_id=link_count,
121 src_node=routers[east_out],
122 dst_node=routers[west_in],
123 src_outport="East",
124 dst_inport="West",
125 latency = link_latency,
126 weight=1))
127 link_count += 1
128
129 # West output to East input links (weight = 1)
130 for row in range(num_rows):
131 for col in range(num_columns):
132 if (col + 1 < num_columns):
133 east_in = col + (row * num_columns)
134 west_out = (col + 1) + (row * num_columns)
135 int_links.append(IntLink(link_id=link_count,
136 src_node=routers[west_out],
137 dst_node=routers[east_in],
138 src_outport="West",
139 dst_inport="East",
140 latency = link_latency,
141 weight=1))
142 link_count += 1
143
144 # North output to South input links (weight = 2)
145 for col in range(num_columns):
146 for row in range(num_rows):
147 if (row + 1 < num_rows):
148 north_out = col + (row * num_columns)
149 south_in = col + ((row + 1) * num_columns)
150 int_links.append(IntLink(link_id=link_count,
151 src_node=routers[north_out],
152 dst_node=routers[south_in],
153 src_outport="North",
154 dst_inport="South",
155 latency = link_latency,
156 weight=2))
157 link_count += 1
158
159 # South output to North input links (weight = 2)
160 for col in range(num_columns):
161 for row in range(num_rows):
162 if (row + 1 < num_rows):
163 north_in = col + (row * num_columns)
164 south_out = col + ((row + 1) * num_columns)
165 int_links.append(IntLink(link_id=link_count,
166 src_node=routers[south_out],
167 dst_node=routers[north_in],
168 src_outport="South",
169 dst_inport="North",
170 latency = link_latency,
171 weight=2))
172 link_count += 1
173
174
175 network.int_links = int_links
176
177 # Register nodes with filesystem
178 def registerTopology(self, options):
179 for i in range(options.num_cpus):
180 FileSystemConfig.register_node([i],
181 MemorySize(options.mem_size) / options.num_cpus, i)