44//
55// Author: Chen Wu <[email protected] >66
7- module floo_route_xymask import floo_pkg :: * ;
8- # (
7+ module floo_route_xymask
8+ import floo_pkg:: * ;
9+ # (
10+ // / Number of output ports
911 parameter int unsigned NumRoutes = 0 ,
12+ // / The type of mask to be computed
13+ // / 1: Determine output directions of the forward path in Multicast
14+ // / 0: Determine input directions of the backward path in Multicast i.e the reduction
15+ parameter bit FwdMode = 1'b1 ,
16+ // / Various types
1017 parameter type flit_t = logic ,
11- parameter type id_t = logic ,
12- // / Mode 1 for deciding the output directions
13- // / Mode 0 for spefifying the expected input directions
14- parameter bit Mode = 1
18+ parameter type id_t = logic
1519) (
20+ // The input flit (only the header is used)
1621 input flit_t channel_i,
22+ // The current XY-coordinate of the router
1723 input id_t xy_id_i,
24+ // The calculated mask for the multicast/reduction
1825 output logic [NumRoutes- 1 : 0 ] route_sel_o
1926);
2027
@@ -24,26 +31,38 @@ module floo_route_xymask import floo_pkg::*;
2431 id_t dst_id_max, dst_id_min;
2532 logic x_matched, y_matched;
2633
27- assign dst_id = Mode? id_t ' (channel_i.hdr.dst_id) : id_t ' (channel_i.hdr.src_id);
28- assign mask_in = Mode?
29- (channel_i.hdr.commtype== CollectB? '0 : id_t ' (channel_i.hdr.mask))
30- : id_t ' (channel_i.hdr.mask);
31- assign src_id = Mode? id_t ' (channel_i.hdr.src_id) : id_t ' (channel_i.hdr.dst_id);
34+ // In the forward path, we use the normal `dst_id` to compute the mask.
35+ // In the backward path, we use the `src_id` which was the original
36+ // `dst_id` in from the forward path.
37+ assign dst_id = (FwdMode)? channel_i.hdr.dst_id : channel_i.hdr.src_id;
38+ assign src_id = (FwdMode)? channel_i.hdr.src_id : channel_i.hdr.dst_id;
39+ // TODO(fischeti): Clarify with Chen why `CollectB` are excluded
40+ assign mask_in = (FwdMode && channel_i.hdr.commtype== CollectB)? '0 : channel_i.hdr.mask;
3241
42+ // We compute minimum and maximum destination IDs, to decide whether
43+ // we need to send left and/or right resp. up and/or down.
3344 assign dst_id_max.x = dst_id.x | mask_in.x;
3445 assign dst_id_max.y = dst_id.y | mask_in.y;
3546 assign dst_id_min.x = dst_id.x & (~ mask_in.x);
3647 assign dst_id_min.y = dst_id.y & (~ mask_in.y);
3748
49+ // `x/y_matched` means whether the current coordinate is a
50+ // receiver of the the multicast.
3851 assign x_matched = & (mask_in.x | ~ (xy_id_i.x ^ dst_id.x));
3952 assign y_matched = & (mask_in.y | ~ (xy_id_i.y ^ dst_id.y));
4053
4154 always_comb begin
4255 route_sel = '0 ;
43- if (Mode) begin : decide_output
56+ if (FwdMode) begin : gen_out_mask
57+ // If both x and y are matched, we eject the flit
4458 if (x_matched && y_matched) begin
4559 route_sel[Eject] = 1 ;
4660 end
61+ // If the multicast was issued from an endpoint in the same row
62+ // i.e. the same Y-coordinate, we forward it to `East` if:
63+ // 1. The request is incoming from `West` or `Eject` and
64+ // 2. There are more multicast destinations in the `East` direction
65+ // The same applies to the `West` direction.
4766 if (xy_id_i.y == src_id.y) begin
4867 if (xy_id_i.x >= src_id.x && xy_id_i.x < dst_id_max.x) begin
4968 route_sel[East] = 1 ;
@@ -52,6 +71,11 @@ module floo_route_xymask import floo_pkg::*;
5271 route_sel[West] = 1 ;
5372 end
5473 end
74+ // If there are multicast destinations in the current column,
75+ // We inject it to `North` if:
76+ // 1. The request is incoming from `South` or `Eject` and
77+ // 2. There are more multicast destinations in the `North` direction
78+ // The same applies to the `South` direction.
5579 if (x_matched) begin
5680 if (xy_id_i.y >= src_id.y && xy_id_i.y < dst_id_max.y) begin
5781 route_sel[North] = 1 ;
@@ -61,10 +85,16 @@ module floo_route_xymask import floo_pkg::*;
6185 end
6286 end
6387 end
64- else begin : specify_input
88+
89+ // TODO(fischeti): Clarify with Chen why `YXRouting` is used
90+ // for the backward path
91+ else begin : gen_in_mask
92+ // If we previously ejected the flit, we expect one again
6593 if (x_matched && y_matched) begin
6694 route_sel[Eject] = 1 ;
6795 end
96+ // This is the same as the forward path, but we use the
97+ // `YXRouting` algorithm to compute the mask.
6898 if (xy_id_i.x == src_id.x) begin
6999 if (xy_id_i.y >= src_id.y && xy_id_i.y < dst_id_max.y) begin
70100 route_sel[North] = 1 ;
0 commit comments