diff --git a/hw/floo_axi_chimney.sv b/hw/floo_axi_chimney.sv index 275dd758..fb830984 100644 --- a/hw/floo_axi_chimney.sv +++ b/hw/floo_axi_chimney.sv @@ -206,7 +206,6 @@ module floo_axi_chimney #( assign axi_ar_queue_valid_out = axi_in_req_i.ar_valid; assign axi_rsp_out.ar_ready = axi_ar_queue_ready_in; end - end else begin : gen_err_slv_port axi_err_slv #( .AxiIdWidth ( AxiCfg.InIdWidth ), diff --git a/hw/floo_nw_chimney.sv b/hw/floo_nw_chimney.sv index 6da15334..4ba45089 100644 --- a/hw/floo_nw_chimney.sv +++ b/hw/floo_nw_chimney.sv @@ -330,7 +330,6 @@ module floo_nw_chimney #( assign axi_wide_ar_queue_valid_out = axi_wide_in_req_i.ar_valid; assign axi_wide_rsp_out.ar_ready = axi_wide_ar_queue_ready_in; end - end else begin : gen_wide_err_slv_port axi_err_slv #( .AxiIdWidth ( AxiCfgW.InIdWidth ), diff --git a/hw/floo_pkg.sv b/hw/floo_pkg.sv index 44b74e39..a94bedbd 100644 --- a/hw/floo_pkg.sv +++ b/hw/floo_pkg.sv @@ -10,7 +10,7 @@ package floo_pkg; /// Currently Supported Routing Algorithms - typedef enum logic[1:0] { + typedef enum logic[2:0] { /// `IdTable` routing uses a table of routing rules to determine to /// which output port a packet should be routed, based on the /// destination ID encoded in the header of the flit. Every router @@ -35,7 +35,10 @@ package floo_pkg; /// XY coordinates, which can be done with addressoffsets `XYAddrOffsetX` /// and `XYAddrOffsetY`, or by indexing the system address map `Sam`. This /// is controlled with the `UseIdTable` parameter. - XYRouting + XYRouting, + YXRouting, + OddEvenRouting, + O1Routing } route_algo_e; /// The directions in a 2D mesh network, mainly useful for indexing diff --git a/hw/floo_route_select.sv b/hw/floo_route_select.sv index ddfb932e..81d13362 100644 --- a/hw/floo_route_select.sv +++ b/hw/floo_route_select.sv @@ -121,6 +121,85 @@ if (RouteAlgo == IdTable) begin : gen_id_table assign channel_o = channel_i; + end else if (RouteAlgo == YXRouting) begin : gen_yx_routing + + id_t id_in; + assign id_in = id_t'(channel_i.hdr.dst_id); + + always_comb begin : proc_route_sel + route_sel_id = East; + if (id_in.x == xy_id_i.x && id_in.y == xy_id_i.y) begin + route_sel_id = Eject + channel_i.hdr.dst_id.port_id; + end else if (id_in.y == xy_id_i.y) begin + if (id_in.x < xy_id_i.x) begin + route_sel_id = West; + end else begin + route_sel_id = East; + end + end else begin + if (id_in.y < xy_id_i.y) begin + route_sel_id = South; + end else begin + route_sel_id = North; + end + end + route_sel = '0; + route_sel[route_sel_id] = 1'b1; + end + + assign channel_o = channel_i; + + end else if (RouteAlgo == OddEvenRouting) begin : gen_oddeven_routing + id_t id_src, id_dst; + assign id_src = id_t'(channel_i.hdr.src_id); + assign id_dst = id_t'(channel_i.hdr.dst_id); + + always_comb begin : proc_route_sel + route_sel_id = East; + if (id_dst.x == xy_id_i.x && id_dst.y == xy_id_i.y) begin + route_sel_id = Eject + channel_i.hdr.dst_id.port_id; + end else if (xy_id_i.x == id_dst.x) begin //currently in the same column as destination + if (xy_id_i.y < id_dst.y) begin + route_sel_id = North; + end else begin + route_sel_id = South; + end + end else if (xy_id_i.x < id_dst.x) begin //eastbound traffic + if (xy_id_i.y == id_dst.y) begin + route_sel_id = East; + end else if (((xy_id_i.x % 2) == 1) || (xy_id_i.x == id_src.x)) begin + if ((((id_dst.x) % 2 == 1) || ((id_dst.x - xy_id_i.x) != 1)) && (^channel_i)) begin + route_sel_id = East; + end else begin + if (xy_id_i.y < id_dst.y) begin + route_sel_id = North; + end else begin + route_sel_id = South; + end + end + end else begin + assert ((id_dst.x % 2 == 1) || (id_dst.x - xy_id_i.x != 1)); + route_sel_id = East; + end + end else begin //westbound traffic + if (xy_id_i.y == id_dst.y) begin + route_sel_id = West; + end else if (((xy_id_i.x % 2) == 0) && (^channel_i)) begin + if (xy_id_i.y < id_dst.y) begin + route_sel_id = North; + end else begin + route_sel_id = South; + end + end else begin + route_sel_id = West; + end + end + route_sel = '0; + route_sel[route_sel_id] = 1'b1; + end + + assign channel_o = channel_i; + end else begin : gen_err // Unknown or unimplemented routing otherwise initial begin diff --git a/hw/floo_router.sv b/hw/floo_router.sv index 323b7be8..b1e3695a 100644 --- a/hw/floo_router.sv +++ b/hw/floo_router.sv @@ -83,28 +83,80 @@ module floo_router .ready_i ( in_ready[in_route][v_chan] ) ); - floo_route_select #( - .NumRoutes ( NumOutput ), - .flit_t ( flit_t ), - .RouteAlgo ( RouteAlgo ), - .IdWidth ( IdWidth ), - .id_t ( id_t ), - .NumAddrRules ( NumAddrRules ), - .addr_rule_t ( addr_rule_t ) - ) i_route_select ( - .clk_i, - .rst_ni, - .test_enable_i, - - .xy_id_i ( xy_id_i ), - .id_route_map_i ( id_route_map_i ), - .channel_i ( in_data [in_route][v_chan] ), - .valid_i ( in_valid [in_route][v_chan] ), - .ready_i ( in_ready [in_route][v_chan] ), - .channel_o ( in_routed_data[in_route][v_chan] ), - .route_sel_o ( route_mask [in_route][v_chan] ), - .route_sel_id_o ( ) - ); + if (RouteAlgo == O1Routing) begin: gen_o1routing + + if (v_chan % 2 == 0) begin: gen_o1routing_xy + floo_route_select #( + .NumRoutes ( NumOutput ), + .flit_t ( flit_t ), + .RouteAlgo ( XYRouting ), + .IdWidth ( IdWidth ), + .id_t ( id_t ), + .NumAddrRules ( NumAddrRules ), + .addr_rule_t ( addr_rule_t ) + ) i_route_select ( + .clk_i, + .rst_ni, + .test_enable_i, + + .xy_id_i ( xy_id_i ), + .id_route_map_i ( id_route_map_i ), + .channel_i ( in_data [in_route][v_chan] ), + .valid_i ( in_valid [in_route][v_chan] ), + .ready_i ( in_ready [in_route][v_chan] ), + .channel_o ( in_routed_data[in_route][v_chan] ), + .route_sel_o ( route_mask [in_route][v_chan] ) + ); + end else begin: gen_o1routing_yx + floo_route_select #( + .NumRoutes ( NumOutput ), + .flit_t ( flit_t ), + .RouteAlgo ( YXRouting ), + .IdWidth ( IdWidth ), + .id_t ( id_t ), + .NumAddrRules ( NumAddrRules ), + .addr_rule_t ( addr_rule_t ) + ) i_route_select ( + .clk_i, + .rst_ni, + .test_enable_i, + + .xy_id_i ( xy_id_i ), + .id_route_map_i ( id_route_map_i ), + .channel_i ( in_data [in_route][v_chan] ), + .valid_i ( in_valid [in_route][v_chan] ), + .ready_i ( in_ready [in_route][v_chan] ), + .channel_o ( in_routed_data[in_route][v_chan] ), + .route_sel_o ( route_mask [in_route][v_chan] ) + ); + end + + end else begin: gen_xyrouting + + floo_route_select #( + .NumRoutes ( NumOutput ), + .flit_t ( flit_t ), + .RouteAlgo ( RouteAlgo ), + .IdWidth ( IdWidth ), + .id_t ( id_t ), + .NumAddrRules ( NumAddrRules ), + .addr_rule_t ( addr_rule_t ) + ) i_route_select ( + .clk_i, + .rst_ni, + .test_enable_i, + + .xy_id_i ( xy_id_i ), + .id_route_map_i ( id_route_map_i ), + .channel_i ( in_data [in_route][v_chan] ), + .valid_i ( in_valid [in_route][v_chan] ), + .ready_i ( in_ready [in_route][v_chan] ), + .channel_o ( in_routed_data[in_route][v_chan] ), + .route_sel_o ( route_mask [in_route][v_chan] ), + .route_sel_id_o ( ) + ); + + end end end