Skip to content

Commit b2cadbd

Browse files
committed
Update Fat-Tree topology to have uniform routers throughout
1 parent 4041977 commit b2cadbd

8 files changed

Lines changed: 114 additions & 127 deletions

File tree

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
0
2-
0
3-
1
42
1
3+
2
4+
3

routing_tables/fat_tree_2_2/1_1.hex

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
0
2-
0
3-
0
4-
0
5-
1
6-
1
72
1
3+
0
84
1
95
2
10-
2
11-
2
12-
2
13-
3
14-
3
156
3
7+
2
168
3
9+
4
10+
5
11+
4
12+
5
13+
6
14+
7
15+
6
16+
7
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
0
2-
0
3-
0
4-
0
5-
1
6-
1
72
1
3+
0
84
1
95
2
10-
2
11-
2
12-
2
13-
3
14-
3
156
3
7+
2
168
3
9+
4
10+
5
11+
4
12+
5
13+
6
14+
7
15+
6
16+
7

routing_tables/fat_tree_4_2/1_2.hex

Lines changed: 0 additions & 16 deletions
This file was deleted.

routing_tables/fat_tree_4_2/1_3.hex

Lines changed: 0 additions & 16 deletions
This file was deleted.

routing_tables/gen_fattree_table.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,23 @@
1616
if not os.path.exists(table_prefix):
1717
os.makedirs(table_prefix)
1818

19+
ROOT_NUM_ROUTERS = 1 if N == 1 else (K ** (N - 1)) // 2
20+
ROOT_RADIX = K if N == 1 else 2 * K
21+
1922
for level in range(N):
20-
for router in range(K ** (N - 1)):
23+
num_routers = ROOT_NUM_ROUTERS if level == N - 1 else K ** (N - 1)
24+
for router in range(num_routers):
2125
table_file = open("%s/%0d_%0d.hex" % (table_prefix, level, router), "w")
2226
for dest_endpoint in range(K ** N):
2327
if level == N - 1:
24-
# Root level: only down ports (0 to K-1)
25-
dest_port = (dest_endpoint // (K ** level)) % K
28+
if N == 1:
29+
dest_port = dest_endpoint % K
30+
else:
31+
# Root level: only down ports (0 to 2*K-1)
32+
target_val = (dest_endpoint // (K ** (N - 1))) % K
33+
# Distribute traffic using lower bits of destination
34+
b = (dest_endpoint // (K ** (N - 2))) % 2
35+
dest_port = 2 * target_val + b
2636
else:
2737
# Check if dest_endpoint is in the subtree of switch (level, router)
2838
is_in_subtree = True

src/topologies/fat_tree.sv

Lines changed: 79 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,14 @@ module fat_tree #(
4747
return result;
4848
endfunction
4949

50+
// Root level configuration parameters
51+
localparam ROOT_NUM_ROUTERS = (N == 1) ? 1 : ((K ** (N - 1)) / 2);
52+
localparam ROOT_RADIX = (N == 1) ? K : (2 * K);
53+
5054
// Disable turns arrays for routers
51-
bit DISABLE_TURNS_K[K][K];
5255
bit DISABLE_TURNS_2K[2 * K][2 * K];
56+
bit DISABLE_TURNS_ROOT[ROOT_RADIX][ROOT_RADIX];
5357
always_comb begin
54-
for (int src_port = 0; src_port < K; src_port = src_port + 1) begin
55-
for (int dst_port = 0; dst_port < K; dst_port = dst_port + 1) begin
56-
if (DISABLE_SELFLOOP && (src_port == dst_port)) begin
57-
DISABLE_TURNS_K[src_port][dst_port] = 1;
58-
end else begin
59-
DISABLE_TURNS_K[src_port][dst_port] = 0;
60-
end
61-
end
62-
end
6358
for (int src_port = 0; src_port < 2 * K; src_port = src_port + 1) begin
6459
for (int dst_port = 0; dst_port < 2 * K; dst_port = dst_port + 1) begin
6560
if (DISABLE_SELFLOOP && (src_port == dst_port)) begin
@@ -71,6 +66,15 @@ module fat_tree #(
7166
end
7267
end
7368
end
69+
for (int src_port = 0; src_port < ROOT_RADIX; src_port = src_port + 1) begin
70+
for (int dst_port = 0; dst_port < ROOT_RADIX; dst_port = dst_port + 1) begin
71+
if (DISABLE_SELFLOOP && (src_port == dst_port)) begin
72+
DISABLE_TURNS_ROOT[src_port][dst_port] = 1;
73+
end else begin
74+
DISABLE_TURNS_ROOT[src_port][dst_port] = 0;
75+
end
76+
end
77+
end
7478
end
7579

7680
// Wires for intermediate level switches (level < N-1)
@@ -87,17 +91,17 @@ module fat_tree #(
8791
logic credit_router_out_int[N][K ** (N - 1)][2 * K];
8892

8993
// Wires for root level switches (level == N-1)
90-
logic [FLIT_WIDTH - 1 : 0] data_router_in_root[K ** (N - 1)][K];
91-
logic [DEST_WIDTH - 1 : 0] dest_router_in_root[K ** (N - 1)][K];
92-
logic is_tail_router_in_root[K ** (N - 1)][K];
93-
logic send_router_in_root[K ** (N - 1)][K];
94-
logic credit_router_in_root[K ** (N - 1)][K];
94+
logic [FLIT_WIDTH - 1 : 0] data_router_in_root[ROOT_NUM_ROUTERS][ROOT_RADIX];
95+
logic [DEST_WIDTH - 1 : 0] dest_router_in_root[ROOT_NUM_ROUTERS][ROOT_RADIX];
96+
logic is_tail_router_in_root[ROOT_NUM_ROUTERS][ROOT_RADIX];
97+
logic send_router_in_root[ROOT_NUM_ROUTERS][ROOT_RADIX];
98+
logic credit_router_in_root[ROOT_NUM_ROUTERS][ROOT_RADIX];
9599

96-
logic [FLIT_WIDTH - 1 : 0] data_router_out_root[K ** (N - 1)][K];
97-
logic [DEST_WIDTH - 1 : 0] dest_router_out_root[K ** (N - 1)][K];
98-
logic is_tail_router_out_root[K ** (N - 1)][K];
99-
logic send_router_out_root[K ** (N - 1)][K];
100-
logic credit_router_out_root[K ** (N - 1)][K];
100+
logic [FLIT_WIDTH - 1 : 0] data_router_out_root[ROOT_NUM_ROUTERS][ROOT_RADIX];
101+
logic [DEST_WIDTH - 1 : 0] dest_router_out_root[ROOT_NUM_ROUTERS][ROOT_RADIX];
102+
logic is_tail_router_out_root[ROOT_NUM_ROUTERS][ROOT_RADIX];
103+
logic send_router_out_root[ROOT_NUM_ROUTERS][ROOT_RADIX];
104+
logic credit_router_out_root[ROOT_NUM_ROUTERS][ROOT_RADIX];
101105

102106
always_comb begin
103107
// Initialize all intermediate signals to 0 to prevent latches/X-propagation
@@ -112,8 +116,8 @@ module fat_tree #(
112116
end
113117
end
114118
end
115-
for (int router_idx = 0; router_idx < K ** (N - 1); router_idx = router_idx + 1) begin
116-
for (int port_idx = 0; port_idx < K; port_idx = port_idx + 1) begin
119+
for (int router_idx = 0; router_idx < ROOT_NUM_ROUTERS; router_idx = router_idx + 1) begin
120+
for (int port_idx = 0; port_idx < ROOT_RADIX; port_idx = port_idx + 1) begin
117121
data_router_in_root [router_idx][port_idx] = '0;
118122
dest_router_in_root [router_idx][port_idx] = '0;
119123
is_tail_router_in_root[router_idx][port_idx] = '0;
@@ -174,19 +178,24 @@ module fat_tree #(
174178
target_switch_idx = switch_idx - (target_port_idx * pow_k(level_idx)) + (port_idx * pow_k(level_idx));
175179

176180
if (level_idx + 1 == N - 1) begin
181+
int root_router_idx;
182+
int root_port_idx;
183+
root_router_idx = (switch_idx * K + port_idx) % ROOT_NUM_ROUTERS;
184+
root_port_idx = (switch_idx * K + port_idx) / ROOT_NUM_ROUTERS;
185+
177186
// Upward flow
178-
data_router_in_root [target_switch_idx][target_port_idx] = data_router_out_int [level_idx][switch_idx][K + port_idx];
179-
dest_router_in_root [target_switch_idx][target_port_idx] = dest_router_out_int [level_idx][switch_idx][K + port_idx];
180-
is_tail_router_in_root[target_switch_idx][target_port_idx] = is_tail_router_out_int[level_idx][switch_idx][K + port_idx];
181-
send_router_in_root [target_switch_idx][target_port_idx] = send_router_out_int [level_idx][switch_idx][K + port_idx];
182-
credit_router_out_int [level_idx][switch_idx][K + port_idx] = credit_router_in_root[target_switch_idx][target_port_idx];
187+
data_router_in_root [root_router_idx][root_port_idx] = data_router_out_int [level_idx][switch_idx][K + port_idx];
188+
dest_router_in_root [root_router_idx][root_port_idx] = dest_router_out_int [level_idx][switch_idx][K + port_idx];
189+
is_tail_router_in_root[root_router_idx][root_port_idx] = is_tail_router_out_int[level_idx][switch_idx][K + port_idx];
190+
send_router_in_root [root_router_idx][root_port_idx] = send_router_out_int [level_idx][switch_idx][K + port_idx];
191+
credit_router_out_int [level_idx][switch_idx][K + port_idx] = credit_router_in_root[root_router_idx][root_port_idx];
183192

184193
// Downward flow
185-
data_router_in_int [level_idx][switch_idx][K + port_idx] = data_router_out_root [target_switch_idx][target_port_idx];
186-
dest_router_in_int [level_idx][switch_idx][K + port_idx] = dest_router_out_root [target_switch_idx][target_port_idx];
187-
is_tail_router_in_int [level_idx][switch_idx][K + port_idx] = is_tail_router_out_root[target_switch_idx][target_port_idx];
188-
send_router_in_int [level_idx][switch_idx][K + port_idx] = send_router_out_root [target_switch_idx][target_port_idx];
189-
credit_router_out_root[target_switch_idx][target_port_idx] = credit_router_in_int [level_idx][switch_idx][K + port_idx];
194+
data_router_in_int [level_idx][switch_idx][K + port_idx] = data_router_out_root [root_router_idx][root_port_idx];
195+
dest_router_in_int [level_idx][switch_idx][K + port_idx] = dest_router_out_root [root_router_idx][root_port_idx];
196+
is_tail_router_in_int [level_idx][switch_idx][K + port_idx] = is_tail_router_out_root[root_router_idx][root_port_idx];
197+
send_router_in_int [level_idx][switch_idx][K + port_idx] = send_router_out_root [root_router_idx][root_port_idx];
198+
credit_router_out_root[root_router_idx][root_port_idx] = credit_router_in_int [level_idx][switch_idx][K + port_idx];
190199
end else begin
191200
// Upward flow
192201
data_router_in_int [level_idx + 1][target_switch_idx][target_port_idx] = data_router_out_int [level_idx][switch_idx][K + port_idx];
@@ -211,41 +220,11 @@ module fat_tree #(
211220

212221
generate begin: gen_fattree_routers
213222
genvar level_gen_idx, router_gen_idx;
214-
for (level_gen_idx = 0; level_gen_idx < N; level_gen_idx = level_gen_idx + 1) begin: for_levels
215-
for (router_gen_idx = 0; router_gen_idx < K ** (N - 1); router_gen_idx = router_gen_idx + 1) begin: for_routers
216-
localparam string routing_table = $sformatf("%s/%0d_%0d.hex", ROUTING_TABLE_PREFIX, level_gen_idx, router_gen_idx);
217-
if (level_gen_idx == N - 1) begin: g_root
218-
router #(
219-
.NOC_NUM_ENDPOINTS (K ** N),
220-
.ROUTING_TABLE_HEX (routing_table),
221-
.NUM_INPUTS (K),
222-
.NUM_OUTPUTS (K),
223-
.DEST_WIDTH (DEST_WIDTH),
224-
.FLIT_WIDTH (FLIT_WIDTH),
225-
.FLIT_BUFFER_DEPTH (FLIT_BUFFER_DEPTH),
226-
.PIPELINE_ROUTE_COMPUTE (ROUTER_PIPELINE_ROUTE_COMPUTE),
227-
.PIPELINE_ARBITER (ROUTER_PIPELINE_ARBITER),
228-
.PIPELINE_OUTPUT (ROUTER_PIPELINE_OUTPUT),
229-
.FORCE_MLAB (ROUTER_FORCE_MLAB)
230-
) router_inst (
231-
.clk (clk),
232-
.rst_n (rst_n),
233223

234-
.data_in (data_router_in_root[router_gen_idx]),
235-
.dest_in (dest_router_in_root[router_gen_idx]),
236-
.is_tail_in (is_tail_router_in_root[router_gen_idx]),
237-
.send_in (send_router_in_root[router_gen_idx]),
238-
.credit_out (credit_router_in_root[router_gen_idx]),
239-
240-
.data_out (data_router_out_root[router_gen_idx]),
241-
.dest_out (dest_router_out_root[router_gen_idx]),
242-
.is_tail_out (is_tail_router_out_root[router_gen_idx]),
243-
.send_out (send_router_out_root[router_gen_idx]),
244-
.credit_in (credit_router_out_root[router_gen_idx]),
245-
246-
.DISABLE_TURNS (DISABLE_TURNS_K)
247-
);
248-
end else begin: g_int
224+
if (N > 1) begin: g_intermediate_levels
225+
for (level_gen_idx = 0; level_gen_idx < N - 1; level_gen_idx = level_gen_idx + 1) begin: for_levels
226+
for (router_gen_idx = 0; router_gen_idx < K ** (N - 1); router_gen_idx = router_gen_idx + 1) begin: for_routers
227+
localparam string routing_table = $sformatf("%s/%0d_%0d.hex", ROUTING_TABLE_PREFIX, level_gen_idx, router_gen_idx);
249228
router #(
250229
.NOC_NUM_ENDPOINTS (K ** N),
251230
.ROUTING_TABLE_HEX (routing_table),
@@ -279,6 +258,40 @@ module fat_tree #(
279258
end
280259
end
281260
end
261+
262+
for (router_gen_idx = 0; router_gen_idx < ROOT_NUM_ROUTERS; router_gen_idx = router_gen_idx + 1) begin: for_root_routers
263+
localparam string routing_table = $sformatf("%s/%0d_%0d.hex", ROUTING_TABLE_PREFIX, N - 1, router_gen_idx);
264+
router #(
265+
.NOC_NUM_ENDPOINTS (K ** N),
266+
.ROUTING_TABLE_HEX (routing_table),
267+
.NUM_INPUTS (ROOT_RADIX),
268+
.NUM_OUTPUTS (ROOT_RADIX),
269+
.DEST_WIDTH (DEST_WIDTH),
270+
.FLIT_WIDTH (FLIT_WIDTH),
271+
.FLIT_BUFFER_DEPTH (FLIT_BUFFER_DEPTH),
272+
.PIPELINE_ROUTE_COMPUTE (ROUTER_PIPELINE_ROUTE_COMPUTE),
273+
.PIPELINE_ARBITER (ROUTER_PIPELINE_ARBITER),
274+
.PIPELINE_OUTPUT (ROUTER_PIPELINE_OUTPUT),
275+
.FORCE_MLAB (ROUTER_FORCE_MLAB)
276+
) router_inst (
277+
.clk (clk),
278+
.rst_n (rst_n),
279+
280+
.data_in (data_router_in_root[router_gen_idx]),
281+
.dest_in (dest_router_in_root[router_gen_idx]),
282+
.is_tail_in (is_tail_router_in_root[router_gen_idx]),
283+
.send_in (send_router_in_root[router_gen_idx]),
284+
.credit_out (credit_router_in_root[router_gen_idx]),
285+
286+
.data_out (data_router_out_root[router_gen_idx]),
287+
.dest_out (dest_router_out_root[router_gen_idx]),
288+
.is_tail_out (is_tail_router_out_root[router_gen_idx]),
289+
.send_out (send_router_out_root[router_gen_idx]),
290+
.credit_in (credit_router_out_root[router_gen_idx]),
291+
292+
.DISABLE_TURNS (DISABLE_TURNS_ROOT)
293+
);
294+
end
282295
end
283296
endgenerate
284297

0 commit comments

Comments
 (0)