`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
|
|
/**************************************
|
/**************************************
|
*
|
*
|
* tree route function
|
* tree route function
|
*
|
*
|
***************************************/
|
***************************************/
|
|
|
// ============================================================
|
// ============================================================
|
// TREE: Nearest Common Ancestor w
|
// TREE: Nearest Common Ancestor w
|
// ============================================================
|
// ============================================================
|
|
|
module tree_nca_routing #(
|
module tree_nca_routing #(
|
parameter K = 2, // number of last level individual router`s endpoints.
|
parameter K = 2, // number of last level individual router`s endpoints.
|
parameter L = 2 // Fattree layer number (The height of FT)
|
parameter L = 2 // Fattree layer number (The height of FT)
|
|
|
)
|
)
|
(
|
(
|
|
|
current_addr_encoded, // connected to current router x address
|
current_addr_encoded, // connected to current router x address
|
current_level, //connected to current router y address
|
current_level, //connected to current router y address
|
dest_addr_encoded, // destination address
|
dest_addr_encoded, // destination address
|
destport_encoded // router output port
|
destport_encoded // router output port
|
|
|
);
|
);
|
|
|
|
|
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
|
Kw = log2(K),
|
Kw = log2(K),
|
LKw= L*Kw,
|
LKw= L*Kw,
|
Lw = log2(L),
|
Lw = log2(L),
|
DSPw= log2(K+1);
|
DSPw= log2(K+1);
|
|
|
input [LKw-1 :0] current_addr_encoded;
|
input [LKw-1 :0] current_addr_encoded;
|
input [Lw-1 :0] current_level;
|
input [Lw-1 :0] current_level;
|
input [LKw-1 :0] dest_addr_encoded;
|
input [LKw-1 :0] dest_addr_encoded;
|
output [DSPw-1:0] destport_encoded;
|
output [DSPw-1:0] destport_encoded;
|
|
|
/******************
|
/******************
|
There is always one destination path that can be selected for each destination endpoint
|
There is always one destination path that can be selected for each destination endpoint
|
Hence we can use the binary address of destination port
|
Hence we can use the binary address of destination port
|
*******************/
|
*******************/
|
|
|
wire [Kw-1 :0] current_addr [L-1 : 0];
|
wire [Kw-1 :0] current_addr [L-1 : 0];
|
wire [Kw-1 :0] parrent_dest_addr [L-1 : 0];
|
wire [Kw-1 :0] parrent_dest_addr [L-1 : 0];
|
wire [Kw-1 :0] dest_addr [L-1 : 0];
|
wire [Kw-1 :0] dest_addr [L-1 : 0];
|
wire [DSPw-1 :0] current_node_dest_port;
|
wire [DSPw-1 :0] current_node_dest_port;
|
|
|
wire [L-1 : 0] parrents_node_missmatch;
|
wire [L-1 : 0] parrents_node_missmatch;
|
|
|
assign current_addr [0]={Kw{1'b0}};
|
assign current_addr [0]={Kw{1'b0}};
|
assign parrent_dest_addr [0]={Kw{1'b0}};
|
assign parrent_dest_addr [0]={Kw{1'b0}};
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for(i=1; i<L; i=i+1)begin : caddr
|
for(i=1; i<L; i=i+1)begin : caddr
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
assign current_addr [i] = (current_level <i)? current_addr_encoded[i*Kw-1 : (i-1)*Kw] : {Kw{1'b0}};
|
assign current_addr [i] = (current_level <i)? current_addr_encoded[i*Kw-1 : (i-1)*Kw] : {Kw{1'b0}};
|
assign parrent_dest_addr [i] = (current_level<i)? dest_addr_encoded[(i+1)*Kw-1 : i*Kw] : {Kw{1'b0}};
|
assign parrent_dest_addr [i] = (current_level<i)? dest_addr_encoded[(i+1)*Kw-1 : i*Kw] : {Kw{1'b0}};
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
end
|
end
|
|
|
|
|
for(i=0; i<L; i=i+1) begin : daddr
|
for(i=0; i<L; i=i+1) begin : daddr
|
// assign current_addr [i] = (current_level >=i)? current_addr_encoded[(i+1)*Kw-1 : i*Kw] : {Kw{1'b0}};
|
// assign current_addr [i] = (current_level >=i)? current_addr_encoded[(i+1)*Kw-1 : i*Kw] : {Kw{1'b0}};
|
|
|
assign dest_addr [i] = dest_addr_encoded[(i+1)*Kw-1 : i*Kw];
|
assign dest_addr [i] = dest_addr_encoded[(i+1)*Kw-1 : i*Kw];
|
assign parrents_node_missmatch[i]= current_addr [i] != parrent_dest_addr [i];
|
assign parrents_node_missmatch[i]= current_addr [i] != parrent_dest_addr [i];
|
end//for
|
end//for
|
|
|
if(DSPw==Kw) begin :eq
|
if(DSPw==Kw) begin :eq
|
assign current_node_dest_port = dest_addr[current_level];
|
assign current_node_dest_port = dest_addr[current_level];
|
end else begin :neq
|
end else begin :neq
|
assign current_node_dest_port = {1'b0,dest_addr[current_level]};
|
assign current_node_dest_port = {1'b0,dest_addr[current_level]};
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
assign destport_encoded = (parrents_node_missmatch != {L{1'b0}}) ? /*go up*/ K[DSPw-1: 0] : /*go down*/current_node_dest_port;
|
assign destport_encoded = (parrents_node_missmatch != {L{1'b0}}) ? /*go up*/ K[DSPw-1: 0] : /*go down*/current_node_dest_port;
|
|
|
endmodule
|
endmodule
|
|
|
|
|
/*************************
|
/*************************
|
* tree_conventional_routing
|
* tree_conventional_routing
|
* **********************/
|
* **********************/
|
|
|
|
|
module tree_conventional_routing #(
|
module tree_conventional_routing #(
|
parameter ROUTE_NAME = "NCA",
|
parameter ROUTE_NAME = "NCA",
|
parameter K = 2, // number of last level individual router`s endpoints.
|
parameter K = 2, // number of last level individual router`s endpoints.
|
parameter L = 2 // Fattree layer number (The height of FT)
|
parameter L = 2 // Fattree layer number (The height of FT)
|
)
|
)
|
(
|
(
|
|
|
current_addr_encoded, // connected to current router x address
|
current_addr_encoded, // connected to current router x address
|
current_level, //connected to current router y address
|
current_level, //connected to current router y address
|
dest_addr_encoded, // destination address
|
dest_addr_encoded, // destination address
|
destport_encoded // router output port
|
destport_encoded // router output port
|
|
|
);
|
);
|
|
|
|
|
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
|
Kw = log2(K),
|
Kw = log2(K),
|
LKw= L*Kw,
|
LKw= L*Kw,
|
Lw = log2(L),
|
Lw = log2(L),
|
DSPw= log2(K+1);
|
DSPw= log2(K+1);
|
|
|
input [LKw-1 :0] current_addr_encoded;
|
input [LKw-1 :0] current_addr_encoded;
|
input [Lw-1 :0] current_level;
|
input [Lw-1 :0] current_level;
|
input [LKw-1 :0] dest_addr_encoded;
|
input [LKw-1 :0] dest_addr_encoded;
|
output [DSPw-1 :0] destport_encoded;
|
output [DSPw-1 :0] destport_encoded;
|
|
|
tree_nca_routing #(
|
tree_nca_routing #(
|
.K(K),
|
.K(K),
|
.L(L)
|
.L(L)
|
)
|
)
|
nca_random_up
|
nca_random_up
|
(
|
(
|
.current_addr_encoded(current_addr_encoded),
|
.current_addr_encoded(current_addr_encoded),
|
.current_level(current_level),
|
.current_level(current_level),
|
.dest_addr_encoded(dest_addr_encoded),
|
.dest_addr_encoded(dest_addr_encoded),
|
.destport_encoded(destport_encoded)
|
.destport_encoded(destport_encoded)
|
);
|
);
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
/************************************************
|
/************************************************
|
deterministic_look_ahead_routing
|
deterministic_look_ahead_routing
|
**********************************************/
|
**********************************************/
|
|
|
module tree_deterministic_look_ahead_routing #(
|
module tree_deterministic_look_ahead_routing #(
|
parameter P=4,
|
parameter P=4,
|
parameter ROUTE_NAME = "NCA_RND_UP",
|
parameter ROUTE_NAME = "NCA_RND_UP",
|
parameter K = 2, // number of last level individual router`s endpoints.
|
parameter K = 2, // number of last level individual router`s endpoints.
|
parameter L = 2 // Fattree layer number (The height of FT)
|
parameter L = 2 // Fattree layer number (The height of FT)
|
|
|
)
|
)
|
(
|
(
|
destport_encoded,// current router destination port
|
destport_encoded,// current router destination port
|
dest_addr_encoded,
|
dest_addr_encoded,
|
neighbors_rx,
|
neighbors_rx,
|
neighbors_ry,
|
neighbors_ry,
|
lkdestport_encoded // look ahead destination port
|
lkdestport_encoded // look ahead destination port
|
);
|
);
|
|
|
|
|
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
|
Kw = log2(K),
|
Kw = log2(K),
|
LKw= L*Kw,
|
LKw= L*Kw,
|
Lw = log2(L),
|
Lw = log2(L),
|
Pw=log2(P),
|
Pw=log2(P),
|
PLw = P * Lw,
|
PLw = P * Lw,
|
PLKw = P * LKw,
|
PLKw = P * LKw,
|
DSPw= log2(K+1);
|
DSPw= log2(K+1);
|
|
|
|
|
input [DSPw-1 :0] destport_encoded;
|
input [DSPw-1 :0] destport_encoded;
|
input [LKw-1 :0] dest_addr_encoded;
|
input [LKw-1 :0] dest_addr_encoded;
|
input [PLKw-1 : 0] neighbors_rx;
|
input [PLKw-1 : 0] neighbors_rx;
|
input [PLw-1 : 0] neighbors_ry;
|
input [PLw-1 : 0] neighbors_ry;
|
output [DSPw-1: 0] lkdestport_encoded;
|
output [DSPw-1: 0] lkdestport_encoded;
|
|
|
|
|
wire [LKw-1 :0] next_addr_encoded;
|
wire [LKw-1 :0] next_addr_encoded;
|
wire [Lw-1 :0] next_level;
|
wire [Lw-1 :0] next_level;
|
wire [DSPw-1:0] lkdestport_encoded;
|
wire [DSPw-1:0] lkdestport_encoded;
|
|
|
next_router_addr_selector_bin #(
|
next_router_addr_selector_bin #(
|
.P(P),
|
.P(P),
|
.RXw(LKw),
|
.RXw(LKw),
|
.RYw(Lw)
|
.RYw(Lw)
|
)
|
)
|
addr_predictor
|
addr_predictor
|
(
|
(
|
.destport_bin(destport_encoded[Pw-1 : 0]),
|
.destport_bin(destport_encoded[Pw-1 : 0]),
|
.neighbors_rx(neighbors_rx),
|
.neighbors_rx(neighbors_rx),
|
.neighbors_ry(neighbors_ry),
|
.neighbors_ry(neighbors_ry),
|
.next_rx(next_addr_encoded),
|
.next_rx(next_addr_encoded),
|
.next_ry(next_level)
|
.next_ry(next_level)
|
);
|
);
|
|
|
|
|
tree_conventional_routing #(
|
tree_conventional_routing #(
|
.ROUTE_NAME(ROUTE_NAME),
|
.ROUTE_NAME(ROUTE_NAME),
|
.K(K),
|
.K(K),
|
.L(L)
|
.L(L)
|
)
|
)
|
conv_routing
|
conv_routing
|
(
|
(
|
|
|
.current_addr_encoded(next_addr_encoded),
|
.current_addr_encoded(next_addr_encoded),
|
.current_level(next_level),
|
.current_level(next_level),
|
.dest_addr_encoded(dest_addr_encoded),
|
.dest_addr_encoded(dest_addr_encoded),
|
.destport_encoded(lkdestport_encoded)
|
.destport_encoded(lkdestport_encoded)
|
);
|
);
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
/************************************
|
/************************************
|
|
|
tree_look_ahead_routing
|
tree_look_ahead_routing
|
|
|
*************************************/
|
*************************************/
|
|
|
module tree_look_ahead_routing #(
|
module tree_look_ahead_routing #(
|
parameter ROUTE_NAME = "NCA",
|
parameter ROUTE_NAME = "NCA",
|
parameter P = 4,
|
parameter P = 4,
|
parameter L = 2,
|
parameter L = 2,
|
parameter K = 2
|
parameter K = 2
|
|
|
)
|
)
|
(
|
(
|
reset,
|
reset,
|
clk,
|
clk,
|
destport_encoded,// current router destination port
|
destport_encoded,// current router destination port
|
dest_addr_encoded,
|
dest_addr_encoded,
|
neighbors_rx,
|
neighbors_rx,
|
neighbors_ry,
|
neighbors_ry,
|
lkdestport_encoded // look ahead destination port
|
lkdestport_encoded // look ahead destination port
|
);
|
);
|
|
|
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
|
Kw = log2(K),
|
Kw = log2(K),
|
LKw= L*Kw,
|
LKw= L*Kw,
|
Lw = log2(L),
|
Lw = log2(L),
|
PLw = P * Lw,
|
PLw = P * Lw,
|
PLKw = P * LKw,
|
PLKw = P * LKw,
|
DSPw= log2(K+1);
|
DSPw= log2(K+1);
|
|
|
input [DSPw-1 :0] destport_encoded;
|
input [DSPw-1 :0] destport_encoded;
|
input [LKw-1 :0] dest_addr_encoded;
|
input [LKw-1 :0] dest_addr_encoded;
|
input [PLKw-1 : 0] neighbors_rx;
|
input [PLKw-1 : 0] neighbors_rx;
|
input [PLw-1 : 0] neighbors_ry;
|
input [PLw-1 : 0] neighbors_ry;
|
output [DSPw-1: 0] lkdestport_encoded;
|
output [DSPw-1: 0] lkdestport_encoded;
|
input reset,clk;
|
input reset,clk;
|
|
|
reg [DSPw-1 :0] destport_encoded_delayed;
|
wire [DSPw-1 :0] destport_encoded_delayed;
|
reg [LKw-1 :0] dest_addr_encoded_delayed;
|
wire [LKw-1 :0] dest_addr_encoded_delayed;
|
|
|
tree_deterministic_look_ahead_routing #(
|
tree_deterministic_look_ahead_routing #(
|
.P(P),
|
.P(P),
|
.ROUTE_NAME(ROUTE_NAME),
|
.ROUTE_NAME(ROUTE_NAME),
|
.K(K),
|
.K(K),
|
.L(L)
|
.L(L)
|
)
|
)
|
look_ahead_routing
|
look_ahead_routing
|
(
|
(
|
.destport_encoded(destport_encoded_delayed),
|
.destport_encoded(destport_encoded_delayed),
|
.dest_addr_encoded(dest_addr_encoded_delayed),
|
.dest_addr_encoded(dest_addr_encoded_delayed),
|
.neighbors_rx(neighbors_rx),
|
.neighbors_rx(neighbors_rx),
|
.neighbors_ry(neighbors_ry),
|
.neighbors_ry(neighbors_ry),
|
.lkdestport_encoded(lkdestport_encoded)
|
.lkdestport_encoded(lkdestport_encoded)
|
);
|
);
|
|
|
|
pronoc_register #(.W(DSPw)) reg1 (.in(destport_encoded ), .out(destport_encoded_delayed), .reset(reset), .clk(clk));
|
|
pronoc_register #(.W(LKw )) reg2 (.in(dest_addr_encoded ), .out(dest_addr_encoded_delayed),.reset(reset), .clk(clk));
|
|
|
|
|
|
|
`ifdef SYNC_RESET_MODE
|
|
always @ (posedge clk )begin
|
|
`else
|
|
always @ (posedge clk or posedge reset)begin
|
|
`endif
|
|
if(reset)begin
|
|
destport_encoded_delayed <= {DSPw{1'b0}};
|
|
dest_addr_encoded_delayed<= {LKw{1'b0}};
|
|
end else begin
|
|
destport_encoded_delayed<=destport_encoded;
|
|
dest_addr_encoded_delayed<=dest_addr_encoded;
|
|
end//else reset
|
|
end//always
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
/*************
|
/*************
|
* tree_destport_encoder
|
* tree_destport_encoder
|
* ***********/
|
* ***********/
|
|
|
module tree_destport_decoder #(
|
module tree_destport_decoder #(
|
parameter K=2
|
parameter K=2
|
)(
|
)(
|
destport_decoded_o,
|
destport_decoded_o,
|
destport_encoded_i
|
destport_encoded_i
|
);
|
);
|
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
|
MAX_P = K+1,
|
MAX_P = K+1,
|
DSPw= log2(MAX_P);
|
DSPw= log2(MAX_P);
|
|
|
input [DSPw-1 : 0] destport_encoded_i;
|
input [DSPw-1 : 0] destport_encoded_i;
|
output [MAX_P-1 : 0] destport_decoded_o;
|
output [MAX_P-1 : 0] destport_decoded_o;
|
|
|
|
|
bin_to_one_hot #(
|
bin_to_one_hot #(
|
.BIN_WIDTH(DSPw),
|
.BIN_WIDTH(DSPw),
|
.ONE_HOT_WIDTH(MAX_P)
|
.ONE_HOT_WIDTH(MAX_P)
|
)
|
)
|
cnvt
|
cnvt
|
(
|
(
|
.bin_code(destport_encoded_i),
|
.bin_code(destport_encoded_i),
|
.one_hot_code(destport_decoded_o)
|
.one_hot_code(destport_decoded_o)
|
);
|
);
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
//decode and mask destport
|
//decode and mask destport
|
module tree_destp_generator #(
|
module tree_destp_generator #(
|
parameter K=2,
|
parameter K=2,
|
parameter P=K+1,
|
parameter P=K+1,
|
parameter SW_LOC=0,
|
parameter SW_LOC=0,
|
parameter DSTPw=4,
|
parameter DSTPw=4,
|
parameter SELF_LOOP_EN = "NO"
|
parameter SELF_LOOP_EN = "NO"
|
)(
|
)(
|
dest_port_in_encoded,
|
dest_port_in_encoded,
|
dest_port_out
|
dest_port_out
|
);
|
);
|
|
|
|
|
localparam
|
localparam
|
MAX_P = K+1,
|
MAX_P = K+1,
|
P_1 = (SELF_LOOP_EN == "NO")? P-1 : P;
|
P_1 = (SELF_LOOP_EN == "NO")? P-1 : P;
|
|
|
input [DSTPw-1:0] dest_port_in_encoded;
|
input [DSTPw-1:0] dest_port_in_encoded;
|
output [P_1-1 : 0] dest_port_out;
|
output [P_1-1 : 0] dest_port_out;
|
|
|
wire [MAX_P-1 : 0] destport_decoded;
|
wire [MAX_P-1 : 0] destport_decoded;
|
|
|
tree_destport_decoder #(
|
tree_destport_decoder #(
|
.K(K)
|
.K(K)
|
)
|
)
|
destport_decoder
|
destport_decoder
|
(
|
(
|
.destport_encoded_i(dest_port_in_encoded),
|
.destport_encoded_i(dest_port_in_encoded),
|
.destport_decoded_o(destport_decoded)
|
.destport_decoded_o(destport_decoded)
|
);
|
);
|
|
|
generate
|
generate
|
if(SELF_LOOP_EN == "NO") begin : nslp
|
if(SELF_LOOP_EN == "NO") begin : nslp
|
remove_sw_loc_one_hot #(
|
remove_sw_loc_one_hot #(
|
.P(P),
|
.P(P),
|
.SW_LOC(SW_LOC)
|
.SW_LOC(SW_LOC)
|
)
|
)
|
conv
|
conv
|
(
|
(
|
.destport_in(destport_decoded[P-1 : 0]),
|
.destport_in(destport_decoded[P-1 : 0]),
|
.destport_out(dest_port_out[P_1-1 : 0 ])
|
.destport_out(dest_port_out[P_1-1 : 0 ])
|
);
|
);
|
end else begin : slp
|
end else begin : slp
|
assign dest_port_out = destport_decoded;
|
assign dest_port_out = destport_decoded;
|
end
|
end
|
endgenerate
|
endgenerate
|
endmodule
|
endmodule
|
|
|