`include "pronoc_def.v"
|
`include "pronoc_def.v"
|
|
|
/**************************************
|
/**************************************
|
* Module: router_bypass
|
* Module: router_bypass
|
* Date:2021-11-14
|
* Date:2021-11-14
|
* Author: alireza
|
* Author: alireza
|
*
|
*
|
* Description:
|
* Description:
|
* This file contains HDL modules that can be added
|
* This file contains HDL modules that can be added
|
* to NoC router to provide multicasting
|
* to NoC router to provide multicasting
|
***************************************/
|
***************************************/
|
|
|
|
|
|
|
|
|
|
|
/************************************
|
/************************************
|
|
|
look_ahead_routing
|
look_ahead_routing
|
|
|
*************************************/
|
*************************************/
|
|
|
module multicast_routing
|
module multicast_routing # (
|
import pronoc_pkg::*;
|
parameter NOC_ID=0,
|
#(
|
parameter SW_LOC=0,
|
parameter P = 5,
|
parameter P=5
|
parameter SW_LOC = 0
|
)(
|
)
|
|
(
|
|
current_r_addr, //current router address
|
current_r_addr, //current router address
|
dest_e_addr, // destination endpoint address
|
dest_e_addr, // destination endpoint address
|
destport
|
destport
|
);
|
);
|
|
|
|
`NOC_CONF
|
|
|
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;
|
output [DSTPw-1 : 0] destport;
|
output [DSTPw-1 : 0] destport;
|
|
|
generate
|
generate
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if(TOPOLOGY=="MESH") begin: mesh
|
if(TOPOLOGY=="MESH") begin: mesh
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
multicast_routing_mesh
|
multicast_routing_mesh #(
|
#(
|
.NOC_ID(NOC_ID),
|
.P(P) ,
|
.P(P) ,
|
.SW_LOC(SW_LOC)
|
.SW_LOC(SW_LOC)
|
)
|
) routing (
|
routing
|
|
(
|
|
.current_r_addr(current_r_addr), //current router address
|
.current_r_addr(current_r_addr), //current router address
|
.dest_e_addr(dest_e_addr), // destination endpoint address
|
.dest_e_addr(dest_e_addr), // destination endpoint address
|
.destport(destport)
|
.destport(destport)
|
);
|
);
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
end else if (TOPOLOGY == "FMESH") begin : fmesh
|
end else if (TOPOLOGY == "FMESH") begin : fmesh
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
multicast_routing_fmesh
|
multicast_routing_fmesh #(
|
#(
|
.NOC_ID(NOC_ID),
|
.P(P) ,
|
.P(P) ,
|
.SW_LOC(SW_LOC)
|
.SW_LOC(SW_LOC)
|
)
|
) routing (
|
routing
|
|
(
|
|
.current_r_addr(current_r_addr), //current router address
|
.current_r_addr(current_r_addr), //current router address
|
.dest_e_addr(dest_e_addr), // destination endpoint address
|
.dest_e_addr(dest_e_addr), // destination endpoint address
|
.destport(destport)
|
.destport(destport)
|
);
|
);
|
|
|
end else begin
|
end else begin
|
initial begin
|
initial begin
|
$display ("ERROR: Multicast/Broadcast is not yet supported for %s Topology",TOPOLOGY);
|
$display ("ERROR: Multicast/Broadcast is not yet supported for %s Topology",TOPOLOGY);
|
$finish;
|
$finish;
|
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
|
|
|
endmodule
|
endmodule
|
|
|
module multicast_routing_mesh
|
module multicast_routing_mesh #(
|
import pronoc_pkg::*;
|
parameter NOC_ID=0,
|
#(
|
parameter SW_LOC=0,
|
parameter P = 5,
|
parameter P=5
|
parameter SW_LOC = 0
|
) (
|
)
|
|
(
|
|
current_r_addr, //current router address
|
current_r_addr, //current router address
|
dest_e_addr, // destination endpoint address
|
dest_e_addr, // destination endpoint address
|
destport
|
destport
|
);
|
);
|
|
|
|
`NOC_CONF
|
|
|
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;
|
output [DSTPw-1 : 0] destport;
|
output [DSTPw-1 : 0] destport;
|
|
|
|
|
localparam
|
localparam
|
NX = T1,
|
|
NY = T2,
|
|
RXw = log2(NX),
|
RXw = log2(NX),
|
RYw = log2(NY),
|
RYw = log2(NY),
|
EXw = RXw,
|
EXw = RXw,
|
EYw = RYw;
|
EYw = RYw;
|
|
|
|
|
//mask gen. x_plus: all rows larger than current router x address are asserted.
|
//mask gen. x_plus: all rows larger than current router x address are asserted.
|
wire [NX-1 : 0] x_plus,x_minus;
|
wire [NX-1 : 0] x_plus,x_minus;
|
//mask generation. Only the corresponding bits to destination located in current column are asserted in each mask
|
//mask generation. Only the corresponding bits to destination located in current column are asserted in each mask
|
wire [NE-1 : 0] y_plus,y_min;
|
wire [NE-1 : 0] y_plus,y_min;
|
//Only one-bit is asserted for each local_p[i]
|
//Only one-bit is asserted for each local_p[i]
|
wire [NE-1 : 0] local_p [NL-1 : 0];
|
wire [NE-1 : 0] local_p [NL-1 : 0];
|
|
|
wire [RXw-1 : 0] current_rx;
|
wire [RXw-1 : 0] current_rx;
|
wire [RYw-1 : 0] current_ry;
|
wire [RYw-1 : 0] current_ry;
|
|
|
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( )
|
);
|
);
|
|
|
|
|
|
|
wire [NX-1 : 0] row_has_any_dest;
|
wire [NX-1 : 0] row_has_any_dest;
|
wire [NE-1 : 0] dest_mcast_all_endp;
|
wire [NE-1 : 0] dest_mcast_all_endp;
|
|
|
mcast_dest_list_decode decode (
|
mcast_dest_list_decode #(
|
|
.NOC_ID(NOC_ID)
|
|
) decode (
|
.dest_e_addr(dest_e_addr),
|
.dest_e_addr(dest_e_addr),
|
.dest_o(dest_mcast_all_endp),
|
.dest_o(dest_mcast_all_endp),
|
.row_has_any_dest(row_has_any_dest),
|
.row_has_any_dest(row_has_any_dest),
|
.is_unicast()
|
.is_unicast()
|
);
|
);
|
|
|
genvar i,j;
|
genvar i,j;
|
generate
|
generate
|
|
|
for(i=0; i< NX; i=i+1) begin : X_
|
for(i=0; i< NX; i=i+1) begin : X_
|
assign x_plus[i] = (current_rx > i);
|
assign x_plus[i] = (current_rx > i);
|
/* verilator lint_off UNSIGNED */
|
/* verilator lint_off UNSIGNED */
|
assign x_minus[i] = (current_rx < i);
|
assign x_minus[i] = (current_rx < i);
|
/* verilator lint_on UNSIGNED */
|
/* verilator lint_on UNSIGNED */
|
end
|
end
|
|
|
//get all endp addresses located in the same x
|
//get all endp addresses located in the same x
|
for(i=0; i< NE; i=i+1) begin : endpoints
|
for(i=0; i< NE; i=i+1) begin : endpoints
|
//Endpoint decoded address
|
//Endpoint decoded address
|
|
|
localparam
|
localparam
|
Y_LOC = ((i/NL) / NX ),
|
Y_LOC = ((i/NL) / NX ),
|
X_LOC = ((i/NL) % NX ),
|
X_LOC = ((i/NL) % NX ),
|
LL = (i % NL);
|
LL = (i % NL);
|
localparam [RYw-1 : 0] YY = Y_LOC [RYw-1 : 0];
|
localparam [RYw-1 : 0] YY = Y_LOC [RYw-1 : 0];
|
localparam [RXw-1 : 0] XX = X_LOC [RXw-1 : 0];
|
localparam [RXw-1 : 0] XX = X_LOC [RXw-1 : 0];
|
|
|
/* verilator lint_off CMPCONST */
|
/* verilator lint_off CMPCONST */
|
assign y_plus[i] = (current_rx == XX) && (current_ry > YY);
|
assign y_plus[i] = (current_rx == XX) && (current_ry > YY);
|
/* verilator lint_on CMPCONST */
|
/* verilator lint_on CMPCONST */
|
|
|
/* verilator lint_off UNSIGNED */
|
/* verilator lint_off UNSIGNED */
|
assign y_min[i] = (current_rx == XX) && (current_ry < YY);
|
assign y_min[i] = (current_rx == XX) && (current_ry < YY);
|
/* verilator lint_on UNSIGNED */
|
/* verilator lint_on UNSIGNED */
|
for(j=0;j
|
for(j=0;j
|
assign local_p[j][i] = (current_rx == XX) && (current_ry == YY) && (LL == j);
|
assign local_p[j][i] = (current_rx == XX) && (current_ry == YY) && (LL == j);
|
end
|
end
|
|
|
end //i
|
end //i
|
|
|
|
|
wire goto_north = |(y_plus & dest_mcast_all_endp);
|
wire goto_north = |(y_plus & dest_mcast_all_endp);
|
wire goto_south = |(y_min & dest_mcast_all_endp);
|
wire goto_south = |(y_min & dest_mcast_all_endp);
|
wire goto_east = |(x_minus & row_has_any_dest);
|
wire goto_east = |(x_minus & row_has_any_dest);
|
wire goto_west = |(x_plus & row_has_any_dest);
|
wire goto_west = |(x_plus & row_has_any_dest);
|
|
|
|
|
wire [NL-1 : 0] goto_local;
|
wire [NL-1 : 0] goto_local;
|
for(i=0; i< NL; i=i+1) begin : endps
|
for(i=0; i< NL; i=i+1) begin : endps
|
assign goto_local[i] = |(local_p[i] & dest_mcast_all_endp);// will be synthesized as single bit assign
|
assign goto_local[i] = |(local_p[i] & dest_mcast_all_endp);// will be synthesized as single bit assign
|
end//for
|
end//for
|
|
|
|
|
|
|
reg [4 : 0] destport_tmp;
|
reg [4 : 0] destport_tmp;
|
|
|
always @(*) begin
|
always @(*) begin
|
destport_tmp = {5{1'b0}};
|
destport_tmp = {5{1'b0}};
|
destport_tmp[LOCAL]=goto_local[LOCAL];
|
destport_tmp[LOCAL]=goto_local[LOCAL];
|
if (SW_LOC == SOUTH) destport_tmp [NORTH] = goto_north;
|
if (SW_LOC == SOUTH) destport_tmp [NORTH] = goto_north;
|
else if(SW_LOC == NORTH) destport_tmp [SOUTH] = goto_south;
|
else if(SW_LOC == NORTH) destport_tmp [SOUTH] = goto_south;
|
else if(SW_LOC == WEST)begin
|
else if(SW_LOC == WEST)begin
|
destport_tmp [NORTH] = goto_north;
|
destport_tmp [NORTH] = goto_north;
|
destport_tmp [SOUTH] = goto_south;
|
destport_tmp [SOUTH] = goto_south;
|
destport_tmp [EAST ] = goto_east;
|
destport_tmp [EAST ] = goto_east;
|
end
|
end
|
else if(SW_LOC == EAST) begin
|
else if(SW_LOC == EAST) begin
|
destport_tmp [NORTH] = goto_north;
|
destport_tmp [NORTH] = goto_north;
|
destport_tmp [SOUTH] = goto_south;
|
destport_tmp [SOUTH] = goto_south;
|
destport_tmp [WEST ] = goto_west;
|
destport_tmp [WEST ] = goto_west;
|
end
|
end
|
else if(SW_LOC == LOCAL || SW_LOC > SOUTH) begin
|
else if(SW_LOC == LOCAL || SW_LOC > SOUTH) begin
|
destport_tmp [NORTH] = goto_north;
|
destport_tmp [NORTH] = goto_north;
|
destport_tmp [SOUTH] = goto_south;
|
destport_tmp [SOUTH] = goto_south;
|
destport_tmp [EAST] = goto_east;
|
destport_tmp [EAST] = goto_east;
|
destport_tmp [WEST] = goto_west;
|
destport_tmp [WEST] = goto_west;
|
end
|
end
|
end
|
end
|
|
|
localparam MSB_DSTP = (DSTPw-1 < SOUTH)? DSTPw-1: SOUTH;
|
localparam MSB_DSTP = (DSTPw-1 < SOUTH)? DSTPw-1: SOUTH;
|
|
|
assign destport [MSB_DSTP : 0] =destport_tmp;
|
assign destport [MSB_DSTP : 0] =destport_tmp;
|
for(i=1;i
|
for(i=1;i
|
assign destport[MSB_DSTP+i]=goto_local[i];
|
assign destport[MSB_DSTP+i]=goto_local[i];
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
module multicast_routing_fmesh #(
|
|
parameter NOC_ID=0,
|
|
parameter SW_LOC=0,
|
module multicast_routing_fmesh
|
parameter P=5
|
import pronoc_pkg::*;
|
) (
|
#(
|
|
parameter P = 5,
|
|
parameter SW_LOC = 0
|
|
)
|
|
(
|
|
current_r_addr, //current router address
|
current_r_addr, //current router address
|
dest_e_addr, // destination endpoint address
|
dest_e_addr, // destination endpoint address
|
destport
|
destport
|
);
|
);
|
|
|
|
`NOC_CONF
|
|
|
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;
|
output [DSTPw-1 : 0] destport;
|
output [DSTPw-1 : 0] destport;
|
|
|
localparam Pw = log2(MAX_P_FMESH);
|
localparam Pw = log2(MAX_P_FMESH);
|
|
|
localparam
|
localparam
|
NX = T1,
|
|
NY = T2,
|
|
RXw = log2(NX),
|
RXw = log2(NX),
|
RYw = log2(NY),
|
RYw = 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;
|
|
|
|
|
//mask gen. x_plus: all rows larger than current router x address are asserted.
|
//mask gen. x_plus: all rows larger than current router x address are asserted.
|
wire [NX-1 : 0] x_plus,x_minus;
|
wire [NX-1 : 0] x_plus,x_minus;
|
//mask generation. Only the corresponding bits to destination located in current column are asserted in each mask
|
//mask generation. Only the corresponding bits to destination located in current column are asserted in each mask
|
wire [NE-1 : 0] y_plus,y_min;
|
wire [NE-1 : 0] y_plus,y_min;
|
//Only one-bit is asserted for each local_p[i]
|
//Only one-bit is asserted for each local_p[i]
|
wire [NE-1 : 0] local_p [MAX_P_FMESH-1 : 0];
|
wire [NE-1 : 0] local_p [MAX_P_FMESH-1 : 0];
|
|
|
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( )
|
);
|
);
|
|
|
|
|
wire [NX-1 : 0] row_has_any_dest;
|
wire [NX-1 : 0] row_has_any_dest;
|
wire [NE-1 : 0] dest_mcast_all_endp;
|
wire [NE-1 : 0] dest_mcast_all_endp;
|
|
|
mcast_dest_list_decode decode (
|
mcast_dest_list_decode # (
|
|
.NOC_ID(NOC_ID)
|
|
) decode (
|
.dest_e_addr(dest_e_addr),
|
.dest_e_addr(dest_e_addr),
|
.dest_o(dest_mcast_all_endp),
|
.dest_o(dest_mcast_all_endp),
|
.row_has_any_dest(row_has_any_dest),
|
.row_has_any_dest(row_has_any_dest),
|
.is_unicast()
|
.is_unicast()
|
);
|
);
|
|
|
|
|
genvar i,j;
|
genvar i,j;
|
generate
|
generate
|
|
|
for(i=0; i< NX; i=i+1) begin : X_
|
for(i=0; i< NX; i=i+1) begin : X_
|
assign x_plus[i] = (current_rx > i);
|
assign x_plus[i] = (current_rx > i);
|
/* verilator lint_off UNSIGNED */
|
/* verilator lint_off UNSIGNED */
|
assign x_minus[i] = (current_rx < i);
|
assign x_minus[i] = (current_rx < i);
|
/* verilator lint_on UNSIGNED */
|
/* verilator lint_on UNSIGNED */
|
end
|
end
|
|
|
//get all endp addresses located in the same x
|
//get all endp addresses located in the same x
|
for(i=0; i< NE; i=i+1) begin : endpoints
|
for(i=0; i< NE; i=i+1) begin : endpoints
|
//Endpoint decoded address
|
//Endpoint decoded address
|
localparam
|
localparam
|
ADR = fmesh_addrencode(i),
|
ADR = fmesh_addrencode(i),
|
XX = ADR [NXw -1 : 0],
|
XX = ADR [NXw -1 : 0],
|
YY = ADR [NXw+NYw-1 : NXw],
|
YY = ADR [NXw+NYw-1 : NXw],
|
PP = ADR [NXw+NYw+Pw-1 : NXw+NYw];
|
PP = ADR [NXw+NYw+Pw-1 : NXw+NYw];
|
|
|
|
|
/* verilator lint_off CMPCONST */
|
/* verilator lint_off CMPCONST */
|
assign y_plus[i] = (current_rx == XX) && (current_ry > YY);
|
assign y_plus[i] = (current_rx == XX) && (current_ry > YY);
|
/* verilator lint_on CMPCONST */
|
/* verilator lint_on CMPCONST */
|
|
|
/* verilator lint_off UNSIGNED */
|
/* verilator lint_off UNSIGNED */
|
assign y_min[i] = (current_rx == XX) && (current_ry < YY);
|
assign y_min[i] = (current_rx == XX) && (current_ry < YY);
|
/* verilator lint_on UNSIGNED */
|
/* verilator lint_on UNSIGNED */
|
|
|
for(j=0;j
|
for(j=0;j
|
assign local_p[j][i] = (current_rx == XX) && (current_ry == YY) && (PP == j);
|
assign local_p[j][i] = (current_rx == XX) && (current_ry == YY) && (PP == j);
|
end
|
end
|
|
|
|
|
|
|
end//for ne
|
end//for ne
|
|
|
wire [MAX_P_FMESH-1 : 0] goto_local;
|
wire [MAX_P_FMESH-1 : 0] goto_local;
|
for(i=0; i
|
for(i=0; i
|
assign goto_local[i] = |(local_p[i] & dest_mcast_all_endp);// will be synthesized as single bit assign
|
assign goto_local[i] = |(local_p[i] & dest_mcast_all_endp);// will be synthesized as single bit assign
|
end//for
|
end//for
|
|
|
|
|
wire goto_north = (|(y_plus & dest_mcast_all_endp)) | goto_local[NORTH];
|
wire goto_north = (|(y_plus & dest_mcast_all_endp)) | goto_local[NORTH];
|
wire goto_south = (|(y_min & dest_mcast_all_endp)) | goto_local[SOUTH];
|
wire goto_south = (|(y_min & dest_mcast_all_endp)) | goto_local[SOUTH];
|
wire goto_east = (|(x_minus & row_has_any_dest)) | goto_local[EAST];
|
wire goto_east = (|(x_minus & row_has_any_dest)) | goto_local[EAST];
|
wire goto_west = (|(x_plus & row_has_any_dest)) | goto_local[WEST];
|
wire goto_west = (|(x_plus & row_has_any_dest)) | goto_local[WEST];
|
|
|
|
|
|
|
|
|
|
|
reg [4 : 0] destport_tmp;
|
reg [4 : 0] destport_tmp;
|
|
|
always @(*) begin
|
always @(*) begin
|
destport_tmp = {DSTPw{1'b0}};
|
destport_tmp = {DSTPw{1'b0}};
|
destport_tmp[LOCAL]=goto_local[LOCAL];
|
destport_tmp[LOCAL]=goto_local[LOCAL];
|
if (SW_LOC == SOUTH)begin
|
if (SW_LOC == SOUTH)begin
|
destport_tmp [NORTH] = goto_north ;
|
destport_tmp [NORTH] = goto_north ;
|
destport_tmp [EAST] = goto_east;
|
destport_tmp [EAST] = goto_east;
|
destport_tmp [WEST] = goto_west;
|
destport_tmp [WEST] = goto_west;
|
end
|
end
|
else if(SW_LOC == NORTH) begin
|
else if(SW_LOC == NORTH) begin
|
destport_tmp [SOUTH] = goto_south ;
|
destport_tmp [SOUTH] = goto_south ;
|
destport_tmp [EAST] = goto_east;
|
destport_tmp [EAST] = goto_east;
|
destport_tmp [WEST] = goto_west;
|
destport_tmp [WEST] = goto_west;
|
end
|
end
|
else if(SW_LOC == WEST)begin
|
else if(SW_LOC == WEST)begin
|
destport_tmp [NORTH] = goto_north ;
|
destport_tmp [NORTH] = goto_north ;
|
destport_tmp [SOUTH] = goto_south;
|
destport_tmp [SOUTH] = goto_south;
|
destport_tmp [EAST ] = goto_east;
|
destport_tmp [EAST ] = goto_east;
|
end
|
end
|
else if(SW_LOC == EAST) begin
|
else if(SW_LOC == EAST) begin
|
destport_tmp [NORTH] = goto_north;
|
destport_tmp [NORTH] = goto_north;
|
destport_tmp [SOUTH] = goto_south;
|
destport_tmp [SOUTH] = goto_south;
|
destport_tmp [WEST ] = goto_west;
|
destport_tmp [WEST ] = goto_west;
|
end
|
end
|
else if(SW_LOC == LOCAL || SW_LOC > SOUTH) begin
|
else if(SW_LOC == LOCAL || SW_LOC > SOUTH) begin
|
destport_tmp [NORTH] = goto_north;
|
destport_tmp [NORTH] = goto_north;
|
destport_tmp [SOUTH] = goto_south;
|
destport_tmp [SOUTH] = goto_south;
|
destport_tmp [EAST] = goto_east;
|
destport_tmp [EAST] = goto_east;
|
destport_tmp [WEST] = goto_west;
|
destport_tmp [WEST] = goto_west;
|
end
|
end
|
end
|
end
|
|
|
localparam MSB_DSTP = (DSTPw-1 < SOUTH)? DSTPw-1: SOUTH;
|
localparam MSB_DSTP = (DSTPw-1 < SOUTH)? DSTPw-1: SOUTH;
|
|
|
assign destport [MSB_DSTP : 0] =destport_tmp;
|
assign destport [MSB_DSTP : 0] =destport_tmp;
|
for(i=1;i
|
for(i=1;i
|
assign destport[MSB_DSTP+i]=goto_local[i];
|
assign destport[MSB_DSTP+i]=goto_local[i];
|
end
|
end
|
|
|
|
|
|
|
endgenerate
|
endgenerate
|
|
|
endmodule
|
endmodule
|
|
|
|
|
module mcast_dest_list_decode
|
module mcast_dest_list_decode #(
|
import pronoc_pkg::*;
|
parameter NOC_ID=0
|
(
|
) (
|
dest_e_addr,
|
dest_e_addr,
|
dest_o,
|
dest_o,
|
row_has_any_dest,
|
row_has_any_dest,
|
is_unicast
|
is_unicast
|
);
|
);
|
|
|
|
`NOC_CONF
|
|
|
input [DAw-1 :0] dest_e_addr;
|
input [DAw-1 :0] dest_e_addr;
|
output [NE-1 : 0] dest_o;
|
output [NE-1 : 0] dest_o;
|
output [NX-1 : 0] row_has_any_dest;
|
output [NX-1 : 0] row_has_any_dest;
|
output is_unicast;
|
output is_unicast;
|
|
|
wire [MCASTw-1 : 0] mcast_dst_coded;
|
wire [MCASTw-1 : 0] mcast_dst_coded;
|
|
|
|
|
|
|
assign {row_has_any_dest,mcast_dst_coded}=dest_e_addr;
|
assign {row_has_any_dest,mcast_dst_coded}=dest_e_addr;
|
|
|
|
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if(CAST_TYPE == "MULTICAST_FULL") begin : full
|
if(CAST_TYPE == "MULTICAST_FULL") begin : full
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
assign dest_o = mcast_dst_coded;
|
assign dest_o = mcast_dst_coded;
|
assign is_unicast = 1'b0;
|
assign is_unicast = 1'b0;
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
end else if (CAST_TYPE == "MULTICAST_PARTIAL") begin : partial
|
end else if (CAST_TYPE == "MULTICAST_PARTIAL") begin : partial
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
wire not_in_cast_list ;
|
wire not_in_cast_list ;
|
wire [EAw-1 : 0] unicast_code;
|
wire [EAw-1 : 0] unicast_code;
|
assign {unicast_code,not_in_cast_list} = mcast_dst_coded [EAw : 0];
|
assign {unicast_code,not_in_cast_list} = mcast_dst_coded [EAw : 0];
|
wire [NE-1 : 0] dest_o_multi;
|
wire [NE-1 : 0] dest_o_multi;
|
reg [NE-1 : 0] dest_o_uni;
|
reg [NE-1 : 0] dest_o_uni;
|
wire [NEw-1 : 0] unicast_id;
|
wire [NEw-1 : 0] unicast_id;
|
assign is_unicast = not_in_cast_list;
|
assign is_unicast = not_in_cast_list;
|
|
|
endp_addr_decoder #(
|
endp_addr_decoder #(
|
.TOPOLOGY (TOPOLOGY),
|
.TOPOLOGY (TOPOLOGY),
|
.T1(T1),
|
.T1(T1),
|
.T2(T2),
|
.T2(T2),
|
.T3(T3),
|
.T3(T3),
|
.EAw(EAw),
|
.EAw(EAw),
|
.NE(NE)
|
.NE(NE)
|
)
|
)
|
decoder
|
decoder
|
(
|
(
|
.code(unicast_code),
|
.code(unicast_code),
|
.id(unicast_id)
|
.id(unicast_id)
|
);
|
);
|
|
|
always @(*)begin
|
always @(*)begin
|
dest_o_uni = {NE{1'b0}};
|
dest_o_uni = {NE{1'b0}};
|
dest_o_uni[unicast_id]=1'b1;
|
dest_o_uni[unicast_id]=1'b1;
|
end
|
end
|
|
|
for(i=0; i< NE; i=i+1) begin : endpoints
|
for(i=0; i< NE; i=i+1) begin : endpoints
|
localparam MCAST_ID = endp_id_to_mcast_id(i);
|
localparam MCAST_ID = endp_id_to_mcast_id(i);
|
assign dest_o_multi [i] = (MCAST_ENDP_LIST[i]==1'b1)? mcast_dst_coded[MCAST_ID+1] : 1'b0;
|
assign dest_o_multi [i] = (MCAST_ENDP_LIST[i]==1'b1)? mcast_dst_coded[MCAST_ID+1] : 1'b0;
|
end
|
end
|
|
|
assign dest_o = (not_in_cast_list)? dest_o_uni : dest_o_multi;
|
assign dest_o = (not_in_cast_list)? dest_o_uni : dest_o_multi;
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
end else if (CAST_TYPE == "BROADCAST_FULL") begin : bcast_full
|
end else if (CAST_TYPE == "BROADCAST_FULL") begin : bcast_full
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
wire not_broad_casted;
|
wire not_broad_casted;
|
wire [EAw-1 : 0] unicast_code;
|
wire [EAw-1 : 0] unicast_code;
|
assign {unicast_code,not_broad_casted} = mcast_dst_coded;
|
assign {unicast_code,not_broad_casted} = mcast_dst_coded;
|
assign is_unicast =not_broad_casted;
|
assign is_unicast =not_broad_casted;
|
wire [NE-1 : 0] dest_o_multi;
|
wire [NE-1 : 0] dest_o_multi;
|
reg [NE-1 : 0] dest_o_uni;
|
reg [NE-1 : 0] dest_o_uni;
|
wire [NEw-1 : 0] unicast_id;
|
wire [NEw-1 : 0] unicast_id;
|
|
|
endp_addr_decoder #(
|
endp_addr_decoder #(
|
.TOPOLOGY (TOPOLOGY),
|
.TOPOLOGY (TOPOLOGY),
|
.T1(T1),
|
.T1(T1),
|
.T2(T2),
|
.T2(T2),
|
.T3(T3),
|
.T3(T3),
|
.EAw(EAw),
|
.EAw(EAw),
|
.NE(NE)
|
.NE(NE)
|
)
|
)
|
decoder
|
decoder
|
(
|
(
|
.code(unicast_code),
|
.code(unicast_code),
|
.id(unicast_id)
|
.id(unicast_id)
|
);
|
);
|
|
|
always @(*)begin
|
always @(*)begin
|
dest_o_uni = {NE{1'b0}};
|
dest_o_uni = {NE{1'b0}};
|
dest_o_uni[unicast_id]=1'b1;
|
dest_o_uni[unicast_id]=1'b1;
|
end
|
end
|
|
|
assign dest_o = (not_broad_casted)? dest_o_uni : {NE{1'b1}};
|
assign dest_o = (not_broad_casted)? dest_o_uni : {NE{1'b1}};
|
|
|
end else begin //BCAST_PARTIAL
|
end else begin //BCAST_PARTIAL
|
wire not_broad_casted;
|
wire not_broad_casted;
|
wire [EAw-1 : 0] unicast_code;
|
wire [EAw-1 : 0] unicast_code;
|
assign {unicast_code,not_broad_casted} = mcast_dst_coded;
|
assign {unicast_code,not_broad_casted} = mcast_dst_coded;
|
assign is_unicast =not_broad_casted;
|
assign is_unicast =not_broad_casted;
|
wire [NE-1 : 0] dest_o_multi;
|
wire [NE-1 : 0] dest_o_multi;
|
reg [NE-1 : 0] dest_o_uni;
|
reg [NE-1 : 0] dest_o_uni;
|
wire [NEw-1 : 0] unicast_id;
|
wire [NEw-1 : 0] unicast_id;
|
|
|
endp_addr_decoder #(
|
endp_addr_decoder #(
|
.TOPOLOGY (TOPOLOGY),
|
.TOPOLOGY (TOPOLOGY),
|
.T1(T1),
|
.T1(T1),
|
.T2(T2),
|
.T2(T2),
|
.T3(T3),
|
.T3(T3),
|
.EAw(EAw),
|
.EAw(EAw),
|
.NE(NE)
|
.NE(NE)
|
)
|
)
|
decoder
|
decoder
|
(
|
(
|
.code(unicast_code),
|
.code(unicast_code),
|
.id(unicast_id)
|
.id(unicast_id)
|
);
|
);
|
|
|
always @(*)begin
|
always @(*)begin
|
dest_o_uni = {NE{1'b0}};
|
dest_o_uni = {NE{1'b0}};
|
dest_o_uni[unicast_id]=1'b1;
|
dest_o_uni[unicast_id]=1'b1;
|
end
|
end
|
|
|
assign dest_o = (not_broad_casted)? dest_o_uni : MCAST_ENDP_LIST;
|
assign dest_o = (not_broad_casted)? dest_o_uni : MCAST_ENDP_LIST;
|
|
|
|
|
|
|
end
|
end
|
|
|
endgenerate
|
endgenerate
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
module multicast_chan_in_process
|
module multicast_chan_in_process #(
|
import pronoc_pkg::*;
|
parameter NOC_ID=0,
|
#(
|
parameter SW_LOC=0,
|
parameter P = 5,
|
parameter P=5
|
parameter SW_LOC = 0
|
) (
|
|
|
)
|
|
(
|
|
endp_port,
|
endp_port,
|
current_r_addr,
|
current_r_addr,
|
chan_in,
|
chan_in,
|
chan_out,
|
chan_out,
|
clk
|
clk
|
);
|
);
|
|
|
|
`NOC_CONF
|
|
|
input endp_port;
|
input endp_port;
|
input [RAw-1 : 0] current_r_addr;
|
input [RAw-1 : 0] current_r_addr;
|
input flit_chanel_t chan_in;
|
input flit_chanel_t chan_in;
|
input clk;
|
input clk;
|
output flit_chanel_t chan_out;
|
output flit_chanel_t chan_out;
|
|
|
|
|
wire [MCASTw-1 : 0] mcast_dst_coded;
|
wire [MCASTw-1 : 0] mcast_dst_coded;
|
wire [NE-1 : 0] dest_mcast_all_endp;
|
wire [NE-1 : 0] dest_mcast_all_endp;
|
wire [NX-1 : 0] row_has_any_dest,row_has_any_dest_in;
|
wire [NX-1 : 0] row_has_any_dest,row_has_any_dest_in;
|
wire [DSTPw-1 : 0] destport,destport_o;
|
wire [DSTPw-1 : 0] destport,destport_o;
|
|
|
|
|
|
|
hdr_flit_t hdr_flit;
|
hdr_flit_t hdr_flit;
|
header_flit_info extract(
|
|
|
header_flit_info #(
|
|
.NOC_ID (NOC_ID)
|
|
) extract (
|
.flit(chan_in.flit),
|
.flit(chan_in.flit),
|
.hdr_flit(hdr_flit),
|
.hdr_flit(hdr_flit),
|
.data_o()
|
.data_o()
|
);
|
);
|
|
|
mcast_dest_list_decode decoder
|
mcast_dest_list_decode #(
|
(
|
.NOC_ID(NOC_ID)
|
|
) decoder (
|
.dest_e_addr(hdr_flit.dest_e_addr),
|
.dest_e_addr(hdr_flit.dest_e_addr),
|
.dest_o(dest_mcast_all_endp),
|
.dest_o(dest_mcast_all_endp),
|
.row_has_any_dest(row_has_any_dest_in),
|
.row_has_any_dest(row_has_any_dest_in),
|
.is_unicast()
|
.is_unicast()
|
);
|
);
|
|
|
localparam MCASTw_= (MCASTw < DAw ) ? MCASTw : DAw;
|
localparam MCASTw_= (MCASTw < DAw ) ? MCASTw : DAw;
|
|
|
assign mcast_dst_coded = hdr_flit.dest_e_addr[MCASTw_-1:0];
|
assign mcast_dst_coded = hdr_flit.dest_e_addr[MCASTw_-1:0];
|
|
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
if(TOPOLOGY == "MESH") begin : mesh_
|
if(TOPOLOGY == "MESH") begin : mesh_
|
if(SW_LOC == LOCAL || SW_LOC > SOUTH) begin :endp
|
if(SW_LOC == LOCAL || SW_LOC > SOUTH) begin :endp
|
|
|
wire [NE/NX-1 : 0] endp_mask [NX-1 : 0];
|
wire [NE/NX-1 : 0] endp_mask [NX-1 : 0];
|
for(i=0; i< NE; i=i+1) begin : endpoints
|
for(i=0; i< NE; i=i+1) begin : endpoints
|
//Endpoint decoded address
|
//Endpoint decoded address
|
localparam
|
localparam
|
MCAST_ID = endp_id_to_mcast_id(i),
|
MCAST_ID = endp_id_to_mcast_id(i),
|
YY = ((i/NL) / NX ),
|
YY = ((i/NL) / NX ),
|
XX = ((i/NL) % NX ),
|
XX = ((i/NL) % NX ),
|
LL = (i % NL),
|
LL = (i % NL),
|
PP = YY*NL + LL;
|
PP = YY*NL + LL;
|
assign endp_mask [XX] [PP] = dest_mcast_all_endp [i];
|
assign endp_mask [XX] [PP] = dest_mcast_all_endp [i];
|
end
|
end
|
|
|
for(i=0;i
|
for(i=0;i
|
assign row_has_any_dest[i] =| endp_mask[i];
|
assign row_has_any_dest[i] =| endp_mask[i];
|
end
|
end
|
|
|
reg [DSTPw-1 : 0] destport_tmp;
|
reg [DSTPw-1 : 0] destport_tmp;
|
always @(*) begin
|
always @(*) begin
|
destport_tmp = destport;
|
destport_tmp = destport;
|
if(SELF_LOOP_EN == "NO") destport_tmp [ SW_LOC ] = 1'b0;
|
if(SELF_LOOP_EN == "NO") destport_tmp [ SW_LOC ] = 1'b0;
|
end
|
end
|
assign destport_o = destport_tmp;
|
assign destport_o = destport_tmp;
|
|
|
end else begin : no_endp
|
end else begin : no_endp
|
assign row_has_any_dest = row_has_any_dest_in;
|
assign row_has_any_dest = row_has_any_dest_in;
|
assign destport_o = destport;
|
assign destport_o = destport;
|
end
|
end
|
end //mesh
|
end //mesh
|
|
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
else if (TOPOLOGY == "FMESH" ) begin :fmesh_
|
else if (TOPOLOGY == "FMESH" ) begin :fmesh_
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
|
|
|
|
|
|
localparam MAX_ENDP_NUM_IN_SAME_ROW = NY * NL + NY + 2;
|
localparam MAX_ENDP_NUM_IN_SAME_ROW = NY * NL + NY + 2;
|
localparam ENDP_NUM_IN_MIDLE_ROW = NY * NL + 2;
|
localparam ENDP_NUM_IN_MIDLE_ROW = NY * NL + 2;
|
localparam Pw = log2(MAX_P_FMESH);
|
localparam Pw = log2(MAX_P_FMESH);
|
|
|
wire [NX-1 : 0] row_has_any_dest_endp_port;
|
wire [NX-1 : 0] row_has_any_dest_endp_port;
|
wire [NY*NL-1 : 0] endp_mask [NX-1 : 0];
|
wire [NY*NL-1 : 0] endp_mask [NX-1 : 0];
|
|
|
for(i=0; i< NE; i=i+1) begin : endpoints
|
for(i=0; i< NE; i=i+1) begin : endpoints
|
//Endpoint decoded address
|
//Endpoint decoded address
|
localparam
|
localparam
|
ADR = fmesh_addrencode(i),
|
ADR = fmesh_addrencode(i),
|
XX = ADR [NXw -1 : 0],
|
XX = ADR [NXw -1 : 0],
|
YY = ADR [NXw+NYw-1 : NXw],
|
YY = ADR [NXw+NYw-1 : NXw],
|
PP = ADR [NXw+NYw+Pw-1 : NXw+NYw];
|
PP = ADR [NXw+NYw+Pw-1 : NXw+NYw];
|
if(PP == LOCAL || PP > SOUTH) begin
|
if(PP == LOCAL || PP > SOUTH) begin
|
localparam MM = (PP==LOCAL) ? YY*NL : (YY*NL) + PP - SOUTH;
|
localparam MM = (PP==LOCAL) ? YY*NL : (YY*NL) + PP - SOUTH;
|
assign endp_mask [XX] [MM] = dest_mcast_all_endp [i];
|
assign endp_mask [XX] [MM] = dest_mcast_all_endp [i];
|
end
|
end
|
end
|
end
|
|
|
wire [NX-1 : 0] north_endps;
|
wire [NX-1 : 0] north_endps;
|
wire [NY-1 : 0] west_endps;
|
wire [NY-1 : 0] west_endps;
|
wire [NX-1 : 0] south_endps;
|
wire [NX-1 : 0] south_endps;
|
wire [NY-1 : 0] east_endps;
|
wire [NY-1 : 0] east_endps;
|
|
|
assign { east_endps, west_endps ,south_endps ,north_endps} = dest_mcast_all_endp [NE-1 : NY*NL*NX];
|
assign { east_endps, west_endps ,south_endps ,north_endps} = dest_mcast_all_endp [NE-1 : NY*NL*NX];
|
|
|
|
|
for(i=0;i
|
for(i=0;i
|
if(i==0) assign row_has_any_dest_endp_port[i] =(| endp_mask[i]) | ( |west_endps) | north_endps[i] | south_endps[i];
|
if(i==0) assign row_has_any_dest_endp_port[i] =(| endp_mask[i]) | ( |west_endps) | north_endps[i] | south_endps[i];
|
else if (i==NX-1) assign row_has_any_dest_endp_port[i] =(| endp_mask[i]) | ( |east_endps) | north_endps[i] | south_endps[i];
|
else if (i==NX-1) assign row_has_any_dest_endp_port[i] =(| endp_mask[i]) | ( |east_endps) | north_endps[i] | south_endps[i];
|
else assign row_has_any_dest_endp_port[i] =(| endp_mask[i]) | north_endps[i] | south_endps[i];
|
else assign row_has_any_dest_endp_port[i] =(| endp_mask[i]) | north_endps[i] | south_endps[i];
|
end
|
end
|
|
|
reg [DSTPw-1 : 0] destport_tmp;
|
reg [DSTPw-1 : 0] destport_tmp;
|
always @(*) begin
|
always @(*) begin
|
destport_tmp = destport;
|
destport_tmp = destport;
|
if(SELF_LOOP_EN == "NO") destport_tmp [ SW_LOC ] = 1'b0;
|
if(SELF_LOOP_EN == "NO") destport_tmp [ SW_LOC ] = 1'b0;
|
end
|
end
|
|
|
|
|
assign destport_o = (endp_port) ? destport : destport_tmp ;
|
assign destport_o = (endp_port) ? destport : destport_tmp ;
|
assign row_has_any_dest = (endp_port) ? row_has_any_dest_endp_port : row_has_any_dest_in;
|
assign row_has_any_dest = (endp_port) ? row_has_any_dest_endp_port : row_has_any_dest_in;
|
|
|
|
|
end
|
end
|
|
|
|
|
|
|
|
|
wire [DAw-1 : 0] dest_e_addr = {row_has_any_dest,mcast_dst_coded};
|
wire [DAw-1 : 0] dest_e_addr = {row_has_any_dest,mcast_dst_coded};
|
|
|
|
|
multicast_routing
|
multicast_routing
|
#(
|
#(
|
|
.NOC_ID(NOC_ID),
|
.P(P) ,
|
.P(P) ,
|
.SW_LOC(SW_LOC)
|
.SW_LOC(SW_LOC)
|
)
|
)
|
routing
|
routing
|
(
|
(
|
.current_r_addr(current_r_addr), //current router address
|
.current_r_addr(current_r_addr), //current router address
|
.dest_e_addr(dest_e_addr), // destination endpoint address
|
.dest_e_addr(dest_e_addr), // destination endpoint address
|
.destport(destport)
|
.destport(destport)
|
);
|
);
|
|
|
|
|
|
|
|
|
always @(*) begin
|
always @(*) begin
|
chan_out=chan_in;
|
chan_out=chan_in;
|
if(chan_in.flit.hdr_flag == 1'b1) begin
|
if(chan_in.flit.hdr_flag == 1'b1) begin
|
chan_out.flit [E_DST_MSB : E_DST_LSB] = dest_e_addr;
|
chan_out.flit [E_DST_MSB : E_DST_LSB] = dest_e_addr;
|
chan_out.flit [DST_P_MSB : DST_P_LSB] = destport_o;
|
chan_out.flit [DST_P_MSB : DST_P_LSB] = destport_o;
|
end
|
end
|
end
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
//synthesis translate_off
|
//synthesis translate_off
|
if(DEBUG_EN) begin :debg
|
if(DEBUG_EN) begin :debg
|
always @(posedge clk) begin
|
always @(posedge clk) begin
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if(CAST_TYPE == "MULTICAST_FULL" || CAST_TYPE == "MULTICAST_PARTIAL")
|
if(CAST_TYPE == "MULTICAST_FULL" || CAST_TYPE == "MULTICAST_PARTIAL")
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
if(chan_in.flit_wr == 1'b1 && chan_in.flit.hdr_flag == 1'b1 && mcast_dst_coded == {MCASTw{1'b0}}) begin
|
if(chan_in.flit_wr == 1'b1 && chan_in.flit.hdr_flag == 1'b1 && mcast_dst_coded == {MCASTw{1'b0}}) begin
|
$display ("%t: ERROR: A multicast packet is injected to the NoC with zero mcast_dst_coded filed %m ",$time);
|
$display ("%t: ERROR: A multicast packet is injected to the NoC with zero mcast_dst_coded filed %m ",$time);
|
$finish;
|
$finish;
|
end
|
end
|
|
|
if(chan_in.flit_wr == 1'b1 && chan_in.flit.hdr_flag == 1'b1 && dest_mcast_all_endp == {NE{1'b0}}) begin
|
if(chan_in.flit_wr == 1'b1 && chan_in.flit.hdr_flag == 1'b1 && dest_mcast_all_endp == {NE{1'b0}}) begin
|
$display ("%t: ERROR: A multicast packet is injected to the NoC without any set destination %m ",$time);
|
$display ("%t: ERROR: A multicast packet is injected to the NoC without any set destination %m ",$time);
|
$finish;
|
$finish;
|
end
|
end
|
|
|
if(chan_in.flit_wr == 1'b1 && chan_in.flit.hdr_flag == 1'b1 && destport_o == {DSTPw{1'b0}}) begin
|
if(chan_in.flit_wr == 1'b1 && chan_in.flit.hdr_flag == 1'b1 && destport_o == {DSTPw{1'b0}}) begin
|
$display ("%t: ERROR: Routing module did not set any destination port for an injected multicast packet %m ",$time);
|
$display ("%t: ERROR: Routing module did not set any destination port for an injected multicast packet %m ",$time);
|
$finish;
|
$finish;
|
end
|
end
|
|
|
end
|
end
|
end//debug
|
end//debug
|
//synthesis translate_on
|
//synthesis translate_on
|
|
|
endgenerate
|
endgenerate
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
module multicast_dst_sel # (
|
|
parameter NOC_ID=0
|
module multicast_dst_sel
|
)(
|
import pronoc_pkg::*;
|
|
(
|
|
|
|
destport_in,
|
destport_in,
|
destport_out
|
destport_out
|
);
|
);
|
|
|
|
`NOC_CONF
|
|
|
input [DSTPw-1 : 0] destport_in;
|
input [DSTPw-1 : 0] destport_in;
|
output [DSTPw-1 : 0] destport_out;
|
output [DSTPw-1 : 0] destport_out;
|
|
|
|
|
wire [DSTPw-1 : 0] arb_in, arb_out;
|
wire [DSTPw-1 : 0] arb_in, arb_out;
|
|
|
function integer mesh_tori_pririty_order;
|
function integer mesh_tori_pririty_order;
|
input integer x;
|
input integer x;
|
begin
|
begin
|
case(x)
|
case(x)
|
0 : mesh_tori_pririty_order = EAST;
|
0 : mesh_tori_pririty_order = EAST;
|
1 : mesh_tori_pririty_order = WEST;
|
1 : mesh_tori_pririty_order = WEST;
|
2 : mesh_tori_pririty_order = NORTH;
|
2 : mesh_tori_pririty_order = NORTH;
|
3 : mesh_tori_pririty_order = SOUTH;
|
3 : mesh_tori_pririty_order = SOUTH;
|
4 : mesh_tori_pririty_order = LOCAL;
|
4 : mesh_tori_pririty_order = LOCAL;
|
default : mesh_tori_pririty_order =x;
|
default : mesh_tori_pririty_order =x;
|
endcase
|
endcase
|
end
|
end
|
endfunction // pririty_order
|
endfunction // pririty_order
|
|
|
function integer ring_lin_pririty_order;
|
function integer ring_lin_pririty_order;
|
input integer x;
|
input integer x;
|
begin
|
begin
|
case(x)
|
case(x)
|
0 : ring_lin_pririty_order = FORWARD;
|
0 : ring_lin_pririty_order = FORWARD;
|
1 : ring_lin_pririty_order = BACKWARD;
|
1 : ring_lin_pririty_order = BACKWARD;
|
2 : ring_lin_pririty_order = LOCAL;
|
2 : ring_lin_pririty_order = LOCAL;
|
default : ring_lin_pririty_order =x;
|
default : ring_lin_pririty_order =x;
|
endcase
|
endcase
|
end
|
end
|
endfunction // pririty_order
|
endfunction // pririty_order
|
|
|
|
|
|
|
|
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for (i=0; i
|
for (i=0; i
|
localparam PR =
|
localparam PR =
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
(TOPOLOGY == "MESH" || TOPOLOGY == "TORUS" || TOPOLOGY == "FMESH" )? mesh_tori_pririty_order(i):
|
(TOPOLOGY == "MESH" || TOPOLOGY == "TORUS" || TOPOLOGY == "FMESH" )? mesh_tori_pririty_order(i):
|
(TOPOLOGY == "RING" || TOPOLOGY == "LINE") ? ring_lin_pririty_order(i) : i;
|
(TOPOLOGY == "RING" || TOPOLOGY == "LINE") ? ring_lin_pririty_order(i) : i;
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
assign arb_in[i] = destport_in[PR];
|
assign arb_in[i] = destport_in[PR];
|
assign destport_out [PR] = arb_out[i];
|
assign destport_out [PR] = arb_out[i];
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
|
fixed_priority_arbiter #(
|
fixed_priority_arbiter #(
|
.ARBITER_WIDTH (DSTPw),
|
.ARBITER_WIDTH (DSTPw),
|
.HIGH_PRORITY_BIT ("LSB")
|
.HIGH_PRORITY_BIT ("LSB")
|
) fixed_priority_arbiter (
|
) fixed_priority_arbiter (
|
.request (arb_in),
|
.request (arb_in),
|
.grant (arb_out),
|
.grant (arb_out),
|
.any_grant ( )
|
.any_grant ( )
|
);
|
);
|
|
|
|
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|