`timescale 1ns/1ps
|
`timescale 1ns/1ps
|
/**********************************************************************
|
/**********************************************************************
|
** File: routing.v
|
** File: routing.v
|
**
|
**
|
** Copyright (C) 2014-2017 Alireza Monemi
|
** Copyright (C) 2014-2017 Alireza Monemi
|
**
|
**
|
** This file is part of ProNoC
|
** This file is part of ProNoC
|
**
|
**
|
** ProNoC ( stands for Prototype Network-on-chip) is free software:
|
** ProNoC ( stands for Prototype Network-on-chip) is free software:
|
** you can redistribute it and/or modify it under the terms of the GNU
|
** you can redistribute it and/or modify it under the terms of the GNU
|
** Lesser General Public License as published by the Free Software Foundation,
|
** Lesser General Public License as published by the Free Software Foundation,
|
** either version 2 of the License, or (at your option) any later version.
|
** either version 2 of the License, or (at your option) any later version.
|
**
|
**
|
** ProNoC is distributed in the hope that it will be useful, but WITHOUT
|
** ProNoC is distributed in the hope that it will be useful, but WITHOUT
|
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
** or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
** or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
** Public License for more details.
|
** Public License for more details.
|
**
|
**
|
** You should have received a copy of the GNU Lesser General Public
|
** You should have received a copy of the GNU Lesser General Public
|
** License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
|
** License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
|
**
|
**
|
**
|
**
|
** Description:
|
** Description:
|
** look-ahead and conventional routing algorithms for Mesh and Torus NoC
|
** look-ahead and conventional routing algorithms for Mesh and Torus NoC
|
**
|
**
|
**
|
**
|
**************************************************************/
|
**************************************************************/
|
|
|
|
|
module conventional_routing #(
|
module conventional_routing #(
|
|
parameter NOC_ID = 0,
|
parameter TOPOLOGY = "MESH",
|
parameter TOPOLOGY = "MESH",
|
parameter ROUTE_NAME = "XY",
|
parameter ROUTE_NAME = "XY",
|
parameter ROUTE_TYPE = "DETERMINISTIC",
|
parameter ROUTE_TYPE = "DETERMINISTIC",
|
parameter T1 = 4,
|
parameter T1 = 4,
|
parameter T2 = 4,
|
parameter T2 = 4,
|
parameter T3 = 4,
|
parameter T3 = 4,
|
parameter RAw = 3,
|
parameter RAw = 3,
|
parameter EAw = 3,
|
parameter EAw = 3,
|
parameter DSTPw = 4,
|
parameter DSTPw = 4,
|
parameter LOCATED_IN_NI = 1 // only needed for mesh and odd-even routing
|
parameter LOCATED_IN_NI = 1 // only needed for mesh and odd-even routing
|
)
|
)
|
(
|
(
|
reset,
|
reset,
|
clk,
|
clk,
|
current_r_addr,
|
current_r_addr,
|
src_e_addr,
|
src_e_addr,
|
dest_e_addr,
|
dest_e_addr,
|
destport
|
destport
|
);
|
);
|
|
|
function integer log2;
|
function integer log2;
|
input integer number; begin
|
input integer number; begin
|
log2=(number <=1) ? 1: 0;
|
log2=(number <=1) ? 1: 0;
|
while(2**log2<number) begin
|
while(2**log2<number) begin
|
log2=log2+1;
|
log2=log2+1;
|
end
|
end
|
end
|
end
|
endfunction // log2
|
endfunction // log2
|
|
|
input reset,clk;
|
input reset,clk;
|
input [RAw-1 :0] current_r_addr;
|
input [RAw-1 :0] current_r_addr;
|
input [EAw-1 :0] src_e_addr;
|
input [EAw-1 :0] src_e_addr;
|
input [EAw-1 :0] dest_e_addr;
|
input [EAw-1 :0] dest_e_addr;
|
output [DSTPw-1 :0] destport;
|
output [DSTPw-1 :0] destport;
|
|
|
generate
|
generate
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if(TOPOLOGY == "MESH" || TOPOLOGY == "FMESH" || TOPOLOGY == "TORUS" || TOPOLOGY == "RING" || TOPOLOGY == "LINE") begin :mesh_torus
|
if(TOPOLOGY == "MESH" || TOPOLOGY == "FMESH" || TOPOLOGY == "TORUS" || TOPOLOGY == "RING" || TOPOLOGY == "LINE") begin :mesh_torus
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
|
|
localparam
|
localparam
|
NX = T1,
|
NX = T1,
|
NY = T2,
|
NY = T2,
|
RXw = log2(NX),
|
RXw = log2(NX),
|
RYw = log2(NY),
|
RYw = (TOPOLOGY=="RING" || TOPOLOGY == "LINE") ? 1 :log2(NY),
|
EXw = RXw,
|
EXw = RXw,
|
EYw = RYw;
|
EYw = (TOPOLOGY=="RING" || TOPOLOGY == "LINE") ? 1 : RYw;
|
|
|
wire [RXw-1 : 0] current_rx;
|
wire [RXw-1 : 0] current_rx;
|
wire [RYw-1 : 0] current_ry;
|
wire [RYw-1 : 0] current_ry;
|
wire [EXw-1 : 0] dest_ex;
|
wire [EXw-1 : 0] dest_ex;
|
wire [EYw-1 : 0] dest_ey;
|
wire [EYw-1 : 0] dest_ey;
|
|
|
|
|
mesh_tori_router_addr_decode #(
|
mesh_tori_router_addr_decode #(
|
.TOPOLOGY(TOPOLOGY),
|
.TOPOLOGY(TOPOLOGY),
|
.T1(T1),
|
.T1(T1),
|
.T2(T2),
|
.T2(T2),
|
.T3(T3),
|
.T3(T3),
|
.RAw(RAw)
|
.RAw(RAw)
|
)
|
)
|
router_addr_decode
|
router_addr_decode
|
(
|
(
|
.r_addr(current_r_addr),
|
.r_addr(current_r_addr),
|
.rx(current_rx),
|
.rx(current_rx),
|
.ry(current_ry),
|
.ry(current_ry),
|
.valid( )
|
.valid( )
|
);
|
);
|
|
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if(TOPOLOGY == "FMESH") begin :fmesh
|
if(TOPOLOGY == "FMESH") begin :fmesh
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
fmesh_endp_addr_decode #(
|
fmesh_endp_addr_decode #(
|
.T1(T1),
|
.T1(T1),
|
.T2(T2),
|
.T2(T2),
|
.T3(T3),
|
.T3(T3),
|
.EAw(EAw)
|
.EAw(EAw)
|
)
|
)
|
end_addr_decode
|
end_addr_decode
|
(
|
(
|
.e_addr(dest_e_addr),
|
.e_addr(dest_e_addr),
|
.ex(dest_ex),
|
.ex(dest_ex),
|
.ey(dest_ey),
|
.ey(dest_ey),
|
.ep( ),
|
.ep( ),
|
.valid()
|
.valid()
|
);
|
);
|
|
|
|
|
|
|
end else begin : mesh
|
end else begin : mesh
|
mesh_tori_endp_addr_decode #(
|
mesh_tori_endp_addr_decode #(
|
.TOPOLOGY(TOPOLOGY),
|
.TOPOLOGY(TOPOLOGY),
|
.T1(T1),
|
.T1(T1),
|
.T2(T2),
|
.T2(T2),
|
.T3(T3),
|
.T3(T3),
|
.EAw(EAw)
|
.EAw(EAw)
|
)
|
)
|
end_addr_decode
|
end_addr_decode
|
(
|
(
|
.e_addr(dest_e_addr),
|
.e_addr(dest_e_addr),
|
.ex(dest_ex),
|
.ex(dest_ex),
|
.ey(dest_ey),
|
.ey(dest_ey),
|
.el( ),
|
.el( ),
|
.valid()
|
.valid()
|
);
|
);
|
end//mesh
|
end//mesh
|
|
|
mesh_torus_conventional_routing #(
|
mesh_torus_conventional_routing #(
|
.TOPOLOGY(TOPOLOGY),
|
.TOPOLOGY(TOPOLOGY),
|
.ROUTE_NAME(ROUTE_NAME),
|
.ROUTE_NAME(ROUTE_NAME),
|
.ROUTE_TYPE(ROUTE_TYPE),
|
.ROUTE_TYPE(ROUTE_TYPE),
|
.NX(T1),
|
.NX(T1),
|
.NY(T2),
|
.NY(T2),
|
.LOCATED_IN_NI(LOCATED_IN_NI)
|
.LOCATED_IN_NI(LOCATED_IN_NI)
|
)
|
)
|
the_conventional_routing
|
the_conventional_routing
|
(
|
(
|
.current_x(current_rx),
|
.current_x(current_rx),
|
.current_y(current_ry),
|
.current_y(current_ry),
|
.dest_x(dest_ex),
|
.dest_x(dest_ex),
|
.dest_y(dest_ey),
|
.dest_y(dest_ey),
|
.destport(destport)
|
.destport(destport)
|
);
|
);
|
|
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
end else if(TOPOLOGY == "FATTREE" || TOPOLOGY == "TREE" ) begin :tree_based
|
end else if(TOPOLOGY == "FATTREE" || TOPOLOGY == "TREE" ) begin :tree_based
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
|
|
localparam
|
localparam
|
K=T1,
|
K=T1,
|
L=T2,
|
L=T2,
|
Kw = log2(K),
|
Kw = log2(K),
|
LKw= L*Kw,
|
LKw= L*Kw,
|
Lw = log2(L);
|
Lw = log2(L);
|
|
|
wire [LKw-1 :0] current_rx;
|
wire [LKw-1 :0] current_rx;
|
wire [Lw-1 :0] current_rl;
|
wire [Lw-1 :0] current_rl;
|
|
|
fattree_router_addr_decode #(
|
fattree_router_addr_decode #(
|
.K(T1),
|
.K(T1),
|
.L(T2)
|
.L(T2)
|
)
|
)
|
router_addr_decode
|
router_addr_decode
|
(
|
(
|
.r_addr(current_r_addr),
|
.r_addr(current_r_addr),
|
.rx(current_rx),
|
.rx(current_rx),
|
.rl(current_rl)
|
.rl(current_rl)
|
);
|
);
|
|
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if(TOPOLOGY == "FATTREE" )begin : fattree
|
if(TOPOLOGY == "FATTREE" )begin : fattree
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
|
|
fattree_conventional_routing #(
|
fattree_conventional_routing #(
|
.ROUTE_NAME(ROUTE_NAME),
|
.ROUTE_NAME(ROUTE_NAME),
|
.K(T1),
|
.K(T1),
|
.L(T2)
|
.L(T2)
|
)
|
)
|
the_conventional_routing
|
the_conventional_routing
|
(
|
(
|
.reset(reset),
|
.reset(reset),
|
.clk(clk),
|
.clk(clk),
|
.current_addr_encoded(current_rx),
|
.current_addr_encoded(current_rx),
|
.current_level(current_rl),
|
.current_level(current_rl),
|
.dest_addr_encoded(dest_e_addr),
|
.dest_addr_encoded(dest_e_addr),
|
.destport_encoded(destport)
|
.destport_encoded(destport)
|
);
|
);
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
end else if(TOPOLOGY == "TREE" )begin : tree
|
end else if(TOPOLOGY == "TREE" )begin : tree
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
tree_conventional_routing #(
|
tree_conventional_routing #(
|
.ROUTE_NAME(ROUTE_NAME),
|
.ROUTE_NAME(ROUTE_NAME),
|
.K(T1),
|
.K(T1),
|
.L(T2)
|
.L(T2)
|
)
|
)
|
the_conventional_routing
|
the_conventional_routing
|
(
|
(
|
|
|
.current_addr_encoded(current_rx),
|
.current_addr_encoded(current_rx),
|
.current_level(current_rl),
|
.current_level(current_rl),
|
.dest_addr_encoded(dest_e_addr),
|
.dest_addr_encoded(dest_e_addr),
|
.destport_encoded(destport)
|
.destport_encoded(destport)
|
);
|
);
|
end // tree
|
end // tree
|
|
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
end else if (TOPOLOGY == "STAR") begin : star
|
end else if (TOPOLOGY == "STAR") begin : star
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
star_conventional_routing #(
|
star_conventional_routing #(
|
.NE(T1)
|
.NE(T1)
|
)
|
)
|
the_conventional_routing
|
the_conventional_routing
|
(
|
(
|
.dest_e_addr(dest_e_addr),
|
.dest_e_addr(dest_e_addr),
|
.destport(destport)
|
.destport(destport)
|
);
|
);
|
|
|
|
|
|
|
|
|
end else begin :custom
|
end else begin :custom
|
|
|
custom_ni_routing #(
|
custom_ni_routing #(
|
.TOPOLOGY(TOPOLOGY),
|
.TOPOLOGY(TOPOLOGY),
|
.ROUTE_NAME(ROUTE_NAME),
|
.ROUTE_NAME(ROUTE_NAME),
|
.ROUTE_TYPE(ROUTE_TYPE),
|
.ROUTE_TYPE(ROUTE_TYPE),
|
.RAw(RAw),
|
.RAw(RAw),
|
.EAw(EAw),
|
.EAw(EAw),
|
.DSTPw(DSTPw)
|
.DSTPw(DSTPw)
|
)
|
)
|
the_conventional_routing
|
the_conventional_routing
|
(
|
(
|
.dest_e_addr(dest_e_addr),
|
.dest_e_addr(dest_e_addr),
|
.src_e_addr(src_e_addr),
|
.src_e_addr(src_e_addr),
|
.destport(destport)
|
.destport(destport)
|
);
|
);
|
|
|
end //custom
|
end //custom
|
endgenerate
|
endgenerate
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/************************************
|
/************************************
|
|
|
look_ahead_routing
|
look_ahead_routing
|
|
|
*************************************/
|
*************************************/
|
|
|
module look_ahead_routing #(
|
module look_ahead_routing #(
|
|
parameter NOC_ID=0,
|
parameter P = 5,
|
parameter P = 5,
|
parameter T1= 8,
|
parameter T1= 8,
|
parameter T2= 8,
|
parameter T2= 8,
|
parameter T3= 8,
|
parameter T3= 8,
|
parameter T4= 8,
|
parameter T4= 8,
|
parameter RAw = 3,
|
parameter RAw = 3,
|
parameter EAw = 3,
|
parameter EAw = 3,
|
parameter DAw = 3,
|
parameter DAw = 3,
|
parameter DSTPw=P-1,
|
parameter DSTPw=P-1,
|
parameter SW_LOC =0,
|
parameter SW_LOC =0,
|
parameter TOPOLOGY ="MESH",//"MESH","TORUS"
|
parameter TOPOLOGY ="MESH",//"MESH","TORUS"
|
parameter ROUTE_NAME="XY",//
|
parameter ROUTE_NAME="XY",//
|
parameter ROUTE_TYPE="DETERMINISTIC"// "DETERMINISTIC", "FULL_ADAPTIVE", "PAR_ADAPTIVE"
|
parameter ROUTE_TYPE="DETERMINISTIC"// "DETERMINISTIC", "FULL_ADAPTIVE", "PAR_ADAPTIVE"
|
)
|
)
|
(
|
(
|
current_r_addr, //current router address
|
current_r_addr, //current router address
|
neighbors_r_addr,
|
neighbors_r_addr,
|
dest_e_addr, // destination endpoint address
|
dest_e_addr, // destination endpoint address
|
src_e_addr, // source endpoint address. Only needed for custom topology
|
src_e_addr, // source endpoint address. Only needed for custom topology
|
destport_encoded, // current router destination port number
|
destport_encoded, // current router destination port number
|
lkdestport_encoded, // look ahead destination port number
|
lkdestport_encoded, // look ahead destination port number
|
reset,
|
reset,
|
clk
|
clk
|
);
|
);
|
|
|
function integer log2;
|
function integer log2;
|
input integer number; begin
|
input integer number; begin
|
log2=(number <=1) ? 1: 0;
|
log2=(number <=1) ? 1: 0;
|
while(2**log2<number) begin
|
while(2**log2<number) begin
|
log2=log2+1;
|
log2=log2+1;
|
end
|
end
|
end
|
end
|
endfunction // log2
|
endfunction // log2
|
|
|
localparam
|
localparam
|
PRAw= P * RAw;
|
PRAw= P * RAw;
|
localparam
|
localparam
|
//K= T1,
|
//K= T1,
|
//L=T2,
|
//L=T2,
|
Kw = log2(T1),
|
Kw = log2(T1),
|
Lw = log2(T2),
|
Lw = log2(T2),
|
LKw= T2 * Kw,
|
LKw= T2 * Kw,
|
PLw = P * Lw,
|
PLw = P * Lw,
|
PLKw = P * LKw;
|
PLKw = P * LKw;
|
|
|
input [PRAw-1: 0] neighbors_r_addr;
|
input [PRAw-1: 0] neighbors_r_addr;
|
input [RAw-1 : 0] current_r_addr;
|
input [RAw-1 : 0] current_r_addr;
|
input [DAw-1 : 0] dest_e_addr;
|
input [DAw-1 : 0] dest_e_addr;
|
input [EAw-1 : 0] src_e_addr;
|
input [EAw-1 : 0] src_e_addr;
|
input [DSTPw-1 : 0] destport_encoded;
|
input [DSTPw-1 : 0] destport_encoded;
|
output [DSTPw-1 : 0] lkdestport_encoded;
|
output [DSTPw-1 : 0] lkdestport_encoded;
|
input reset,clk;
|
input reset,clk;
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if(TOPOLOGY == "MESH" || TOPOLOGY == "FMESH" || TOPOLOGY == "TORUS" || TOPOLOGY == "RING" || TOPOLOGY == "LINE")begin :mesh_torus
|
if(TOPOLOGY == "MESH" || TOPOLOGY == "FMESH" || TOPOLOGY == "TORUS" || TOPOLOGY == "RING" || TOPOLOGY == "LINE")begin :mesh_torus
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
|
|
localparam
|
localparam
|
NX = T1,
|
NX = T1,
|
NY = T2,
|
NY = T2,
|
RXw = log2(NX),
|
RXw = log2(NX),
|
RYw = log2(NY),
|
RYw = (TOPOLOGY=="RING" || TOPOLOGY == "LINE")? 1 : log2(NY),
|
EXw = RXw,
|
EXw = RXw,
|
EYw = RYw;
|
EYw = RYw;
|
|
|
wire [RXw-1 : 0] current_rx;
|
wire [RXw-1 : 0] current_rx;
|
wire [RYw-1 : 0] current_ry;
|
wire [RYw-1 : 0] current_ry;
|
wire [EXw-1 : 0] dest_ex;
|
wire [EXw-1 : 0] dest_ex;
|
wire [EYw-1 : 0] dest_ey;
|
wire [EYw-1 : 0] dest_ey;
|
|
|
localparam SL_SW_LOC = ( SW_LOC > P-T3) ? 0 : SW_LOC; //single_local
|
localparam SL_SW_LOC = ( SW_LOC > P-T3) ? 0 : SW_LOC; //single_local
|
|
|
mesh_tori_router_addr_decode #(
|
mesh_tori_router_addr_decode #(
|
.TOPOLOGY(TOPOLOGY),
|
.TOPOLOGY(TOPOLOGY),
|
.T1(T1),
|
.T1(T1),
|
.T2(T2),
|
.T2(T2),
|
.T3(T3),
|
.T3(T3),
|
.RAw(RAw)
|
.RAw(RAw)
|
)
|
)
|
router_addr_decode
|
router_addr_decode
|
(
|
(
|
.r_addr(current_r_addr),
|
.r_addr(current_r_addr),
|
.rx(current_rx),
|
.rx(current_rx),
|
.ry(current_ry),
|
.ry(current_ry),
|
.valid( )
|
.valid( )
|
);
|
);
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if(TOPOLOGY == "FMESH") begin :fmesh
|
if(TOPOLOGY == "FMESH") begin :fmesh
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
fmesh_endp_addr_decode #(
|
fmesh_endp_addr_decode #(
|
.T1(T1),
|
.T1(T1),
|
.T2(T2),
|
.T2(T2),
|
.T3(T3),
|
.T3(T3),
|
.EAw(EAw)
|
.EAw(EAw)
|
)
|
)
|
end_addr_decode
|
end_addr_decode
|
(
|
(
|
.e_addr(dest_e_addr),
|
.e_addr(dest_e_addr),
|
.ex(dest_ex),
|
.ex(dest_ex),
|
.ey(dest_ey),
|
.ey(dest_ey),
|
.ep( ),
|
.ep( ),
|
.valid()
|
.valid()
|
);
|
);
|
end else begin :mesh
|
end else begin :mesh
|
mesh_tori_endp_addr_decode #(
|
mesh_tori_endp_addr_decode #(
|
.TOPOLOGY(TOPOLOGY),
|
.TOPOLOGY(TOPOLOGY),
|
.T1(T1),
|
.T1(T1),
|
.T2(T2),
|
.T2(T2),
|
.T3(T3),
|
.T3(T3),
|
.EAw(EAw)
|
.EAw(EAw)
|
)
|
)
|
end_addr_decode
|
end_addr_decode
|
(
|
(
|
.e_addr(dest_e_addr),
|
.e_addr(dest_e_addr),
|
.ex(dest_ex),
|
.ex(dest_ex),
|
.ey(dest_ey),
|
.ey(dest_ey),
|
.el( ),
|
.el( ),
|
.valid()
|
.valid()
|
);
|
);
|
|
|
|
|
end
|
end
|
|
|
mesh_torus_look_ahead_routing #(
|
mesh_torus_look_ahead_routing #(
|
.NX(T1),
|
.NX(T1),
|
.NY(T2),
|
.NY(T2),
|
.SW_LOC(SL_SW_LOC),
|
.SW_LOC(SL_SW_LOC),
|
.TOPOLOGY(TOPOLOGY),
|
.TOPOLOGY(TOPOLOGY),
|
.ROUTE_NAME(ROUTE_NAME),
|
.ROUTE_NAME(ROUTE_NAME),
|
.ROUTE_TYPE(ROUTE_TYPE)
|
.ROUTE_TYPE(ROUTE_TYPE)
|
)
|
)
|
look_ahead_route
|
look_ahead_route
|
(
|
(
|
.current_x(current_rx),
|
.current_x(current_rx),
|
.current_y(current_ry),
|
.current_y(current_ry),
|
.dest_x(dest_ex),
|
.dest_x(dest_ex),
|
.dest_y(dest_ey),
|
.dest_y(dest_ey),
|
.destport_encoded(destport_encoded),
|
.destport_encoded(destport_encoded),
|
.lkdestport_encoded(lkdestport_encoded),
|
.lkdestport_encoded(lkdestport_encoded),
|
.reset(reset),
|
.reset(reset),
|
.clk(clk)
|
.clk(clk)
|
);
|
);
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
end else if (TOPOLOGY == "FATTREE") begin: fat
|
end else if (TOPOLOGY == "FATTREE") begin: fat
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
|
|
wire [PLKw-1 : 0] neighbors_rx;
|
wire [PLKw-1 : 0] neighbors_rx;
|
wire [PLw-1 : 0] neighbors_ry;
|
wire [PLw-1 : 0] neighbors_ry;
|
|
|
for (i=0; i<P; i=i+1) begin : port
|
for (i=0; i<P; i=i+1) begin : port
|
assign neighbors_rx[(i+1)*LKw-1: i*LKw] = neighbors_r_addr[(i*RAw)+LKw-1 : i*RAw];
|
assign neighbors_rx[(i+1)*LKw-1: i*LKw] = neighbors_r_addr[(i*RAw)+LKw-1 : i*RAw];
|
assign neighbors_ry[(i+1)*Lw-1 : i*Lw] = neighbors_r_addr[(i+1)*RAw-1: (i*RAw)+LKw];
|
assign neighbors_ry[(i+1)*Lw-1 : i*Lw] = neighbors_r_addr[(i+1)*RAw-1: (i*RAw)+LKw];
|
end//port
|
end//port
|
|
|
fattree_look_ahead_routing #(
|
fattree_look_ahead_routing #(
|
.ROUTE_NAME(ROUTE_NAME),
|
.ROUTE_NAME(ROUTE_NAME),
|
.P(P),
|
.P(P),
|
.K(T1),
|
.K(T1),
|
.L(T2)
|
.L(T2)
|
)
|
)
|
look_ahead_route
|
look_ahead_route
|
(
|
(
|
.destport_encoded(destport_encoded),
|
.destport_encoded(destport_encoded),
|
.dest_addr_encoded(dest_e_addr),
|
.dest_addr_encoded(dest_e_addr),
|
.neighbors_rx(neighbors_rx),
|
.neighbors_rx(neighbors_rx),
|
.neighbors_ry(neighbors_ry),
|
.neighbors_ry(neighbors_ry),
|
.lkdestport_encoded(lkdestport_encoded),
|
.lkdestport_encoded(lkdestport_encoded),
|
.reset(reset),
|
.reset(reset),
|
.clk(clk)
|
.clk(clk)
|
);
|
);
|
|
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
end else if (TOPOLOGY == "TREE") begin: tree
|
end else if (TOPOLOGY == "TREE") begin: tree
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
|
|
wire [PLKw-1 : 0] neighbors_rx_tree;
|
wire [PLKw-1 : 0] neighbors_rx_tree;
|
wire [PLw-1 : 0] neighbors_ry_tree;
|
wire [PLw-1 : 0] neighbors_ry_tree;
|
|
|
for (i=0; i<P; i=i+1) begin : port
|
for (i=0; i<P; i=i+1) begin : port
|
assign neighbors_rx_tree[(i+1)*LKw-1: i*LKw] = neighbors_r_addr[(i*RAw)+LKw-1 : i*RAw];
|
assign neighbors_rx_tree[(i+1)*LKw-1: i*LKw] = neighbors_r_addr[(i*RAw)+LKw-1 : i*RAw];
|
assign neighbors_ry_tree[(i+1)*Lw-1 : i*Lw] = neighbors_r_addr[(i+1)*RAw-1: (i*RAw)+LKw];
|
assign neighbors_ry_tree[(i+1)*Lw-1 : i*Lw] = neighbors_r_addr[(i+1)*RAw-1: (i*RAw)+LKw];
|
end//port
|
end//port
|
|
|
|
|
tree_look_ahead_routing #(
|
tree_look_ahead_routing #(
|
.ROUTE_NAME(ROUTE_NAME),
|
.ROUTE_NAME(ROUTE_NAME),
|
.P(P),
|
.P(P),
|
.L(T2),
|
.L(T2),
|
.K(T1)
|
.K(T1)
|
)
|
)
|
look_ahead_routing
|
look_ahead_routing
|
(
|
(
|
.destport_encoded(destport_encoded),
|
.destport_encoded(destport_encoded),
|
.dest_addr_encoded(dest_e_addr),
|
.dest_addr_encoded(dest_e_addr),
|
.neighbors_rx(neighbors_rx_tree),
|
.neighbors_rx(neighbors_rx_tree),
|
.neighbors_ry(neighbors_ry_tree),
|
.neighbors_ry(neighbors_ry_tree),
|
.lkdestport_encoded(lkdestport_encoded),
|
.lkdestport_encoded(lkdestport_encoded),
|
.reset(reset),
|
.reset(reset),
|
.clk(clk)
|
.clk(clk)
|
);
|
);
|
|
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
end else if (TOPOLOGY == "STAR") begin : star
|
end else if (TOPOLOGY == "STAR") begin : star
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
//look-ahead routing is not needed in star topology as there is only one router
|
//look-ahead routing is not needed in star topology as there is only one router
|
assign lkdestport_encoded={DSTPw{1'b0}};
|
assign lkdestport_encoded={DSTPw{1'b0}};
|
|
|
end else begin : custom
|
end else begin : custom
|
|
|
custom_lkh_routing #(
|
custom_lkh_routing #(
|
.TOPOLOGY(TOPOLOGY),
|
.TOPOLOGY(TOPOLOGY),
|
.ROUTE_NAME(ROUTE_NAME),
|
.ROUTE_NAME(ROUTE_NAME),
|
.ROUTE_TYPE(ROUTE_TYPE),
|
.ROUTE_TYPE(ROUTE_TYPE),
|
.RAw(RAw),
|
.RAw(RAw),
|
.EAw(EAw),
|
.EAw(EAw),
|
.DSTPw(DSTPw)
|
.DSTPw(DSTPw)
|
)
|
)
|
look_ahead_routing
|
look_ahead_routing
|
(
|
(
|
.current_r_addr(current_r_addr),
|
.current_r_addr(current_r_addr),
|
.dest_e_addr(dest_e_addr),
|
.dest_e_addr(dest_e_addr),
|
.src_e_addr(src_e_addr),
|
.src_e_addr(src_e_addr),
|
.destport(lkdestport_encoded),
|
.destport(lkdestport_encoded),
|
.reset(reset),
|
.reset(reset),
|
.clk(clk)
|
.clk(clk)
|
);
|
);
|
|
|
end
|
end
|
endgenerate
|
endgenerate
|
endmodule
|
endmodule
|
|
|
/********************************************************
|
/********************************************************
|
|
|
next_router_addr_selector
|
next_router_addr_selector
|
|
|
Determine the next router address based on the packet destination port
|
Determine the next router address based on the packet destination port
|
|
|
********************************************************/
|
********************************************************/
|
|
|
|
|
module next_router_addr_selector_onehot #(
|
module next_router_addr_selector_onehot #(
|
parameter P = 5,
|
parameter P = 5,
|
parameter RXw = 3, // The router's x dimension adress width in bits
|
parameter RXw = 3, // The router's x dimension adress width in bits
|
parameter RYw = 3 // The router's y dimension adress width in bits
|
parameter RYw = 3 // The router's y dimension adress width in bits
|
)
|
)
|
(
|
(
|
destport_onehot,
|
destport_onehot,
|
neighbors_rx,
|
neighbors_rx,
|
neighbors_ry,
|
neighbors_ry,
|
next_rx,
|
next_rx,
|
next_ry
|
next_ry
|
);
|
);
|
|
|
localparam
|
localparam
|
PRXw = P * RXw,
|
PRXw = P * RXw,
|
PRYw = P * RYw;
|
PRYw = P * RYw;
|
|
|
input [P-1 : 0] destport_onehot;
|
input [P-1 : 0] destport_onehot;
|
input [PRXw-1: 0] neighbors_rx;
|
input [PRXw-1: 0] neighbors_rx;
|
input [PRYw-1: 0] neighbors_ry;
|
input [PRYw-1: 0] neighbors_ry;
|
output[RXw-1 : 0] next_rx;
|
output[RXw-1 : 0] next_rx;
|
output[RYw-1 : 0] next_ry;
|
output[RYw-1 : 0] next_ry;
|
|
|
onehot_mux_1D #(
|
onehot_mux_1D #(
|
.W(RXw),
|
.W(RXw),
|
.N(P)
|
.N(P)
|
)
|
)
|
next_x_mux
|
next_x_mux
|
(
|
(
|
.in(neighbors_rx),
|
.in(neighbors_rx),
|
.out(next_rx),
|
.out(next_rx),
|
.sel(destport_onehot)
|
.sel(destport_onehot)
|
);
|
);
|
|
|
onehot_mux_1D #(
|
onehot_mux_1D #(
|
.W(RYw),
|
.W(RYw),
|
.N(P)
|
.N(P)
|
)
|
)
|
next_y_mux
|
next_y_mux
|
(
|
(
|
.in(neighbors_ry),
|
.in(neighbors_ry),
|
.out(next_ry),
|
.out(next_ry),
|
.sel(destport_onehot)
|
.sel(destport_onehot)
|
);
|
);
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
module next_router_addr_selector_bin #(
|
module next_router_addr_selector_bin #(
|
parameter P = 5,
|
parameter P = 5,
|
parameter RXw = 3, // The router's x dimension adress width in bits
|
parameter RXw = 3, // The router's x dimension adress width in bits
|
parameter RYw = 3 // The router's y dimension adress width in bits
|
parameter RYw = 3 // The router's y dimension adress width in bits
|
)
|
)
|
(
|
(
|
destport_bin,
|
destport_bin,
|
neighbors_rx,
|
neighbors_rx,
|
neighbors_ry,
|
neighbors_ry,
|
next_rx,
|
next_rx,
|
next_ry
|
next_ry
|
|
|
);
|
);
|
|
|
function integer log2;
|
function integer log2;
|
input integer number; begin
|
input integer number; begin
|
log2=(number <=1) ? 1: 0;
|
log2=(number <=1) ? 1: 0;
|
while(2**log2<number) begin
|
while(2**log2<number) begin
|
log2=log2+1;
|
log2=log2+1;
|
end
|
end
|
end
|
end
|
endfunction // log2
|
endfunction // log2
|
|
|
localparam
|
localparam
|
Pw = log2(P),
|
Pw = log2(P),
|
PRXw = P * RXw,
|
PRXw = P * RXw,
|
PRYw = P * RYw;
|
PRYw = P * RYw;
|
|
|
input [Pw-1 : 0] destport_bin;
|
input [Pw-1 : 0] destport_bin;
|
input [PRXw-1: 0] neighbors_rx;
|
input [PRXw-1: 0] neighbors_rx;
|
input [PRYw-1: 0] neighbors_ry;
|
input [PRYw-1: 0] neighbors_ry;
|
output[RXw-1 : 0] next_rx;
|
output[RXw-1 : 0] next_rx;
|
output[RYw-1 : 0] next_ry;
|
output[RYw-1 : 0] next_ry;
|
|
|
binary_mux #(
|
binary_mux #(
|
.IN_WIDTH(PRXw),
|
.IN_WIDTH(PRXw),
|
.OUT_WIDTH(RXw)
|
.OUT_WIDTH(RXw)
|
)
|
)
|
next_x_mux
|
next_x_mux
|
(
|
(
|
.mux_in(neighbors_rx),
|
.mux_in(neighbors_rx),
|
.mux_out(next_rx),
|
.mux_out(next_rx),
|
.sel(destport_bin)
|
.sel(destport_bin)
|
);
|
);
|
|
|
binary_mux #(
|
binary_mux #(
|
.IN_WIDTH(PRYw),
|
.IN_WIDTH(PRYw),
|
.OUT_WIDTH(RYw)
|
.OUT_WIDTH(RYw)
|
)
|
)
|
next_y_mux
|
next_y_mux
|
(
|
(
|
.mux_in(neighbors_ry),
|
.mux_in(neighbors_ry),
|
.mux_out(next_ry),
|
.mux_out(next_ry),
|
.sel(destport_bin)
|
.sel(destport_bin)
|
);
|
);
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|