`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
|
|
/**********************************************************************
|
/**********************************************************************
|
** File: wrra.v
|
** File: wrra.v
|
** Date:2017-07-11
|
** Date:2017-07-11
|
**
|
**
|
** 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:
|
** Weighted round robin arbiter support for QoS support in NoC:
|
** Weighted round robin arbiter support for QoS support in NoC:
|
** Packets are injected with initial weights. The defualt value is 1.
|
** Packets are injected with initial weights. The defualt value is 1.
|
** Weights are assigned to each input ports according to contention degree.
|
** Weights are assigned to each input ports according to contention degree.
|
** The contention degree is calculated based on the accumulation of input ports
|
** The contention degree is calculated based on the accumulation of input ports
|
** weight sending packet to the same output ports.
|
** weight sending packet to the same output ports.
|
** Swich allocator's output arbters' priority is lucked until the winner's
|
** Swich allocator's output arbters' priority is lucked until the winner's
|
** input weight is not consumed. A weight is consumed when a packet is sent.
|
** input weight is not consumed. A weight is consumed when a packet is sent.
|
**
|
**
|
** PROPOGATE_EQUALL = (WRRA_CONFIG_INDEX==0 );
|
** PROPOGATE_EQUALL = (WRRA_CONFIG_INDEX==0 );
|
** PROPOGATE_LIMITED = (WRRA_CONFIG_INDEX==1 );
|
** PROPOGATE_LIMITED = (WRRA_CONFIG_INDEX==1 );
|
** PROPOGATE_NEQ1 = (WRRA_CONFIG_INDEX==2 );
|
** PROPOGATE_NEQ1 = (WRRA_CONFIG_INDEX==2 );
|
** PROPOGATE_NEQ2 = (WRRA_CONFIG_INDEX==3 );
|
** PROPOGATE_NEQ2 = (WRRA_CONFIG_INDEX==3 );
|
*****************************************************************/
|
*****************************************************************/
|
|
|
`include "pronoc_def.v"
|
`include "pronoc_def.v"
|
|
|
module wrra #(
|
module wrra #(
|
parameter ARBITER_WIDTH = 8,
|
parameter ARBITER_WIDTH = 8,
|
parameter WEIGHTw = 4, // maximum weight size in bits
|
parameter WEIGHTw = 4, // maximum weight size in bits
|
parameter EXT_P_EN = 1
|
parameter EXT_P_EN = 1
|
|
|
)
|
)
|
(
|
(
|
|
|
ext_pr_en_i,
|
ext_pr_en_i,
|
clk,
|
clk,
|
reset,
|
reset,
|
request,
|
request,
|
grant,
|
grant,
|
any_grant,
|
any_grant,
|
weight_array,
|
weight_array,
|
winner_weight_consumed
|
winner_weight_consumed
|
);
|
);
|
|
|
localparam WEIGHT_ARRAYw= WEIGHTw * ARBITER_WIDTH;
|
localparam WEIGHT_ARRAYw= WEIGHTw * ARBITER_WIDTH;
|
|
|
input ext_pr_en_i;
|
input ext_pr_en_i;
|
input [ARBITER_WIDTH-1 : 0] request;
|
input [ARBITER_WIDTH-1 : 0] request;
|
output [ARBITER_WIDTH-1 : 0] grant;
|
output [ARBITER_WIDTH-1 : 0] grant;
|
output any_grant;
|
output any_grant;
|
input clk;
|
input clk;
|
input reset;
|
input reset;
|
input [WEIGHT_ARRAYw-1 : 0] weight_array;
|
input [WEIGHT_ARRAYw-1 : 0] weight_array;
|
output winner_weight_consumed;
|
output winner_weight_consumed;
|
|
|
|
|
wire [WEIGHTw-1 : 0] weight [ARBITER_WIDTH-1 : 0];
|
wire [WEIGHTw-1 : 0] weight [ARBITER_WIDTH-1 : 0];
|
wire [ARBITER_WIDTH-1: 0] weight_counter_is_reset;
|
wire [ARBITER_WIDTH-1: 0] weight_counter_is_reset;
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for (i=0; i<ARBITER_WIDTH; i=i+1) begin : wcount
|
for (i=0; i<ARBITER_WIDTH; i=i+1) begin : wcount
|
// seperate wieghts
|
// seperate wieghts
|
assign weight [i] = weight_array [ ((i+1)*WEIGHTw)-1 : i*WEIGHTw];
|
assign weight [i] = weight_array [ ((i+1)*WEIGHTw)-1 : i*WEIGHTw];
|
|
|
weight_counter #(
|
weight_counter #(
|
.WEIGHTw(WEIGHTw)
|
.WEIGHTw(WEIGHTw)
|
)
|
)
|
w_counter
|
w_counter
|
(
|
(
|
.load_i(1'b0),
|
.load_i(1'b0),
|
.weight_i(weight [i]),
|
.weight_i(weight [i]),
|
.reset(reset),
|
.reset(reset),
|
.clk(clk),
|
.clk(clk),
|
.decr(grant[i]),
|
.decr(grant[i]),
|
.out(weight_counter_is_reset[i])
|
.out(weight_counter_is_reset[i])
|
);
|
);
|
|
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
|
|
|
// one hot mux
|
// one hot mux
|
|
|
onehot_mux_1D #(
|
onehot_mux_1D #(
|
.W(1),
|
.W(1),
|
.N(ARBITER_WIDTH)
|
.N(ARBITER_WIDTH)
|
)
|
)
|
mux
|
mux
|
(
|
(
|
.in(weight_counter_is_reset),
|
.in(weight_counter_is_reset),
|
.out(winner_weight_consumed),
|
.out(winner_weight_consumed),
|
.sel(grant)
|
.sel(grant)
|
);
|
);
|
|
|
wire priority_en = (EXT_P_EN == 1) ? ext_pr_en_i & winner_weight_consumed : winner_weight_consumed;
|
wire priority_en = (EXT_P_EN == 1) ? ext_pr_en_i & winner_weight_consumed : winner_weight_consumed;
|
|
|
//round robin arbiter with external priority
|
//round robin arbiter with external priority
|
|
|
arbiter_priority_en #(
|
arbiter_priority_en #(
|
.ARBITER_WIDTH(ARBITER_WIDTH)
|
.ARBITER_WIDTH(ARBITER_WIDTH)
|
)
|
)
|
rra
|
rra
|
(
|
(
|
.request(request),
|
.request(request),
|
.grant(grant),
|
.grant(grant),
|
.any_grant(any_grant),
|
.any_grant(any_grant),
|
.clk(clk),
|
.clk(clk),
|
.reset(reset),
|
.reset(reset),
|
.priority_en(priority_en)
|
.priority_en(priority_en)
|
);
|
);
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|
module rra_priority_lock #(
|
module rra_priority_lock #(
|
parameter ARBITER_WIDTH =8
|
parameter ARBITER_WIDTH =8
|
)
|
)
|
(
|
(
|
|
|
ext_pr_en_i,
|
ext_pr_en_i,
|
winner_weight_consumed,
|
winner_weight_consumed,
|
pr_en_array_i,
|
pr_en_array_i,
|
|
|
clk,
|
clk,
|
reset,
|
reset,
|
|
|
request,
|
request,
|
grant,
|
grant,
|
any_grant
|
any_grant
|
);
|
);
|
|
|
|
|
input [ARBITER_WIDTH-1: 0] pr_en_array_i;
|
input [ARBITER_WIDTH-1: 0] pr_en_array_i;
|
input ext_pr_en_i;
|
input ext_pr_en_i;
|
output winner_weight_consumed;
|
output winner_weight_consumed;
|
input [ARBITER_WIDTH-1 : 0] request;
|
input [ARBITER_WIDTH-1 : 0] request;
|
output [ARBITER_WIDTH-1 : 0] grant;
|
output [ARBITER_WIDTH-1 : 0] grant;
|
output any_grant;
|
output any_grant;
|
input clk;
|
input clk;
|
input reset;
|
input reset;
|
|
|
|
|
// one hot mux
|
// one hot mux
|
|
|
onehot_mux_1D #(
|
onehot_mux_1D #(
|
.W(1),
|
.W(1),
|
.N(ARBITER_WIDTH)
|
.N(ARBITER_WIDTH)
|
)
|
)
|
mux
|
mux
|
(
|
(
|
.in(pr_en_array_i),
|
.in(pr_en_array_i),
|
.out(winner_weight_consumed),
|
.out(winner_weight_consumed),
|
.sel(grant)
|
.sel(grant)
|
);
|
);
|
|
|
wire priority_en = ext_pr_en_i & winner_weight_consumed;
|
wire priority_en = ext_pr_en_i & winner_weight_consumed;
|
|
|
//round robin arbiter with external priority
|
//round robin arbiter with external priority
|
|
|
arbiter_priority_en #(
|
arbiter_priority_en #(
|
.ARBITER_WIDTH(ARBITER_WIDTH)
|
.ARBITER_WIDTH(ARBITER_WIDTH)
|
)
|
)
|
rra
|
rra
|
(
|
(
|
.request(request),
|
.request(request),
|
.grant(grant),
|
.grant(grant),
|
.any_grant(any_grant),
|
.any_grant(any_grant),
|
.clk(clk),
|
.clk(clk),
|
.reset(reset),
|
.reset(reset),
|
.priority_en(priority_en)
|
.priority_en(priority_en)
|
);
|
);
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
/**************
|
/**************
|
* weight_counter
|
* weight_counter
|
*
|
*
|
***************/
|
***************/
|
|
|
|
|
module weight_counter #(
|
module weight_counter #(
|
parameter WEIGHTw=4
|
parameter WEIGHTw=4
|
)(
|
)(
|
|
|
weight_i,
|
weight_i,
|
decr,
|
decr,
|
load_i,
|
load_i,
|
out,
|
out,
|
reset,
|
reset,
|
clk
|
clk
|
|
|
);
|
);
|
|
|
input [WEIGHTw-1 : 0] weight_i;
|
input [WEIGHTw-1 : 0] weight_i;
|
input reset,clk,decr,load_i;
|
input reset,clk,decr,load_i;
|
output out;
|
output out;
|
wire [WEIGHTw-1 : 0] weight;
|
wire [WEIGHTw-1 : 0] weight;
|
|
|
reg [WEIGHTw-1 : 0] counter_next;
|
reg [WEIGHTw-1 : 0] counter_next;
|
wire [WEIGHTw-1 : 0] counter;
|
wire [WEIGHTw-1 : 0] counter;
|
wire couner_zero, load;
|
wire couner_zero, load;
|
|
|
assign couner_zero = counter == {WEIGHTw{1'b0}};
|
assign couner_zero = counter == {WEIGHTw{1'b0}};
|
assign load = (counter > weight_i) | load_i;
|
assign load = (counter > weight_i) | load_i;
|
assign out = couner_zero;
|
assign out = couner_zero;
|
assign weight= (weight_i == {WEIGHTw{1'b0}} )? 1 : weight_i; // minimum weight is 1;
|
assign weight= (weight_i == {WEIGHTw{1'b0}} )? 1 : weight_i; // minimum weight is 1;
|
always @(*)begin
|
always @(*)begin
|
counter_next = counter;
|
counter_next = counter;
|
if(load) counter_next = weight- 1'b1 ;
|
if(load) counter_next = weight- 1'b1 ;
|
if(decr) counter_next = (couner_zero)? weight-1'b1 : counter - 1'b1; // if the couner has zero value then the load is active not decrese
|
if(decr) counter_next = (couner_zero)? weight-1'b1 : counter - 1'b1; // if the couner has zero value then the load is active not decrese
|
|
|
end
|
end
|
|
|
pronoc_register #(.W(WEIGHTw)) reg2 (.in(counter_next ), .out(counter), .reset(reset), .clk(clk));
|
pronoc_register #(.W(WEIGHTw)) reg2 (.in(counter_next ), .out(counter), .reset(reset), .clk(clk));
|
|
|
|
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
/**************
|
/**************
|
* weight_counter
|
* weight_counter
|
*
|
*
|
***************/
|
***************/
|
|
|
|
|
module classic_weight_counter #(
|
module classic_weight_counter #(
|
parameter WEIGHTw=4
|
parameter WEIGHTw=4
|
)(
|
)(
|
|
|
weight_i,
|
weight_i,
|
decr,
|
decr,
|
load_i,
|
load_i,
|
out,
|
out,
|
reset,
|
reset,
|
clk
|
clk
|
|
|
);
|
);
|
|
|
input [WEIGHTw-1 : 0] weight_i;
|
input [WEIGHTw-1 : 0] weight_i;
|
input reset,clk,decr,load_i;
|
input reset,clk,decr,load_i;
|
output out;
|
output out;
|
wire [WEIGHTw-1 : 0] weight;
|
wire [WEIGHTw-1 : 0] weight;
|
|
|
reg [WEIGHTw-1 : 0] counter_next;
|
reg [WEIGHTw-1 : 0] counter_next;
|
wire [WEIGHTw-1 : 0] counter;
|
wire [WEIGHTw-1 : 0] counter;
|
wire couner_zero, load;
|
wire couner_zero, load;
|
|
|
assign couner_zero = counter == {WEIGHTw{1'b0}};
|
assign couner_zero = counter == {WEIGHTw{1'b0}};
|
assign load = (counter > weight_i) | load_i;
|
assign load = (counter > weight_i) | load_i;
|
assign out = couner_zero;
|
assign out = couner_zero;
|
assign weight= (weight_i == {WEIGHTw{1'b0}} )? 1 : weight_i; // minimum weight is 1;
|
assign weight= (weight_i == {WEIGHTw{1'b0}} )? 1 : weight_i; // minimum weight is 1;
|
always @(*)begin
|
always @(*)begin
|
counter_next = counter;
|
counter_next = counter;
|
if(load) counter_next = weight- 1'b1 ;
|
if(load) counter_next = weight- 1'b1 ;
|
if(decr && !couner_zero) counter_next = counter - 1'b1; // if the couner has zero value then the load is active not decrese
|
if(decr && !couner_zero) counter_next = counter - 1'b1; // if the couner has zero value then the load is active not decrese
|
|
|
end
|
end
|
|
|
pronoc_register #(.W(WEIGHTw)) reg2 (.in(counter_next ), .out(counter), .reset(reset), .clk(clk));
|
pronoc_register #(.W(WEIGHTw)) reg2 (.in(counter_next ), .out(counter), .reset(reset), .clk(clk));
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
/***************
|
/***************
|
* weight_control
|
* weight_control
|
***************/
|
***************/
|
|
|
|
|
module weight_control #(
|
module weight_control #(
|
parameter ARBITER_TYPE="WRRA",
|
parameter ARBITER_TYPE="WRRA",
|
parameter SW_LOC=0,
|
parameter SW_LOC=0,
|
parameter WEIGHTw= 4,
|
parameter WEIGHTw= 4,
|
parameter WRRA_CONFIG_INDEX=0,
|
parameter WRRA_CONFIG_INDEX=0,
|
parameter P=5,
|
parameter P=5,
|
parameter SELF_LOOP_EN = "NO"
|
parameter SELF_LOOP_EN = "NO"
|
)
|
)
|
(
|
(
|
|
|
sw_is_granted,
|
sw_is_granted,
|
flit_is_tail,
|
flit_is_tail,
|
iport_weight,
|
iport_weight,
|
granted_dest_port,
|
granted_dest_port,
|
weight_is_consumed_o,
|
weight_is_consumed_o,
|
oports_weight,
|
oports_weight,
|
refresh_w_counter,
|
refresh_w_counter,
|
clk,
|
clk,
|
reset
|
reset
|
);
|
);
|
|
|
localparam
|
localparam
|
W = WEIGHTw,
|
W = WEIGHTw,
|
WP = W * P,
|
WP = W * P,
|
P_1 = (SELF_LOOP_EN=="NO") ? P-1 : P;
|
P_1 = (SELF_LOOP_EN=="NO") ? P-1 : P;
|
|
|
localparam [W-1 : 0] INIT_WEIGHT = 1;
|
localparam [W-1 : 0] INIT_WEIGHT = 1;
|
localparam [W-1 : 0] MAX_WEIGHT = {W{1'b1}}-1'b1;
|
localparam [W-1 : 0] MAX_WEIGHT = {W{1'b1}}-1'b1;
|
|
|
localparam PROPOGATE_EQUALL = (WRRA_CONFIG_INDEX==0 ),
|
localparam PROPOGATE_EQUALL = (WRRA_CONFIG_INDEX==0 ),
|
PROPOGATE_LIMITED = (WRRA_CONFIG_INDEX==1 ),
|
PROPOGATE_LIMITED = (WRRA_CONFIG_INDEX==1 ),
|
PROPOGATE_NEQ1 = (WRRA_CONFIG_INDEX==2 ),
|
PROPOGATE_NEQ1 = (WRRA_CONFIG_INDEX==2 ),
|
PROPOGATE_NEQ2 = (WRRA_CONFIG_INDEX==3 );
|
PROPOGATE_NEQ2 = (WRRA_CONFIG_INDEX==3 );
|
|
|
input sw_is_granted , flit_is_tail;
|
input sw_is_granted , flit_is_tail;
|
input [WEIGHTw-1 : 0] iport_weight;
|
input [WEIGHTw-1 : 0] iport_weight;
|
input clk,reset;
|
input clk,reset;
|
output weight_is_consumed_o;
|
output weight_is_consumed_o;
|
input [P_1-1 : 0] granted_dest_port;
|
input [P_1-1 : 0] granted_dest_port;
|
output [WP-1 : 0] oports_weight;
|
output [WP-1 : 0] oports_weight;
|
input refresh_w_counter;
|
input refresh_w_counter;
|
|
|
// wire ivc_empty = ~ivc_not_empty;
|
// wire ivc_empty = ~ivc_not_empty;
|
wire counter_is_reset;
|
wire counter_is_reset;
|
wire weight_dcrease_en = sw_is_granted & flit_is_tail;
|
wire weight_dcrease_en = sw_is_granted & flit_is_tail;
|
wire [P-1 : 0] dest_port;
|
wire [P-1 : 0] dest_port;
|
reg [W-1 : 0] oport_weight_counter [P-1 : 0];
|
reg [W-1 : 0] oport_weight_counter [P-1 : 0];
|
reg [W-1 : 0] oport_weight [P-1 : 0];
|
reg [W-1 : 0] oport_weight [P-1 : 0];
|
|
|
generate
|
generate
|
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(SW_LOC)
|
.SW_LOC(SW_LOC)
|
)
|
)
|
add_sw_loc
|
add_sw_loc
|
(
|
(
|
.destport_in(granted_dest_port),
|
.destport_in(granted_dest_port),
|
.destport_out(dest_port)
|
.destport_out(dest_port)
|
);
|
);
|
end else begin : slp
|
end else begin : slp
|
assign dest_port = granted_dest_port;
|
assign dest_port = granted_dest_port;
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
assign oports_weight [W-1 : 0] = {W{1'b0}};
|
assign oports_weight [W-1 : 0] = {W{1'b0}};
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
|
|
|
|
if(PROPOGATE_EQUALL | PROPOGATE_LIMITED )begin : eq
|
if(PROPOGATE_EQUALL | PROPOGATE_LIMITED )begin : eq
|
|
|
for (i=1;i<P;i=i+1)begin : port
|
for (i=1;i<P;i=i+1)begin : port
|
if(i==SW_LOC) begin : if1
|
if(i==SW_LOC) begin : if1
|
assign oports_weight [(i+1)*W-1 : i*W] = {W{1'b0}};
|
assign oports_weight [(i+1)*W-1 : i*W] = {W{1'b0}};
|
end else begin :else1
|
end else begin :else1
|
assign oports_weight[(i+1)*W-1 : i*W] = iport_weight;
|
assign oports_weight[(i+1)*W-1 : i*W] = iport_weight;
|
end
|
end
|
end //for
|
end //for
|
|
|
end else if (PROPOGATE_NEQ1) begin :neq1
|
end else if (PROPOGATE_NEQ1) begin :neq1
|
|
|
always @(*)begin
|
always @(*)begin
|
oport_weight_counter[0]= {W{1'b0}};// the output port weight of local port is useless. hence fix it as zero.
|
oport_weight_counter[0]= {W{1'b0}};// the output port weight of local port is useless. hence fix it as zero.
|
oport_weight[0]= {W{1'b0}};
|
oport_weight[0]= {W{1'b0}};
|
end
|
end
|
|
|
|
|
for (i=1;i<P;i=i+1)begin : port
|
for (i=1;i<P;i=i+1)begin : port
|
if(i==SW_LOC) begin : if1
|
if(i==SW_LOC) begin : if1
|
|
|
always @(*) begin
|
always @(*) begin
|
oport_weight_counter[i]= {W{1'b0}};// The loopback injection is forbiden hence it will be always as zero.
|
oport_weight_counter[i]= {W{1'b0}};// The loopback injection is forbiden hence it will be always as zero.
|
oport_weight[i]= {W{1'b0}};
|
oport_weight[i]= {W{1'b0}};
|
end
|
end
|
assign oports_weight [(i+1)*W-1 : i*W] = {W{1'b0}};
|
assign oports_weight [(i+1)*W-1 : i*W] = {W{1'b0}};
|
end else begin :else1
|
end else begin :else1
|
|
|
|
|
always @ (`pronoc_clk_reset_edge )begin
|
always @ (`pronoc_clk_reset_edge )begin
|
if(`pronoc_reset) begin
|
if(`pronoc_reset) begin
|
oport_weight_counter[i]<=INIT_WEIGHT;
|
oport_weight_counter[i]<=INIT_WEIGHT;
|
end else begin
|
end else begin
|
if (weight_dcrease_en && counter_is_reset) oport_weight_counter[i]<= INIT_WEIGHT;
|
if (weight_dcrease_en && counter_is_reset) oport_weight_counter[i]<= INIT_WEIGHT;
|
else if (weight_dcrease_en && dest_port[i] && oport_weight_counter[i] != {W{1'b1}} )oport_weight_counter[i]<= oport_weight_counter[i] +1'b1;
|
else if (weight_dcrease_en && dest_port[i] && oport_weight_counter[i] != {W{1'b1}} )oport_weight_counter[i]<= oport_weight_counter[i] +1'b1;
|
end
|
end
|
end //always
|
end //always
|
|
|
always @ (`pronoc_clk_reset_edge )begin
|
always @ (`pronoc_clk_reset_edge )begin
|
if(`pronoc_reset) begin
|
if(`pronoc_reset) begin
|
oport_weight[i]<={W{1'b0}};
|
oport_weight[i]<={W{1'b0}};
|
end else begin
|
end else begin
|
if (weight_dcrease_en && counter_is_reset) oport_weight[i]<= oport_weight_counter[i]; //capture oweight counters
|
if (weight_dcrease_en && counter_is_reset) oport_weight[i]<= oport_weight_counter[i]; //capture oweight counters
|
end
|
end
|
end //always
|
end //always
|
assign oports_weight [(i+1)*W-1 : i*W] = oport_weight[i];
|
assign oports_weight [(i+1)*W-1 : i*W] = oport_weight[i];
|
end //else
|
end //else
|
|
|
|
|
|
|
end //for
|
end //for
|
|
|
|
|
end else begin : neq2 //if (PROPOGATE_NEQ1) :neq1
|
end else begin : neq2 //if (PROPOGATE_NEQ1) :neq1
|
|
|
|
|
|
|
for (i=0;i<P;i=i+1)begin : port
|
for (i=0;i<P;i=i+1)begin : port
|
if(i==0) begin : local_p
|
if(i==0) begin : local_p
|
always @ (posedge clk)begin
|
always @ (posedge clk)begin
|
oport_weight_counter[i]<= {W{1'b0}};// the output port weight of local port is useless. hence fix it as zero.
|
oport_weight_counter[i]<= {W{1'b0}};// the output port weight of local port is useless. hence fix it as zero.
|
oport_weight[i]<= {W{1'b0}};
|
oport_weight[i]<= {W{1'b0}};
|
end//always
|
end//always
|
end//local_p
|
end//local_p
|
|
|
else if(i==SW_LOC) begin : if1
|
else if(i==SW_LOC) begin : if1
|
|
|
always @ (posedge clk)begin
|
always @ (posedge clk)begin
|
oport_weight_counter[i]<= {W{1'b0}};// The loopback injection is forbiden hence it will be always as zero.
|
oport_weight_counter[i]<= {W{1'b0}};// The loopback injection is forbiden hence it will be always as zero.
|
oport_weight[i]<= {W{1'b0}};
|
oport_weight[i]<= {W{1'b0}};
|
end
|
end
|
assign oports_weight [(i+1)*W-1 : i*W] = {W{1'b0}};
|
assign oports_weight [(i+1)*W-1 : i*W] = {W{1'b0}};
|
end else begin :else1
|
end else begin :else1
|
|
|
always @ (`pronoc_clk_reset_edge )begin
|
always @ (`pronoc_clk_reset_edge )begin
|
if(`pronoc_reset) begin
|
if(`pronoc_reset) begin
|
oport_weight_counter[i]<= INIT_WEIGHT;
|
oport_weight_counter[i]<= INIT_WEIGHT;
|
end else begin
|
end else begin
|
if (weight_dcrease_en && counter_is_reset) oport_weight_counter[i]<= INIT_WEIGHT;
|
if (weight_dcrease_en && counter_is_reset) oport_weight_counter[i]<= INIT_WEIGHT;
|
else if (weight_dcrease_en && dest_port[i] && oport_weight_counter[i] <MAX_WEIGHT )oport_weight_counter[i]<= oport_weight_counter[i] +1'b1;
|
else if (weight_dcrease_en && dest_port[i] && oport_weight_counter[i] <MAX_WEIGHT )oport_weight_counter[i]<= oport_weight_counter[i] +1'b1;
|
end
|
end
|
end //always
|
end //always
|
|
|
always @ (`pronoc_clk_reset_edge )begin
|
always @ (`pronoc_clk_reset_edge )begin
|
if(`pronoc_reset) begin
|
if(`pronoc_reset) begin
|
oport_weight[i]<={W{1'b0}};
|
oport_weight[i]<={W{1'b0}};
|
end else begin
|
end else begin
|
if(oport_weight[i]>iport_weight) oport_weight[i]<=iport_weight;// weight counter should always be smaller than iport weight
|
if(oport_weight[i]>iport_weight) oport_weight[i]<=iport_weight;// weight counter should always be smaller than iport weight
|
else if (weight_dcrease_en)begin
|
else if (weight_dcrease_en)begin
|
if( counter_is_reset ) begin
|
if( counter_is_reset ) begin
|
oport_weight[i]<= (oport_weight_counter[i]>0)? oport_weight_counter[i]: 1;
|
oport_weight[i]<= (oport_weight_counter[i]>0)? oport_weight_counter[i]: 1;
|
end//counter_reset
|
end//counter_reset
|
else begin
|
else begin
|
if (oport_weight_counter[i]>0 && oport_weight[i] < oport_weight_counter[i]) oport_weight[i]<= oport_weight_counter[i];
|
if (oport_weight_counter[i]>0 && oport_weight[i] < oport_weight_counter[i]) oport_weight[i]<= oport_weight_counter[i];
|
end
|
end
|
end//weight_dcr
|
end//weight_dcr
|
end//else reset
|
end//else reset
|
end //always
|
end //always
|
|
|
assign oports_weight [(i+1)*W-1 : i*W] = oport_weight[i];
|
assign oports_weight [(i+1)*W-1 : i*W] = oport_weight[i];
|
end //else
|
end //else
|
|
|
end //for
|
end //for
|
|
|
end
|
end
|
|
|
|
|
|
|
|
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if(ARBITER_TYPE == "WRRA_CLASSIC") begin : wrra_classic
|
if(ARBITER_TYPE == "WRRA_CLASSIC") begin : wrra_classic
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
// use classic WRRA. only for compasrion with propsoed wrra
|
// use classic WRRA. only for compasrion with propsoed wrra
|
|
|
classic_weight_counter #(
|
classic_weight_counter #(
|
.WEIGHTw(WEIGHTw)
|
.WEIGHTw(WEIGHTw)
|
)
|
)
|
iport_weight_counter
|
iport_weight_counter
|
(
|
(
|
.load_i(refresh_w_counter),
|
.load_i(refresh_w_counter),
|
.weight_i(iport_weight),
|
.weight_i(iport_weight),
|
.reset(reset),
|
.reset(reset),
|
.clk(clk),
|
.clk(clk),
|
.decr(weight_dcrease_en),
|
.decr(weight_dcrease_en),
|
.out(counter_is_reset)
|
.out(counter_is_reset)
|
);
|
);
|
|
|
end else begin : wrra_mine
|
end else begin : wrra_mine
|
// weight counters
|
// weight counters
|
weight_counter #(
|
weight_counter #(
|
.WEIGHTw(WEIGHTw)
|
.WEIGHTw(WEIGHTw)
|
)
|
)
|
iport_weight_counter
|
iport_weight_counter
|
(
|
(
|
.load_i(refresh_w_counter),
|
.load_i(refresh_w_counter),
|
.weight_i(iport_weight),
|
.weight_i(iport_weight),
|
.reset(reset),
|
.reset(reset),
|
.clk(clk),
|
.clk(clk),
|
.decr(weight_dcrease_en),
|
.decr(weight_dcrease_en),
|
.out(counter_is_reset)
|
.out(counter_is_reset)
|
);
|
);
|
|
|
|
|
end
|
end
|
|
|
endgenerate
|
endgenerate
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assign weight_is_consumed_o = counter_is_reset; // & flit_is_tail ;
|
assign weight_is_consumed_o = counter_is_reset; // & flit_is_tail ;
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
/***************
|
/***************
|
* wrra_contention_gen
|
* wrra_contention_gen
|
* generate contention based on number of request to
|
* generate contention based on number of request to
|
* the same output port
|
* the same output port
|
***************/
|
***************/
|
|
|
|
|
module wrra_contention_gen #(
|
module wrra_contention_gen #(
|
parameter V=4,
|
parameter V=4,
|
parameter P=5,
|
parameter P=5,
|
parameter WRRA_CONFIG_INDEX=0,
|
parameter WRRA_CONFIG_INDEX=0,
|
parameter WEIGHTw = 4, // WRRA width
|
parameter WEIGHTw = 4, // WRRA width
|
parameter SELF_LOOP_EN ="NO"
|
parameter SELF_LOOP_EN ="NO"
|
)(
|
)(
|
ovc_is_assigned_all,
|
ovc_is_assigned_all,
|
ivc_request_all,
|
ivc_request_all,
|
dest_port_all,
|
dest_port_all,
|
iport_weight_all,
|
iport_weight_all,
|
oports_weight_all,
|
oports_weight_all,
|
contention_all,
|
contention_all,
|
limited_oport_weight_all
|
limited_oport_weight_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
|
P_1 = (SELF_LOOP_EN == "NO") ? P-1 : P,
|
P_1 = (SELF_LOOP_EN == "NO") ? P-1 : P,
|
PV = P * V,
|
PV = P * V,
|
VP_1= V * P_1,
|
VP_1= V * P_1,
|
PVP_1 = PV * P_1,
|
PVP_1 = PV * P_1,
|
Pw= log2(P),
|
Pw= log2(P),
|
PwP= Pw *P,
|
PwP= Pw *P,
|
W= WEIGHTw,
|
W= WEIGHTw,
|
WP= W * P,
|
WP= W * P,
|
WPP = WP * P;
|
WPP = WP * P;
|
|
|
localparam
|
localparam
|
VALID_IF_HAS_FLIT = 1, //1: has flit 0: VC-Assigned
|
VALID_IF_HAS_FLIT = 1, //1: has flit 0: VC-Assigned
|
PROPOGATE_EQUALL = (WRRA_CONFIG_INDEX==0 ),
|
PROPOGATE_EQUALL = (WRRA_CONFIG_INDEX==0 ),
|
PROPOGATE_LIMITED = (WRRA_CONFIG_INDEX==1 );
|
PROPOGATE_LIMITED = (WRRA_CONFIG_INDEX==1 );
|
|
|
|
|
input [PVP_1-1 : 0] dest_port_all;
|
input [PVP_1-1 : 0] dest_port_all;
|
input [PV-1 : 0] ovc_is_assigned_all;
|
input [PV-1 : 0] ovc_is_assigned_all;
|
input [PV-1 : 0] ivc_request_all;
|
input [PV-1 : 0] ivc_request_all;
|
input [WP-1 : 0] iport_weight_all;
|
input [WP-1 : 0] iport_weight_all;
|
output [WP-1 : 0] contention_all;
|
output [WP-1 : 0] contention_all;
|
input [WPP-1 : 0] oports_weight_all;
|
input [WPP-1 : 0] oports_weight_all;
|
input [WP-1 : 0] limited_oport_weight_all;
|
input [WP-1 : 0] limited_oport_weight_all;
|
|
|
|
|
wire [P-1 : 0] destport_sum [P-1 : 0];//destport_sum[inport-num][out-num]= out-port is requested by inport-num
|
wire [P-1 : 0] destport_sum [P-1 : 0];//destport_sum[inport-num][out-num]= out-port is requested by inport-num
|
wire [P-1 : 0] contention_one_hot [P-1 : 0]; //contention_one_hot[outport-num][inport-num]= inport- is requesting this outport
|
wire [P-1 : 0] contention_one_hot [P-1 : 0]; //contention_one_hot[outport-num][inport-num]= inport- is requesting this outport
|
|
|
wire [W-1 : 0] iport_weight [P-1 : 0];
|
wire [W-1 : 0] iport_weight [P-1 : 0];
|
wire [W-1 : 0] weight_sum [P-1 : 0];
|
wire [W-1 : 0] weight_sum [P-1 : 0];
|
wire [W-1 : 0] contention [P-1 : 0];
|
wire [W-1 : 0] contention [P-1 : 0];
|
wire [WP-1 : 0] weight_array_per_outport [P-1 : 0];
|
wire [WP-1 : 0] weight_array_per_outport [P-1 : 0];
|
wire [WP-1: 0] oports_weight [P-1 : 0];
|
wire [WP-1: 0] oports_weight [P-1 : 0];
|
// weight_array_per_outport[outport-num][inport-num]= weight-inport-num if inport- is requesting this outport
|
// weight_array_per_outport[outport-num][inport-num]= weight-inport-num if inport- is requesting this outport
|
|
|
|
|
wire [PV-1 : 0] weight_is_valid = (VALID_IF_HAS_FLIT)? ivc_request_all : ovc_is_assigned_all ;
|
wire [PV-1 : 0] weight_is_valid = (VALID_IF_HAS_FLIT)? ivc_request_all : ovc_is_assigned_all ;
|
|
|
genvar j,i;
|
genvar j,i;
|
generate
|
generate
|
for (i=0;i<P; i=i+1) begin : port_lp
|
for (i=0;i<P; i=i+1) begin : port_lp
|
assign iport_weight[i]= iport_weight_all[(i+1)*W-1 : i*W];
|
assign iport_weight[i]= iport_weight_all[(i+1)*W-1 : i*W];
|
assign oports_weight[i]= oports_weight_all [(i+1)*WP-1 : i*WP];
|
assign oports_weight[i]= oports_weight_all [(i+1)*WP-1 : i*WP];
|
|
|
//get the lis of all destination ports requested by each port
|
//get the lis of all destination ports requested by each port
|
wrra_inputport_destports_sum #(
|
wrra_inputport_destports_sum #(
|
.V(V),
|
.V(V),
|
.P(P),
|
.P(P),
|
.SW_LOC(i),
|
.SW_LOC(i),
|
.SELF_LOOP_EN(SELF_LOOP_EN)
|
.SELF_LOOP_EN(SELF_LOOP_EN)
|
)
|
)
|
destports_sum
|
destports_sum
|
(
|
(
|
.weight_is_valid(weight_is_valid[(i+1)*V-1 : i*V]),
|
.weight_is_valid(weight_is_valid[(i+1)*V-1 : i*V]),
|
.dest_ports(dest_port_all [(i+1)*VP_1-1 : i*VP_1]),
|
.dest_ports(dest_port_all [(i+1)*VP_1-1 : i*VP_1]),
|
.destports_sum(destport_sum[i])
|
.destports_sum(destport_sum[i])
|
);
|
);
|
|
|
|
|
|
|
|
|
for (j=0;j<P;j=j+1) begin : outlp1
|
for (j=0;j<P;j=j+1) begin : outlp1
|
assign contention_one_hot[j][i] = destport_sum[i][j];
|
assign contention_one_hot[j][i] = destport_sum[i][j];
|
if(PROPOGATE_EQUALL | PROPOGATE_LIMITED ) begin : peq
|
if(PROPOGATE_EQUALL | PROPOGATE_LIMITED ) begin : peq
|
assign weight_array_per_outport[j][(i+1)*W-1 : i*W] = (contention_one_hot[j][i])? iport_weight[i] : {W{1'b0}};
|
assign weight_array_per_outport[j][(i+1)*W-1 : i*W] = (contention_one_hot[j][i])? iport_weight[i] : {W{1'b0}};
|
end
|
end
|
else begin : pneq
|
else begin : pneq
|
assign weight_array_per_outport[j][(i+1)*W-1 : i*W] = (contention_one_hot[j][i])? oports_weight[i][(j+1)*W-1 : j*W] : {W{1'b0}};
|
assign weight_array_per_outport[j][(i+1)*W-1 : i*W] = (contention_one_hot[j][i])? oports_weight[i][(j+1)*W-1 : j*W] : {W{1'b0}};
|
end
|
end
|
end//for
|
end//for
|
|
|
|
|
//contention is the sum of all inputports weights requesting this outputport
|
//contention is the sum of all inputports weights requesting this outputport
|
accumulator #(
|
accumulator #(
|
.INw(WP),
|
.INw(WP),
|
.OUTw(W),
|
.OUTw(W),
|
.NUM(P)
|
.NUM(P)
|
|
|
)
|
)
|
accum
|
accum
|
(
|
(
|
.in_all(weight_array_per_outport[i]),
|
.in_all(weight_array_per_outport[i]),
|
.out(weight_sum[i])
|
.out(weight_sum[i])
|
);
|
);
|
|
|
|
|
if(PROPOGATE_LIMITED) begin : limted
|
if(PROPOGATE_LIMITED) begin : limted
|
|
|
wire [W-1 : 0] limited_oport_weight [P-1 : 0];
|
wire [W-1 : 0] limited_oport_weight [P-1 : 0];
|
for (j=0;j<P;j=j+1) begin : outlp1
|
for (j=0;j<P;j=j+1) begin : outlp1
|
assign limited_oport_weight [j] = limited_oport_weight_all [(j+1)*W-1 : j*W];
|
assign limited_oport_weight [j] = limited_oport_weight_all [(j+1)*W-1 : j*W];
|
assign contention[j] = (limited_oport_weight [j] > weight_sum [j]) ? weight_sum [j] : limited_oport_weight [j];
|
assign contention[j] = (limited_oport_weight [j] > weight_sum [j]) ? weight_sum [j] : limited_oport_weight [j];
|
|
|
end
|
end
|
|
|
|
|
end else begin : eq_or_actual
|
end else begin : eq_or_actual
|
for (j=0;j<P;j=j+1) begin : outlp1
|
for (j=0;j<P;j=j+1) begin : outlp1
|
assign contention[j] = weight_sum [j];
|
assign contention[j] = weight_sum [j];
|
end
|
end
|
end
|
end
|
|
|
|
|
|
|
|
|
|
|
assign contention_all[(i+1)*W-1 : i*W] = contention[i];
|
assign contention_all[(i+1)*W-1 : i*W] = contention[i];
|
|
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
endmodule
|
endmodule
|
|
|
|
|
module wrra_inputport_destports_sum #(
|
module wrra_inputport_destports_sum #(
|
parameter V=4,
|
parameter V=4,
|
parameter P=5,
|
parameter P=5,
|
parameter SW_LOC=0,
|
parameter SW_LOC=0,
|
parameter SELF_LOOP_EN = "NO"
|
parameter SELF_LOOP_EN = "NO"
|
)(
|
)(
|
weight_is_valid,
|
weight_is_valid,
|
dest_ports,
|
dest_ports,
|
destports_sum
|
destports_sum
|
|
|
);
|
);
|
|
|
localparam
|
localparam
|
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;
|
|
|
input [V-1 : 0] weight_is_valid;
|
input [V-1 : 0] weight_is_valid;
|
input [VP_1-1 : 0] dest_ports;
|
input [VP_1-1 : 0] dest_ports;
|
output [P-1 : 0] destports_sum;
|
output [P-1 : 0] destports_sum;
|
|
|
wire [VP_1-1 : 0] dest_ports_masked;
|
wire [VP_1-1 : 0] dest_ports_masked;
|
|
|
|
|
wire [P_1-1 : 0] sum;
|
wire [P_1-1 : 0] sum;
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for (i=0;i<V; i=i+1) begin : port_lp
|
for (i=0;i<V; i=i+1) begin : port_lp
|
assign dest_ports_masked [(i+1)*P_1-1 : i*P_1] = (weight_is_valid[i]) ? dest_ports [(i+1)*P_1-1 : i*P_1] : {P_1{1'b0}};
|
assign dest_ports_masked [(i+1)*P_1-1 : i*P_1] = (weight_is_valid[i]) ? dest_ports [(i+1)*P_1-1 : i*P_1] : {P_1{1'b0}};
|
end
|
end
|
|
|
|
|
custom_or #(
|
custom_or #(
|
.IN_NUM(V),
|
.IN_NUM(V),
|
.OUT_WIDTH(P_1)
|
.OUT_WIDTH(P_1)
|
)
|
)
|
custom_or(
|
custom_or(
|
.or_in(dest_ports_masked),
|
.or_in(dest_ports_masked),
|
.or_out(sum)
|
.or_out(sum)
|
);
|
);
|
|
|
|
|
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(SW_LOC)
|
.SW_LOC(SW_LOC)
|
)
|
)
|
add_sw_loc
|
add_sw_loc
|
(
|
(
|
.destport_in(sum),
|
.destport_in(sum),
|
.destport_out(destports_sum)
|
.destport_out(destports_sum)
|
);
|
);
|
end else begin : slp
|
end else begin : slp
|
assign destports_sum = sum;
|
assign destports_sum = sum;
|
end
|
end
|
endgenerate
|
endgenerate
|
endmodule
|
endmodule
|
|
|
/***************
|
/***************
|
* weights_update
|
* weights_update
|
*
|
*
|
***************/
|
***************/
|
|
|
module weights_update # (
|
module weights_update # (
|
|
parameter NOC_ID=0,
|
parameter ARBITER_TYPE="WRRA",
|
parameter ARBITER_TYPE="WRRA",
|
parameter V=4,
|
parameter V=4,
|
parameter P=5,
|
parameter P=5,
|
parameter Fw = 36, //flit width;
|
parameter Fw = 36, //flit width;
|
parameter WEIGHTw=4,
|
parameter WEIGHTw=4,
|
parameter C = 4,
|
parameter C = 4,
|
parameter WRRA_CONFIG_INDEX=0,
|
parameter WRRA_CONFIG_INDEX=0,
|
parameter TOPOLOGY = "MESH",//"MESH","TORUS","RING"
|
parameter TOPOLOGY = "MESH",//"MESH","TORUS","RING"
|
parameter EAw = 3,
|
parameter EAw = 3,
|
parameter DSTPw=P-1,
|
parameter DSTPw=P-1,
|
parameter ADD_PIPREG_AFTER_CROSSBAR=0
|
parameter ADD_PIPREG_AFTER_CROSSBAR=0
|
|
|
|
|
)(
|
)(
|
limited_oports_weight,
|
limited_oports_weight,
|
contention_all,
|
contention_all,
|
flit_in_all,
|
flit_in_all,
|
flit_out_all,
|
flit_out_all,
|
flit_out_wr_all,
|
flit_out_wr_all,
|
iport_weight_all,
|
iport_weight_all,
|
refresh_w_counter,
|
refresh_w_counter,
|
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
|
localparam
|
PFw = P * Fw,
|
PFw = P * Fw,
|
W= WEIGHTw,
|
W= WEIGHTw,
|
WP= W * P,
|
WP= W * P,
|
ALL_WEIGHTw=log2(WP);
|
ALL_WEIGHTw=log2(WP);
|
|
|
localparam PROPOGATE_LIMITED = (WRRA_CONFIG_INDEX==1 ),
|
localparam PROPOGATE_LIMITED = (WRRA_CONFIG_INDEX==1 ),
|
INIT_WEIGHT = 1;
|
INIT_WEIGHT = 1;
|
|
|
|
|
input [WP-1 : 0] contention_all;
|
input [WP-1 : 0] contention_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;
|
input [P-1 : 0] flit_out_wr_all;
|
input [P-1 : 0] flit_out_wr_all;
|
input [WP-1: 0] iport_weight_all;
|
input [WP-1: 0] iport_weight_all;
|
output[WP-1 : 0] limited_oports_weight;
|
output[WP-1 : 0] limited_oports_weight;
|
output refresh_w_counter;
|
output refresh_w_counter;
|
input clk,reset;
|
input clk,reset;
|
|
|
//assign refresh_w_counter = 1'b0;
|
//assign refresh_w_counter = 1'b0;
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
//nonlocal port
|
//nonlocal port
|
for (i=1; i<P; i=i+1) begin : non_local_port
|
for (i=1; i<P; i=i+1) begin : non_local_port
|
|
|
weight_update_per_port #(
|
weight_update_per_port #(
|
|
.NOC_ID(NOC_ID),
|
.V(V),
|
.V(V),
|
.C(C),
|
.C(C),
|
.P(P),
|
.P(P),
|
.Fw(Fw),
|
.Fw(Fw),
|
.EAw(EAw),
|
.EAw(EAw),
|
.DSTPw(DSTPw),
|
.DSTPw(DSTPw),
|
.TOPOLOGY(TOPOLOGY),
|
.TOPOLOGY(TOPOLOGY),
|
.WEIGHTw(WEIGHTw),
|
.WEIGHTw(WEIGHTw),
|
.WRRA_CONFIG_INDEX(WRRA_CONFIG_INDEX),
|
.WRRA_CONFIG_INDEX(WRRA_CONFIG_INDEX),
|
.ADD_PIPREG_AFTER_CROSSBAR(ADD_PIPREG_AFTER_CROSSBAR)
|
.ADD_PIPREG_AFTER_CROSSBAR(ADD_PIPREG_AFTER_CROSSBAR)
|
)
|
)
|
update_per_port
|
update_per_port
|
(
|
(
|
.contention_in(contention_all[(i+1)*W-1 : i*W]),
|
.contention_in(contention_all[(i+1)*W-1 : i*W]),
|
.flit_in(flit_in_all[ (i+1)*Fw-1 : i*Fw]),
|
.flit_in(flit_in_all[ (i+1)*Fw-1 : i*Fw]),
|
.flit_out(flit_out_all[(i+1)*Fw-1 : i*Fw]),
|
.flit_out(flit_out_all[(i+1)*Fw-1 : i*Fw]),
|
.flit_out_wr(flit_out_wr_all[i]),
|
.flit_out_wr(flit_out_wr_all[i]),
|
.clk(clk),
|
.clk(clk),
|
.reset(reset)
|
.reset(reset)
|
);
|
);
|
|
|
end
|
end
|
|
|
|
|
if(PROPOGATE_LIMITED) begin : limited
|
if(PROPOGATE_LIMITED) begin : limited
|
|
|
wire [ALL_WEIGHTw-1 : 0] iweight_sum;
|
wire [ALL_WEIGHTw-1 : 0] iweight_sum;
|
wire [P-1 : 0] flit_out_is_tail,tail_flit_is_sent;
|
wire [P-1 : 0] flit_out_is_tail,tail_flit_is_sent;
|
wire any_tail_is_sent;
|
wire any_tail_is_sent;
|
|
|
wire capture_o_weights;
|
wire capture_o_weights;
|
reg [W-1 : 0] oport_weight_counter [P-1 : 0];
|
reg [W-1 : 0] oport_weight_counter [P-1 : 0];
|
reg [W-1 : 0] limited_oport_weight [P-1 : 0];
|
reg [W-1 : 0] limited_oport_weight [P-1 : 0];
|
|
|
assign tail_flit_is_sent = (flit_out_wr_all & flit_out_is_tail);
|
assign tail_flit_is_sent = (flit_out_wr_all & flit_out_is_tail);
|
assign any_tail_is_sent = | tail_flit_is_sent;
|
assign any_tail_is_sent = | tail_flit_is_sent;
|
for (i=0; i<P; i=i+1) begin : lp
|
for (i=0; i<P; i=i+1) begin : lp
|
assign flit_out_is_tail[i] = flit_out_all[(i+1)*Fw-2];
|
assign flit_out_is_tail[i] = flit_out_all[(i+1)*Fw-2];
|
|
|
always @ (`pronoc_clk_reset_edge )begin
|
always @ (`pronoc_clk_reset_edge )begin
|
if(`pronoc_reset) begin
|
if(`pronoc_reset) begin
|
oport_weight_counter[i]<=INIT_WEIGHT;
|
oport_weight_counter[i]<=INIT_WEIGHT;
|
end else begin
|
end else begin
|
if (any_tail_is_sent && capture_o_weights) oport_weight_counter[i]<= INIT_WEIGHT;
|
if (any_tail_is_sent && capture_o_weights) oport_weight_counter[i]<= INIT_WEIGHT;
|
else if (any_tail_is_sent && tail_flit_is_sent[i] && oport_weight_counter[i] != {W{1'b1}})oport_weight_counter[i]<= oport_weight_counter[i] +1'b1;
|
else if (any_tail_is_sent && tail_flit_is_sent[i] && oport_weight_counter[i] != {W{1'b1}})oport_weight_counter[i]<= oport_weight_counter[i] +1'b1;
|
end
|
end
|
end //always
|
end //always
|
|
|
always @ (`pronoc_clk_reset_edge )begin
|
always @ (`pronoc_clk_reset_edge )begin
|
if(`pronoc_reset) begin
|
if(`pronoc_reset) begin
|
limited_oport_weight[i]<={W{1'b0}};
|
limited_oport_weight[i]<={W{1'b0}};
|
end else begin
|
end else begin
|
if (any_tail_is_sent && capture_o_weights) limited_oport_weight[i]<= oport_weight_counter[i]; //capture oweight counters
|
if (any_tail_is_sent && capture_o_weights) limited_oport_weight[i]<= oport_weight_counter[i]; //capture oweight counters
|
end
|
end
|
end //always
|
end //always
|
|
|
assign limited_oports_weight [(i+1)*W-1 : i*W] = limited_oport_weight[i];
|
assign limited_oports_weight [(i+1)*W-1 : i*W] = limited_oport_weight[i];
|
|
|
|
|
end
|
end
|
//all input wights summation
|
//all input wights summation
|
accumulator #(
|
accumulator #(
|
.INw(WP),
|
.INw(WP),
|
.OUTw(ALL_WEIGHTw),
|
.OUTw(ALL_WEIGHTw),
|
.NUM(P)
|
.NUM(P)
|
|
|
)
|
)
|
accum
|
accum
|
(
|
(
|
.in_all(iport_weight_all),
|
.in_all(iport_weight_all),
|
.out(iweight_sum)
|
.out(iweight_sum)
|
);
|
);
|
|
|
|
|
|
|
weight_counter #(
|
weight_counter #(
|
.WEIGHTw(ALL_WEIGHTw)
|
.WEIGHTw(ALL_WEIGHTw)
|
)
|
)
|
weight_counter
|
weight_counter
|
(
|
(
|
.weight_i(iweight_sum),
|
.weight_i(iweight_sum),
|
.reset(reset),
|
.reset(reset),
|
.clk(clk),
|
.clk(clk),
|
.decr(any_tail_is_sent),
|
.decr(any_tail_is_sent),
|
.load_i(1'b0),
|
.load_i(1'b0),
|
.out(capture_o_weights )
|
.out(capture_o_weights )
|
// .out(refresh_w_counter)
|
// .out(refresh_w_counter)
|
);
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
end else begin :dontcare
|
end else begin :dontcare
|
assign limited_oports_weight = {WP{1'bX}};
|
assign limited_oports_weight = {WP{1'bX}};
|
end
|
end
|
|
|
|
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if(ARBITER_TYPE == "WRRA")begin : wrra
|
if(ARBITER_TYPE == "WRRA")begin : wrra
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
|
|
assign refresh_w_counter=1'b0;
|
assign refresh_w_counter=1'b0;
|
|
|
|
|
end else begin :wrra_classic
|
end else begin :wrra_classic
|
|
|
|
|
|
|
wire [ALL_WEIGHTw-1 : 0] iweight_sum;
|
wire [ALL_WEIGHTw-1 : 0] iweight_sum;
|
wire any_tail_is_sent;
|
wire any_tail_is_sent;
|
wire [P-1 : 0] flit_out_is_tail,tail_flit_is_sent;
|
wire [P-1 : 0] flit_out_is_tail,tail_flit_is_sent;
|
for (i=0; i<P; i=i+1) begin : lp2
|
for (i=0; i<P; i=i+1) begin : lp2
|
assign flit_out_is_tail[i] = flit_out_all[(i+1)*Fw-2];
|
assign flit_out_is_tail[i] = flit_out_all[(i+1)*Fw-2];
|
end
|
end
|
|
|
|
|
assign tail_flit_is_sent = (flit_out_wr_all & flit_out_is_tail);
|
assign tail_flit_is_sent = (flit_out_wr_all & flit_out_is_tail);
|
assign any_tail_is_sent = | tail_flit_is_sent;
|
assign any_tail_is_sent = | tail_flit_is_sent;
|
|
|
|
|
|
|
//all input wights summation
|
//all input wights summation
|
accumulator #(
|
accumulator #(
|
.INw(WP),
|
.INw(WP),
|
.OUTw(ALL_WEIGHTw),
|
.OUTw(ALL_WEIGHTw),
|
.NUM(P)
|
.NUM(P)
|
|
|
)
|
)
|
accum
|
accum
|
(
|
(
|
.in_all(iport_weight_all),
|
.in_all(iport_weight_all),
|
.out(iweight_sum)
|
.out(iweight_sum)
|
);
|
);
|
|
|
|
|
|
|
weight_counter #(
|
weight_counter #(
|
.WEIGHTw(ALL_WEIGHTw)
|
.WEIGHTw(ALL_WEIGHTw)
|
)
|
)
|
weight_counter
|
weight_counter
|
(
|
(
|
.weight_i(iweight_sum-1),
|
.weight_i(iweight_sum-1),
|
.reset(reset),
|
.reset(reset),
|
.clk(clk),
|
.clk(clk),
|
.decr(any_tail_is_sent),
|
.decr(any_tail_is_sent),
|
.load_i(1'b0),
|
.load_i(1'b0),
|
.out(refresh_w_counter)
|
.out(refresh_w_counter)
|
);
|
);
|
|
|
end
|
end
|
|
|
endgenerate
|
endgenerate
|
|
|
|
|
|
|
|
|
// localport
|
// localport
|
assign flit_out_all[Fw-1 : 0] = flit_in_all [Fw-1 : 0];
|
assign flit_out_all[Fw-1 : 0] = flit_in_all [Fw-1 : 0];
|
|
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
module weight_update_per_port # (
|
module weight_update_per_port # (
|
|
parameter NOC_ID=0,
|
parameter V=4,
|
parameter V=4,
|
parameter C=2,
|
parameter C=2,
|
parameter P=5,
|
parameter P=5,
|
parameter Fw =36,
|
parameter Fw =36,
|
parameter WEIGHTw=4,
|
parameter WEIGHTw=4,
|
parameter EAw=3,
|
parameter EAw=3,
|
parameter DSTPw=P-1,
|
parameter DSTPw=P-1,
|
parameter TOPOLOGY = "MESH",//"MESH","TORUS","RING"
|
parameter TOPOLOGY = "MESH",//"MESH","TORUS","RING"
|
parameter WRRA_CONFIG_INDEX=0,
|
parameter WRRA_CONFIG_INDEX=0,
|
parameter ADD_PIPREG_AFTER_CROSSBAR=0
|
parameter ADD_PIPREG_AFTER_CROSSBAR=0
|
|
|
)(
|
)(
|
contention_in,
|
contention_in,
|
flit_in,
|
flit_in,
|
flit_out,
|
flit_out,
|
flit_out_wr,
|
flit_out_wr,
|
clk,
|
clk,
|
reset
|
reset
|
);
|
);
|
|
|
|
|
|
|
localparam
|
localparam
|
W=WEIGHTw;
|
W=WEIGHTw,
|
|
WEIGHT_LATCHED = 0; //(WRRA_CONFIG_INDEX==0 || WRRA_CONFIG_INDEX==1 || WRRA_CONFIG_INDEX==2 || WRRA_CONFIG_INDEX==3 ); //1: no latched 0: latched
|
|
|
|
|
localparam WEIGHT_LATCHED = 0; //(WRRA_CONFIG_INDEX==0 || WRRA_CONFIG_INDEX==1 || WRRA_CONFIG_INDEX==2 || WRRA_CONFIG_INDEX==3 ); //1: no latched 0: latched
|
|
|
|
|
|
input [W-1 : 0] contention_in;
|
input [W-1 : 0] contention_in;
|
input [Fw-1 : 0] flit_in;
|
input [Fw-1 : 0] flit_in;
|
output[Fw-1 : 0] flit_out;
|
output[Fw-1 : 0] flit_out;
|
input flit_out_wr;
|
input flit_out_wr;
|
input clk,reset;
|
input clk,reset;
|
|
|
|
|
wire flit_is_hdr = flit_in[Fw-1];
|
wire flit_is_hdr = flit_in[Fw-1];
|
reg [W-1 : 0] contention;
|
reg [W-1 : 0] contention;
|
|
|
generate
|
generate
|
if(WEIGHT_LATCHED == 1) begin : add_latch
|
if(WEIGHT_LATCHED == 1) begin : add_latch
|
|
|
wire update = flit_out_wr & flit_is_hdr;
|
wire update = flit_out_wr & flit_is_hdr;
|
wire [W-1 : 0] contention_out;
|
wire [W-1 : 0] contention_out;
|
output_weight_latch #(
|
output_weight_latch #(
|
.WEIGHTw (WEIGHTw)
|
.WEIGHTw (WEIGHTw)
|
)
|
)
|
out_weight_latch
|
out_weight_latch
|
(
|
(
|
.weight_in(contention_in),
|
.weight_in(contention_in),
|
.weight_out(contention_out),
|
.weight_out(contention_out),
|
.clk(clk),
|
.clk(clk),
|
.reset(reset),
|
.reset(reset),
|
.update( update )
|
.update( update )
|
);
|
);
|
always @ (*) begin
|
always @ (*) begin
|
contention= contention_out;
|
contention= contention_out;
|
end
|
end
|
|
|
end else if(ADD_PIPREG_AFTER_CROSSBAR==1)begin : add_reg
|
end else if(ADD_PIPREG_AFTER_CROSSBAR==1)begin : add_reg
|
|
|
always @ (`pronoc_clk_reset_edge )begin
|
always @ (`pronoc_clk_reset_edge )begin
|
if(`pronoc_reset) begin
|
if(`pronoc_reset) begin
|
contention<={W{1'b0}};
|
contention<={W{1'b0}};
|
end else begin
|
end else begin
|
contention<= contention_in;
|
contention<= contention_in;
|
end
|
end
|
end//always
|
end//always
|
|
|
|
|
end else begin : no_reg
|
end else begin : no_reg
|
always @ (*) begin
|
always @ (*) begin
|
contention= contention_in;
|
contention= contention_in;
|
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
wire [Fw-1 : 0] hdr_flit_new;
|
wire [Fw-1 : 0] hdr_flit_new;
|
|
|
hdr_flit_weight_update updater
|
hdr_flit_weight_update #(
|
(
|
.NOC_ID(NOC_ID)
|
|
) updater (
|
.new_weight(contention),
|
.new_weight(contention),
|
.flit_in(flit_in),
|
.flit_in(flit_in),
|
.flit_out(hdr_flit_new)
|
.flit_out(hdr_flit_new)
|
);
|
);
|
|
|
|
|
// assign flit_out = (flit_is_hdr) ? {flit_in[Fw-1 : WEIGHT_LSB+WEIGHTw ] ,contention, flit_in[WEIGHT_LSB-1 : 0] } : flit_in;
|
// assign flit_out = (flit_is_hdr) ? {flit_in[Fw-1 : WEIGHT_LSB+WEIGHTw ] ,contention, flit_in[WEIGHT_LSB-1 : 0] } : flit_in;
|
assign flit_out = (flit_is_hdr) ? hdr_flit_new : flit_in;
|
assign flit_out = (flit_is_hdr) ? hdr_flit_new : flit_in;
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
module output_weight_latch #(
|
module output_weight_latch #(
|
parameter WEIGHTw =4
|
parameter WEIGHTw =4
|
)(
|
)(
|
weight_in,
|
weight_in,
|
weight_out,
|
weight_out,
|
clk,
|
clk,
|
reset,
|
reset,
|
update
|
update
|
);
|
);
|
|
|
localparam W=WEIGHTw;
|
localparam W=WEIGHTw;
|
|
|
input [W-1 : 0] weight_in;
|
input [W-1 : 0] weight_in;
|
output reg [W-1 : 0] weight_out;
|
output reg [W-1 : 0] weight_out;
|
input clk, reset, update;
|
input clk, reset, update;
|
|
|
reg [W-1 : 0] counter,counter_next,weight_out_next;
|
reg [W-1 : 0] counter,counter_next,weight_out_next;
|
|
|
wire less = weight_in < weight_out;
|
wire less = weight_in < weight_out;
|
wire counter_is_zero = counter == {W{1'b0}};
|
wire counter_is_zero = counter == {W{1'b0}};
|
|
|
always @ (*)begin
|
always @ (*)begin
|
counter_next = counter;
|
counter_next = counter;
|
weight_out_next = weight_out;
|
weight_out_next = weight_out;
|
if(update)begin
|
if(update)begin
|
if (less ) begin // input weight is smaller than the captured one before
|
if (less ) begin // input weight is smaller than the captured one before
|
if(counter_is_zero) begin //
|
if(counter_is_zero) begin //
|
weight_out_next = weight_in;
|
weight_out_next = weight_in;
|
end else begin
|
end else begin
|
counter_next = counter - 1'b1;
|
counter_next = counter - 1'b1;
|
end
|
end
|
end
|
end
|
else begin
|
else begin
|
counter_next = (weight_in[W-1] != 1'b1) ? {weight_in[W-2:0],1'b0} : {W{1'b1}};
|
counter_next = (weight_in[W-1] != 1'b1) ? {weight_in[W-2:0],1'b0} : {W{1'b1}};
|
weight_out_next = weight_in;
|
weight_out_next = weight_in;
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
|
|
always @ (`pronoc_clk_reset_edge )begin
|
always @ (`pronoc_clk_reset_edge )begin
|
if(`pronoc_reset) begin
|
if(`pronoc_reset) begin
|
counter = {WEIGHTw{1'b0}};
|
counter = {WEIGHTw{1'b0}};
|
weight_out = {WEIGHTw{1'b0}};
|
weight_out = {WEIGHTw{1'b0}};
|
end else begin
|
end else begin
|
counter = counter_next;
|
counter = counter_next;
|
weight_out = weight_out_next;
|
weight_out = weight_out_next;
|
end
|
end
|
end//always
|
end//always
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|