`timescale 1ns/1ps
|
`timescale 1ns/1ps
|
/**********************************************************************
|
/**********************************************************************
|
** File: congestion_analyzer.v
|
** File: congestion_analyzer.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:
|
** This file includes all files for getting congestion information and
|
** This file includes all files for getting congestion information and
|
** Port selection modules for supporting adaptive routing
|
** Port selection modules for supporting adaptive routing
|
**
|
**
|
**************************************************************/
|
**************************************************************/
|
|
|
|
|
|
|
|
|
/*****************************
|
/*****************************
|
|
|
port_presel
|
port_presel
|
|
|
*****************************/
|
*****************************/
|
|
|
|
|
|
|
/***************************************
|
/***************************************
|
|
|
port_presel_based_dst_ports_vc
|
port_presel_based_dst_ports_vc
|
CONGESTION_INDEX==0
|
CONGESTION_INDEX==0
|
***************************************/
|
***************************************/
|
|
|
|
|
//congestion analyzer based on number of occupied VCs
|
//congestion analyzer based on number of occupied VCs
|
module port_presel_based_dst_ports_vc #(
|
module port_presel_based_dst_ports_vc #(
|
parameter PPSw=4,
|
parameter PPSw=4,
|
parameter P = 5,
|
parameter P = 5,
|
parameter V = 4
|
parameter V = 4
|
)
|
)
|
(
|
(
|
ovc_status,
|
ovc_status,
|
port_pre_sel
|
port_pre_sel
|
);
|
);
|
|
|
|
|
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 P_1 = P-1,
|
localparam P_1 = P-1,
|
P_1V = P_1*V,
|
P_1V = P_1*V,
|
CNTw = log2(V+1);
|
CNTw = log2(V+1);
|
|
|
input [P_1V-1 : 0] ovc_status;
|
input [P_1V-1 : 0] ovc_status;
|
output [PPSw-1 : 0] port_pre_sel;
|
output [PPSw-1 : 0] port_pre_sel;
|
wire [P_1-1 : 0] conjestion_cmp;
|
wire [P_1-1 : 0] conjestion_cmp;
|
//VC counter on all ports exept the local
|
//VC counter on all ports exept the local
|
wire [V-1 : 0] ovc_status_per_port [P-1-1 : 0];
|
wire [V-1 : 0] ovc_status_per_port [P-1-1 : 0];
|
wire [CNTw -1 : 0] vc_counter [P_1-1 : 0];
|
wire [CNTw -1 : 0] vc_counter [P_1-1 : 0];
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for( i= 0;i<P_1;i=i+1) begin : p_loop
|
for( i= 0;i<P_1;i=i+1) begin : p_loop
|
//seperate all credit counters
|
//seperate all credit counters
|
|
|
assign ovc_status_per_port[i] = ovc_status[(i+1)*V-1 : i*V];
|
assign ovc_status_per_port[i] = ovc_status[(i+1)*V-1 : i*V];
|
//count number of busy OVCs
|
//count number of busy OVCs
|
accumulator #(
|
accumulator #(
|
.INw(V),
|
.INw(V),
|
.OUTw(CNTw),
|
.OUTw(CNTw),
|
.NUM(V)
|
.NUM(V)
|
)
|
)
|
counter
|
counter
|
(
|
(
|
.in_all(ovc_status_per_port[i]),
|
.in_all(ovc_status_per_port[i]),
|
.out(vc_counter[i])
|
.out(vc_counter[i])
|
);
|
);
|
|
|
|
|
/*
|
/*
|
parallel_counter #(
|
parallel_counter #(
|
.IN_WIDTH(V)
|
.IN_WIDTH(V)
|
)counter
|
)counter
|
(
|
(
|
.in (ovc_status_per_port[i]),
|
.in (ovc_status_per_port[i]),
|
.out (vc_counter[i])
|
.out (vc_counter[i])
|
);
|
);
|
*/
|
*/
|
|
|
|
|
end//for
|
end//for
|
endgenerate
|
endgenerate
|
/*******************
|
/*******************
|
pre-sel[xy]
|
pre-sel[xy]
|
y
|
y
|
1 | 3
|
1 | 3
|
|
|
|
|
-------x
|
-------x
|
0 | 2
|
0 | 2
|
|
|
|
|
|
|
|
|
pre_sel
|
pre_sel
|
0: xdir is preferable
|
0: xdir is preferable
|
1: ydir is preferable
|
1: ydir is preferable
|
*******************/
|
*******************/
|
|
|
|
|
|
|
//location in counter
|
//location in counter
|
localparam X_PLUS = 0,//EAST
|
localparam X_PLUS = 0,//EAST
|
Y_PLUS = 1,//NORTH
|
Y_PLUS = 1,//NORTH
|
X_MINUS = 2,//WEST
|
X_MINUS = 2,//WEST
|
Y_MINUS = 3;//SOUTH
|
Y_MINUS = 3;//SOUTH
|
|
|
//location in port-pre-select
|
//location in port-pre-select
|
localparam X_PLUS_Y_PLUS = 3,
|
localparam X_PLUS_Y_PLUS = 3,
|
X_MINUS_Y_PLUS = 1,
|
X_MINUS_Y_PLUS = 1,
|
X_PLUS_Y_MINUS = 2,
|
X_PLUS_Y_MINUS = 2,
|
X_MINUS_Y_MINUS= 0;
|
X_MINUS_Y_MINUS= 0;
|
|
|
assign conjestion_cmp[X_PLUS_Y_PLUS] = (vc_counter[X_PLUS] > vc_counter[Y_PLUS]);
|
assign conjestion_cmp[X_PLUS_Y_PLUS] = (vc_counter[X_PLUS] > vc_counter[Y_PLUS]);
|
assign conjestion_cmp[X_MINUS_Y_PLUS] = (vc_counter[X_MINUS] > vc_counter[Y_PLUS]);
|
assign conjestion_cmp[X_MINUS_Y_PLUS] = (vc_counter[X_MINUS] > vc_counter[Y_PLUS]);
|
assign conjestion_cmp[X_PLUS_Y_MINUS] = (vc_counter[X_PLUS] > vc_counter[Y_MINUS]);
|
assign conjestion_cmp[X_PLUS_Y_MINUS] = (vc_counter[X_PLUS] > vc_counter[Y_MINUS]);
|
assign conjestion_cmp[X_MINUS_Y_MINUS]= (vc_counter[X_MINUS] > vc_counter[Y_MINUS]);
|
assign conjestion_cmp[X_MINUS_Y_MINUS]= (vc_counter[X_MINUS] > vc_counter[Y_MINUS]);
|
|
|
//assign port_pre_sel = conjestion_cmp;
|
//assign port_pre_sel = conjestion_cmp;
|
|
|
|
|
assign port_pre_sel = conjestion_cmp;
|
assign port_pre_sel = conjestion_cmp;
|
|
|
|
|
|
|
|
|
|
|
endmodule
|
endmodule
|
|
|
/*************************************
|
/*************************************
|
*
|
*
|
* port_presel_based_dst_ports_credit
|
* port_presel_based_dst_ports_credit
|
* CONGESTION_INDEX==1
|
* CONGESTION_INDEX==1
|
*************************************/
|
*************************************/
|
|
|
|
|
//congestion analyzer based on number of total available credit of a port
|
//congestion analyzer based on number of total available credit of a port
|
module port_presel_based_dst_ports_credit #(
|
module port_presel_based_dst_ports_credit #(
|
parameter PPSw=4,
|
parameter PPSw=4,
|
parameter P = 5,
|
parameter P = 5,
|
parameter V = 4,
|
parameter V = 4,
|
parameter B = 4
|
parameter B = 4
|
)
|
)
|
(
|
(
|
credit_decreased_all,
|
credit_decreased_all,
|
credit_increased_all,
|
credit_increased_all,
|
port_pre_sel,
|
port_pre_sel,
|
clk,
|
clk,
|
reset
|
reset
|
);
|
);
|
|
|
|
|
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 P_1 = P-1,
|
localparam P_1 = P-1,
|
P_1V = (P_1)*V,
|
P_1V = (P_1)*V,
|
BV = B*V,
|
BV = B*V,
|
BV_1 = BV-1,
|
BV_1 = BV-1,
|
BVw = log2(BV);
|
BVw = log2(BV);
|
|
|
localparam [BVw-1 : 0] C_INT = BV_1 [BVw-1 : 0];
|
localparam [BVw-1 : 0] C_INT = BV_1 [BVw-1 : 0];
|
|
|
|
|
input [P_1V-1 : 0] credit_decreased_all;
|
input [P_1V-1 : 0] credit_decreased_all;
|
input [P_1V-1 : 0] credit_increased_all;
|
input [P_1V-1 : 0] credit_increased_all;
|
input reset,clk;
|
input reset,clk;
|
output [PPSw-1 : 0] port_pre_sel;
|
output [PPSw-1 : 0] port_pre_sel;
|
|
|
|
|
|
|
reg [BVw-1 : 0] credit_per_port_next [P_1-1 : 0];
|
reg [BVw-1 : 0] credit_per_port_next [P_1-1 : 0];
|
reg [BVw-1 : 0] credit_per_port [P_1-1 : 0];
|
wire [BVw-1 : 0] credit_per_port [P_1-1 : 0];
|
wire [P_1-1 : 0] credit_increased_per_port;
|
wire [P_1-1 : 0] credit_increased_per_port;
|
wire [P_1-1 : 0] credit_decreased_per_port;
|
wire [P_1-1 : 0] credit_decreased_per_port;
|
wire [P_1-1 : 0] conjestion_cmp;
|
wire [P_1-1 : 0] conjestion_cmp;
|
|
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for(i=0; i<P_1; i=i+1) begin :sep
|
for(i=0; i<P_1; i=i+1) begin :sep
|
assign credit_increased_per_port[i]=|credit_increased_all[((i+1)*V)-1 : i*V];
|
assign credit_increased_per_port[i]=|credit_increased_all[((i+1)*V)-1 : i*V];
|
assign credit_decreased_per_port[i]=|credit_decreased_all[((i+1)*V)-1 : i*V];
|
assign credit_decreased_per_port[i]=|credit_decreased_all[((i+1)*V)-1 : i*V];
|
end//for
|
end//for
|
|
|
|
|
for(i=0; i<P; i=i+1'b1) begin :blk1
|
for(i=0; i<P; i=i+1'b1) begin :blk1
|
always @(*) begin
|
always @(*) begin
|
credit_per_port_next[i] = credit_per_port[i];
|
credit_per_port_next[i] = credit_per_port[i];
|
if(credit_increased_per_port[i] & ~credit_decreased_per_port[i]) begin
|
if(credit_increased_per_port[i] & ~credit_decreased_per_port[i]) begin
|
credit_per_port_next[i] = credit_per_port[i]+1'b1;
|
credit_per_port_next[i] = credit_per_port[i]+1'b1;
|
end else if (~credit_increased_per_port[i] & credit_decreased_per_port[i])begin
|
end else if (~credit_increased_per_port[i] & credit_decreased_per_port[i])begin
|
credit_per_port_next[i] = credit_per_port[i]-1'b1;
|
credit_per_port_next[i] = credit_per_port[i]-1'b1;
|
end
|
end
|
end//for
|
end//for
|
end//always
|
end//always
|
|
|
for(i=0; i<P_1; i=i+1'b1) begin :blk2
|
for(i=0; i<P_1; i=i+1'b1) begin :blk2
|
`ifdef SYNC_RESET_MODE
|
|
always @ (posedge clk )begin
|
pronoc_register #(
|
`else
|
.W(BVw),
|
always @ (posedge clk or posedge reset)begin
|
.RESET_TO(C_INT)
|
`endif
|
) reg1 (
|
|
.in(credit_per_port_next[i]),
|
if(reset) begin
|
.reset(reset),
|
credit_per_port[i] <= C_INT;
|
.clk(clk),
|
end else begin
|
.out(credit_per_port[i])
|
credit_per_port[i] <= credit_per_port_next[i];
|
);
|
end
|
|
end//for
|
end//for
|
end
|
|
|
|
endgenerate//always
|
endgenerate
|
|
|
/*******************
|
/*******************
|
pre-sel[xy]
|
pre-sel[xy]
|
y
|
y
|
1 | 3
|
1 | 3
|
|
|
|
|
-------x
|
-------x
|
0 | 2
|
0 | 2
|
|
|
|
|
|
|
|
|
pre_sel
|
pre_sel
|
0: xdir
|
0: xdir
|
1: ydir
|
1: ydir
|
*******************/
|
*******************/
|
|
|
//location in counter
|
//location in counter
|
localparam X_PLUS = 0,//EAST
|
localparam X_PLUS = 0,//EAST
|
Y_PLUS = 1,//NORTH
|
Y_PLUS = 1,//NORTH
|
X_MINUS = 2,//WEST
|
X_MINUS = 2,//WEST
|
Y_MINUS = 3;//SOUTH
|
Y_MINUS = 3;//SOUTH
|
|
|
//location in port-pre-select
|
//location in port-pre-select
|
localparam X_PLUS_Y_PLUS = 3,
|
localparam X_PLUS_Y_PLUS = 3,
|
X_MINUS_Y_PLUS = 1,
|
X_MINUS_Y_PLUS = 1,
|
X_PLUS_Y_MINUS = 2,
|
X_PLUS_Y_MINUS = 2,
|
X_MINUS_Y_MINUS= 0;
|
X_MINUS_Y_MINUS= 0;
|
|
|
assign conjestion_cmp[X_PLUS_Y_PLUS] = (credit_per_port[X_PLUS] < credit_per_port[Y_PLUS]);
|
assign conjestion_cmp[X_PLUS_Y_PLUS] = (credit_per_port[X_PLUS] < credit_per_port[Y_PLUS]);
|
assign conjestion_cmp[X_MINUS_Y_PLUS] = (credit_per_port[X_MINUS] < credit_per_port[Y_PLUS]);
|
assign conjestion_cmp[X_MINUS_Y_PLUS] = (credit_per_port[X_MINUS] < credit_per_port[Y_PLUS]);
|
assign conjestion_cmp[X_PLUS_Y_MINUS] = (credit_per_port[X_PLUS] < credit_per_port[Y_MINUS]);
|
assign conjestion_cmp[X_PLUS_Y_MINUS] = (credit_per_port[X_PLUS] < credit_per_port[Y_MINUS]);
|
assign conjestion_cmp[X_MINUS_Y_MINUS]= (credit_per_port[X_MINUS] < credit_per_port[Y_MINUS]);
|
assign conjestion_cmp[X_MINUS_Y_MINUS]= (credit_per_port[X_MINUS] < credit_per_port[Y_MINUS]);
|
|
|
// assign port_pre_sel = conjestion_cmp;
|
// assign port_pre_sel = conjestion_cmp;
|
|
|
|
|
|
|
assign port_pre_sel = conjestion_cmp;
|
assign port_pre_sel = conjestion_cmp;
|
|
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
/*********************************
|
/*********************************
|
|
|
port_presel_based_dst_routers_ovc
|
port_presel_based_dst_routers_ovc
|
CONGESTION_INDEX==2,3,4,5,6,7,9
|
CONGESTION_INDEX==2,3,4,5,6,7,9
|
********************************/
|
********************************/
|
|
|
|
|
module mesh_torus_port_presel_based_dst_routers_vc #(
|
module mesh_torus_port_presel_based_dst_routers_vc #(
|
parameter PPSw=4,
|
parameter PPSw=4,
|
parameter P=5,
|
parameter P=5,
|
parameter CONGw=2 //congestion width per port
|
parameter CONGw=2 //congestion width per port
|
)
|
)
|
(
|
(
|
port_pre_sel,
|
port_pre_sel,
|
congestion_in_all,
|
congestion_in_all,
|
reset,clk
|
reset,clk
|
);
|
);
|
|
|
|
|
localparam CONG_ALw= CONGw* P; // congestion width per router;
|
localparam CONG_ALw= CONGw* P; // congestion width per router;
|
|
|
localparam XDIR =1'b0;
|
localparam XDIR =1'b0;
|
localparam YDIR =1'b1;
|
localparam YDIR =1'b1;
|
|
|
//location in port-pre-select
|
//location in port-pre-select
|
localparam X_PLUS_Y_PLUS = 3,
|
localparam X_PLUS_Y_PLUS = 3,
|
X_MINUS_Y_PLUS = 1,
|
X_MINUS_Y_PLUS = 1,
|
X_PLUS_Y_MINUS = 2,
|
X_PLUS_Y_MINUS = 2,
|
X_MINUS_Y_MINUS= 0;
|
X_MINUS_Y_MINUS= 0;
|
|
|
|
|
|
|
input [CONG_ALw-1 : 0] congestion_in_all;
|
input [CONG_ALw-1 : 0] congestion_in_all;
|
output [PPSw-1 : 0] port_pre_sel;
|
output [PPSw-1 : 0] port_pre_sel;
|
input reset,clk;
|
input reset,clk;
|
|
|
wire [CONGw-1 : 0] congestion_x_plus,congestion_y_plus,congestion_x_min,congestion_y_min;
|
wire [CONGw-1 : 0] congestion_x_plus,congestion_y_plus,congestion_x_min,congestion_y_min;
|
wire [PPSw-1 : 0] conjestion_cmp;
|
wire [PPSw-1 : 0] conjestion_cmp;
|
|
|
|
|
assign {congestion_y_min,congestion_x_min,congestion_y_plus,congestion_x_plus} = congestion_in_all[(CONGw*5)-1 : CONGw];
|
assign {congestion_y_min,congestion_x_min,congestion_y_plus,congestion_x_plus} = congestion_in_all[(CONGw*5)-1 : CONGw];
|
|
|
/****************
|
/****************
|
congestion:
|
congestion:
|
0: list congested
|
0: list congested
|
3: most congested
|
3: most congested
|
pre_sel
|
pre_sel
|
0: xdir
|
0: xdir
|
1: ydir
|
1: ydir
|
*******************/
|
*******************/
|
assign conjestion_cmp[X_PLUS_Y_PLUS] = (congestion_x_plus > congestion_y_plus)? YDIR : XDIR;
|
assign conjestion_cmp[X_PLUS_Y_PLUS] = (congestion_x_plus > congestion_y_plus)? YDIR : XDIR;
|
assign conjestion_cmp[X_MINUS_Y_PLUS] = (congestion_x_min > congestion_y_plus)? YDIR : XDIR;
|
assign conjestion_cmp[X_MINUS_Y_PLUS] = (congestion_x_min > congestion_y_plus)? YDIR : XDIR;
|
assign conjestion_cmp[X_PLUS_Y_MINUS] = (congestion_x_plus > congestion_y_min)? YDIR : XDIR;
|
assign conjestion_cmp[X_PLUS_Y_MINUS] = (congestion_x_plus > congestion_y_min)? YDIR : XDIR;
|
assign conjestion_cmp[X_MINUS_Y_MINUS]= (congestion_x_min > congestion_y_min)? YDIR : XDIR;
|
assign conjestion_cmp[X_MINUS_Y_MINUS]= (congestion_x_min > congestion_y_min)? YDIR : XDIR;
|
|
|
|
|
|
|
|
|
// assign port_pre_sel = conjestion_cmp;
|
// assign port_pre_sel = conjestion_cmp;
|
register #(.W(PPSw)) reg1 (.in(conjestion_cmp ), .reset(reset), .clk(clk), .out(port_pre_sel));
|
pronoc_register #(.W(PPSw)) reg1 (.in(conjestion_cmp ), .reset(reset), .clk(clk), .out(port_pre_sel));
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
/*********************************
|
/*********************************
|
|
|
port_presel_based_dst_routers_ovc
|
port_presel_based_dst_routers_ovc
|
CONGESTION_INDEX==8,10
|
CONGESTION_INDEX==8,10
|
********************************/
|
********************************/
|
|
|
|
|
module port_presel_based_dst_routers_ovc #(
|
module port_presel_based_dst_routers_ovc #(
|
parameter PPSw=4,
|
parameter PPSw=4,
|
parameter P=5,
|
parameter P=5,
|
parameter V=4,
|
parameter V=4,
|
parameter CONGw=2 //congestion width per port
|
parameter CONGw=2 //congestion width per port
|
)
|
)
|
(
|
(
|
port_pre_sel,
|
port_pre_sel,
|
congestion_in_all
|
congestion_in_all
|
);
|
);
|
|
|
|
|
localparam P_1 = P-1,
|
localparam P_1 = P-1,
|
CONG_ALw= CONGw* P; // congestion width per router;
|
CONG_ALw= CONGw* P; // congestion width per router;
|
|
|
|
|
input [CONG_ALw-1 : 0] congestion_in_all;
|
input [CONG_ALw-1 : 0] congestion_in_all;
|
output [PPSw-1 : 0] port_pre_sel;
|
output [PPSw-1 : 0] port_pre_sel;
|
|
|
|
|
|
|
|
|
/*************
|
/*************
|
N
|
N
|
Q1 | Q3
|
Q1 | Q3
|
w--------E
|
w--------E
|
Q0 | Q2
|
Q0 | Q2
|
S
|
S
|
***************/
|
***************/
|
|
|
localparam Q3 = 3,
|
localparam Q3 = 3,
|
Q1 = 1,
|
Q1 = 1,
|
Q2 = 2,
|
Q2 = 2,
|
Q0 = 0;
|
Q0 = 0;
|
|
|
localparam EAST = 0,
|
localparam EAST = 0,
|
NORTH= 1,
|
NORTH= 1,
|
WEST = 2,
|
WEST = 2,
|
SOUTH= 3;
|
SOUTH= 3;
|
|
|
localparam XDIR =1'b0,
|
localparam XDIR =1'b0,
|
YDIR =1'b1;
|
YDIR =1'b1;
|
|
|
wire [CONGw-1 : 0] congestion_in [P_1-1 : 0];
|
wire [CONGw-1 : 0] congestion_in [P_1-1 : 0];
|
assign {congestion_in[SOUTH],congestion_in[WEST],congestion_in[NORTH],congestion_in[EAST]} = congestion_in_all[CONG_ALw-1 : CONGw];
|
assign {congestion_in[SOUTH],congestion_in[WEST],congestion_in[NORTH],congestion_in[EAST]} = congestion_in_all[CONG_ALw-1 : CONGw];
|
|
|
wire [(CONGw/2)-1 : 0]cong_from_west_Q1 , cong_from_west_Q0;
|
wire [(CONGw/2)-1 : 0]cong_from_west_Q1 , cong_from_west_Q0;
|
wire [(CONGw/2)-1 : 0]cong_from_south_Q0 , cong_from_south_Q2;
|
wire [(CONGw/2)-1 : 0]cong_from_south_Q0 , cong_from_south_Q2;
|
wire [(CONGw/2)-1 : 0]cong_from_east_Q2 , cong_from_east_Q3;
|
wire [(CONGw/2)-1 : 0]cong_from_east_Q2 , cong_from_east_Q3;
|
wire [(CONGw/2)-1 : 0]cong_from_north_Q3 , cong_from_north_Q1;
|
wire [(CONGw/2)-1 : 0]cong_from_north_Q3 , cong_from_north_Q1;
|
|
|
|
|
|
|
assign {cong_from_west_Q1 ,cong_from_west_Q0 }=congestion_in[WEST];
|
assign {cong_from_west_Q1 ,cong_from_west_Q0 }=congestion_in[WEST];
|
assign {cong_from_south_Q0 ,cong_from_south_Q2 }=congestion_in[SOUTH];
|
assign {cong_from_south_Q0 ,cong_from_south_Q2 }=congestion_in[SOUTH];
|
assign {cong_from_east_Q2 ,cong_from_east_Q3 }=congestion_in[EAST];
|
assign {cong_from_east_Q2 ,cong_from_east_Q3 }=congestion_in[EAST];
|
assign {cong_from_north_Q3 ,cong_from_north_Q1 }=congestion_in[NORTH];
|
assign {cong_from_north_Q3 ,cong_from_north_Q1 }=congestion_in[NORTH];
|
|
|
/****************
|
/****************
|
congestion:
|
congestion:
|
0: list congested
|
0: list congested
|
3: most congested
|
3: most congested
|
pre_sel
|
pre_sel
|
0: xdir
|
0: xdir
|
1: ydir
|
1: ydir
|
*******************/
|
*******************/
|
wire [P_1-1 : 0] conjestion_cmp;
|
wire [P_1-1 : 0] conjestion_cmp;
|
|
|
|
|
|
|
assign conjestion_cmp[Q3] = (cong_from_east_Q3 > cong_from_north_Q3)? YDIR :XDIR;
|
assign conjestion_cmp[Q3] = (cong_from_east_Q3 > cong_from_north_Q3)? YDIR :XDIR;
|
assign conjestion_cmp[Q2] = (cong_from_east_Q2 > cong_from_south_Q2)? YDIR :XDIR;
|
assign conjestion_cmp[Q2] = (cong_from_east_Q2 > cong_from_south_Q2)? YDIR :XDIR;
|
assign conjestion_cmp[Q1] = (cong_from_west_Q1 > cong_from_north_Q1)? YDIR :XDIR;
|
assign conjestion_cmp[Q1] = (cong_from_west_Q1 > cong_from_north_Q1)? YDIR :XDIR;
|
assign conjestion_cmp[Q0] = (cong_from_west_Q0 > cong_from_south_Q0)? YDIR :XDIR;
|
assign conjestion_cmp[Q0] = (cong_from_west_Q0 > cong_from_south_Q0)? YDIR :XDIR;
|
|
|
|
|
|
|
|
|
|
|
|
|
assign port_pre_sel = conjestion_cmp;
|
assign port_pre_sel = conjestion_cmp;
|
|
|
|
|
|
|
|
|
|
|
endmodule
|
endmodule
|
|
|
/***********************
|
/***********************
|
|
|
port_pre_sel_gen
|
port_pre_sel_gen
|
|
|
|
|
************************/
|
************************/
|
|
|
|
|
|
|
module port_pre_sel_gen #(
|
module port_pre_sel_gen #(
|
parameter PPSw=4,
|
parameter PPSw=4,
|
parameter P=5,
|
parameter P=5,
|
parameter V=4,
|
parameter V=4,
|
parameter B=4,
|
parameter B=4,
|
parameter CONGESTION_INDEX=2,
|
parameter CONGESTION_INDEX=2,
|
parameter CONGw=2,
|
parameter CONGw=2,
|
parameter ROUTE_TYPE="ADAPTIVE",
|
parameter ROUTE_TYPE="ADAPTIVE",
|
parameter [V-1 : 0] ESCAP_VC_MASK= 4'b0001
|
parameter [V-1 : 0] ESCAP_VC_MASK= 4'b0001
|
|
|
)(
|
)(
|
port_pre_sel,
|
port_pre_sel,
|
ovc_status,
|
ovc_status,
|
ovc_avalable_all,
|
ovc_avalable_all,
|
congestion_in_all,
|
congestion_in_all,
|
credit_decreased_all,
|
credit_decreased_all,
|
credit_increased_all,
|
credit_increased_all,
|
reset,
|
reset,
|
clk
|
clk
|
|
|
);
|
);
|
|
|
localparam P_1 = P-1,
|
localparam P_1 = P-1,
|
PV = P * V,
|
PV = P * V,
|
CONG_ALw = CONGw * P;
|
CONG_ALw = CONGw * P;
|
|
|
output [PPSw-1 : 0] port_pre_sel;
|
output [PPSw-1 : 0] port_pre_sel;
|
input [PV-1 : 0] ovc_status;
|
input [PV-1 : 0] ovc_status;
|
input [PV-1 : 0] ovc_avalable_all;
|
input [PV-1 : 0] ovc_avalable_all;
|
input [PV-1 : 0] credit_decreased_all;
|
input [PV-1 : 0] credit_decreased_all;
|
input [PV-1 : 0] credit_increased_all;
|
input [PV-1 : 0] credit_increased_all;
|
input [CONG_ALw-1 : 0] congestion_in_all;
|
input [CONG_ALw-1 : 0] congestion_in_all;
|
input reset,clk;
|
input reset,clk;
|
|
|
|
|
generate
|
generate
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if(ROUTE_TYPE == "DETERMINISTIC") begin : detrministic
|
if(ROUTE_TYPE == "DETERMINISTIC") begin : detrministic
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
assign port_pre_sel = {PPSw{1'b0}};
|
assign port_pre_sel = {PPSw{1'b0}};
|
|
|
end else begin : adaptive
|
end else begin : adaptive
|
if(CONGESTION_INDEX==0) begin:indx0
|
if(CONGESTION_INDEX==0) begin:indx0
|
|
|
port_presel_based_dst_ports_vc #(
|
port_presel_based_dst_ports_vc #(
|
.PPSw(PPSw),
|
.PPSw(PPSw),
|
.P(P),
|
.P(P),
|
.V(V)
|
.V(V)
|
|
|
)
|
)
|
port_presel_gen
|
port_presel_gen
|
(
|
(
|
.ovc_status (ovc_status [PV-1 : V]),
|
.ovc_status (ovc_status [PV-1 : V]),
|
.port_pre_sel(port_pre_sel)
|
.port_pre_sel(port_pre_sel)
|
|
|
|
|
);
|
);
|
|
|
end else if(CONGESTION_INDEX==1) begin :indx1
|
end else if(CONGESTION_INDEX==1) begin :indx1
|
|
|
port_presel_based_dst_ports_credit #(
|
port_presel_based_dst_ports_credit #(
|
.PPSw(PPSw),
|
.PPSw(PPSw),
|
.P(P),
|
.P(P),
|
.V(V),
|
.V(V),
|
.B(B)
|
.B(B)
|
)
|
)
|
port_presel_gen
|
port_presel_gen
|
(
|
(
|
.credit_decreased_all (credit_decreased_all [PV-1 : V]),//remove local port signals
|
.credit_decreased_all (credit_decreased_all [PV-1 : V]),//remove local port signals
|
.credit_increased_all (credit_increased_all [PV-1 : V]),
|
.credit_increased_all (credit_increased_all [PV-1 : V]),
|
.port_pre_sel (port_pre_sel),
|
.port_pre_sel (port_pre_sel),
|
.clk (clk),
|
.clk (clk),
|
.reset (reset)
|
.reset (reset)
|
);
|
);
|
end else if ( (CONGESTION_INDEX==2) || (CONGESTION_INDEX==3) ||
|
end else if ( (CONGESTION_INDEX==2) || (CONGESTION_INDEX==3) ||
|
(CONGESTION_INDEX==4) || (CONGESTION_INDEX==5) ||
|
(CONGESTION_INDEX==4) || (CONGESTION_INDEX==5) ||
|
(CONGESTION_INDEX==6) || (CONGESTION_INDEX==7) ||
|
(CONGESTION_INDEX==6) || (CONGESTION_INDEX==7) ||
|
(CONGESTION_INDEX==9) ||
|
(CONGESTION_INDEX==9) ||
|
(CONGESTION_INDEX==11)|| (CONGESTION_INDEX==12)) begin :dst_vc
|
(CONGESTION_INDEX==11)|| (CONGESTION_INDEX==12)) begin :dst_vc
|
|
|
mesh_torus_port_presel_based_dst_routers_vc #(
|
mesh_torus_port_presel_based_dst_routers_vc #(
|
.PPSw(PPSw),
|
.PPSw(PPSw),
|
.P(P),
|
.P(P),
|
.CONGw(CONGw)
|
.CONGw(CONGw)
|
)
|
)
|
port_presel_gen
|
port_presel_gen
|
(
|
(
|
.congestion_in_all(congestion_in_all),
|
.congestion_in_all(congestion_in_all),
|
.port_pre_sel(port_pre_sel),
|
.port_pre_sel(port_pre_sel),
|
.reset(reset),
|
.reset(reset),
|
.clk(clk)
|
.clk(clk)
|
);
|
);
|
end else if((CONGESTION_INDEX==8) || (CONGESTION_INDEX==10) )begin :dst_ovc
|
end else if((CONGESTION_INDEX==8) || (CONGESTION_INDEX==10) )begin :dst_ovc
|
|
|
port_presel_based_dst_routers_ovc #(
|
port_presel_based_dst_routers_ovc #(
|
.PPSw(PPSw),
|
.PPSw(PPSw),
|
.P(P),
|
.P(P),
|
.V(V),
|
.V(V),
|
.CONGw(CONGw)
|
.CONGw(CONGw)
|
)
|
)
|
port_presel_gen
|
port_presel_gen
|
(
|
(
|
.port_pre_sel(port_pre_sel),
|
.port_pre_sel(port_pre_sel),
|
.congestion_in_all(congestion_in_all)
|
.congestion_in_all(congestion_in_all)
|
);
|
);
|
|
|
|
|
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
endmodule
|
endmodule
|
|
|
|
|
|
|
/*********************************
|
/*********************************
|
|
|
congestion_out_gen
|
congestion_out_gen
|
|
|
********************************/
|
********************************/
|
|
|
|
|
|
|
|
|
|
|
/*******************************
|
/*******************************
|
|
|
congestion based on number of active ivc
|
congestion based on number of active ivc
|
CONGESTION_INDEX==2 CONGw = 2
|
CONGESTION_INDEX==2 CONGw = 2
|
CONGESTION_INDEX==3 CONGw = 3
|
CONGESTION_INDEX==3 CONGw = 3
|
********************************/
|
********************************/
|
module congestion_out_based_ivc_req #(
|
module congestion_out_based_ivc_req #(
|
parameter P=5,
|
parameter P=5,
|
parameter V=4,
|
parameter V=4,
|
parameter CONGw = 2 //congestion width per port
|
parameter CONGw = 2 //congestion width per port
|
|
|
)
|
)
|
(
|
(
|
ivc_request_all,
|
ivc_request_all,
|
congestion_out_all
|
congestion_out_all
|
|
|
);
|
);
|
|
|
|
|
localparam PV = (V * P),
|
localparam PV = (V * P),
|
CONG_ALw= (CONGw* P); // congestion width per router;
|
CONG_ALw= (CONGw* P); // congestion width per router;
|
|
|
|
|
|
|
|
|
input [PV-1 : 0] ivc_request_all;
|
input [PV-1 : 0] ivc_request_all;
|
output [CONG_ALw-1 : 0] congestion_out_all;
|
output [CONG_ALw-1 : 0] congestion_out_all;
|
|
|
|
|
wire [CONGw-1 : 0] congestion_out ;
|
wire [CONGw-1 : 0] congestion_out ;
|
|
|
parallel_count_normalize #(
|
parallel_count_normalize #(
|
.INw (PV),
|
.INw (PV),
|
.OUTw (CONGw)
|
.OUTw (CONGw)
|
)
|
)
|
ivc_req_counter
|
ivc_req_counter
|
(
|
(
|
.in (ivc_request_all),
|
.in (ivc_request_all),
|
.out (congestion_out)
|
.out (congestion_out)
|
|
|
);
|
);
|
|
|
|
|
|
|
assign congestion_out_all = {P{congestion_out}};
|
assign congestion_out_all = {P{congestion_out}};
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
/*******************************
|
/*******************************
|
|
|
congestion based on number of
|
congestion based on number of
|
active ivc requests that are not granted
|
active ivc requests that are not granted
|
CONGESTION_INDEX==4 CONGw = 2
|
CONGESTION_INDEX==4 CONGw = 2
|
CONGESTION_INDEX==5 CONGw = 3
|
CONGESTION_INDEX==5 CONGw = 3
|
********************************/
|
********************************/
|
module congestion_out_based_ivc_notgrant #(
|
module congestion_out_based_ivc_notgrant #(
|
parameter P=5,
|
parameter P=5,
|
parameter V=4,
|
parameter V=4,
|
parameter CONGw=2 //congestion width per port
|
parameter CONGw=2 //congestion width per port
|
|
|
)
|
)
|
(
|
(
|
ivc_request_all,
|
ivc_request_all,
|
congestion_out_all,
|
congestion_out_all,
|
ivc_num_getting_sw_grant,
|
ivc_num_getting_sw_grant,
|
clk,
|
clk,
|
reset
|
reset
|
|
|
);
|
);
|
|
|
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 PV = (V * P),
|
localparam PV = (V * P),
|
CONG_ALw= CONGw* P, // congestion width per router;
|
CONG_ALw= CONGw* P, // congestion width per router;
|
IVC_CNTw= log2(PV+1);
|
IVC_CNTw= log2(PV+1);
|
|
|
|
|
|
|
|
|
input [PV-1 : 0] ivc_request_all,ivc_num_getting_sw_grant;
|
input [PV-1 : 0] ivc_request_all,ivc_num_getting_sw_grant;
|
output [CONG_ALw-1 : 0] congestion_out_all;
|
output [CONG_ALw-1 : 0] congestion_out_all;
|
input clk,reset;
|
input clk,reset;
|
|
|
wire [IVC_CNTw-1 : 0] ivc_req_num;
|
wire [IVC_CNTw-1 : 0] ivc_req_num;
|
reg [CONGw-1 : 0] congestion_out ;
|
reg [CONGw-1 : 0] congestion_out ;
|
reg [PV-1 : 0] ivc_request_not_granted;
|
wire [PV-1 : 0] ivc_request_not_granted;
|
|
|
`ifdef SYNC_RESET_MODE
|
|
always @ (posedge clk )begin
|
pronoc_register #(
|
`else
|
.W(PV)
|
always @ (posedge clk or posedge reset)begin
|
) reg1 (
|
`endif
|
.in(ivc_request_all & ~ivc_num_getting_sw_grant),
|
if(reset) begin
|
.reset(reset),
|
ivc_request_not_granted <= 0;
|
.clk(clk),
|
end else begin
|
.out(ivc_request_not_granted)
|
ivc_request_not_granted <= ivc_request_all & ~(ivc_num_getting_sw_grant);
|
);
|
end//reset
|
|
end //always
|
|
|
|
|
|
accumulator #(
|
accumulator #(
|
.INw(PV),
|
.INw(PV),
|
.OUTw(IVC_CNTw),
|
.OUTw(IVC_CNTw),
|
.NUM(PV)
|
.NUM(PV)
|
)
|
)
|
ivc_req_counter
|
ivc_req_counter
|
(
|
(
|
.in_all(ivc_request_not_granted),
|
.in_all(ivc_request_not_granted),
|
.out(ivc_req_num)
|
.out(ivc_req_num)
|
);
|
);
|
|
|
/*
|
/*
|
parallel_counter #(
|
parallel_counter #(
|
.IN_WIDTH(PV)
|
.IN_WIDTH(PV)
|
)
|
)
|
ivc_req_counter
|
ivc_req_counter
|
(
|
(
|
.in(ivc_request_not_granted),
|
.in(ivc_request_not_granted),
|
.out(ivc_req_num)
|
.out(ivc_req_num)
|
);
|
);
|
*/
|
*/
|
|
|
|
|
generate
|
generate
|
if(CONGw==2)begin :w2
|
if(CONGw==2)begin :w2
|
always @(*)begin
|
always @(*)begin
|
if (ivc_req_num <= (PV/10) ) congestion_out=2'd0; //0~10
|
if (ivc_req_num <= (PV/10) ) congestion_out=2'd0; //0~10
|
else if (ivc_req_num <= (PV/5) ) congestion_out=2'd1; //10~20
|
else if (ivc_req_num <= (PV/5) ) congestion_out=2'd1; //10~20
|
else if (ivc_req_num <= (PV/2) ) congestion_out=2'd2; //20~50
|
else if (ivc_req_num <= (PV/2) ) congestion_out=2'd2; //20~50
|
else congestion_out=2'd3; //50~100
|
else congestion_out=2'd3; //50~100
|
end
|
end
|
end else begin :w3 // CONGw==3
|
end else begin :w3 // CONGw==3
|
always @(*)begin
|
always @(*)begin
|
if (ivc_req_num < ((PV*1)/8) ) congestion_out=3'd0;
|
if (ivc_req_num < ((PV*1)/8) ) congestion_out=3'd0;
|
else if (ivc_req_num < ((PV*2)/8) ) congestion_out=3'd1;
|
else if (ivc_req_num < ((PV*2)/8) ) congestion_out=3'd1;
|
else if (ivc_req_num < ((PV*3)/8) ) congestion_out=3'd2;
|
else if (ivc_req_num < ((PV*3)/8) ) congestion_out=3'd2;
|
else if (ivc_req_num < ((PV*4)/8) ) congestion_out=3'd3;
|
else if (ivc_req_num < ((PV*4)/8) ) congestion_out=3'd3;
|
else if (ivc_req_num < ((PV*5)/8) ) congestion_out=3'd4;
|
else if (ivc_req_num < ((PV*5)/8) ) congestion_out=3'd4;
|
else if (ivc_req_num < ((PV*6)/8) ) congestion_out=3'd5;
|
else if (ivc_req_num < ((PV*6)/8) ) congestion_out=3'd5;
|
else if (ivc_req_num < ((PV*7)/8) ) congestion_out=3'd6;
|
else if (ivc_req_num < ((PV*7)/8) ) congestion_out=3'd6;
|
else congestion_out=3'd7;
|
else congestion_out=3'd7;
|
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
assign congestion_out_all = {P{congestion_out}};
|
assign congestion_out_all = {P{congestion_out}};
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|
/*******************************
|
/*******************************
|
|
|
congestion based on number of
|
congestion based on number of
|
availabe ovc in all 3ports of next router
|
availabe ovc in all 3ports of next router
|
CONGESTION_INDEX==6 CONGw=2
|
CONGESTION_INDEX==6 CONGw=2
|
CONGESTION_INDEX==7 CONGw=3
|
CONGESTION_INDEX==7 CONGw=3
|
********************************/
|
********************************/
|
module congestion_out_based_3port_avb_ovc #(
|
module congestion_out_based_3port_avb_ovc #(
|
parameter P=5,
|
parameter P=5,
|
parameter V=4,
|
parameter V=4,
|
parameter CONGw=2 //congestion width per port
|
parameter CONGw=2 //congestion width per port
|
|
|
)
|
)
|
(
|
(
|
ovc_avalable_all,
|
ovc_avalable_all,
|
congestion_out_all
|
congestion_out_all
|
|
|
);
|
);
|
|
|
|
|
localparam P_1 = P-1,
|
localparam P_1 = P-1,
|
PV = (V * P),
|
PV = (V * P),
|
CONG_ALw= CONGw* P;
|
CONG_ALw= CONGw* P;
|
|
|
|
|
localparam EAST =0,
|
localparam EAST =0,
|
NORTH =1,
|
NORTH =1,
|
WEST =2,
|
WEST =2,
|
SOUTH =3;
|
SOUTH =3;
|
|
|
localparam CNT_Iw = 3*V;
|
localparam CNT_Iw = 3*V;
|
|
|
input [PV-1 : 0] ovc_avalable_all;
|
input [PV-1 : 0] ovc_avalable_all;
|
output [CONG_ALw-1 : 0] congestion_out_all;
|
output [CONG_ALw-1 : 0] congestion_out_all;
|
|
|
|
|
|
|
wire [V-1 : 0] ovc_not_avb [P_1-1 : 0];
|
wire [V-1 : 0] ovc_not_avb [P_1-1 : 0];
|
wire [CNT_Iw-1 : 0] counter_in [P_1-1 : 0];
|
wire [CNT_Iw-1 : 0] counter_in [P_1-1 : 0];
|
wire [CONGw-1 : 0] congestion_out[P_1-1 : 0];
|
wire [CONGw-1 : 0] congestion_out[P_1-1 : 0];
|
|
|
assign {ovc_not_avb[SOUTH], ovc_not_avb[WEST], ovc_not_avb[NORTH], ovc_not_avb[EAST]}= ~ovc_avalable_all[PV-1 : V];
|
assign {ovc_not_avb[SOUTH], ovc_not_avb[WEST], ovc_not_avb[NORTH], ovc_not_avb[EAST]}= ~ovc_avalable_all[PV-1 : V];
|
assign counter_in[EAST] ={ovc_not_avb[NORTH],ovc_not_avb[WEST] ,ovc_not_avb[SOUTH]};
|
assign counter_in[EAST] ={ovc_not_avb[NORTH],ovc_not_avb[WEST] ,ovc_not_avb[SOUTH]};
|
assign counter_in[NORTH] ={ovc_not_avb[EAST] ,ovc_not_avb[WEST] ,ovc_not_avb[SOUTH]};
|
assign counter_in[NORTH] ={ovc_not_avb[EAST] ,ovc_not_avb[WEST] ,ovc_not_avb[SOUTH]};
|
assign counter_in[WEST] ={ovc_not_avb[EAST] ,ovc_not_avb[NORTH] ,ovc_not_avb[SOUTH]};
|
assign counter_in[WEST] ={ovc_not_avb[EAST] ,ovc_not_avb[NORTH] ,ovc_not_avb[SOUTH]};
|
assign counter_in[SOUTH] ={ovc_not_avb[EAST] ,ovc_not_avb[NORTH] ,ovc_not_avb[WEST]};
|
assign counter_in[SOUTH] ={ovc_not_avb[EAST] ,ovc_not_avb[NORTH] ,ovc_not_avb[WEST]};
|
|
|
|
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for (i=0;i<4;i=i+1) begin :lp
|
for (i=0;i<4;i=i+1) begin :lp
|
|
|
parallel_count_normalize #(
|
parallel_count_normalize #(
|
.INw(CNT_Iw),
|
.INw(CNT_Iw),
|
.OUTw(CONGw)
|
.OUTw(CONGw)
|
)
|
)
|
ovc_avb_east
|
ovc_avb_east
|
(
|
(
|
.in(counter_in[i]),
|
.in(counter_in[i]),
|
.out(congestion_out[i])
|
.out(congestion_out[i])
|
);
|
);
|
|
|
|
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
|
|
|
assign congestion_out_all = {congestion_out[SOUTH],congestion_out[WEST],congestion_out[NORTH],congestion_out[EAST],{CONGw{1'b0}}};
|
assign congestion_out_all = {congestion_out[SOUTH],congestion_out[WEST],congestion_out[NORTH],congestion_out[EAST],{CONGw{1'b0}}};
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*******************************
|
/*******************************
|
|
|
congestion based on number of
|
congestion based on number of
|
availabe ovc in destination router
|
availabe ovc in destination router
|
CONGESTION_INDEX==8 CONGw=2
|
CONGESTION_INDEX==8 CONGw=2
|
********************************/
|
********************************/
|
|
|
|
|
module congestion_out_based_avb_ovc_w2 #(
|
module congestion_out_based_avb_ovc_w2 #(
|
parameter P=5,
|
parameter P=5,
|
parameter V=4
|
parameter V=4
|
|
|
|
|
)
|
)
|
(
|
(
|
ovc_avalable_all,
|
ovc_avalable_all,
|
congestion_out_all
|
congestion_out_all
|
|
|
);
|
);
|
localparam CONGw=2; //congestion width per port
|
localparam CONGw=2; //congestion width per port
|
|
|
localparam P_1 = P-1,
|
localparam P_1 = P-1,
|
PV = (V * P),
|
PV = (V * P),
|
CONG_ALw= CONGw* P,
|
CONG_ALw= CONGw* P,
|
CNT_Iw = 2*V;
|
CNT_Iw = 2*V;
|
|
|
|
|
|
|
|
|
|
|
input [PV-1 : 0] ovc_avalable_all;
|
input [PV-1 : 0] ovc_avalable_all;
|
output [CONG_ALw-1 : 0] congestion_out_all;
|
output [CONG_ALw-1 : 0] congestion_out_all;
|
|
|
/*************
|
/*************
|
N
|
N
|
Q1 | Q3
|
Q1 | Q3
|
w--------E
|
w--------E
|
Q0 | Q2
|
Q0 | Q2
|
S
|
S
|
***************/
|
***************/
|
|
|
localparam Q3 = 3,
|
localparam Q3 = 3,
|
Q1 = 1,
|
Q1 = 1,
|
Q2 = 2,
|
Q2 = 2,
|
Q0 = 0;
|
Q0 = 0;
|
|
|
localparam EAST = 0,
|
localparam EAST = 0,
|
NORTH= 1,
|
NORTH= 1,
|
WEST = 2,
|
WEST = 2,
|
SOUTH= 3;
|
SOUTH= 3;
|
|
|
|
|
|
|
|
|
|
|
|
|
wire [V-1 : 0] ovc_not_avb [P_1-1 : 0];
|
wire [V-1 : 0] ovc_not_avb [P_1-1 : 0];
|
wire [CNT_Iw-1 : 0] counter_in [P_1-1 : 0];
|
wire [CNT_Iw-1 : 0] counter_in [P_1-1 : 0];
|
wire [CONGw-1 : 0] congestion_out [P_1-1 : 0];
|
wire [CONGw-1 : 0] congestion_out [P_1-1 : 0];
|
wire [P_1-1 : 0] threshold;
|
wire [P_1-1 : 0] threshold;
|
|
|
|
|
assign {ovc_not_avb[SOUTH], ovc_not_avb[WEST], ovc_not_avb[NORTH], ovc_not_avb[EAST]}= ~ovc_avalable_all[PV-1 : V];
|
assign {ovc_not_avb[SOUTH], ovc_not_avb[WEST], ovc_not_avb[NORTH], ovc_not_avb[EAST]}= ~ovc_avalable_all[PV-1 : V];
|
|
|
assign counter_in[Q3] ={ovc_not_avb[EAST ],ovc_not_avb[NORTH]};
|
assign counter_in[Q3] ={ovc_not_avb[EAST ],ovc_not_avb[NORTH]};
|
assign counter_in[Q1] ={ovc_not_avb[NORTH],ovc_not_avb[WEST ]};
|
assign counter_in[Q1] ={ovc_not_avb[NORTH],ovc_not_avb[WEST ]};
|
assign counter_in[Q2] ={ovc_not_avb[SOUTH],ovc_not_avb[EAST ]};
|
assign counter_in[Q2] ={ovc_not_avb[SOUTH],ovc_not_avb[EAST ]};
|
assign counter_in[Q0] ={ovc_not_avb[WEST ],ovc_not_avb[SOUTH]};
|
assign counter_in[Q0] ={ovc_not_avb[WEST ],ovc_not_avb[SOUTH]};
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for (i=0;i<4;i=i+1) begin :lp
|
for (i=0;i<4;i=i+1) begin :lp
|
|
|
parallel_count_normalize #(
|
parallel_count_normalize #(
|
.INw(CNT_Iw),
|
.INw(CNT_Iw),
|
.OUTw(1)
|
.OUTw(1)
|
)
|
)
|
ovc_not_avb_cnt
|
ovc_not_avb_cnt
|
(
|
(
|
.in(counter_in[i]),
|
.in(counter_in[i]),
|
.out(threshold[i])
|
.out(threshold[i])
|
);
|
);
|
|
|
|
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
|
|
|
|
|
|
|
|
|
assign congestion_out[EAST] = {threshold[Q1],threshold[Q0]};
|
assign congestion_out[EAST] = {threshold[Q1],threshold[Q0]};
|
assign congestion_out[NORTH] = {threshold[Q0],threshold[Q2]};
|
assign congestion_out[NORTH] = {threshold[Q0],threshold[Q2]};
|
assign congestion_out[WEST] = {threshold[Q2],threshold[Q3]};
|
assign congestion_out[WEST] = {threshold[Q2],threshold[Q3]};
|
assign congestion_out[SOUTH] = {threshold[Q3],threshold[Q1]};
|
assign congestion_out[SOUTH] = {threshold[Q3],threshold[Q1]};
|
|
|
assign congestion_out_all = {congestion_out[SOUTH],congestion_out[WEST],congestion_out[NORTH],congestion_out[EAST],{CONGw{1'b0}}};
|
assign congestion_out_all = {congestion_out[SOUTH],congestion_out[WEST],congestion_out[NORTH],congestion_out[EAST],{CONGw{1'b0}}};
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|
/*******************************
|
/*******************************
|
|
|
congestion based on number of
|
congestion based on number of
|
availabe ovc in destination router
|
availabe ovc in destination router
|
CONGESTION_INDEX==9 CONGw=3
|
CONGESTION_INDEX==9 CONGw=3
|
********************************/
|
********************************/
|
|
|
module congestion_out_based_avb_ovc_w3 #(
|
module congestion_out_based_avb_ovc_w3 #(
|
parameter P=5,
|
parameter P=5,
|
parameter V=4
|
parameter V=4
|
|
|
|
|
)
|
)
|
(
|
(
|
ovc_avalable_all,
|
ovc_avalable_all,
|
congestion_out_all
|
congestion_out_all
|
|
|
);
|
);
|
localparam CONGw=3; //congestion width per port
|
localparam CONGw=3; //congestion width per port
|
|
|
localparam P_1 = P-1,
|
localparam P_1 = P-1,
|
PV = (V * P),
|
PV = (V * P),
|
CONG_ALw= CONGw* P;
|
CONG_ALw= CONGw* P;
|
|
|
|
|
localparam EAST =0,
|
localparam EAST =0,
|
NORTH =1,
|
NORTH =1,
|
WEST =2,
|
WEST =2,
|
SOUTH =3;
|
SOUTH =3;
|
|
|
|
|
|
|
input [PV-1 : 0] ovc_avalable_all;
|
input [PV-1 : 0] ovc_avalable_all;
|
output [CONG_ALw-1 : 0] congestion_out_all;
|
output [CONG_ALw-1 : 0] congestion_out_all;
|
|
|
|
|
|
|
wire [V-1 : 0] ovc_not_avb [P_1-1 : 0];
|
wire [V-1 : 0] ovc_not_avb [P_1-1 : 0];
|
wire [CONGw-1 : 0] congestion_out[P_1-1 : 0];
|
wire [CONGw-1 : 0] congestion_out[P_1-1 : 0];
|
|
|
wire [P_1-1 : 0] threshold;
|
wire [P_1-1 : 0] threshold;
|
|
|
assign {ovc_not_avb[SOUTH], ovc_not_avb[WEST], ovc_not_avb[NORTH], ovc_not_avb[EAST]}=~ovc_avalable_all[PV-1 : V];
|
assign {ovc_not_avb[SOUTH], ovc_not_avb[WEST], ovc_not_avb[NORTH], ovc_not_avb[EAST]}=~ovc_avalable_all[PV-1 : V];
|
|
|
|
|
|
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
|
|
|
|
for (i=0;i<4;i=i+1) begin :lp
|
for (i=0;i<4;i=i+1) begin :lp
|
|
|
parallel_count_normalize #(
|
parallel_count_normalize #(
|
.INw(V),
|
.INw(V),
|
.OUTw(1)
|
.OUTw(1)
|
)
|
)
|
ovc_avb_east
|
ovc_avb_east
|
(
|
(
|
.in(ovc_not_avb[i]),
|
.in(ovc_not_avb[i]),
|
.out(threshold[i])
|
.out(threshold[i])
|
);
|
);
|
|
|
|
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
assign congestion_out[EAST] = {threshold[NORTH],threshold[WEST ],threshold[SOUTH]};
|
assign congestion_out[EAST] = {threshold[NORTH],threshold[WEST ],threshold[SOUTH]};
|
assign congestion_out[NORTH] = {threshold[WEST ],threshold[SOUTH],threshold[EAST ]};
|
assign congestion_out[NORTH] = {threshold[WEST ],threshold[SOUTH],threshold[EAST ]};
|
assign congestion_out[WEST] = {threshold[SOUTH],threshold[EAST ],threshold[NORTH]};
|
assign congestion_out[WEST] = {threshold[SOUTH],threshold[EAST ],threshold[NORTH]};
|
assign congestion_out[SOUTH] = {threshold[EAST ],threshold[NORTH],threshold[WEST ]};
|
assign congestion_out[SOUTH] = {threshold[EAST ],threshold[NORTH],threshold[WEST ]};
|
|
|
assign congestion_out_all = {congestion_out[SOUTH],congestion_out[WEST],congestion_out[NORTH],congestion_out[EAST],{CONGw{1'b0}}};
|
assign congestion_out_all = {congestion_out[SOUTH],congestion_out[WEST],congestion_out[NORTH],congestion_out[EAST],{CONGw{1'b0}}};
|
|
|
endmodule
|
endmodule
|
|
|
|
|
/*******************************
|
/*******************************
|
|
|
congestion based on number of
|
congestion based on number of
|
availabe ovc in destination router
|
availabe ovc in destination router
|
CONGESTION_INDEX==10 CONGw=4
|
CONGESTION_INDEX==10 CONGw=4
|
********************************/
|
********************************/
|
module congestion_out_based_avb_ovc_w4 #(
|
module congestion_out_based_avb_ovc_w4 #(
|
parameter P=5,
|
parameter P=5,
|
parameter V=4
|
parameter V=4
|
|
|
|
|
)
|
)
|
(
|
(
|
ovc_avalable_all,
|
ovc_avalable_all,
|
congestion_out_all
|
congestion_out_all
|
|
|
);
|
);
|
localparam CONGw=4; //congestion width per port
|
localparam CONGw=4; //congestion width per port
|
|
|
localparam P_1 = P-1,
|
localparam P_1 = P-1,
|
PV = (V * P),
|
PV = (V * P),
|
CONG_ALw= CONGw* P,
|
CONG_ALw= CONGw* P,
|
CNT_Iw = 2*V;
|
CNT_Iw = 2*V;
|
|
|
|
|
|
|
|
|
input [PV-1 : 0] ovc_avalable_all;
|
input [PV-1 : 0] ovc_avalable_all;
|
output [CONG_ALw-1 : 0] congestion_out_all;
|
output [CONG_ALw-1 : 0] congestion_out_all;
|
|
|
|
|
|
|
|
|
/*************
|
/*************
|
N
|
N
|
Q1 | Q3
|
Q1 | Q3
|
w--------E
|
w--------E
|
Q0 | Q2
|
Q0 | Q2
|
S
|
S
|
***************/
|
***************/
|
|
|
localparam Q3 = 3,
|
localparam Q3 = 3,
|
Q1 = 1,
|
Q1 = 1,
|
Q2 = 2,
|
Q2 = 2,
|
Q0 = 0;
|
Q0 = 0;
|
|
|
localparam EAST = 0,
|
localparam EAST = 0,
|
NORTH= 1,
|
NORTH= 1,
|
WEST = 2,
|
WEST = 2,
|
SOUTH= 3;
|
SOUTH= 3;
|
|
|
|
|
|
|
|
|
|
|
wire [V-1 : 0] ovc_not_avb [P_1-1 : 0];
|
wire [V-1 : 0] ovc_not_avb [P_1-1 : 0];
|
wire [CNT_Iw-1 : 0] counter_in [P_1-1 : 0];
|
wire [CNT_Iw-1 : 0] counter_in [P_1-1 : 0];
|
wire [CONGw-1 : 0] congestion_out [P_1-1 : 0];
|
wire [CONGw-1 : 0] congestion_out [P_1-1 : 0];
|
wire [1 : 0] threshold [P_1-1 : 0];
|
wire [1 : 0] threshold [P_1-1 : 0];
|
|
|
|
|
assign {ovc_not_avb[SOUTH], ovc_not_avb[WEST], ovc_not_avb[NORTH], ovc_not_avb[EAST]}= ~ovc_avalable_all[PV-1 : V];
|
assign {ovc_not_avb[SOUTH], ovc_not_avb[WEST], ovc_not_avb[NORTH], ovc_not_avb[EAST]}= ~ovc_avalable_all[PV-1 : V];
|
|
|
assign counter_in[Q3] ={ovc_not_avb[EAST ],ovc_not_avb[NORTH]};
|
assign counter_in[Q3] ={ovc_not_avb[EAST ],ovc_not_avb[NORTH]};
|
assign counter_in[Q1] ={ovc_not_avb[NORTH],ovc_not_avb[WEST ]};
|
assign counter_in[Q1] ={ovc_not_avb[NORTH],ovc_not_avb[WEST ]};
|
assign counter_in[Q2] ={ovc_not_avb[SOUTH],ovc_not_avb[EAST ]};
|
assign counter_in[Q2] ={ovc_not_avb[SOUTH],ovc_not_avb[EAST ]};
|
assign counter_in[Q0] ={ovc_not_avb[WEST ],ovc_not_avb[SOUTH]};
|
assign counter_in[Q0] ={ovc_not_avb[WEST ],ovc_not_avb[SOUTH]};
|
|
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for (i=0;i<4;i=i+1) begin :lp
|
for (i=0;i<4;i=i+1) begin :lp
|
|
|
parallel_count_normalize #(
|
parallel_count_normalize #(
|
.INw(CNT_Iw),
|
.INw(CNT_Iw),
|
.OUTw(2)
|
.OUTw(2)
|
)
|
)
|
ovc_not_avb_cnt
|
ovc_not_avb_cnt
|
(
|
(
|
.in(counter_in[i]),
|
.in(counter_in[i]),
|
.out(threshold[i])
|
.out(threshold[i])
|
);
|
);
|
|
|
|
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
|
|
|
|
|
|
|
|
|
assign congestion_out[EAST] = {threshold[Q1],threshold[Q0]};
|
assign congestion_out[EAST] = {threshold[Q1],threshold[Q0]};
|
assign congestion_out[NORTH] = {threshold[Q0],threshold[Q2]};
|
assign congestion_out[NORTH] = {threshold[Q0],threshold[Q2]};
|
assign congestion_out[WEST] = {threshold[Q2],threshold[Q3]};
|
assign congestion_out[WEST] = {threshold[Q2],threshold[Q3]};
|
assign congestion_out[SOUTH] = {threshold[Q3],threshold[Q1]};
|
assign congestion_out[SOUTH] = {threshold[Q3],threshold[Q1]};
|
|
|
assign congestion_out_all = {congestion_out[SOUTH],congestion_out[WEST],congestion_out[NORTH],congestion_out[EAST],{CONGw{1'b0}}};
|
assign congestion_out_all = {congestion_out[SOUTH],congestion_out[WEST],congestion_out[NORTH],congestion_out[EAST],{CONGw{1'b0}}};
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
/*******************************
|
/*******************************
|
|
|
congestion based on number of
|
congestion based on number of
|
availabe ovc and not granted
|
availabe ovc and not granted
|
ivc in next router
|
ivc in next router
|
CONGESTION_INDEX==11 CONGw=2
|
CONGESTION_INDEX==11 CONGw=2
|
CONGESTION_INDEX==12 CONGw=3
|
CONGESTION_INDEX==12 CONGw=3
|
|
|
|
|
********************************/
|
********************************/
|
module congestion_out_based_avb_ovc_not_granted_ivc #(
|
module congestion_out_based_avb_ovc_not_granted_ivc #(
|
parameter P=5,
|
parameter P=5,
|
parameter V=4,
|
parameter V=4,
|
parameter CONGw=3 //congestion width per port
|
parameter CONGw=3 //congestion width per port
|
|
|
)
|
)
|
(
|
(
|
ovc_avalable_all,
|
ovc_avalable_all,
|
ivc_request_all,
|
ivc_request_all,
|
ivc_num_getting_sw_grant,
|
ivc_num_getting_sw_grant,
|
clk,
|
clk,
|
reset,
|
reset,
|
congestion_out_all
|
congestion_out_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 P_1 = P-1,
|
localparam P_1 = P-1,
|
PV = (V * P),
|
PV = (V * P),
|
CONG_ALw = CONGw* P,
|
CONG_ALw = CONGw* P,
|
CNT_Iw = 3*V,
|
CNT_Iw = 3*V,
|
CNT_Ow = log2((3*V)+1),
|
CNT_Ow = log2((3*V)+1),
|
CNG_w = log2((6*V)+1),
|
CNG_w = log2((6*V)+1),
|
CNT_Vw = log2(V+1),
|
CNT_Vw = log2(V+1),
|
EAST = 0,
|
EAST = 0,
|
NORTH = 1,
|
NORTH = 1,
|
WEST = 2,
|
WEST = 2,
|
SOUTH = 3;
|
SOUTH = 3;
|
|
|
|
|
|
|
input [PV-1 : 0] ovc_avalable_all;
|
input [PV-1 : 0] ovc_avalable_all;
|
output [CONG_ALw-1 : 0] congestion_out_all;
|
output [CONG_ALw-1 : 0] congestion_out_all;
|
input [PV-1 : 0] ivc_request_all,ivc_num_getting_sw_grant;
|
input [PV-1 : 0] ivc_request_all,ivc_num_getting_sw_grant;
|
|
|
input reset,clk;
|
input reset,clk;
|
|
|
// counting not available ovc
|
// counting not available ovc
|
wire [V-1 : 0] ovc_not_avb [P_1-1 : 0];
|
wire [V-1 : 0] ovc_not_avb [P_1-1 : 0];
|
wire [CNT_Iw-1 : 0] counter_in [P_1-1 : 0];
|
wire [CNT_Iw-1 : 0] counter_in [P_1-1 : 0];
|
wire [CNT_Ow-1 : 0] counter_o [P_1-1 : 0];
|
wire [CNT_Ow-1 : 0] counter_o [P_1-1 : 0];
|
wire [CONGw-1 : 0] congestion_out[P_1-1 : 0];
|
wire [CONGw-1 : 0] congestion_out[P_1-1 : 0];
|
|
|
assign {ovc_not_avb[SOUTH], ovc_not_avb[WEST], ovc_not_avb[NORTH], ovc_not_avb[EAST]}= ~ovc_avalable_all[PV-1 : V];
|
assign {ovc_not_avb[SOUTH], ovc_not_avb[WEST], ovc_not_avb[NORTH], ovc_not_avb[EAST]}= ~ovc_avalable_all[PV-1 : V];
|
assign counter_in[EAST] ={ovc_not_avb[NORTH],ovc_not_avb[WEST] ,ovc_not_avb[SOUTH]};
|
assign counter_in[EAST] ={ovc_not_avb[NORTH],ovc_not_avb[WEST] ,ovc_not_avb[SOUTH]};
|
assign counter_in[NORTH] ={ovc_not_avb[EAST] ,ovc_not_avb[WEST] ,ovc_not_avb[SOUTH]};
|
assign counter_in[NORTH] ={ovc_not_avb[EAST] ,ovc_not_avb[WEST] ,ovc_not_avb[SOUTH]};
|
assign counter_in[WEST] ={ovc_not_avb[EAST] ,ovc_not_avb[NORTH] ,ovc_not_avb[SOUTH]};
|
assign counter_in[WEST] ={ovc_not_avb[EAST] ,ovc_not_avb[NORTH] ,ovc_not_avb[SOUTH]};
|
assign counter_in[SOUTH] ={ovc_not_avb[EAST] ,ovc_not_avb[NORTH] ,ovc_not_avb[WEST]};
|
assign counter_in[SOUTH] ={ovc_not_avb[EAST] ,ovc_not_avb[NORTH] ,ovc_not_avb[WEST]};
|
|
|
// counting not granted requests
|
// counting not granted requests
|
reg [PV-1 : 0] ivc_request_not_granted;
|
wire [PV-1 : 0] ivc_request_not_granted;
|
wire [V-1 : 0] ivc_not_grnt [P_1-1 : 0];
|
wire [V-1 : 0] ivc_not_grnt [P_1-1 : 0];
|
wire [CNT_Vw-1 : 0] ivc_not_grnt_num [P_1-1 : 0];
|
wire [CNT_Vw-1 : 0] ivc_not_grnt_num [P_1-1 : 0];
|
|
|
`ifdef SYNC_RESET_MODE
|
|
always @ (posedge clk )begin
|
|
`else
|
|
always @ (posedge clk or posedge reset)begin
|
|
`endif
|
|
if(reset) begin
|
|
ivc_request_not_granted <= 0;
|
|
end else begin
|
|
ivc_request_not_granted <= ivc_request_all & ~(ivc_num_getting_sw_grant);
|
|
end//reset
|
|
end //always
|
|
|
|
|
pronoc_register #(
|
|
.W(PV)
|
|
) reg1 (
|
|
.in(ivc_request_all & ~ivc_num_getting_sw_grant),
|
|
.reset(reset),
|
|
.clk(clk),
|
|
.out(ivc_request_not_granted)
|
|
);
|
|
|
assign {ivc_not_grnt[SOUTH], ivc_not_grnt[WEST], ivc_not_grnt[NORTH],ivc_not_grnt[EAST]}= ivc_request_not_granted[PV-1 : V];
|
assign {ivc_not_grnt[SOUTH], ivc_not_grnt[WEST], ivc_not_grnt[NORTH],ivc_not_grnt[EAST]}= ivc_request_not_granted[PV-1 : V];
|
|
|
|
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for (i=0;i<4;i=i+1) begin :lp
|
for (i=0;i<4;i=i+1) begin :lp
|
|
|
/*
|
/*
|
parallel_counter #(
|
parallel_counter #(
|
.IN_WIDTH(CNT_Iw)
|
.IN_WIDTH(CNT_Iw)
|
)
|
)
|
ovc_counter
|
ovc_counter
|
(
|
(
|
.in(counter_in[i]),
|
.in(counter_in[i]),
|
.out(counter_o[i])
|
.out(counter_o[i])
|
);
|
);
|
*/
|
*/
|
|
|
accumulator #(
|
accumulator #(
|
.INw(CNT_Iw),
|
.INw(CNT_Iw),
|
.OUTw(CNT_Ow),
|
.OUTw(CNT_Ow),
|
.NUM(CNT_Iw)
|
.NUM(CNT_Iw)
|
)
|
)
|
ovc_counter
|
ovc_counter
|
(
|
(
|
.in_all(counter_in[i]),
|
.in_all(counter_in[i]),
|
.out(counter_o[i])
|
.out(counter_o[i])
|
);
|
);
|
|
|
|
|
|
|
/*
|
/*
|
parallel_counter #(
|
parallel_counter #(
|
.IN_WIDTH(V)
|
.IN_WIDTH(V)
|
|
|
)
|
)
|
ivc_counter
|
ivc_counter
|
(
|
(
|
.in(ivc_not_grnt[i]),
|
.in(ivc_not_grnt[i]),
|
.out(ivc_not_grnt_num[i])
|
.out(ivc_not_grnt_num[i])
|
);
|
);
|
*/
|
*/
|
|
|
|
|
accumulator #(
|
accumulator #(
|
.INw(V),
|
.INw(V),
|
.OUTw(CNT_Vw),
|
.OUTw(CNT_Vw),
|
.NUM(V)
|
.NUM(V)
|
)
|
)
|
ivc_counter
|
ivc_counter
|
(
|
(
|
.in_all(ivc_not_grnt[i]),
|
.in_all(ivc_not_grnt[i]),
|
.out(ivc_not_grnt_num[i])
|
.out(ivc_not_grnt_num[i])
|
);
|
);
|
|
|
|
|
wire [CNG_w-1 : 0] congestion_num [P_1-1 : 0];
|
wire [CNG_w-1 : 0] congestion_num [P_1-1 : 0];
|
|
|
|
|
assign congestion_num [i]= counter_o[i]+ ivc_not_grnt_num[i]+ {ivc_not_grnt_num[i],1'b0};
|
assign congestion_num [i]= counter_o[i]+ ivc_not_grnt_num[i]+ {ivc_not_grnt_num[i],1'b0};
|
|
|
normalizer #(
|
normalizer #(
|
.MAX_IN(6*V),
|
.MAX_IN(6*V),
|
.OUTw(CONGw)
|
.OUTw(CONGw)
|
|
|
)norm
|
)norm
|
(
|
(
|
.in(congestion_num [i]),
|
.in(congestion_num [i]),
|
.out(congestion_out[i])
|
.out(congestion_out[i])
|
|
|
);
|
);
|
|
|
|
|
end//for
|
end//for
|
endgenerate
|
endgenerate
|
|
|
|
|
|
|
|
|
assign congestion_out_all = {congestion_out[SOUTH],congestion_out[WEST],congestion_out[NORTH],congestion_out[EAST],{CONGw{1'b0}}};
|
assign congestion_out_all = {congestion_out[SOUTH],congestion_out[WEST],congestion_out[NORTH],congestion_out[EAST],{CONGw{1'b0}}};
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
/**********************
|
/**********************
|
|
|
parallel_count_normalize
|
parallel_count_normalize
|
|
|
**********************/
|
**********************/
|
module parallel_count_normalize #(
|
module parallel_count_normalize #(
|
parameter INw = 12,
|
parameter INw = 12,
|
parameter OUTw= 2
|
parameter OUTw= 2
|
|
|
)(
|
)(
|
in,
|
in,
|
out
|
out
|
|
|
);
|
);
|
|
|
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 [INw-1 : 0] in;
|
input [INw-1 : 0] in;
|
output [OUTw-1 : 0] out;
|
output [OUTw-1 : 0] out;
|
|
|
localparam CNTw = log2(INw+1);
|
localparam CNTw = log2(INw+1);
|
wire [CNTw-1 : 0] counter;
|
wire [CNTw-1 : 0] counter;
|
/*
|
/*
|
parallel_counter #(
|
parallel_counter #(
|
.IN_WIDTH(INw)
|
.IN_WIDTH(INw)
|
)
|
)
|
ovc_avb_cnt
|
ovc_avb_cnt
|
(
|
(
|
.in(in),
|
.in(in),
|
.out(counter)
|
.out(counter)
|
);
|
);
|
*/
|
*/
|
|
|
accumulator #(
|
accumulator #(
|
.INw(INw),
|
.INw(INw),
|
.OUTw(CNTw),
|
.OUTw(CNTw),
|
.NUM(INw)
|
.NUM(INw)
|
)
|
)
|
ovc_avb_cnt
|
ovc_avb_cnt
|
(
|
(
|
.in_all(in),
|
.in_all(in),
|
.out(counter)
|
.out(counter)
|
);
|
);
|
|
|
|
|
normalizer #(
|
normalizer #(
|
.MAX_IN(INw),
|
.MAX_IN(INw),
|
.OUTw(OUTw)
|
.OUTw(OUTw)
|
|
|
)norm
|
)norm
|
(
|
(
|
.in(counter),
|
.in(counter),
|
.out(out)
|
.out(out)
|
);
|
);
|
|
|
|
|
endmodule
|
endmodule
|
|
|
/**************
|
/**************
|
|
|
normalizer
|
normalizer
|
|
|
***************/
|
***************/
|
|
|
module normalizer #(
|
module normalizer #(
|
parameter MAX_IN= 10,
|
parameter MAX_IN= 10,
|
parameter OUTw= 2
|
parameter OUTw= 2
|
|
|
)(
|
)(
|
in,
|
in,
|
out
|
out
|
|
|
);
|
);
|
|
|
|
|
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 INw= log2(MAX_IN+1),
|
localparam INw= log2(MAX_IN+1),
|
OUT_ON_HOT_NUM = 2**OUTw;
|
OUT_ON_HOT_NUM = 2**OUTw;
|
|
|
|
|
input [INw-1 : 0] in;
|
input [INw-1 : 0] in;
|
output [OUTw-1 : 0] out;
|
output [OUTw-1 : 0] out;
|
|
|
wire [OUT_ON_HOT_NUM-1 : 0] one_hot_out;
|
wire [OUT_ON_HOT_NUM-1 : 0] one_hot_out;
|
|
|
|
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for(i=0;i< OUT_ON_HOT_NUM;i=i+1)begin :lp
|
for(i=0;i< OUT_ON_HOT_NUM;i=i+1)begin :lp
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if(i==0) begin : i0 assign one_hot_out[i]= (in<= (MAX_IN /OUT_ON_HOT_NUM)); end
|
if(i==0) begin : i0 assign one_hot_out[i]= (in<= (MAX_IN /OUT_ON_HOT_NUM)); end
|
else begin :ib0 assign one_hot_out[i]= ((in> ((MAX_IN *i)/OUT_ON_HOT_NUM)) && (in<= ((MAX_IN *(i+1))/OUT_ON_HOT_NUM))); end
|
else begin :ib0 assign one_hot_out[i]= ((in> ((MAX_IN *i)/OUT_ON_HOT_NUM)) && (in<= ((MAX_IN *(i+1))/OUT_ON_HOT_NUM))); end
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
end//for
|
end//for
|
endgenerate
|
endgenerate
|
|
|
|
|
|
|
one_hot_to_bin#(
|
one_hot_to_bin#(
|
.ONE_HOT_WIDTH(OUT_ON_HOT_NUM)
|
.ONE_HOT_WIDTH(OUT_ON_HOT_NUM)
|
)
|
)
|
conv
|
conv
|
(
|
(
|
.one_hot_code(one_hot_out),
|
.one_hot_code(one_hot_out),
|
.bin_code(out)
|
.bin_code(out)
|
);
|
);
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**************************
|
/**************************
|
|
|
|
|
congestion_out_gen
|
congestion_out_gen
|
|
|
|
|
**************************/
|
**************************/
|
|
|
|
|
|
|
|
|
module congestion_out_gen #(
|
module congestion_out_gen #(
|
parameter P=5,
|
parameter P=5,
|
parameter V=4,
|
parameter V=4,
|
parameter ROUTE_TYPE ="ADAPTIVE",
|
parameter ROUTE_TYPE ="ADAPTIVE",
|
parameter CONGESTION_INDEX=2,
|
parameter CONGESTION_INDEX=2,
|
parameter CONGw=2
|
parameter CONGw=2
|
|
|
)
|
)
|
(
|
(
|
ivc_request_all,
|
ivc_request_all,
|
ivc_num_getting_sw_grant,
|
ivc_num_getting_sw_grant,
|
ovc_avalable_all,
|
ovc_avalable_all,
|
congestion_out_all,
|
congestion_out_all,
|
clk,
|
clk,
|
reset
|
reset
|
);
|
);
|
|
|
localparam PV = P*V,
|
localparam PV = P*V,
|
CONG_ALw = CONGw* P; // congestion width per router;;
|
CONG_ALw = CONGw* P; // congestion width per router;;
|
|
|
input [PV-1 : 0] ovc_avalable_all;
|
input [PV-1 : 0] ovc_avalable_all;
|
input [PV-1 : 0] ivc_request_all;
|
input [PV-1 : 0] ivc_request_all;
|
input [PV-1 : 0] ivc_num_getting_sw_grant;
|
input [PV-1 : 0] ivc_num_getting_sw_grant;
|
output reg [CONG_ALw-1 : 0] congestion_out_all;
|
output [CONG_ALw-1 : 0] congestion_out_all;
|
input clk,reset;
|
input clk,reset;
|
|
|
wire [CONG_ALw-1 : 0] congestion_out_all_next;
|
wire [CONG_ALw-1 : 0] congestion_out_all_next;
|
generate
|
generate
|
if(ROUTE_TYPE != "DETERMINISTIC") begin :adpt
|
if(ROUTE_TYPE != "DETERMINISTIC") begin :adpt
|
if((CONGESTION_INDEX==2) || (CONGESTION_INDEX==3)) begin :based_ivc
|
if((CONGESTION_INDEX==2) || (CONGESTION_INDEX==3)) begin :based_ivc
|
congestion_out_based_ivc_req #(
|
congestion_out_based_ivc_req #(
|
.P(P),
|
.P(P),
|
.V(V),
|
.V(V),
|
.CONGw(CONGw)
|
.CONGw(CONGw)
|
)
|
)
|
the_congestion_out_gen
|
the_congestion_out_gen
|
(
|
(
|
.ivc_request_all(ivc_request_all),
|
.ivc_request_all(ivc_request_all),
|
.congestion_out_all(congestion_out_all_next)
|
.congestion_out_all(congestion_out_all_next)
|
);
|
);
|
end else if((CONGESTION_INDEX==4) || (CONGESTION_INDEX==5)) begin :based_ng_ivc
|
end else if((CONGESTION_INDEX==4) || (CONGESTION_INDEX==5)) begin :based_ng_ivc
|
|
|
congestion_out_based_ivc_notgrant #(
|
congestion_out_based_ivc_notgrant #(
|
.P(P),
|
.P(P),
|
.V(V),
|
.V(V),
|
.CONGw(CONGw)
|
.CONGw(CONGw)
|
)
|
)
|
the_congestion_out_gen
|
the_congestion_out_gen
|
(
|
(
|
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant),
|
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant),
|
.ivc_request_all(ivc_request_all),
|
.ivc_request_all(ivc_request_all),
|
.congestion_out_all(congestion_out_all_next),
|
.congestion_out_all(congestion_out_all_next),
|
.clk(clk),
|
.clk(clk),
|
.reset(reset)
|
.reset(reset)
|
);
|
);
|
|
|
end else if ((CONGESTION_INDEX==6) || (CONGESTION_INDEX==7)) begin :avb_ovc1
|
end else if ((CONGESTION_INDEX==6) || (CONGESTION_INDEX==7)) begin :avb_ovc1
|
|
|
congestion_out_based_3port_avb_ovc#(
|
congestion_out_based_3port_avb_ovc#(
|
.P(P),
|
.P(P),
|
.V(V),
|
.V(V),
|
.CONGw(CONGw)
|
.CONGw(CONGw)
|
)
|
)
|
the_congestion_out_gen
|
the_congestion_out_gen
|
(
|
(
|
.ovc_avalable_all(ovc_avalable_all),
|
.ovc_avalable_all(ovc_avalable_all),
|
.congestion_out_all(congestion_out_all_next)
|
.congestion_out_all(congestion_out_all_next)
|
);
|
);
|
|
|
|
|
end else if (CONGESTION_INDEX==8) begin :indx8
|
end else if (CONGESTION_INDEX==8) begin :indx8
|
|
|
|
|
congestion_out_based_avb_ovc_w2 #(
|
congestion_out_based_avb_ovc_w2 #(
|
.P(P),
|
.P(P),
|
.V(V)
|
.V(V)
|
)
|
)
|
the_congestion_out_gen
|
the_congestion_out_gen
|
(
|
(
|
.ovc_avalable_all(ovc_avalable_all),
|
.ovc_avalable_all(ovc_avalable_all),
|
.congestion_out_all(congestion_out_all_next)
|
.congestion_out_all(congestion_out_all_next)
|
|
|
);
|
);
|
end else if (CONGESTION_INDEX==9) begin :indx9
|
end else if (CONGESTION_INDEX==9) begin :indx9
|
|
|
congestion_out_based_avb_ovc_w3 #(
|
congestion_out_based_avb_ovc_w3 #(
|
.P(P),
|
.P(P),
|
.V(V)
|
.V(V)
|
)
|
)
|
the_congestion_out_gen
|
the_congestion_out_gen
|
(
|
(
|
.ovc_avalable_all(ovc_avalable_all),
|
.ovc_avalable_all(ovc_avalable_all),
|
.congestion_out_all(congestion_out_all_next)
|
.congestion_out_all(congestion_out_all_next)
|
|
|
);
|
);
|
end else if (CONGESTION_INDEX==10) begin :indx10
|
end else if (CONGESTION_INDEX==10) begin :indx10
|
|
|
congestion_out_based_avb_ovc_w4 #(
|
congestion_out_based_avb_ovc_w4 #(
|
.P(P),
|
.P(P),
|
.V(V)
|
.V(V)
|
)
|
)
|
the_congestion_out_gen
|
the_congestion_out_gen
|
(
|
(
|
.ovc_avalable_all(ovc_avalable_all),
|
.ovc_avalable_all(ovc_avalable_all),
|
.congestion_out_all(congestion_out_all_next)
|
.congestion_out_all(congestion_out_all_next)
|
|
|
);
|
);
|
|
|
end else if (CONGESTION_INDEX==11 || CONGESTION_INDEX==12) begin :indx11
|
end else if (CONGESTION_INDEX==11 || CONGESTION_INDEX==12) begin :indx11
|
|
|
congestion_out_based_avb_ovc_not_granted_ivc #(
|
congestion_out_based_avb_ovc_not_granted_ivc #(
|
.P(P),
|
.P(P),
|
.V(V),
|
.V(V),
|
.CONGw(CONGw) //congestion width per port
|
.CONGw(CONGw) //congestion width per port
|
)
|
)
|
the_congestion_out_gen
|
the_congestion_out_gen
|
(
|
(
|
.ovc_avalable_all(ovc_avalable_all),
|
.ovc_avalable_all(ovc_avalable_all),
|
.ivc_request_all(ivc_request_all),
|
.ivc_request_all(ivc_request_all),
|
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant),
|
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant),
|
.clk(clk),
|
.clk(clk),
|
.reset(reset),
|
.reset(reset),
|
.congestion_out_all(congestion_out_all_next)
|
.congestion_out_all(congestion_out_all_next)
|
);
|
);
|
|
|
|
|
end else begin :nocong assign congestion_out_all_next = {CONG_ALw{1'bx}}; end
|
end else begin :nocong assign congestion_out_all_next = {CONG_ALw{1'bx}}; end
|
|
|
|
|
end else begin :dtrmn
|
end else begin :dtrmn
|
assign congestion_out_all_next = {CONG_ALw{1'bx}};
|
assign congestion_out_all_next = {CONG_ALw{1'bx}};
|
|
|
end
|
end
|
|
|
endgenerate
|
endgenerate
|
|
|
`ifdef SYNC_RESET_MODE
|
|
always @ (posedge clk )begin
|
|
`else
|
|
always @ (posedge clk or posedge reset)begin
|
|
`endif
|
|
if(reset)begin
|
|
congestion_out_all <= {CONG_ALw{1'b0}};
|
|
end else begin
|
|
congestion_out_all <= congestion_out_all_next;
|
|
|
|
end
|
pronoc_register #(
|
end //always
|
.W(CONG_ALw)
|
|
) reg1 (
|
|
.in(congestion_out_all_next),
|
|
.reset(reset),
|
|
.clk(clk),
|
|
.out(congestion_out_all)
|
|
);
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
/*************************
|
/*************************
|
|
|
deadlock_detector
|
deadlock_detector
|
|
|
**************************/
|
**************************/
|
|
|
module deadlock_detector #(
|
module deadlock_detector #(
|
parameter P=5,
|
parameter P=5,
|
parameter V=4,
|
parameter V=4,
|
parameter MAX_CLK = 16
|
parameter MAX_CLK = 16
|
|
|
)(
|
)(
|
ivc_num_getting_sw_grant,
|
ivc_num_getting_sw_grant,
|
ivc_request_all,
|
ivc_request_all,
|
reset,
|
reset,
|
clk,
|
clk,
|
detect
|
detect
|
|
|
);
|
);
|
|
|
|
|
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 PV = P*V,
|
localparam PV = P*V,
|
CNTw = log2(MAX_CLK);
|
CNTw = log2(MAX_CLK);
|
|
|
|
|
input [PV-1 : 0] ivc_num_getting_sw_grant, ivc_request_all;
|
input [PV-1 : 0] ivc_num_getting_sw_grant, ivc_request_all;
|
input reset,clk;
|
input reset,clk;
|
output detect;
|
output detect;
|
|
|
reg [CNTw-1 : 0] counter [V-1 : 0];
|
wire [CNTw-1 : 0] counter [V-1 : 0];
|
|
reg [CNTw-1 : 0] counter_next [V-1 : 0];
|
wire [P-1 : 0] counter_rst_gen [V-1 : 0];
|
wire [P-1 : 0] counter_rst_gen [V-1 : 0];
|
wire [P-1 : 0] counter_en_gen [V-1 : 0];
|
wire [P-1 : 0] counter_en_gen [V-1 : 0];
|
wire [V-1 : 0] counter_rst,counter_en,detect_gen;
|
wire [V-1 : 0] counter_rst,counter_en,detect_gen;
|
reg [PV-1 : 0] ivc_num_getting_sw_grant_reg;
|
wire [PV-1 : 0] ivc_num_getting_sw_grant_reg;
|
|
|
|
|
|
pronoc_register #(
|
|
.W(PV)
|
|
) reg1 (
|
|
.in(ivc_num_getting_sw_grant),
|
|
.reset(reset),
|
|
.clk(clk),
|
|
.out(ivc_num_getting_sw_grant_reg)
|
|
);
|
|
|
|
|
`ifdef SYNC_RESET_MODE
|
|
always @ (posedge clk )begin
|
|
`else
|
|
always @ (posedge clk or posedge reset)begin
|
|
`endif
|
|
|
|
if(reset) begin
|
|
ivc_num_getting_sw_grant_reg <= {PV{1'b0}};
|
|
end else begin
|
|
ivc_num_getting_sw_grant_reg <= ivc_num_getting_sw_grant;
|
|
end
|
|
end
|
|
|
|
//seperate all same virtual chanels requests
|
//seperate all same virtual chanels requests
|
genvar i,j;
|
genvar i,j;
|
generate
|
generate
|
for (i=0;i<V;i=i+1)begin:v_loop
|
for (i=0;i<V;i=i+1)begin:v_loop
|
for (j=0;j<P;j=j+1)begin :p_loop
|
for (j=0;j<P;j=j+1)begin :p_loop
|
assign counter_rst_gen[i][j]=ivc_num_getting_sw_grant_reg[j*V+i];
|
assign counter_rst_gen[i][j]=ivc_num_getting_sw_grant_reg[j*V+i];
|
assign counter_en_gen [i][j]=ivc_request_all[j*V+i];
|
assign counter_en_gen [i][j]=ivc_request_all[j*V+i];
|
end//j
|
end//j
|
//sum all signals belong to the same VC
|
//sum all signals belong to the same VC
|
assign counter_rst[i] =|counter_rst_gen[i];
|
assign counter_rst[i] =|counter_rst_gen[i];
|
assign counter_en[i] =|counter_en_gen [i];
|
assign counter_en[i] =|counter_en_gen [i];
|
// generate the counter
|
// generate the counter
|
`ifdef SYNC_RESET_MODE
|
|
always @ (posedge clk )begin
|
|
`else
|
|
always @ (posedge clk or posedge reset)begin
|
|
`endif
|
|
if(reset) begin
|
|
counter[i]<={CNTw{1'b0}};
|
|
end else begin
|
|
if(counter_rst[i]) counter[i]<={CNTw{1'b0}};
|
|
else if(counter_en[i]) counter[i]<=counter[i]+1'b1;
|
|
end//reset
|
|
end//always
|
|
// check counters value to detect deadlock
|
|
assign detect_gen[i]= (counter[i]== MAX_CLK-1);
|
|
|
|
end//i
|
|
|
|
assign detect=|detect_gen;
|
always @ (*) begin
|
|
counter_next[i] = counter[i];
|
|
if(counter_rst[i]) counter_next[i] = {CNTw{1'b0}};
|
|
else if(counter_en[i]) counter_next[i] = counter[i]+1'b1;
|
|
end//always
|
|
|
|
|
|
pronoc_register #(
|
|
.W(CNTw)
|
|
) reg2 (
|
|
.in(counter_next[i]),
|
|
.reset(reset),
|
|
.clk(clk),
|
|
.out(counter[i])
|
|
);
|
|
|
|
// check counters value to detect deadlock
|
|
assign detect_gen[i]= (counter[i]== MAX_CLK-1);
|
|
|
|
end//i
|
endgenerate
|
endgenerate
|
|
|
|
assign detect=|detect_gen;
|
|
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|