`include "pronoc_def.v"
|
`include "pronoc_def.v"
|
|
|
/**************************************
|
/**************************************
|
* Module: router_bypass
|
* Module: router_bypass
|
* Date:2020-11-24
|
* Date:2020-11-24
|
* Author: alireza
|
* Author: alireza
|
*
|
*
|
* Description:
|
* Description:
|
* This file contains HDL modules that can be added
|
* This file contains HDL modules that can be added
|
* to a 2-stage NoC router and provides router bypassing
|
* to a 2-stage NoC router and provides router bypassing
|
***************************************/
|
***************************************/
|
|
|
/**************************
|
/**************************
|
* SMART_flags_gen:
|
* SMART_flags_gen:
|
* generate SMART flags based on NoC parameter, current router's port and address,
|
* generate SMART flags based on NoC parameter, current router's port and address,
|
* and destination router address
|
* and destination router address
|
* located in router output port (port number:SPB_OPORT_NUM)
|
* located in router output port (port number:SPB_OPORT_NUM)
|
* smart_flag_o indicates how many more router in direct line can be bypassed
|
* smart_flag_o indicates how many more router in direct line can be bypassed
|
* if SPB_OPORT_NUM is also one of the possible output port in
|
* if SPB_OPORT_NUM is also one of the possible output port in
|
* lk-ahead routing, The packet can by-pass the next router once the bypassing condition are met
|
* lk-ahead routing, The packet can by-pass the next router once the bypassing condition are met
|
***************************/
|
***************************/
|
|
|
`include "pronoc_def.v"
|
`include "pronoc_def.v"
|
|
|
|
|
module reduction_or #(
|
module reduction_or #(
|
parameter W = 5,//out width
|
parameter W = 5,//out width
|
parameter N = 4 //array lenght
|
parameter N = 4 //array lenght
|
)(
|
)(
|
in,
|
in,
|
out
|
out
|
);
|
);
|
input [W-1 : 0] in [N-1 : 0];
|
input [W-1 : 0] in [N-1 : 0];
|
output reg [W-1 : 0] out;
|
output reg [W-1 : 0] out;
|
|
|
// assign out = in.or(); //it is not synthesizable able by some compiler
|
// assign out = in.or(); //it is not synthesizable able by some compiler
|
always_comb begin
|
always_comb begin
|
out = {W{1'b0}};
|
out = {W{1'b0}};
|
for (int i = 0; i < N; i++)
|
for (int i = 0; i < N; i++)
|
out |= in[i];
|
out |= in[i];
|
end
|
end
|
|
|
|
|
endmodule
|
endmodule
|
|
|
module onehot_mux_2D #(
|
module onehot_mux_2D #(
|
parameter W = 5,//out width
|
parameter W = 5,//out width
|
parameter N = 4 //sel width
|
parameter N = 4 //sel width
|
)(
|
)(
|
in,
|
in,
|
sel,
|
sel,
|
out
|
out
|
);
|
);
|
|
|
input [W-1 : 0] in [N-1 : 0];
|
input [W-1 : 0] in [N-1 : 0];
|
input [N-1 : 0] sel;
|
input [N-1 : 0] sel;
|
output reg [W-1 : 0] out;
|
output reg [W-1 : 0] out;
|
|
|
|
|
always_comb begin
|
always_comb begin
|
out = {W{1'b0}};
|
out = {W{1'b0}};
|
for (int i = 0; i < N; i++)
|
for (int i = 0; i < N; i++)
|
out |= (sel[i]) ? in[i] : {W{1'b0}};
|
out |= (sel[i]) ? in[i] : {W{1'b0}};
|
end
|
end
|
|
|
|
|
endmodule
|
endmodule
|
|
|
module onehot_mux_1D #(
|
module onehot_mux_1D #(
|
parameter W = 5,//out width
|
parameter W = 5,//out width
|
parameter N = 4 //sel width
|
parameter N = 4 //sel width
|
)(
|
)(
|
input [W*N-1 : 0] in,
|
input [W*N-1 : 0] in,
|
input [N-1 : 0] sel,
|
input [N-1 : 0] sel,
|
output [W-1 : 0] out
|
output [W-1 : 0] out
|
);
|
);
|
|
|
wire [W-1 : 0] in_array [N-1 : 0];
|
wire [W-1 : 0] in_array [N-1 : 0];
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for (i=0;i
|
for (i=0;i
|
assign in_array[i] = in[(i+1)*W-1 : i*W];
|
assign in_array[i] = in[(i+1)*W-1 : i*W];
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
|
onehot_mux_2D #(
|
onehot_mux_2D #(
|
.W (W ),
|
.W (W),
|
.N (N )
|
.N (N)
|
) onehot_mux_2D (
|
) onehot_mux_2D (
|
.in (in_array ),
|
.in (in_array),
|
.sel (sel ),
|
.sel (sel),
|
.out (out ));
|
.out (out));
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
module onehot_mux_1D_reverse #(
|
module onehot_mux_1D_reverse #(
|
parameter W = 5,//out width p
|
parameter W = 5,//out width p
|
parameter N = 4 //sel width v
|
parameter N = 4 //sel width v
|
)(
|
)(
|
input [W*N-1 : 0] in,
|
input [W*N-1 : 0] in,
|
input [N-1 : 0] sel,
|
input [N-1 : 0] sel,
|
output [W-1 : 0] out
|
output [W-1 : 0] out
|
);
|
);
|
|
|
wire [N-1 : 0] in_array [W-1 : 0];
|
wire [N-1 : 0] in_array [W-1 : 0];
|
wire [W-1 : 0] in_array2[N-1 : 0];
|
wire [W-1 : 0] in_array2[N-1 : 0];
|
|
|
genvar i,j;
|
genvar i,j;
|
generate
|
generate
|
for (i=0;i
|
for (i=0;i
|
assign in_array[i] = in[(i+1)*N-1 : i*N];
|
assign in_array[i] = in[(i+1)*N-1 : i*N];
|
for (j=0;j
|
for (j=0;j
|
assign in_array2[j][i] = in_array[i][j];
|
assign in_array2[j][i] = in_array[i][j];
|
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
|
onehot_mux_2D #(
|
onehot_mux_2D #(
|
.W (N ),
|
.W (N),
|
.N (W )
|
.N (W)
|
) onehot_mux_2D (
|
) onehot_mux_2D (
|
.in (in_array2 ),
|
.in (in_array2),
|
.sel (sel ),
|
.sel (sel),
|
.out (out ));
|
.out (out));
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
module header_flit_info #(
|
|
parameter NOC_ID = 0,
|
|
|
module header_flit_info
|
|
import pronoc_pkg::*;
|
|
#(
|
|
parameter DATA_w = 0
|
parameter DATA_w = 0
|
)(
|
)(
|
flit,
|
flit,
|
hdr_flit,
|
hdr_flit,
|
data_o
|
data_o
|
);
|
);
|
|
|
|
`NOC_CONF
|
|
|
localparam
|
localparam
|
Dw = (DATA_w==0)? 1 : DATA_w;
|
Dw = (DATA_w==0)? 1 : DATA_w;
|
|
|
input flit_t flit;
|
input flit_t flit;
|
output hdr_flit_t hdr_flit;
|
output hdr_flit_t hdr_flit;
|
output [Dw-1 : 0] data_o;
|
output [Dw-1 : 0] data_o;
|
|
|
|
|
localparam
|
localparam
|
DATA_LSB= MSB_BE+1, DATA_MSB= (DATA_LSB + DATA_w)
|
DATA_LSB= MSB_BE+1, DATA_MSB= (DATA_LSB + DATA_w)
|
OFFSETw = DATA_MSB - DATA_LSB +1;
|
OFFSETw = DATA_MSB - DATA_LSB +1;
|
|
|
wire [OFFSETw-1 : 0 ] offset;
|
wire [OFFSETw-1 : 0 ] offset;
|
|
|
assign hdr_flit.src_e_addr = flit.payload [E_SRC_MSB : E_SRC_LSB];
|
assign hdr_flit.src_e_addr = flit.payload [E_SRC_MSB : E_SRC_LSB];
|
assign hdr_flit.dest_e_addr = flit.payload [E_DST_MSB : E_DST_LSB];
|
assign hdr_flit.dest_e_addr = flit.payload [E_DST_MSB : E_DST_LSB];
|
assign hdr_flit.destport = flit.payload [DST_P_MSB : DST_P_LSB];
|
assign hdr_flit.destport = flit.payload [DST_P_MSB : DST_P_LSB];
|
|
|
|
|
generate
|
generate
|
if(C>1)begin : have_class
|
if(C>1)begin : have_class
|
assign hdr_flit.message_class = flit.payload [CLASS_MSB : CLASS_LSB];
|
assign hdr_flit.message_class = flit.payload [CLASS_MSB : CLASS_LSB];
|
end else begin : no_class
|
end else begin : no_class
|
assign hdr_flit.message_class = {Cw{1'b0}};
|
assign hdr_flit.message_class = {Cw{1'b0}};
|
end
|
end
|
|
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if(SWA_ARBITER_TYPE != "RRA")begin : wrra_b
|
if(SWA_ARBITER_TYPE != "RRA")begin : wrra_b
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
assign hdr_flit.weight = flit.payload [WEIGHT_MSB : WEIGHT_LSB];
|
assign hdr_flit.weight = flit.payload [WEIGHT_MSB : WEIGHT_LSB];
|
end else begin : rra_b
|
end else begin : rra_b
|
assign hdr_flit.weight = {WEIGHTw{1'bX}};
|
assign hdr_flit.weight = {WEIGHTw{1'bX}};
|
end
|
end
|
|
|
if( BYTE_EN ) begin : be_1
|
if( BYTE_EN) begin : be_1
|
assign hdr_flit.be = flit.payload [BE_MSB : BE_LSB];
|
assign hdr_flit.be = flit.payload [BE_MSB : BE_LSB];
|
end else begin : be_0
|
end else begin : be_0
|
assign hdr_flit.be = {BEw{1'bX}};
|
assign hdr_flit.be = {BEw{1'bX}};
|
end
|
end
|
|
|
|
|
assign offset = flit.payload [DATA_MSB : DATA_LSB];
|
assign offset = flit.payload [DATA_MSB : DATA_LSB];
|
|
|
|
|
if(Dw > OFFSETw) begin : if1
|
if(Dw > OFFSETw) begin : if1
|
assign data_o={{(Dw-OFFSETw){1'b0}},offset};
|
assign data_o={{(Dw-OFFSETw){1'b0}},offset};
|
end else begin : if2
|
end else begin : if2
|
assign data_o=offset[Dw-1 : 0];
|
assign data_o=offset[Dw-1 : 0];
|
end
|
end
|
|
|
endgenerate
|
endgenerate
|
|
|
|
|
|
|
endmodule
|
endmodule
|
|
|
//synthesis translate_off
|
//synthesis translate_off
|
//synopsys translate_off
|
//synopsys translate_off
|
|
|
module smart_chanel_check
|
module smart_chanel_check #(
|
import pronoc_pkg::*;
|
parameter NOC_ID=0
|
(
|
) (
|
flit_chanel,
|
flit_chanel,
|
smart_chanel,
|
smart_chanel,
|
reset,
|
reset,
|
clk
|
clk
|
);
|
);
|
|
|
|
`NOC_CONF
|
|
|
input flit_chanel_t flit_chanel;
|
input flit_chanel_t flit_chanel;
|
input smart_chanel_t smart_chanel;
|
input smart_chanel_t smart_chanel;
|
input reset,clk;
|
input reset,clk;
|
|
|
smart_chanel_t smart_chanel_delay;
|
smart_chanel_t smart_chanel_delay;
|
always @(posedge clk) smart_chanel_delay<=smart_chanel;
|
always @(posedge clk) smart_chanel_delay<=smart_chanel;
|
|
|
hdr_flit_t hdr_flit;
|
hdr_flit_t hdr_flit;
|
header_flit_info extract(
|
header_flit_info #(
|
|
.NOC_ID (NOC_ID)
|
|
) extract (
|
.flit(flit_chanel.flit),
|
.flit(flit_chanel.flit),
|
.hdr_flit(hdr_flit),
|
.hdr_flit(hdr_flit),
|
.data_o()
|
.data_o()
|
);
|
);
|
|
|
always @(posedge clk) begin
|
always @(posedge clk) begin
|
if(flit_chanel.flit_wr) begin
|
if(flit_chanel.flit_wr) begin
|
if(smart_chanel_delay.ovc!=flit_chanel.flit.vc) begin
|
if(smart_chanel_delay.ovc!=flit_chanel.flit.vc) begin
|
$display("%t: ERROR: smart ovc %d is not equal with flit ovc %d. %m",$time,smart_chanel_delay.ovc,flit_chanel.flit.vc );
|
$display("%t: ERROR: smart ovc %d is not equal with flit ovc %d. %m",$time,smart_chanel_delay.ovc,flit_chanel.flit.vc);
|
$finish;
|
$finish;
|
end
|
end
|
if(flit_chanel.flit.hdr_flag==1'b1 && hdr_flit.dest_e_addr != smart_chanel_delay.dest_e_addr) begin
|
if(flit_chanel.flit.hdr_flag==1'b1 && hdr_flit.dest_e_addr != smart_chanel_delay.dest_e_addr) begin
|
$display("%t: ERROR: smart dest_e_addr %d is not equal with flit dest_e_addr %d. %m",$time,smart_chanel_delay.dest_e_addr,hdr_flit.dest_e_addr );
|
$display("%t: ERROR: smart dest_e_addr %d is not equal with flit dest_e_addr %d. %m",$time,smart_chanel_delay.dest_e_addr,hdr_flit.dest_e_addr);
|
$finish;
|
$finish;
|
end
|
end
|
if(flit_chanel.flit.hdr_flag!=smart_chanel_delay.hdr_flit) begin
|
if(flit_chanel.flit.hdr_flag!=smart_chanel_delay.hdr_flit) begin
|
$display("%t: ERROR: smart and current hdr flag (%d!=%d) miss-match. %m",$time, smart_chanel_delay.hdr_flit, flit_chanel.flit.hdr_flag);
|
$display("%t: ERROR: smart and current hdr flag (%d!=%d) miss-match. %m",$time, smart_chanel_delay.hdr_flit, flit_chanel.flit.hdr_flag);
|
$finish;
|
$finish;
|
end
|
end
|
|
|
end
|
end
|
|
|
end
|
end
|
endmodule
|
endmodule
|
|
|
//synopsys translate_on
|
//synopsys translate_on
|
//synthesis translate_on
|
//synthesis translate_on
|
|
|
|
|
|
module smart_forward_ivc_info #(
|
|
parameter NOC_ID=0,
|
|
|
module smart_forward_ivc_info
|
|
import pronoc_pkg::*;
|
|
#(
|
|
parameter P=5
|
parameter P=5
|
)(
|
) (
|
ivc_info,
|
ivc_info,
|
iport_info,
|
iport_info,
|
oport_info,
|
oport_info,
|
smart_chanel,
|
smart_chanel,
|
ovc_locally_requested,
|
ovc_locally_requested,
|
reset,clk
|
reset,clk
|
);
|
);
|
|
|
|
`NOC_CONF
|
|
|
//ivc info
|
//ivc info
|
input reset,clk;
|
input reset,clk;
|
input ivc_info_t ivc_info [P-1 : 0][V-1 : 0];
|
input ivc_info_t ivc_info [P-1 : 0][V-1 : 0];
|
input iport_info_t iport_info [P-1 : 0];
|
input iport_info_t iport_info [P-1 : 0];
|
input oport_info_t oport_info [P-1 : 0];
|
input oport_info_t oport_info [P-1 : 0];
|
output smart_chanel_t smart_chanel [P-1 : 0];
|
output smart_chanel_t smart_chanel [P-1 : 0];
|
output [V-1 : 0] ovc_locally_requested [P-1 : 0];
|
output [V-1 : 0] ovc_locally_requested [P-1 : 0];
|
|
|
smart_ivc_info_t smart_ivc_info [P-1 : 0][V-1 : 0];
|
smart_ivc_info_t smart_ivc_info [P-1 : 0][V-1 : 0];
|
smart_ivc_info_t smart_ivc_mux [P-1 : 0];
|
smart_ivc_info_t smart_ivc_mux [P-1 : 0];
|
|
|
smart_ivc_info_t smart_ivc_info_all_port [P-1 : 0] [P-1 : 0];
|
smart_ivc_info_t smart_ivc_info_all_port [P-1 : 0] [P-1 : 0];
|
smart_ivc_info_t smart_vc_info_o [P-1 : 0];
|
smart_ivc_info_t smart_vc_info_o [P-1 : 0];
|
|
|
wire [V-1 : 0] assigned_ovc [P-1:0];
|
wire [V-1 : 0] assigned_ovc [P-1:0];
|
wire [V-1 : 0] non_assigned_vc_req [P-1:0];
|
wire [V-1 : 0] non_assigned_vc_req [P-1:0];
|
wire [P-1 : 0] mask_gen [P-1 : 0][V-1 :0];
|
wire [P-1 : 0] mask_gen [P-1 : 0][V-1 :0];
|
wire [V-1 : 0] ovc_locally_requested_next [P-1 : 0];
|
wire [V-1 : 0] ovc_locally_requested_next [P-1 : 0];
|
|
|
/*
|
/*
|
P V P P V p
|
P V P P V p
|
non_assigned_vc_req[i][j] destport_one_hot[z]--> [z][ j][i]
|
non_assigned_vc_req[i][j] destport_one_hot[z]--> [z][ j][i]
|
non_assigned_vc_req[0][0] destport_one_hot[3]--> | [3][0] [0]
|
non_assigned_vc_req[0][0] destport_one_hot[3]--> | [3][0] [0]
|
non_assigned_vc_req[1][0] destport_one_hot[3]--> | [3][0] [1]
|
non_assigned_vc_req[1][0] destport_one_hot[3]--> | [3][0] [1]
|
non_assigned_vc_req[2][0] destport_one_hot[3]--> | [3][0] [2]
|
non_assigned_vc_req[2][0] destport_one_hot[3]--> | [3][0] [2]
|
*/
|
*/
|
|
|
smart_chanel_t smart_chanel_next [P-1 : 0];
|
smart_chanel_t smart_chanel_next [P-1 : 0];
|
|
|
|
|
genvar i,j,z;
|
genvar i,j,z;
|
generate
|
generate
|
for (i=0;i
|
for (i=0;i
|
|
|
for (j=0; j < V; j=j+1) begin : ivc
|
for (j=0; j < V; j=j+1) begin : ivc
|
assign smart_ivc_info[i][j].dest_e_addr = ivc_info[i][j].dest_e_addr;
|
assign smart_ivc_info[i][j].dest_e_addr = ivc_info[i][j].dest_e_addr;
|
assign smart_ivc_info[i][j].ovc_is_assigned= ivc_info[i][j].ovc_is_assigned;
|
assign smart_ivc_info[i][j].ovc_is_assigned= ivc_info[i][j].ovc_is_assigned;
|
assign smart_ivc_info[i][j].assigned_ovc_bin=ivc_info[i][j].assigned_ovc_bin;
|
assign smart_ivc_info[i][j].assigned_ovc_bin=ivc_info[i][j].assigned_ovc_bin;
|
assign non_assigned_vc_req[i][j] = ~ivc_info[i][j].ovc_is_assigned & ivc_info[i][j].ivc_req;
|
assign non_assigned_vc_req[i][j] = ~ivc_info[i][j].ovc_is_assigned & ivc_info[i][j].ivc_req;
|
for (z=0; z < P; z=z+1) begin : port
|
for (z=0; z < P; z=z+1) begin : port
|
assign mask_gen[z][j][i] = non_assigned_vc_req[i][j] & ivc_info[i][j].destport_one_hot[z];
|
assign mask_gen[z][j][i] = non_assigned_vc_req[i][j] & ivc_info[i][j].destport_one_hot[z];
|
end
|
end
|
assign ovc_locally_requested_next[i][j]=|mask_gen[i][j];
|
assign ovc_locally_requested_next[i][j]=|mask_gen[i][j];
|
end//V
|
end//V
|
|
|
pronoc_register #(.W(V)) reg1 (.in(ovc_locally_requested_next[i] ), .reset(reset), .clk(clk), .out(ovc_locally_requested[i]));
|
pronoc_register #(.W(V)) reg1 (.in(ovc_locally_requested_next[i]), .reset(reset), .clk(clk), .out(ovc_locally_requested[i]));
|
|
|
|
|
|
|
|
|
onehot_mux_2D #(.W(SMART_IVC_w),.N(V)) mux1 ( .in(smart_ivc_info[i]), .sel(iport_info[i].swa_first_level_grant), .out(smart_ivc_mux[i]));
|
onehot_mux_2D #(.W(SMART_IVC_w),.N(V)) mux1 ( .in(smart_ivc_info[i]), .sel(iport_info[i].swa_first_level_grant), .out(smart_ivc_mux[i]));
|
//demux
|
//demux
|
for (j=0;j
|
for (j=0;j
|
assign smart_ivc_info_all_port[j][i] = (iport_info[i].granted_oport_one_hot[j]==1'b1)? smart_ivc_mux[i] : {SMART_IVC_w{1'b0}};
|
assign smart_ivc_info_all_port[j][i] = (iport_info[i].granted_oport_one_hot[j]==1'b1)? smart_ivc_mux[i] : {SMART_IVC_w{1'b0}};
|
end
|
end
|
|
|
//assign smart_vc_info_o[i] = smart_ivc_info_all_port[i].or; not synthesizable
|
//assign smart_vc_info_o[i] = smart_ivc_info_all_port[i].or; not synthesizable
|
// assign smart_vc_info_o[i] = smart_ivc_info_all_port[i].[0] | smart_ivc_info_all_port[i].[1] | smart_ivc_info_all_port[i].[2] ... | smart_ivc_info_all_port[i].[p-1];
|
// assign smart_vc_info_o[i] = smart_ivc_info_all_port[i].[0] | smart_ivc_info_all_port[i].[1] | smart_ivc_info_all_port[i].[2] ... | smart_ivc_info_all_port[i].[p-1];
|
reduction_or #(
|
reduction_or #(
|
.W (SMART_IVC_w ),
|
.W (SMART_IVC_w),
|
.N (P )
|
.N (P)
|
) _or (
|
) _or (
|
.in (smart_ivc_info_all_port[i] ),
|
.in (smart_ivc_info_all_port[i]),
|
.out (smart_vc_info_o[i] )
|
.out (smart_vc_info_o[i])
|
);
|
);
|
/*
|
/*
|
always_comb begin
|
always_comb begin
|
smart_vc_info_o[i] = {SMART_IVC_w{1'b0}};
|
smart_vc_info_o[i] = {SMART_IVC_w{1'b0}};
|
for (int ii = 0; ii < P; ii++)
|
for (int ii = 0; ii < P; ii++)
|
smart_vc_info_o[i] |= smart_ivc_info_all_port[i][ii];
|
smart_vc_info_o[i] |= smart_ivc_info_all_port[i][ii];
|
end
|
end
|
*/
|
*/
|
|
|
|
|
bin_to_one_hot #(
|
bin_to_one_hot #(
|
.BIN_WIDTH (Vw),
|
.BIN_WIDTH (Vw),
|
.ONE_HOT_WIDTH (V )
|
.ONE_HOT_WIDTH (V)
|
) conv (
|
) conv (
|
.bin_code (smart_vc_info_o[i].assigned_ovc_bin ),
|
.bin_code (smart_vc_info_o[i].assigned_ovc_bin),
|
.one_hot_code (assigned_ovc[i] )
|
.one_hot_code (assigned_ovc[i])
|
);
|
);
|
|
|
|
|
|
|
assign smart_chanel_next[i].dest_e_addr= smart_vc_info_o[i].dest_e_addr;
|
assign smart_chanel_next[i].dest_e_addr= smart_vc_info_o[i].dest_e_addr;
|
assign smart_chanel_next[i].ovc= (smart_vc_info_o[i].ovc_is_assigned)? assigned_ovc[i] : oport_info[i].non_smart_ovc_is_allocated;
|
assign smart_chanel_next[i].ovc= (smart_vc_info_o[i].ovc_is_assigned)? assigned_ovc[i] : oport_info[i].non_smart_ovc_is_allocated;
|
assign smart_chanel_next[i].hdr_flit=~smart_vc_info_o[i].ovc_is_assigned;
|
assign smart_chanel_next[i].hdr_flit=~smart_vc_info_o[i].ovc_is_assigned;
|
assign smart_chanel_next[i].requests = (oport_info[i].any_ovc_granted)? {SMART_NUM{1'b1}}:{SMART_NUM{1'b0}} ;
|
assign smart_chanel_next[i].requests = (oport_info[i].any_ovc_granted)? {SMART_NUM{1'b1}}:{SMART_NUM{1'b0}} ;
|
assign smart_chanel_next[i].bypassed_num = {BYPASSw{1'b0}} ;
|
assign smart_chanel_next[i].bypassed_num = {BYPASSw{1'b0}} ;
|
|
|
|
|
if( ADD_PIPREG_AFTER_CROSSBAR == 1 ) begin :link_reg
|
if( ADD_PIPREG_AFTER_CROSSBAR == 1) begin :link_reg
|
pronoc_register #(
|
pronoc_register #(
|
.W ( SMART_CHANEL_w )
|
.W ( SMART_CHANEL_w)
|
) register (
|
) register (
|
.in (smart_chanel_next[i] ),
|
.in (smart_chanel_next[i]),
|
.reset (reset ),
|
.reset (reset),
|
.clk (clk ),
|
.clk (clk),
|
.out (smart_chanel[i] ));
|
.out (smart_chanel[i]));
|
|
|
end else begin :no_link_reg
|
end else begin :no_link_reg
|
assign smart_chanel[i] = smart_chanel_next[i];
|
assign smart_chanel[i] = smart_chanel_next[i];
|
end
|
end
|
/*
|
/*
|
|
|
always @ (`pronoc_clk_reset_edge )begin
|
always @ (`pronoc_clk_reset_edge)begin
|
if(`pronoc_reset) begin
|
if(`pronoc_reset) begin
|
smart_chanel[i].dest_e_addr<= {EAw{1'b0}};
|
smart_chanel[i].dest_e_addr<= {EAw{1'b0}};
|
smart_chanel[i].ovc<= {V{1'b0}};
|
smart_chanel[i].ovc<= {V{1'b0}};
|
smart_chanel[i].hdr_flit<=1'b0;
|
smart_chanel[i].hdr_flit<=1'b0;
|
end else begin
|
end else begin
|
smart_chanel[i].dest_e_addr<= smart_vc_info_o[i].dest_e_addr;
|
smart_chanel[i].dest_e_addr<= smart_vc_info_o[i].dest_e_addr;
|
smart_chanel[i].ovc<= (smart_vc_info_o[i].ovc_is_assigned)? assigned_ovc[i] : oport_info[i].non_smart_ovc_is_allocated;
|
smart_chanel[i].ovc<= (smart_vc_info_o[i].ovc_is_assigned)? assigned_ovc[i] : oport_info[i].non_smart_ovc_is_allocated;
|
smart_chanel[i].hdr_flit<=~smart_vc_info_o[i].ovc_is_assigned;
|
smart_chanel[i].hdr_flit<=~smart_vc_info_o[i].ovc_is_assigned;
|
smart_chanel[i].requests <= (oport_info[i].any_ovc_granted)? {SMART_NUM{1'b1}}:{SMART_NUM{1'b0}} ;
|
smart_chanel[i].requests <= (oport_info[i].any_ovc_granted)? {SMART_NUM{1'b1}}:{SMART_NUM{1'b0}} ;
|
end
|
end
|
end
|
end
|
|
|
*/
|
*/
|
|
|
|
|
|
|
|
|
|
|
end//port_
|
end//port_
|
endgenerate
|
endgenerate
|
|
|
// generate for (i=0; i < P; i=i+1) begin : port
|
// generate for (i=0; i < P; i=i+1) begin : port
|
// assign smart_ivc_info_o[i] = (granted_dest_port[i]==1'b1)? ivc_info_mux : {SMART_IVC_w{1'b0}};
|
// assign smart_ivc_info_o[i] = (granted_dest_port[i]==1'b1)? ivc_info_mux : {SMART_IVC_w{1'b0}};
|
// end endgenerate
|
// end endgenerate
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
module smart_bypass_chanels
|
module smart_bypass_chanels #(
|
import pronoc_pkg::*;
|
parameter NOC_ID=0,
|
#(
|
|
parameter P=5
|
parameter P=5
|
)(
|
) (
|
ivc_info,
|
ivc_info,
|
iport_info,
|
iport_info,
|
oport_info,
|
oport_info,
|
smart_chanel_new,
|
smart_chanel_new,
|
smart_chanel_in,
|
smart_chanel_in,
|
smart_chanel_out,
|
smart_chanel_out,
|
smart_req,
|
smart_req,
|
reset,
|
reset,
|
clk
|
clk
|
|
|
);
|
);
|
|
|
|
`NOC_CONF
|
|
|
input reset,clk;
|
input reset,clk;
|
input smart_chanel_t smart_chanel_new [P-1 : 0];
|
input smart_chanel_t smart_chanel_new [P-1 : 0];
|
input smart_chanel_t smart_chanel_in [P-1 : 0];
|
input smart_chanel_t smart_chanel_in [P-1 : 0];
|
input ivc_info_t ivc_info [P-1 : 0][V-1 : 0];
|
input ivc_info_t ivc_info [P-1 : 0][V-1 : 0];
|
input iport_info_t iport_info [P-1 : 0];
|
input iport_info_t iport_info [P-1 : 0];
|
input oport_info_t oport_info [P-1 : 0];
|
input oport_info_t oport_info [P-1 : 0];
|
|
|
output [P-1 : 0] smart_req;
|
output [P-1 : 0] smart_req;
|
output smart_chanel_t smart_chanel_out [P-1 : 0];
|
output smart_chanel_t smart_chanel_out [P-1 : 0];
|
|
|
|
|
smart_chanel_t smart_chanel_shifted [P-1 : 0];
|
smart_chanel_t smart_chanel_shifted [P-1 : 0];
|
localparam DISABLE = P;
|
localparam DISABLE = P;
|
|
|
wire [V-1 : 0 ] ivc_forwardable [P-1 : 0];
|
wire [V-1 : 0 ] ivc_forwardable [P-1 : 0];
|
wire [P-1 :0] smart_forwardable;
|
wire [P-1 :0] smart_forwardable;
|
logic [P-1 :0] outport_is_granted;
|
logic [P-1 :0] outport_is_granted;
|
reg [P-1 : 0] rq;
|
reg [P-1 : 0] rq;
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for (i=0;i
|
for (i=0;i
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
assign ivc_forwardable[i] = (PCK_TYPE == "SINGLE_FLIT")? 1'b1 :~iport_info[i].ivc_req;
|
assign ivc_forwardable[i] = (PCK_TYPE == "SINGLE_FLIT")? 1'b1 :~iport_info[i].ivc_req;
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
|
|
|
|
if( ADD_PIPREG_AFTER_CROSSBAR == 1 ) begin :link_reg
|
if( ADD_PIPREG_AFTER_CROSSBAR == 1) begin :link_reg
|
always @( posedge clk)begin
|
always @( posedge clk)begin
|
outport_is_granted[i] <= oport_info[i].any_ovc_granted;
|
outport_is_granted[i] <= oport_info[i].any_ovc_granted;
|
end
|
end
|
end else begin
|
end else begin
|
assign outport_is_granted[i] = oport_info[i].any_ovc_granted;
|
assign outport_is_granted[i] = oport_info[i].any_ovc_granted;
|
end
|
end
|
|
|
localparam SS_PORT = strieght_port (P,i); // the straight port number
|
localparam SS_PORT = strieght_port (P,i); // the straight port number
|
if(SS_PORT != DISABLE) begin: ssp
|
if(SS_PORT != DISABLE) begin: ssp
|
|
|
//smart_chanel_shifter
|
//smart_chanel_shifter
|
assign smart_forwardable[i] = | (ivc_forwardable[i] & smart_chanel_in[i].ovc);
|
assign smart_forwardable[i] = | (ivc_forwardable[i] & smart_chanel_in[i].ovc);
|
always @(*) begin
|
always @(*) begin
|
smart_chanel_shifted[i] = smart_chanel_in [i];
|
smart_chanel_shifted[i] = smart_chanel_in [i];
|
{smart_chanel_shifted[i].requests,rq[i]} =(smart_forwardable[i])? {1'b0,smart_chanel_in[i].requests}:{{SMART_NUM{1'b0}},smart_chanel_in[i].requests[0]};
|
{smart_chanel_shifted[i].requests,rq[i]} =(smart_forwardable[i])? {1'b0,smart_chanel_in[i].requests}:{{SMART_NUM{1'b0}},smart_chanel_in[i].requests[0]};
|
smart_chanel_shifted[i].bypassed_num = smart_chanel_in [i].bypassed_num +1'b1;
|
smart_chanel_shifted[i].bypassed_num = smart_chanel_in [i].bypassed_num +1'b1;
|
end
|
end
|
assign smart_req[i]=rq[i];
|
assign smart_req[i]=rq[i];
|
// mux out smart chanel
|
// mux out smart chanel
|
assign smart_chanel_out[i] = (outport_is_granted[i])? smart_chanel_new[i] : smart_chanel_shifted[SS_PORT];
|
assign smart_chanel_out[i] = (outport_is_granted[i])? smart_chanel_new[i] : smart_chanel_shifted[SS_PORT];
|
|
|
|
|
|
|
|
|
end else begin
|
end else begin
|
assign {smart_chanel_shifted[i].requests,smart_req[i]} = {(SMART_NUM+1){1'b0}};
|
assign {smart_chanel_shifted[i].requests,smart_req[i]} = {(SMART_NUM+1){1'b0}};
|
assign smart_chanel_out[i] = {SMART_CHANEL_w{1'b0}};
|
assign smart_chanel_out[i] = {SMART_CHANEL_w{1'b0}};
|
end
|
end
|
|
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|
module check_straight_oport #(
|
module check_straight_oport #(
|
parameter TOPOLOGY = "MESH",
|
parameter TOPOLOGY = "MESH",
|
parameter ROUTE_NAME = "XY",
|
parameter ROUTE_NAME = "XY",
|
parameter ROUTE_TYPE = "DETERMINISTIC",
|
parameter ROUTE_TYPE = "DETERMINISTIC",
|
parameter DSTPw = 4,
|
parameter DSTPw = 4,
|
parameter SS_PORT_LOC = 1
|
parameter SS_PORT_LOC = 1
|
)(
|
)(
|
destport_coded_i,
|
destport_coded_i,
|
goes_straight_o
|
goes_straight_o
|
);
|
);
|
|
|
input [DSTPw-1 : 0] destport_coded_i;
|
input [DSTPw-1 : 0] destport_coded_i;
|
output goes_straight_o;
|
output goes_straight_o;
|
|
|
generate
|
generate
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if(TOPOLOGY == "MESH" || TOPOLOGY == "TORUS" || TOPOLOGY =="FMESH" ) begin :twoD
|
if(TOPOLOGY == "MESH" || TOPOLOGY == "TORUS" || TOPOLOGY =="FMESH") begin :twoD
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
if (SS_PORT_LOC == 0 || SS_PORT_LOC > 4) begin : local_ports
|
if (SS_PORT_LOC == 0 || SS_PORT_LOC > 4) begin : local_ports
|
assign goes_straight_o = 1'b0; // There is not a next router in this case at all
|
assign goes_straight_o = 1'b0; // There is not a next router in this case at all
|
end
|
end
|
else begin :non_local
|
else begin :non_local
|
|
|
wire [4 : 0 ] destport_one_hot;
|
wire [4 : 0 ] destport_one_hot;
|
mesh_tori_decode_dstport decoder(
|
mesh_tori_decode_dstport decoder(
|
.dstport_encoded(destport_coded_i),
|
.dstport_encoded(destport_coded_i),
|
.dstport_one_hot(destport_one_hot)
|
.dstport_one_hot(destport_one_hot)
|
);
|
);
|
|
|
assign goes_straight_o = destport_one_hot [SS_PORT_LOC];
|
assign goes_straight_o = destport_one_hot [SS_PORT_LOC];
|
end//else
|
end//else
|
end//mesh_tori
|
end//mesh_tori
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
else if(TOPOLOGY == "RING" || TOPOLOGY == "LINE" ) begin :oneD
|
else if(TOPOLOGY == "RING" || TOPOLOGY == "LINE") begin :oneD
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
if (SS_PORT_LOC == 0 || SS_PORT_LOC > 2) begin : local_ports
|
if (SS_PORT_LOC == 0 || SS_PORT_LOC > 2) begin : local_ports
|
assign goes_straight_o = 1'b0; // There is not a next router in this case at all
|
assign goes_straight_o = 1'b0; // There is not a next router in this case at all
|
end
|
end
|
else begin :non_local
|
else begin :non_local
|
|
|
wire [2: 0 ] destport_one_hot;
|
wire [2: 0 ] destport_one_hot;
|
|
|
line_ring_decode_dstport decoder(
|
line_ring_decode_dstport decoder(
|
.dstport_encoded(destport_coded_i),
|
.dstport_encoded(destport_coded_i),
|
.dstport_one_hot(destport_one_hot)
|
.dstport_one_hot(destport_one_hot)
|
|
|
);
|
);
|
assign goes_straight_o = destport_one_hot [SS_PORT_LOC];
|
assign goes_straight_o = destport_one_hot [SS_PORT_LOC];
|
|
|
end //non_local
|
end //non_local
|
end// oneD
|
end// oneD
|
|
|
//TODO Add fattree & custom
|
//TODO Add fattree & custom
|
|
|
endgenerate
|
endgenerate
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
module smart_validity_check_per_ivc
|
module smart_validity_check_per_ivc #(
|
import pronoc_pkg::*;
|
parameter NOC_ID=0,
|
#(
|
|
parameter IVC_NUM = 0
|
parameter IVC_NUM = 0
|
)(
|
) (
|
reset ,
|
reset,
|
clk ,
|
clk,
|
//smart channel
|
//smart channel
|
goes_straight ,
|
goes_straight ,
|
smart_requests_i ,
|
smart_requests_i,
|
smart_ivc_i ,
|
smart_ivc_i,
|
smart_hdr_flit ,
|
smart_hdr_flit,
|
//flit
|
//flit
|
flit_hdr_flag_i ,
|
flit_hdr_flag_i,
|
flit_tail_flag_i ,
|
flit_tail_flag_i,
|
flit_wr_i ,
|
flit_wr_i,
|
//router ivc status
|
//router ivc status
|
ovc_locally_requested ,
|
ovc_locally_requested,
|
assigned_to_ss_ovc ,
|
assigned_to_ss_ovc,
|
assigned_ovc_not_full ,
|
assigned_ovc_not_full,
|
ovc_is_assigned ,
|
ovc_is_assigned,
|
ivc_request ,
|
ivc_request,
|
//ss port status
|
//ss port status
|
ss_ovc_avalable_in_ss_port ,
|
ss_ovc_avalable_in_ss_port,
|
ss_port_link_reg_flit_wr ,
|
ss_port_link_reg_flit_wr,
|
ss_ovc_crossbar_wr ,
|
ss_ovc_crossbar_wr,
|
//output
|
//output
|
smart_single_flit_pck_o ,
|
smart_single_flit_pck_o,
|
smart_ivc_smart_en_o ,
|
smart_ivc_smart_en_o,
|
smart_credit_o ,
|
smart_credit_o,
|
smart_buff_space_decreased_o ,
|
smart_buff_space_decreased_o,
|
smart_ss_ovc_is_allocated_o ,
|
smart_ss_ovc_is_allocated_o,
|
smart_ss_ovc_is_released_o ,
|
smart_ss_ovc_is_released_o,
|
smart_mask_available_ss_ovc_o ,
|
smart_mask_available_ss_ovc_o,
|
smart_ivc_num_getting_ovc_grant_o,
|
smart_ivc_num_getting_ovc_grant_o,
|
smart_ivc_reset_o,
|
smart_ivc_reset_o,
|
smart_ivc_granted_ovc_num_o
|
smart_ivc_granted_ovc_num_o
|
);
|
);
|
|
|
|
|
|
`NOC_CONF
|
|
|
|
|
input reset, clk;
|
input reset, clk;
|
//smart channel
|
//smart channel
|
input goes_straight ,
|
input goes_straight,
|
smart_requests_i ,
|
smart_requests_i,
|
smart_ivc_i ,
|
smart_ivc_i,
|
smart_hdr_flit ,
|
smart_hdr_flit,
|
//flit
|
//flit
|
flit_hdr_flag_i ,
|
flit_hdr_flag_i ,
|
flit_tail_flag_i ,
|
flit_tail_flag_i,
|
flit_wr_i ,
|
flit_wr_i,
|
//router ivc status
|
//router ivc status
|
ovc_locally_requested ,
|
ovc_locally_requested,
|
assigned_to_ss_ovc ,
|
assigned_to_ss_ovc,
|
assigned_ovc_not_full ,
|
assigned_ovc_not_full,
|
ovc_is_assigned ,
|
ovc_is_assigned,
|
ivc_request ,
|
ivc_request,
|
//ss port status
|
//ss port status
|
ss_ovc_avalable_in_ss_port ,
|
ss_ovc_avalable_in_ss_port,
|
ss_ovc_crossbar_wr,
|
ss_ovc_crossbar_wr,
|
ss_port_link_reg_flit_wr ;
|
ss_port_link_reg_flit_wr;
|
//output
|
//output
|
output
|
output
|
smart_single_flit_pck_o ,
|
smart_single_flit_pck_o ,
|
smart_ivc_smart_en_o ,
|
smart_ivc_smart_en_o,
|
smart_credit_o ,
|
smart_credit_o,
|
smart_buff_space_decreased_o ,
|
smart_buff_space_decreased_o,
|
smart_ss_ovc_is_allocated_o ,
|
smart_ss_ovc_is_allocated_o,
|
smart_ss_ovc_is_released_o ,
|
smart_ss_ovc_is_released_o,
|
smart_ivc_num_getting_ovc_grant_o,
|
smart_ivc_num_getting_ovc_grant_o,
|
smart_ivc_reset_o,
|
smart_ivc_reset_o,
|
smart_mask_available_ss_ovc_o;
|
smart_mask_available_ss_ovc_o;
|
|
|
output reg [V-1 : 0] smart_ivc_granted_ovc_num_o;
|
output reg [V-1 : 0] smart_ivc_granted_ovc_num_o;
|
|
|
always @(*) begin
|
always @(*) begin
|
smart_ivc_granted_ovc_num_o={V{1'b0}};
|
smart_ivc_granted_ovc_num_o={V{1'b0}};
|
smart_ivc_granted_ovc_num_o[IVC_NUM]=smart_ivc_num_getting_ovc_grant_o;
|
smart_ivc_granted_ovc_num_o[IVC_NUM]=smart_ivc_num_getting_ovc_grant_o;
|
end
|
end
|
|
|
|
|
|
|
wire smart_req_valid_next = smart_requests_i & smart_ivc_i & goes_straight;
|
wire smart_req_valid_next = smart_requests_i & smart_ivc_i & goes_straight;
|
logic smart_req_valid;
|
logic smart_req_valid;
|
wire smart_hdr_flit_req_next = smart_req_valid_next & smart_hdr_flit;
|
wire smart_hdr_flit_req_next = smart_req_valid_next & smart_hdr_flit;
|
logic smart_hdr_flit_req;
|
logic smart_hdr_flit_req;
|
|
|
pronoc_register #(.W(1)) req1 (.in(smart_req_valid_next), .reset(reset), .clk(clk), .out(smart_req_valid));
|
pronoc_register #(.W(1)) req1 (.in(smart_req_valid_next), .reset(reset), .clk(clk), .out(smart_req_valid));
|
pronoc_register #(.W(1)) req2 (.in(smart_hdr_flit_req_next), .reset(reset), .clk(clk), .out(smart_hdr_flit_req));
|
pronoc_register #(.W(1)) req2 (.in(smart_hdr_flit_req_next), .reset(reset), .clk(clk), .out(smart_hdr_flit_req));
|
|
|
|
|
|
|
|
|
// condition1: new smart vc allocation condition
|
// condition1: new smart vc allocation condition
|
wire hdr_flit_condition = ~ovc_locally_requested & ss_ovc_avalable_in_ss_port;
|
wire hdr_flit_condition = ~ovc_locally_requested & ss_ovc_avalable_in_ss_port;
|
wire nonhdr_flit_condition = assigned_to_ss_ovc & assigned_ovc_not_full;
|
wire nonhdr_flit_condition = assigned_to_ss_ovc & assigned_ovc_not_full;
|
wire condition1 =
|
wire condition1 =
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
(PCK_TYPE == "SINGLE_FLIT")? hdr_flit_condition :
|
(PCK_TYPE == "SINGLE_FLIT")? hdr_flit_condition :
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
(ovc_is_assigned)? nonhdr_flit_condition : hdr_flit_condition;
|
(ovc_is_assigned)? nonhdr_flit_condition : hdr_flit_condition;
|
wire condition2;
|
wire condition2;
|
generate
|
generate
|
|
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
wire non_empty_ivc_condition =(PCK_TYPE == "SINGLE_FLIT")? 1'b0 :ivc_request;
|
wire non_empty_ivc_condition =(PCK_TYPE == "SINGLE_FLIT")? 1'b0 :ivc_request;
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
|
|
|
|
if( ADD_PIPREG_AFTER_CROSSBAR == 1 ) begin :link_reg
|
if( ADD_PIPREG_AFTER_CROSSBAR == 1) begin :link_reg
|
assign condition2= ~(non_empty_ivc_condition | ss_port_link_reg_flit_wr| ss_ovc_crossbar_wr);
|
assign condition2= ~(non_empty_ivc_condition | ss_port_link_reg_flit_wr| ss_ovc_crossbar_wr);
|
end else begin : no_link_reg
|
end else begin : no_link_reg
|
assign condition2= ~(non_empty_ivc_condition | ss_port_link_reg_flit_wr); // ss_port_link_reg_flit_wr are identical with ss_ovc_crossbar_wr when there is no link reg
|
assign condition2= ~(non_empty_ivc_condition | ss_port_link_reg_flit_wr); // ss_port_link_reg_flit_wr are identical with ss_ovc_crossbar_wr when there is no link reg
|
end
|
end
|
|
|
endgenerate
|
endgenerate
|
wire conditions_met = condition1 & condition2;
|
wire conditions_met = condition1 & condition2;
|
assign smart_ivc_smart_en_o = conditions_met & smart_req_valid;
|
assign smart_ivc_smart_en_o = conditions_met & smart_req_valid;
|
|
|
|
|
|
|
assign smart_single_flit_pck_o =
|
assign smart_single_flit_pck_o =
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
(PCK_TYPE == "SINGLE_FLIT")? 1'b1 :
|
(PCK_TYPE == "SINGLE_FLIT")? 1'b1 :
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
(MIN_PCK_SIZE==1)? flit_tail_flag_i & flit_hdr_flag_i : 1'b0;
|
(MIN_PCK_SIZE==1)? flit_tail_flag_i & flit_hdr_flag_i : 1'b0;
|
|
|
assign smart_buff_space_decreased_o = smart_ivc_smart_en_o & flit_wr_i ;
|
assign smart_buff_space_decreased_o = smart_ivc_smart_en_o & flit_wr_i ;
|
assign smart_ivc_num_getting_ovc_grant_o = smart_buff_space_decreased_o & !ovc_is_assigned & flit_hdr_flag_i;
|
assign smart_ivc_num_getting_ovc_grant_o = smart_buff_space_decreased_o & !ovc_is_assigned & flit_hdr_flag_i;
|
assign smart_ivc_reset_o = smart_buff_space_decreased_o & flit_tail_flag_i;
|
assign smart_ivc_reset_o = smart_buff_space_decreased_o & flit_tail_flag_i;
|
assign smart_ss_ovc_is_released_o = smart_ivc_reset_o & ~smart_single_flit_pck_o;
|
assign smart_ss_ovc_is_released_o = smart_ivc_reset_o & ~smart_single_flit_pck_o;
|
assign smart_ss_ovc_is_allocated_o = smart_ivc_num_getting_ovc_grant_o & ~smart_single_flit_pck_o;
|
assign smart_ss_ovc_is_allocated_o = smart_ivc_num_getting_ovc_grant_o & ~smart_single_flit_pck_o;
|
|
|
|
|
|
|
|
|
//mask the available SS OVC for local requests allocation if the following conditions met
|
//mask the available SS OVC for local requests allocation if the following conditions met
|
assign smart_mask_available_ss_ovc_o = smart_hdr_flit_req & ~ovc_locally_requested & condition2;
|
assign smart_mask_available_ss_ovc_o = smart_hdr_flit_req & ~ovc_locally_requested & condition2;
|
|
|
|
|
pronoc_register #(.W(1)) credit(.in(smart_buff_space_decreased_o), .reset(reset), .clk(clk), .out(smart_credit_o));
|
pronoc_register #(.W(1)) credit(.in(smart_buff_space_decreased_o), .reset(reset), .clk(clk), .out(smart_credit_o));
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
module smart_allocator_per_iport
|
module smart_allocator_per_iport # (
|
import pronoc_pkg::*;
|
parameter NOC_ID=0,
|
#(
|
|
parameter P=5,
|
parameter P=5,
|
parameter SW_LOC=0,
|
parameter SW_LOC=0,
|
parameter SS_PORT_LOC=1
|
parameter SS_PORT_LOC=1
|
)(
|
) (
|
//general
|
//general
|
clk,
|
clk,
|
reset,
|
reset,
|
current_r_addr_i,
|
current_r_addr_i,
|
neighbors_r_addr_i,
|
neighbors_r_addr_i,
|
//smart_chanel & flit in
|
//smart_chanel & flit in
|
smart_chanel_i,
|
smart_chanel_i,
|
flit_chanel_i,
|
flit_chanel_i,
|
//router status signals
|
//router status signals
|
ivc_info,
|
ivc_info,
|
ss_ovc_info,
|
ss_ovc_info,
|
ovc_locally_requested,//make sure no conflict is existed between local & SMART VC allocation
|
ovc_locally_requested,//make sure no conflict is existed between local & SMART VC allocation
|
ss_port_link_reg_flit_wr,
|
ss_port_link_reg_flit_wr,
|
ss_smart_chanel_new,
|
ss_smart_chanel_new,
|
//output
|
//output
|
smart_destport_o,
|
smart_destport_o,
|
smart_lk_destport_o,
|
smart_lk_destport_o,
|
smart_ivc_smart_en_o,
|
smart_ivc_smart_en_o,
|
smart_credit_o,
|
smart_credit_o,
|
smart_buff_space_decreased_o,
|
smart_buff_space_decreased_o,
|
smart_ss_ovc_is_allocated_o,
|
smart_ss_ovc_is_allocated_o,
|
smart_ss_ovc_is_released_o,
|
smart_ss_ovc_is_released_o,
|
smart_ivc_num_getting_ovc_grant_o,
|
smart_ivc_num_getting_ovc_grant_o,
|
smart_ivc_reset_o,
|
smart_ivc_reset_o,
|
smart_mask_available_ss_ovc_o,
|
smart_mask_available_ss_ovc_o,
|
smart_hdr_flit_req_o,
|
smart_hdr_flit_req_o,
|
smart_ivc_granted_ovc_num_o,
|
smart_ivc_granted_ovc_num_o,
|
smart_ivc_single_flit_pck_o,
|
smart_ivc_single_flit_pck_o,
|
smart_ovc_single_flit_pck_o
|
smart_ovc_single_flit_pck_o
|
);
|
);
|
|
|
|
`NOC_CONF
|
|
|
//general
|
//general
|
input clk, reset;
|
input clk, reset;
|
input [RAw-1 :0] current_r_addr_i;
|
input [RAw-1 :0] current_r_addr_i;
|
input [RAw-1: 0] neighbors_r_addr_i [P-1 : 0];
|
input [RAw-1: 0] neighbors_r_addr_i [P-1 : 0];
|
//channels
|
//channels
|
input smart_chanel_t smart_chanel_i;
|
input smart_chanel_t smart_chanel_i;
|
input flit_chanel_t flit_chanel_i;
|
input flit_chanel_t flit_chanel_i;
|
//ivc
|
//ivc
|
input ivc_info_t ivc_info [V-1 : 0];
|
input ivc_info_t ivc_info [V-1 : 0];
|
input [V-1 : 0] ovc_locally_requested;
|
input [V-1 : 0] ovc_locally_requested;
|
//ss port
|
//ss port
|
input ovc_info_t ss_ovc_info [V-1 : 0];
|
input ovc_info_t ss_ovc_info [V-1 : 0];
|
input ss_port_link_reg_flit_wr;
|
input ss_port_link_reg_flit_wr;
|
input smart_chanel_t ss_smart_chanel_new;
|
input smart_chanel_t ss_smart_chanel_new;
|
//output
|
//output
|
output [DSTPw-1 : 0] smart_destport_o,smart_lk_destport_o;
|
output [DSTPw-1 : 0] smart_destport_o,smart_lk_destport_o;
|
output smart_hdr_flit_req_o;
|
output smart_hdr_flit_req_o;
|
output [V-1 : 0]
|
output [V-1 : 0]
|
smart_ivc_smart_en_o,
|
smart_ivc_smart_en_o,
|
smart_credit_o,
|
smart_credit_o,
|
smart_buff_space_decreased_o,
|
smart_buff_space_decreased_o,
|
smart_ss_ovc_is_allocated_o,
|
smart_ss_ovc_is_allocated_o,
|
smart_ss_ovc_is_released_o,
|
smart_ss_ovc_is_released_o,
|
smart_mask_available_ss_ovc_o,
|
smart_mask_available_ss_ovc_o,
|
smart_ivc_num_getting_ovc_grant_o,
|
smart_ivc_num_getting_ovc_grant_o,
|
smart_ivc_reset_o,
|
smart_ivc_reset_o,
|
smart_ivc_single_flit_pck_o,
|
smart_ivc_single_flit_pck_o,
|
smart_ovc_single_flit_pck_o;
|
smart_ovc_single_flit_pck_o;
|
output [V*V-1 : 0] smart_ivc_granted_ovc_num_o;
|
output [V*V-1 : 0] smart_ivc_granted_ovc_num_o;
|
|
|
assign smart_ovc_single_flit_pck_o = smart_ivc_single_flit_pck_o;
|
assign smart_ovc_single_flit_pck_o = smart_ivc_single_flit_pck_o;
|
wire [DSTPw-1 : 0] destport,lkdestport;
|
wire [DSTPw-1 : 0] destport,lkdestport;
|
wire goes_straight;
|
wire goes_straight;
|
|
|
|
|
|
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
localparam LOCATED_IN_NI=
|
localparam LOCATED_IN_NI=
|
(TOPOLOGY=="RING" || TOPOLOGY=="LINE") ? (SW_LOC == 0 || SW_LOC>2) :
|
(TOPOLOGY=="RING" || TOPOLOGY=="LINE") ? (SW_LOC == 0 || SW_LOC>2) :
|
(TOPOLOGY =="MESH" || TOPOLOGY=="TORUS" || TOPOLOGY == "FMESH")? (SW_LOC == 0 || SW_LOC>4) : 0;
|
(TOPOLOGY =="MESH" || TOPOLOGY=="TORUS" || TOPOLOGY == "FMESH")? (SW_LOC == 0 || SW_LOC>4) : 0;
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
|
|
// does the route computation for the current router
|
// does the route computation for the current router
|
conventional_routing #(
|
conventional_routing #(
|
|
.NOC_ID (NOC_ID),
|
.TOPOLOGY (TOPOLOGY ),
|
.TOPOLOGY (TOPOLOGY ),
|
.ROUTE_NAME (ROUTE_NAME ),
|
.ROUTE_NAME (ROUTE_NAME),
|
.ROUTE_TYPE (ROUTE_TYPE ),
|
.ROUTE_TYPE (ROUTE_TYPE),
|
.T1 (T1 ),
|
.T1 (T1),
|
.T2 (T2 ),
|
.T2 (T2),
|
.T3 (T3 ),
|
.T3 (T3),
|
.RAw (RAw ),
|
.RAw (RAw),
|
.EAw (EAw ),
|
.EAw (EAw),
|
.DSTPw (DSTPw ),
|
.DSTPw (DSTPw),
|
.LOCATED_IN_NI (LOCATED_IN_NI )
|
.LOCATED_IN_NI (LOCATED_IN_NI)
|
) routing (
|
) routing (
|
.reset (reset ),
|
.reset (reset),
|
.clk (clk ),
|
.clk (clk),
|
.current_r_addr (current_r_addr_i ),
|
.current_r_addr (current_r_addr_i),
|
.src_e_addr ( ),// needed only for custom routing
|
.src_e_addr ( ),// needed only for custom routing
|
.dest_e_addr (smart_chanel_i.dest_e_addr ),
|
.dest_e_addr (smart_chanel_i.dest_e_addr),
|
.destport (destport)
|
.destport (destport)
|
);
|
);
|
|
|
pronoc_register #(.W(DSTPw)) reg1 (.in(destport), .reset(reset), .clk(clk), .out(smart_destport_o));
|
pronoc_register #(.W(DSTPw)) reg1 (.in(destport), .reset(reset), .clk(clk), .out(smart_destport_o));
|
|
|
check_straight_oport #(
|
check_straight_oport #(
|
.TOPOLOGY ( TOPOLOGY ),
|
.TOPOLOGY ( TOPOLOGY),
|
.ROUTE_NAME ( ROUTE_NAME ),
|
.ROUTE_NAME ( ROUTE_NAME),
|
.ROUTE_TYPE ( ROUTE_TYPE ),
|
.ROUTE_TYPE ( ROUTE_TYPE),
|
.DSTPw ( DSTPw ),
|
.DSTPw ( DSTPw),
|
.SS_PORT_LOC ( SS_PORT_LOC)
|
.SS_PORT_LOC ( SS_PORT_LOC)
|
) check_straight (
|
) check_straight (
|
.destport_coded_i (destport),
|
.destport_coded_i (destport),
|
.goes_straight_o (goes_straight)
|
.goes_straight_o (goes_straight)
|
);
|
);
|
|
|
//look ahead routing. take straight next router address as input
|
//look ahead routing. take straight next router address as input
|
conventional_routing #(
|
conventional_routing #(
|
|
.NOC_ID(NOC_ID),
|
.TOPOLOGY (TOPOLOGY ),
|
.TOPOLOGY (TOPOLOGY ),
|
.ROUTE_NAME (ROUTE_NAME ),
|
.ROUTE_NAME (ROUTE_NAME),
|
.ROUTE_TYPE (ROUTE_TYPE ),
|
.ROUTE_TYPE (ROUTE_TYPE),
|
.T1 (T1 ),
|
.T1 (T1),
|
.T2 (T2 ),
|
.T2 (T2),
|
.T3 (T3 ),
|
.T3 (T3),
|
.RAw (RAw ),
|
.RAw (RAw),
|
.EAw (EAw ),
|
.EAw (EAw),
|
.DSTPw (DSTPw ),
|
.DSTPw (DSTPw),
|
.LOCATED_IN_NI (LOCATED_IN_NI )
|
.LOCATED_IN_NI (LOCATED_IN_NI)
|
) lkrouting (
|
) lkrouting (
|
.reset (reset ),
|
.reset (reset),
|
.clk (clk ),
|
.clk (clk),
|
.current_r_addr (neighbors_r_addr_i[SS_PORT_LOC] ),
|
.current_r_addr (neighbors_r_addr_i[SS_PORT_LOC]),
|
.src_e_addr ( ),// needed only for custom routing
|
.src_e_addr ( ),// needed only for custom routing
|
.dest_e_addr (smart_chanel_i.dest_e_addr ),
|
.dest_e_addr (smart_chanel_i.dest_e_addr),
|
.destport (lkdestport)
|
.destport (lkdestport)
|
);
|
);
|
|
|
pronoc_register #(.W(DSTPw)) reg2 (.in(lkdestport), .reset(reset), .clk(clk), .out(smart_lk_destport_o));
|
pronoc_register #(.W(DSTPw)) reg2 (.in(lkdestport), .reset(reset), .clk(clk), .out(smart_lk_destport_o));
|
|
|
wire [V-1 : 0] ss_ovc_crossbar_wr;//If asserted, a flit will be injected to ovc at next clk cycle
|
wire [V-1 : 0] ss_ovc_crossbar_wr;//If asserted, a flit will be injected to ovc at next clk cycle
|
assign ss_ovc_crossbar_wr = (ss_smart_chanel_new.requests[0] ) ? ss_smart_chanel_new.ovc : {V{1'b0}};
|
assign ss_ovc_crossbar_wr = (ss_smart_chanel_new.requests[0]) ? ss_smart_chanel_new.ovc : {V{1'b0}};
|
|
|
|
|
|
|
//assign smart_ivc_num_getting_ovc_grant_o = smart_ss_ovc_is_allocated_o;
|
//assign smart_ivc_num_getting_ovc_grant_o = smart_ss_ovc_is_allocated_o;
|
//assign smart_ivc_reset_o = smart_ss_ovc_is_released_o;
|
//assign smart_ivc_reset_o = smart_ss_ovc_is_released_o;
|
|
|
genvar i,j;
|
genvar i,j;
|
generate
|
generate
|
for (i=0;i
|
for (i=0;i
|
smart_validity_check_per_ivc #(
|
smart_validity_check_per_ivc #(
|
|
.NOC_ID(NOC_ID),
|
.IVC_NUM(i)
|
.IVC_NUM(i)
|
) validity_check (
|
) validity_check (
|
.reset (reset ),
|
.reset (reset),
|
.clk (clk ),
|
.clk (clk),
|
.goes_straight (goes_straight),
|
.goes_straight (goes_straight),
|
.smart_requests_i (smart_chanel_i.requests[0] ),
|
.smart_requests_i (smart_chanel_i.requests[0] ),
|
.smart_ivc_i (smart_chanel_i.ovc [i] ),
|
.smart_ivc_i (smart_chanel_i.ovc [i] ),
|
.smart_hdr_flit (smart_chanel_i.hdr_flit ),
|
.smart_hdr_flit (smart_chanel_i.hdr_flit),
|
|
|
.flit_hdr_flag_i (flit_chanel_i.flit.hdr_flag ),
|
.flit_hdr_flag_i (flit_chanel_i.flit.hdr_flag),
|
.flit_tail_flag_i (flit_chanel_i.flit.tail_flag ),
|
.flit_tail_flag_i (flit_chanel_i.flit.tail_flag),
|
.flit_wr_i (flit_chanel_i.flit_wr ),
|
.flit_wr_i (flit_chanel_i.flit_wr),
|
|
|
.ovc_locally_requested (ovc_locally_requested[i] ),
|
.ovc_locally_requested (ovc_locally_requested[i] ),
|
|
|
.assigned_to_ss_ovc (ivc_info[i].assigned_ovc_num[i]),
|
.assigned_to_ss_ovc (ivc_info[i].assigned_ovc_num[i]),
|
.assigned_ovc_not_full (~ss_ovc_info[i].full),
|
.assigned_ovc_not_full (~ss_ovc_info[i].full),
|
.ovc_is_assigned (ivc_info[i].ovc_is_assigned),
|
.ovc_is_assigned (ivc_info[i].ovc_is_assigned),
|
.ivc_request (ivc_info[i].ivc_req ),
|
.ivc_request (ivc_info[i].ivc_req ),
|
|
|
.ss_ovc_avalable_in_ss_port (ss_ovc_info[i].avalable),
|
.ss_ovc_avalable_in_ss_port (ss_ovc_info[i].avalable),
|
.ss_port_link_reg_flit_wr (ss_port_link_reg_flit_wr ),
|
.ss_port_link_reg_flit_wr (ss_port_link_reg_flit_wr),
|
.ss_ovc_crossbar_wr (ss_ovc_crossbar_wr[i]),
|
.ss_ovc_crossbar_wr (ss_ovc_crossbar_wr[i]),
|
|
|
.smart_single_flit_pck_o (smart_ivc_single_flit_pck_o[i] ),
|
.smart_single_flit_pck_o (smart_ivc_single_flit_pck_o[i]),
|
.smart_ivc_smart_en_o (smart_ivc_smart_en_o[i] ),
|
.smart_ivc_smart_en_o (smart_ivc_smart_en_o[i] ),
|
.smart_credit_o (smart_credit_o[i] ),
|
.smart_credit_o (smart_credit_o[i]),
|
.smart_buff_space_decreased_o (smart_buff_space_decreased_o[i]),
|
.smart_buff_space_decreased_o (smart_buff_space_decreased_o[i]),
|
.smart_ss_ovc_is_allocated_o (smart_ss_ovc_is_allocated_o[i] ),
|
.smart_ss_ovc_is_allocated_o (smart_ss_ovc_is_allocated_o[i]),
|
.smart_ss_ovc_is_released_o (smart_ss_ovc_is_released_o[i] ),
|
.smart_ss_ovc_is_released_o (smart_ss_ovc_is_released_o[i]),
|
.smart_mask_available_ss_ovc_o (smart_mask_available_ss_ovc_o[i] ),
|
.smart_mask_available_ss_ovc_o (smart_mask_available_ss_ovc_o[i]),
|
.smart_ivc_num_getting_ovc_grant_o(smart_ivc_num_getting_ovc_grant_o[i]),
|
.smart_ivc_num_getting_ovc_grant_o(smart_ivc_num_getting_ovc_grant_o[i]),
|
.smart_ivc_reset_o (smart_ivc_reset_o[i]),
|
.smart_ivc_reset_o (smart_ivc_reset_o[i]),
|
.smart_ivc_granted_ovc_num_o (smart_ivc_granted_ovc_num_o[(i+1)*V-1 : i*V])
|
.smart_ivc_granted_ovc_num_o (smart_ivc_granted_ovc_num_o[(i+1)*V-1 : i*V])
|
);
|
);
|
|
|
|
|
|
|
|
|
|
|
end//for
|
end//for
|
endgenerate
|
endgenerate
|
|
|
|
|
pronoc_register #(.W(1)) reg3 (.in(smart_chanel_i.hdr_flit), .reset(reset), .clk(clk), .out(smart_hdr_flit_req_o));
|
pronoc_register #(.W(1)) reg3 (.in(smart_chanel_i.hdr_flit), .reset(reset), .clk(clk), .out(smart_hdr_flit_req_o));
|
|
|
endmodule
|
endmodule
|
|
|
//
|
//
|
module smart_credit_manage #(
|
module smart_credit_manage #(
|
parameter V=4,
|
parameter V=4,
|
parameter B=2
|
parameter B=2
|
)(
|
)(
|
credit_in,
|
credit_in,
|
smart_credit_in,
|
smart_credit_in,
|
credit_out,
|
credit_out,
|
reset,
|
reset,
|
clk
|
clk
|
);
|
);
|
localparam Bw=$clog2(B);
|
localparam Bw=$clog2(B);
|
|
|
input [V-1 : 0] credit_in, smart_credit_in;
|
input [V-1 : 0] credit_in, smart_credit_in;
|
input reset, clk;
|
input reset, clk;
|
output [V-1 : 0] credit_out;
|
output [V-1 : 0] credit_out;
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for (i=0;i
|
for (i=0;i
|
smart_credit_manage_per_vc #(
|
smart_credit_manage_per_vc #(
|
.Bw(Bw)
|
.Bw(Bw)
|
)credit(
|
)credit(
|
.credit_in(credit_in[i]),
|
.credit_in(credit_in[i]),
|
.smart_credit_in(smart_credit_in[i]),
|
.smart_credit_in(smart_credit_in[i]),
|
.credit_out(credit_out[i]),
|
.credit_out(credit_out[i]),
|
.reset(reset),
|
.reset(reset),
|
.clk(clk)
|
.clk(clk)
|
);
|
);
|
end
|
end
|
endgenerate
|
endgenerate
|
endmodule
|
endmodule
|
|
|
module smart_credit_manage_per_vc #(
|
module smart_credit_manage_per_vc #(
|
parameter Bw=2
|
parameter Bw=2
|
)(
|
)(
|
credit_in,
|
credit_in,
|
smart_credit_in,
|
smart_credit_in,
|
credit_out,
|
credit_out,
|
reset,
|
reset,
|
clk
|
clk
|
);
|
);
|
|
|
input credit_in, smart_credit_in, reset, clk;
|
input credit_in, smart_credit_in, reset, clk;
|
output credit_out;
|
output credit_out;
|
|
|
logic [Bw : 0] counter, counter_next;
|
logic [Bw : 0] counter, counter_next;
|
|
|
always @(*) begin
|
always @(*) begin
|
counter_next=counter;
|
counter_next=counter;
|
if(credit_in & smart_credit_in ) counter_next = counter +1'b1;
|
if(credit_in & smart_credit_in) counter_next = counter +1'b1;
|
else if(credit_in | smart_credit_in ) counter_next=counter;
|
else if(credit_in | smart_credit_in) counter_next=counter;
|
else if(counter > 0) counter_next = counter -1'b1;
|
else if(counter > 0) counter_next = counter -1'b1;
|
end
|
end
|
|
|
assign credit_out = credit_in | smart_credit_in | (counter > 0);
|
assign credit_out = credit_in | smart_credit_in | (counter > 0);
|
|
|
pronoc_register #(.W(Bw+1)) reg1 (.in(counter_next), .reset(reset), .clk(clk), .out(counter));
|
pronoc_register #(.W(Bw+1)) reg1 (.in(counter_next), .reset(reset), .clk(clk), .out(counter));
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|