Skip to content

Commit

Permalink
routing: Add possibility to compute XY coordinates with a routing table
Browse files Browse the repository at this point in the history
  • Loading branch information
fischeti committed Nov 24, 2023
1 parent 7828bb4 commit a6e981a
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 103 deletions.
1 change: 1 addition & 0 deletions Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ sources:
- src/floo_fifo.sv
- src/floo_cdc.sv
- src/floo_route_select.sv
- src/floo_route_comp.sv
- src/floo_vc_arbiter.sv
- src/floo_wormhole_arbiter.sv
- src/floo_simple_rob.sv
Expand Down
80 changes: 50 additions & 30 deletions src/floo_axi_chimney.sv
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,35 @@ module floo_axi_chimney
parameter int unsigned MaxAtomicTxns = 1,
/// Routing Algorithm
parameter route_algo_e RouteAlgo = IdTable,
/// Whether to look up the coordinates in a table or
/// directly read them from the request address
parameter bit UseIdTable = 1'b0,
/// X Coordinate address offset for XY routing
parameter int unsigned XYAddrOffsetX = 0,
/// Y Coordinate address offset for XY routing
parameter int unsigned XYAddrOffsetY = 0,
/// ID address offset for ID routing
parameter int unsigned IdTableAddrOffset = 8,
/// Number of maximum oustanding requests
parameter int unsigned IdAddrOffset = 0,
/// Number of Endpoints in the system, only used for Table based routing
parameter int unsigned NumIDs = 0,
/// Number of rules in the routing table, only used for Table based routing
parameter int unsigned NumRules = 0,
/// ID address offset for ID routing
parameter int unsigned MaxTxns = 32,
/// Maximum number of outstanding requests per ID
parameter int unsigned MaxTxnsPerId = MaxTxns,
/// Type of the narrow reorder buffer
parameter rob_type_e RoBType = NoRoB,
/// Capacity of the reorder buffer
parameter int unsigned ReorderBufferSize = 32,
/// Type of Coordinates/Id
parameter type id_t = logic,
/// Cut timing paths of outgoing requests
parameter bit CutAx = 1'b0,
/// Cut timing paths of incoming responses
parameter bit CutRsp = 1'b1,
/// Type of Coordinates/Id
parameter type id_t = logic,
/// Only used for IDRouting
parameter type id_rule_t = logic,
/// Type for implementation inputs and outputs
parameter type sram_cfg_t = logic
) (
Expand All @@ -60,6 +69,8 @@ module floo_axi_chimney
input axi_out_rsp_t axi_out_rsp_i,
/// Coordinates/ID of the current tile
input id_t id_i,
/// Routing table
input id_rule_t[NumRules-1:0] id_map_i,
/// Output to NoC
output floo_req_t floo_req_o,
output floo_rsp_t floo_rsp_o,
Expand Down Expand Up @@ -349,33 +360,42 @@ module floo_axi_chimney
// ROUTING //
/////////////////

typedef enum logic [1:0] {AwReq, ArReq, NumAddrDecoders} axi_req_ch_e;

id_t axi_aw_id_q;

axi_in_addr_t [NumAddrDecoders-1:0] addr_to_decode;
id_t [NumAddrDecoders-1:0] decoded_id;
assign addr_to_decode[AwReq] = axi_aw_queue.addr;
assign addr_to_decode[ArReq] = axi_ar_queue.addr;

floo_route_comp #(
.RouteAlgo ( RouteAlgo ),
.UseIdTable ( UseIdTable ),
.XYAddrOffsetX ( XYAddrOffsetX ),
.XYAddrOffsetY ( XYAddrOffsetY ),
.IdAddrOffset ( IdAddrOffset ),
.NumIDs ( NumIDs ),
.NumRules ( NumRules ),
.id_t ( id_t ),
.id_rule_t ( id_rule_t ),
.addr_t ( axi_in_addr_t )
) i_floo_narrow_route_comp [NumAddrDecoders-1:0] (
.clk_i,
.rst_ni,
.id_map_i,
.addr_i ( addr_to_decode ),
.id_o ( decoded_id )
);

assign dst_id[AxiAw] = decoded_id[AwReq];
assign dst_id[AxiW] = axi_aw_id_q;
assign dst_id[AxiAr] = decoded_id[ArReq];
assign dst_id[AxiB] = aw_out_data_out.src_id;
assign dst_id[AxiR] = ar_out_data_out.src_id;
`FFL(axi_aw_id_q, dst_id[AxiAw], axi_aw_queue_valid_out &&
axi_aw_queue_ready_in, '0)

if (RouteAlgo == XYRouting) begin : gen_xy_routing
id_t aw_xy_id_q, aw_xy_id, ar_xy_id;
assign aw_xy_id.x = axi_aw_queue.addr[XYAddrOffsetX+:$bits(id_i.x)];
assign aw_xy_id.y = axi_aw_queue.addr[XYAddrOffsetY+:$bits(id_i.y)];
assign ar_xy_id.x = axi_ar_queue.addr[XYAddrOffsetX+:$bits(id_i.x)];
assign ar_xy_id.y = axi_ar_queue.addr[XYAddrOffsetY+:$bits(id_i.y)];
assign dst_id[AxiAw] = aw_xy_id;
assign dst_id[AxiAr] = ar_xy_id;
assign dst_id[AxiW] = aw_xy_id_q;
assign dst_id[AxiB] = aw_out_data_out.src_id;
assign dst_id[AxiR] = ar_out_data_out.src_id;
`FFL(aw_xy_id_q, aw_xy_id, axi_aw_queue_valid_out && axi_aw_queue_ready_in, '0)
end else if (RouteAlgo == IdTable) begin : gen_id_table_routing
id_t aw_id_q, aw_id, ar_id;
assign aw_id = axi_aw_queue.addr[IdTableAddrOffset+:$bits(id_i)];
assign ar_id = axi_ar_queue.addr[IdTableAddrOffset+:$bits(id_i)];
assign dst_id[AxiAw] = aw_id;
assign dst_id[AxiAr] = ar_id;
assign dst_id[AxiW] = aw_id_q;
assign dst_id[AxiB] = aw_out_data_out.src_id;
assign dst_id[AxiR] = ar_out_data_out.src_id;
`FFL(aw_id_q, aw_id, axi_aw_queue_valid_out && axi_aw_queue_ready_in, '0)
end else begin : gen_no_routing
// TODO: Implement other routing algorithms
$fatal(1, "Routing algorithm not implemented");
end

///////////////////
// FLIT PACKING //
Expand Down
131 changes: 58 additions & 73 deletions src/floo_narrow_wide_chimney.sv
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,19 @@ module floo_narrow_wide_chimney
parameter int unsigned MaxAtomicTxns = 1,
/// Routing Algorithm
parameter route_algo_e RouteAlgo = IdTable,
/// Whether to look up the coordinates in a table or
/// directly read them from the request address with an offset
parameter bit UseIdTable = 1'b0,
/// X Coordinate address offset for XY routing
parameter int unsigned XYAddrOffsetX = 0,
/// Y Coordinate address offset for XY routing
parameter int unsigned XYAddrOffsetY = 0,
/// ID address offset for ID routing
parameter int unsigned IdAddrOffset = 0,
/// Number of Endpoints in the system, only used for Table based routing
parameter int unsigned NumIDs = 0,
/// Number of rules in the routing table, only used for Table based routing
parameter int unsigned NumRules = 0,
/// Number of maximum oustanding requests on the narrow network
parameter int unsigned NarrowMaxTxns = 32,
/// Number of maximum oustanding requests on the wide network
Expand All @@ -59,8 +68,6 @@ module floo_narrow_wide_chimney
parameter type id_t = logic,
/// Only used for IDRouting
parameter type id_rule_t = logic,
parameter int unsigned NumIDs = 1,
parameter int unsigned NumRules = NumIDs,
/// Type for implementation inputs and outputs
parameter type sram_cfg_t = logic
) (
Expand Down Expand Up @@ -603,78 +610,51 @@ module floo_narrow_wide_chimney
// ROUTING //
/////////////////

typedef enum logic [2:0] {NarrowAwReq, NarrowArReq, WideAwReq, WideArReq, NumAddrDecoders} axi_req_ch_e;

Check warning on line 613 in src/floo_narrow_wide_chimney.sv

View workflow job for this annotation

GitHub Actions / verible-verilog-lint

[verible-verilog-lint] src/floo_narrow_wide_chimney.sv#L613

Line length exceeds max: 100; is: 106 [Style: line-length] [line-length]
Raw output
message:"Line length exceeds max: 100; is: 106 [Style: line-length] [line-length]" location:{path:"./src/floo_narrow_wide_chimney.sv" range:{start:{line:613 column:101}}} severity:WARNING source:{name:"verible-verilog-lint" url:"https://github.com/chipsalliance/verible"}
typedef axi_narrow_in_addr_t addr_t;

id_t narrow_aw_id_q, wide_aw_id_q;

addr_t [NumAddrDecoders-1:0] addr_to_decode;
id_t [NumAddrDecoders-1:0] decoded_id;
assign addr_to_decode[NarrowAwReq] = axi_narrow_aw_queue.addr;
assign addr_to_decode[NarrowArReq] = axi_narrow_ar_queue.addr;
assign addr_to_decode[WideAwReq] = axi_wide_aw_queue.addr;
assign addr_to_decode[WideArReq] = axi_wide_ar_queue.addr;

floo_route_comp #(
.RouteAlgo ( RouteAlgo ),
.UseIdTable ( UseIdTable ),
.XYAddrOffsetX ( XYAddrOffsetX ),
.XYAddrOffsetY ( XYAddrOffsetY ),
.IdAddrOffset ( IdAddrOffset ),
.NumIDs ( NumIDs ),
.NumRules ( NumRules ),
.id_t ( id_t ),
.id_rule_t ( id_rule_t ),
.addr_t ( addr_t )
) i_floo_narrow_route_comp [NumAddrDecoders-1:0] (
.clk_i,
.rst_ni,
.id_map_i,
.addr_i ( addr_to_decode ),
.id_o ( decoded_id )
);

if (RouteAlgo == XYRouting) begin : gen_xy_routing
id_t narrow_aw_xy_id_q, narrow_aw_xy_id, narrow_ar_xy_id;
id_t wide_aw_xy_id_q, wide_aw_xy_id, wide_ar_xy_id;
assign narrow_aw_xy_id.x = axi_narrow_aw_queue.addr[XYAddrOffsetX+:$bits(id_i.x)];
assign narrow_aw_xy_id.y = axi_narrow_aw_queue.addr[XYAddrOffsetY+:$bits(id_i.y)];
assign narrow_ar_xy_id.x = axi_narrow_ar_queue.addr[XYAddrOffsetX+:$bits(id_i.x)];
assign narrow_ar_xy_id.y = axi_narrow_ar_queue.addr[XYAddrOffsetY+:$bits(id_i.y)];
assign wide_aw_xy_id.x = axi_wide_aw_queue.addr[XYAddrOffsetX+:$bits(id_i.x)];
assign wide_aw_xy_id.y = axi_wide_aw_queue.addr[XYAddrOffsetY+:$bits(id_i.y)];
assign wide_ar_xy_id.x = axi_wide_ar_queue.addr[XYAddrOffsetX+:$bits(id_i.x)];
assign wide_ar_xy_id.y = axi_wide_ar_queue.addr[XYAddrOffsetY+:$bits(id_i.y)];
assign dst_id[NarrowAw] = narrow_aw_xy_id;
assign dst_id[NarrowAr] = narrow_ar_xy_id;
assign dst_id[NarrowW] = narrow_aw_xy_id_q;
assign dst_id[NarrowB] = narrow_aw_out_data_out.src_id;
assign dst_id[NarrowR] = narrow_ar_out_data_out.src_id;
assign dst_id[WideAw] = wide_aw_xy_id;
assign dst_id[WideAr] = wide_ar_xy_id;
assign dst_id[WideW] = wide_aw_xy_id_q;
assign dst_id[WideB] = wide_aw_out_data_out.src_id;
assign dst_id[WideR] = wide_ar_out_data_out.src_id;
`FFL(narrow_aw_xy_id_q,narrow_aw_xy_id, axi_narrow_aw_queue_valid_out &&
axi_narrow_aw_queue_ready_in,'0)
`FFL(wide_aw_xy_id_q, wide_aw_xy_id, axi_wide_aw_queue_valid_out &&
axi_wide_aw_queue_ready_in, '0)
end else if (RouteAlgo == IdTable) begin : gen_id_table_routing
typedef enum logic [1:0] {NarrowAwReq, NarrowArReq, WideAwReq, WideArReq} axi_req_ch_e;
id_t narrow_aw_id_q, wide_aw_id_q;
axi_narrow_in_addr_t [WideArReq:NarrowAwReq] decode_addr_in;
id_t [WideArReq:NarrowAwReq] dst_addr_out;

assign decode_addr_in[NarrowAwReq] = axi_narrow_aw_queue.addr;
assign decode_addr_in[NarrowArReq] = axi_narrow_ar_queue.addr;
assign decode_addr_in[WideAwReq] = axi_wide_aw_queue.addr;
assign decode_addr_in[WideArReq] = axi_wide_ar_queue.addr;

addr_decode #(
.NoIndices ( NumIDs ),
.NoRules ( NumRules ),
.addr_t ( axi_narrow_in_addr_t ),
.rule_t ( id_rule_t ),
.idx_t ( id_t )
) i_addr_dst_decode [3:0] (
.addr_i ( decode_addr_in ),
.addr_map_i ( id_map_i ),
.idx_o ( dst_addr_out ),
.dec_valid_o ( ),
.dec_error_o ( ),
.en_default_idx_i ( 1'b0 ),
.default_idx_i ( '0 )
);

assign src_id = id_i;
assign dst_id[NarrowAw] = dst_addr_out[NarrowAwReq];
assign dst_id[NarrowW] = narrow_aw_id_q;
assign dst_id[NarrowAr] = dst_addr_out[NarrowArReq];
assign dst_id[NarrowB] = narrow_aw_out_data_out.src_id;
assign dst_id[NarrowR] = narrow_ar_out_data_out.src_id;
assign dst_id[WideAw] = dst_addr_out[WideAwReq];
assign dst_id[WideW] = wide_aw_id_q;
assign dst_id[WideAr] = dst_addr_out[WideArReq];
assign dst_id[WideB] = wide_aw_out_data_out.src_id;
assign dst_id[WideR] = wide_ar_out_data_out.src_id;
`FFL(narrow_aw_id_q, dst_id[NarrowAw], axi_narrow_aw_queue_valid_out &&
axi_narrow_aw_queue_ready_in, '0)
`FFL(wide_aw_id_q, dst_id[WideAw], axi_wide_aw_queue_valid_out &&
axi_wide_aw_queue_ready_in, '0)
end else begin : gen_no_routing
// TODO: Implement other routing algorithms
$fatal(1, "Routing algorithm not implemented");
end
assign dst_id[NarrowAw] = decoded_id[NarrowAwReq];
assign dst_id[NarrowW] = narrow_aw_id_q;
assign dst_id[NarrowAr] = decoded_id[NarrowArReq];
assign dst_id[NarrowB] = narrow_aw_out_data_out.src_id;
assign dst_id[NarrowR] = narrow_ar_out_data_out.src_id;
assign dst_id[WideAw] = decoded_id[WideAwReq];
assign dst_id[WideW] = wide_aw_id_q;
assign dst_id[WideAr] = decoded_id[WideArReq];
assign dst_id[WideB] = wide_aw_out_data_out.src_id;
assign dst_id[WideR] = wide_ar_out_data_out.src_id;
`FFL(narrow_aw_id_q, dst_id[NarrowAw], axi_narrow_aw_queue_valid_out &&
axi_narrow_aw_queue_ready_in, '0)
`FFL(wide_aw_id_q, dst_id[WideAw], axi_wide_aw_queue_valid_out &&
axi_wide_aw_queue_ready_in, '0)

///////////////////
// FLIT PACKING //
Expand Down Expand Up @@ -1153,6 +1133,11 @@ module floo_narrow_wide_chimney
`ASSERT_INIT(NoNarrowSbrPortRobType, EnNarrowSbrPort || (NarrowRoBType == NoRoB))
`ASSERT_INIT(NoWideSbrPortRobType, EnWideSbrPort || (WideRoBType == NoRoB))

// Check that all addresses have the same width
`ASSERT_INIT(SameAddrWidth1, NarrowInAddrWidth == NarrowOutAddrWidth)
`ASSERT_INIT(SameAddrWidth2, WideInAddrWidth == NarrowOutAddrWidth)
`ASSERT_INIT(SameAddrWidth3, WideInAddrWidth == WideOutAddrWidth)

// Data and valid signals must be stable/asserted when ready is low
`ASSERT(NarrowReqOutStableValid, floo_req_o.valid &&
!floo_req_i.ready |=> floo_req_o.valid)
Expand Down
72 changes: 72 additions & 0 deletions src/floo_route_comp.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright 2023 ETH Zurich and University of Bologna.
// Solderpad Hardware License, Version 0.51, see LICENSE for details.
// SPDX-License-Identifier: SHL-0.51
//
// Author: Tim Fischer <[email protected]>

`include "common_cells/assertions.svh"

module floo_route_comp
import floo_pkg::*;
#(
/// The type of routing algorithms to use
parameter route_algo_e RouteAlgo = IdTable,
/// Whether to use a routing table with address decoder
/// In case of XY Routing or the coordinates should be
/// directly read from the request address
parameter bit UseIdTable = 1'b1,
/// The offset bit to read the X coordinate from
parameter int unsigned XYAddrOffsetX = 0,
/// The offset bit to read the Y coordinate from
parameter int unsigned XYAddrOffsetY = 0,
/// The offset bit to read the ID from
parameter int unsigned IdAddrOffset = 0,
/// The number of possible endpoints
parameter int unsigned NumIDs = 0,
/// The number of possible rules
parameter int unsigned NumRules = 0,
/// The type of the coordinates or IDs
parameter type id_t = logic,
/// The type of the rules
parameter type id_rule_t = logic,
/// The address type
parameter type addr_t = logic
) (
input logic clk_i,
input logic rst_ni,
input addr_t addr_i,
input id_rule_t [NumRules-1:0] id_map_i,
output id_t id_o
);

if (UseIdTable && ((RouteAlgo == IdTable) || (RouteAlgo == XYRouting)))
begin : gen_table_routing
logic dec_error;

addr_decode #(
.NoIndices ( NumIDs ),
.NoRules ( NumRules ),
.addr_t ( addr_t ),
.rule_t ( id_rule_t ),
.idx_t ( id_t )
) i_addr_dst_decode (
.addr_i ( addr_i ),
.addr_map_i ( id_map_i ),
.idx_o ( id_o ),
.dec_valid_o ( ),
.dec_error_o ( dec_error ),
.en_default_idx_i ( 1'b0 ),
.default_idx_i ( '0 )
);

`ASSERT(DecodeError, !dec_error)
end else if (RouteAlgo == XYRouting) begin : gen_xy_bits_routing
assign id_o.x = addr_i[XYAddrOffsetX +: $bits(id_o.x)];
assign id_o.y = addr_i[XYAddrOffsetY +: $bits(id_o.y)];
end else if (RouteAlgo == IdTable) begin : gen_id_bits_routing
assign id_o = addr_i[IdAddrOffset +: $bits(id_o)];
end else begin : gen_error
$fatal(1, "Routing algorithm not implemented");
end

endmodule

0 comments on commit a6e981a

Please sign in to comment.