`timescale 1ns/1ps
|
`timescale 1ns/1ps
|
/**********************************************************************
|
/**********************************************************************
|
** File: crossbar.v
|
** File: crossbar.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:
|
** NoC router crosbar module
|
** NoC router crosbar module
|
**
|
**
|
**************************************************************/
|
**************************************************************/
|
|
|
module crossbar #(
|
module crossbar #(
|
|
parameter NOC_ID=0,
|
parameter TOPOLOGY = "MESH",
|
parameter TOPOLOGY = "MESH",
|
parameter V = 4, // vc_num_per_port
|
parameter V = 4, // vc_num_per_port
|
parameter P = 5, // router port num
|
parameter P = 5, // router port num
|
parameter Fw = 36,
|
parameter Fw = 36,
|
parameter MUX_TYPE="BINARY", //"ONE_HOT" or "BINARY"
|
parameter MUX_TYPE="BINARY", //"ONE_HOT" or "BINARY"
|
parameter SSA_EN="YES", // "YES" , "NO"
|
parameter SSA_EN="YES", // "YES" , "NO"
|
parameter SELF_LOOP_EN= "NO"
|
parameter SELF_LOOP_EN= "NO"
|
)
|
)
|
(
|
(
|
granted_dest_port_all,
|
granted_dest_port_all,
|
flit_in_all,
|
flit_in_all,
|
flit_out_all,
|
flit_out_all,
|
flit_out_wr_all,
|
flit_out_wr_all,
|
ssa_flit_wr_all
|
ssa_flit_wr_all
|
);
|
);
|
|
|
|
|
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
|
PV = V * P,
|
PV = V * P,
|
VV = V * V,
|
VV = V * V,
|
PP = P * P,
|
PP = P * P,
|
PVV = PV * V,
|
PVV = PV * V,
|
P_1 = (SELF_LOOP_EN == "NO")? P-1 : P,
|
P_1 = (SELF_LOOP_EN == "NO")? P-1 : P,
|
VP_1 = V * P_1,
|
VP_1 = V * P_1,
|
PP_1 = P_1 * P,
|
PP_1 = P_1 * P,
|
PVP_1 = PV * P_1,
|
PVP_1 = PV * P_1,
|
PFw = P*Fw,
|
PFw = P*Fw,
|
P_1Fw = P_1 * Fw,
|
P_1Fw = P_1 * Fw,
|
P_1w = log2(P_1);
|
P_1w = log2(P_1);
|
|
|
|
|
input [PP_1-1 : 0] granted_dest_port_all;
|
input [PP_1-1 : 0] granted_dest_port_all;
|
input [PFw-1 : 0] flit_in_all;
|
input [PFw-1 : 0] flit_in_all;
|
output [PFw-1 : 0] flit_out_all;
|
output [PFw-1 : 0] flit_out_all;
|
output [P-1 : 0] flit_out_wr_all;
|
output [P-1 : 0] flit_out_wr_all;
|
input [P-1 : 0] ssa_flit_wr_all;
|
input [P-1 : 0] ssa_flit_wr_all;
|
|
|
|
|
wire [P-1 : 0] flit_we_mux_out;
|
wire [P-1 : 0] flit_we_mux_out;
|
wire [P_1-1 : 0] granted_dest_port [P-1 : 0];
|
wire [P_1-1 : 0] granted_dest_port [P-1 : 0];
|
wire [P_1Fw-1 : 0] mux_in [P-1 : 0];
|
wire [P_1Fw-1 : 0] mux_in [P-1 : 0];
|
wire [P_1-1 : 0] mux_sel_pre [P-1 : 0];
|
wire [P_1-1 : 0] mux_sel_pre [P-1 : 0];
|
wire [P_1-1 : 0] mux_sel [P-1 : 0];
|
wire [P_1-1 : 0] mux_sel [P-1 : 0];
|
wire [P_1w-1 : 0] mux_sel_bin [P-1 : 0];
|
wire [P_1w-1 : 0] mux_sel_bin [P-1 : 0];
|
wire [PP-1 : 0] flit_out_wr_gen;
|
wire [PP-1 : 0] flit_out_wr_gen;
|
|
|
genvar i,j;
|
genvar i,j;
|
generate
|
generate
|
for(i=0;i<P;i=i+1)begin : port_loop
|
for(i=0;i<P;i=i+1)begin : port_loop
|
assign granted_dest_port[i] = granted_dest_port_all[(i+1)*P_1-1 : i*P_1];
|
assign granted_dest_port[i] = granted_dest_port_all[(i+1)*P_1-1 : i*P_1];
|
for(j=0;j<P;j=j+1)begin : port_loop2
|
for(j=0;j<P;j=j+1)begin : port_loop2
|
if(SELF_LOOP_EN == "NO") begin : nslp
|
if(SELF_LOOP_EN == "NO") begin : nslp
|
//remove sender port flit from flit list
|
//remove sender port flit from flit list
|
if(i>j) begin :if1
|
if(i>j) begin :if1
|
assign mux_in[i][(j+1)*Fw-1 : j*Fw]= flit_in_all[(j+1)*Fw-1 : j*Fw];
|
assign mux_in[i][(j+1)*Fw-1 : j*Fw]= flit_in_all[(j+1)*Fw-1 : j*Fw];
|
assign mux_sel_pre[i][j] = granted_dest_port[j][i-1];
|
assign mux_sel_pre[i][j] = granted_dest_port[j][i-1];
|
end
|
end
|
else if(i<j) begin :if2
|
else if(i<j) begin :if2
|
assign mux_in[i][j*Fw-1 : (j-1)*Fw]= flit_in_all[(j+1)*Fw-1 : j*Fw];
|
assign mux_in[i][j*Fw-1 : (j-1)*Fw]= flit_in_all[(j+1)*Fw-1 : j*Fw];
|
assign mux_sel_pre[i][j-1] = granted_dest_port[j][i];
|
assign mux_sel_pre[i][j-1] = granted_dest_port[j][i];
|
end
|
end
|
end else begin : slp
|
end else begin : slp
|
assign mux_in[i][(j+1)*Fw-1 : j*Fw]= flit_in_all[(j+1)*Fw-1 : j*Fw];
|
assign mux_in[i][(j+1)*Fw-1 : j*Fw]= flit_in_all[(j+1)*Fw-1 : j*Fw];
|
assign mux_sel_pre[i][j] = granted_dest_port[j][i];
|
assign mux_sel_pre[i][j] = granted_dest_port[j][i];
|
end
|
end
|
end//for j
|
end//for j
|
|
|
|
|
|
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if (SSA_EN =="YES")begin :predict //If no output is granted replace the output port with SS port
|
if (SSA_EN =="YES")begin :predict //If no output is granted replace the output port with SS port
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
add_ss_port #(
|
add_ss_port #(
|
|
.NOC_ID(NOC_ID),
|
.SW_LOC(i),
|
.SW_LOC(i),
|
.P(P)
|
.P(P)
|
)
|
)
|
ss_port
|
ss_port
|
(
|
(
|
.destport_in (mux_sel_pre[i]),
|
.destport_in (mux_sel_pre[i]),
|
.destport_out(mux_sel [i])
|
.destport_out(mux_sel [i])
|
);
|
);
|
|
|
end else begin :nopredict
|
end else begin :nopredict
|
assign mux_sel[i]= mux_sel_pre[i];
|
assign mux_sel[i]= mux_sel_pre[i];
|
|
|
end
|
end
|
|
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if (MUX_TYPE == "ONE_HOT") begin : one_hot_gen
|
if (MUX_TYPE == "ONE_HOT") begin : one_hot_gen
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
onehot_mux_1D #(
|
onehot_mux_1D #(
|
.W (Fw),
|
.W (Fw),
|
.N (P_1)
|
.N (P_1)
|
)
|
)
|
cross_mux
|
cross_mux
|
(
|
(
|
.in (mux_in [i]),
|
.in (mux_in [i]),
|
.out (flit_out_all[(i+1)*Fw-1 : i*Fw]),
|
.out (flit_out_all[(i+1)*Fw-1 : i*Fw]),
|
.sel (mux_sel[i])
|
.sel (mux_sel[i])
|
|
|
);
|
);
|
end else begin : binary
|
end else begin : binary
|
|
|
one_hot_to_bin #(
|
one_hot_to_bin #(
|
.ONE_HOT_WIDTH(P_1),
|
.ONE_HOT_WIDTH(P_1),
|
.BIN_WIDTH(P_1w)
|
.BIN_WIDTH(P_1w)
|
)
|
)
|
conv
|
conv
|
(
|
(
|
.one_hot_code(mux_sel[i]),
|
.one_hot_code(mux_sel[i]),
|
.bin_code(mux_sel_bin[i])
|
.bin_code(mux_sel_bin[i])
|
|
|
);
|
);
|
|
|
|
|
binary_mux #(
|
binary_mux #(
|
.IN_WIDTH(P_1Fw),
|
.IN_WIDTH(P_1Fw),
|
.OUT_WIDTH(Fw)
|
.OUT_WIDTH(Fw)
|
)
|
)
|
cross_mux
|
cross_mux
|
(
|
(
|
.mux_in(mux_in [i]),
|
.mux_in(mux_in [i]),
|
.mux_out(flit_out_all[(i+1)*Fw-1 : i*Fw]),
|
.mux_out(flit_out_all[(i+1)*Fw-1 : i*Fw]),
|
.sel(mux_sel_bin[i])
|
.sel(mux_sel_bin[i])
|
|
|
);
|
);
|
end//binary
|
end//binary
|
|
|
|
|
if(SELF_LOOP_EN == "NO") begin : nslp
|
if(SELF_LOOP_EN == "NO") begin : nslp
|
add_sw_loc_one_hot #(
|
add_sw_loc_one_hot #(
|
.P(P),
|
.P(P),
|
.SW_LOC(i)
|
.SW_LOC(i)
|
)
|
)
|
add_sw_loc
|
add_sw_loc
|
(
|
(
|
.destport_in(granted_dest_port_all[(i+1)*P_1-1 : i*P_1]),
|
.destport_in(granted_dest_port_all[(i+1)*P_1-1 : i*P_1]),
|
.destport_out(flit_out_wr_gen [(i+1)*P-1 : i*P])
|
.destport_out(flit_out_wr_gen [(i+1)*P-1 : i*P])
|
);
|
);
|
end else begin :slp
|
end else begin :slp
|
assign flit_out_wr_gen [(i+1)*P-1 : i*P] = granted_dest_port_all[(i+1)*P_1-1 : i*P_1];
|
assign flit_out_wr_gen [(i+1)*P-1 : i*P] = granted_dest_port_all[(i+1)*P_1-1 : i*P_1];
|
end
|
end
|
|
|
end//for i
|
end//for i
|
endgenerate
|
endgenerate
|
|
|
custom_or #(
|
custom_or #(
|
.IN_NUM(P),
|
.IN_NUM(P),
|
.OUT_WIDTH(P)
|
.OUT_WIDTH(P)
|
)
|
)
|
wide_or
|
wide_or
|
(
|
(
|
.or_in(flit_out_wr_gen),
|
.or_in(flit_out_wr_gen),
|
.or_out(flit_we_mux_out)
|
.or_out(flit_we_mux_out)
|
);
|
);
|
|
|
assign flit_out_wr_all = flit_we_mux_out | ssa_flit_wr_all;
|
assign flit_out_wr_all = flit_we_mux_out | ssa_flit_wr_all;
|
|
|
|
|
|
|
endmodule
|
endmodule
|
|
|