@@ -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