`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
/**************************************
|
/**************************************
|
*
|
*
|
* fattree rout function
|
* fattree rout function
|
*
|
*
|
***************************************/
|
***************************************/
|
|
|
// ============================================================
|
// ============================================================
|
// FATTREE: Nearest Common Ancestor w/ Random Routing Up
|
// FATTREE: Nearest Common Ancestor w/ Random Routing Up
|
// ============================================================
|
// ============================================================
|
|
|
module fattree_nca_random_up_routing #(
|
module fattree_nca_random_up_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)
|
|
|
)
|
)
|
(
|
(
|
reset,
|
reset,
|
clk,
|
clk,
|
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);
|
|
|
|
|
|
|
input reset,clk;
|
input reset,clk;
|
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 [K :0] destport_encoded;
|
output [K :0] destport_encoded;
|
/******************
|
/******************
|
destport_encoded format in fat tree. K+1 bit
|
destport_encoded format in fat tree. K+1 bit
|
destport[K]
|
destport[K]
|
1'b0 : go down
|
1'b0 : go down
|
1'b1 : go up
|
1'b1 : go up
|
destport[K-1: 0]:
|
destport[K-1: 0]:
|
onehot coded. asserted bit show the output port locatation
|
onehot coded. asserted bit show the output port locatation
|
*******************/
|
*******************/
|
|
|
|
|
|
|
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 [Kw-1 :0] current_node_dest_port;
|
wire [Kw-1 :0] current_node_dest_port;
|
|
|
wire [L-1 : 0] parrents_node_missmatch;
|
wire [L-1 : 0] parrents_node_missmatch;
|
|
|
reg [K-1 : 0] counter; // a one hot counter. The value of the counter is used as a random destination port number when going to the up ports
|
wire [K-1 : 0] counter; // a one hot counter. The value of the counter is used as a random destination port number when going to the up ports
|
|
|
|
pronoc_register #(
|
|
.W(K),
|
|
.RESET_TO(1)
|
|
) reg1 (
|
|
.in({counter[0],counter[K-1:1]}),
|
|
.reset(reset),
|
|
.clk(clk),
|
|
.out(counter)
|
|
);
|
|
|
|
|
|
|
|
|
`ifdef SYNC_RESET_MODE
|
|
always @ (posedge clk )begin
|
|
`else
|
|
always @ (posedge clk or posedge reset)begin
|
|
`endif
|
|
if(reset) begin
|
|
counter <= 1;
|
|
end
|
|
else begin
|
|
counter <= {counter[0],counter[K-1:1]};
|
|
end
|
|
end
|
|
|
|
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
|
endgenerate
|
endgenerate
|
|
|
assign current_node_dest_port = dest_addr[current_level];
|
assign current_node_dest_port = dest_addr[current_level];
|
wire [K-1:0] current_node_dest_port_one_hot;
|
wire [K-1:0] current_node_dest_port_one_hot;
|
|
|
bin_to_one_hot #(
|
bin_to_one_hot #(
|
.BIN_WIDTH(Kw),
|
.BIN_WIDTH(Kw),
|
.ONE_HOT_WIDTH(K)
|
.ONE_HOT_WIDTH(K)
|
)
|
)
|
conv
|
conv
|
(
|
(
|
.bin_code(current_node_dest_port),
|
.bin_code(current_node_dest_port),
|
.one_hot_code(current_node_dest_port_one_hot)
|
.one_hot_code(current_node_dest_port_one_hot)
|
);
|
);
|
|
|
assign destport_encoded = (parrents_node_missmatch != {L{1'b0}}) ? /*go up*/{1'b1,counter} : /*go down*/{1'b0,current_node_dest_port_one_hot};
|
assign destport_encoded = (parrents_node_missmatch != {L{1'b0}}) ? /*go up*/{1'b1,counter} : /*go down*/{1'b0,current_node_dest_port_one_hot};
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
// ============================================================
|
// ============================================================
|
// FATTREE: Nearest Common Ancestor w/ destination port Up.
|
// FATTREE: Nearest Common Ancestor w/ destination port Up.
|
// The up port is selected based on destination connected port num
|
// The up port is selected based on destination connected port num
|
// ============================================================
|
// ============================================================
|
|
|
module fattree_nca_destp_up_routing #(
|
module fattree_nca_destp_up_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)
|
|
|
)
|
)
|
(
|
(
|
reset,
|
reset,
|
clk,
|
clk,
|
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);
|
|
|
|
|
|
|
input reset,clk;
|
input reset,clk;
|
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 [K :0] destport_encoded;
|
output [K :0] destport_encoded;
|
/******************
|
/******************
|
destport_encoded format in fat tree. K+1 bit
|
destport_encoded format in fat tree. K+1 bit
|
destport[K]
|
destport[K]
|
1'b0 : go down
|
1'b0 : go down
|
1'b1 : go up
|
1'b1 : go up
|
destport[K-1: 0]:
|
destport[K-1: 0]:
|
onehot coded. asserted bit show the output port locatation
|
onehot coded. asserted bit show the output port locatation
|
*******************/
|
*******************/
|
|
|
|
|
|
|
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 [Kw-1 :0] current_node_dest_port;
|
wire [Kw-1 :0] current_node_dest_port;
|
|
|
wire [L-1 : 0] parrents_node_missmatch;
|
wire [L-1 : 0] parrents_node_missmatch;
|
|
|
reg [K-1 : 0] counter; // a one hot counter. The value of the counter is used as a random destination port number when going to the up ports
|
wire [K-1 : 0] counter; // a one hot counter. The value of the counter is used as a random destination port number when going to the up ports
|
|
|
`ifdef SYNC_RESET_MODE
|
pronoc_register #(
|
always @ (posedge clk )begin
|
.W(K),
|
`else
|
.RESET_TO(1)
|
always @ (posedge clk or posedge reset)begin
|
) reg1 (
|
`endif
|
.in({counter[0],counter[K-1:1]}),
|
if(reset) begin
|
.reset(reset),
|
counter <= 1;
|
.clk(clk),
|
end
|
.out(counter)
|
else begin
|
);
|
counter <= {counter[0],counter[K-1:1]};
|
|
end
|
|
end
|
|
|
|
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
|
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}};
|
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
|
endgenerate
|
endgenerate
|
|
|
assign current_node_dest_port = dest_addr[current_level];
|
assign current_node_dest_port = dest_addr[current_level];
|
wire [K-1:0] current_node_dest_port_one_hot;
|
wire [K-1:0] current_node_dest_port_one_hot;
|
|
|
bin_to_one_hot #(
|
bin_to_one_hot #(
|
.BIN_WIDTH(Kw),
|
.BIN_WIDTH(Kw),
|
.ONE_HOT_WIDTH(K)
|
.ONE_HOT_WIDTH(K)
|
)
|
)
|
conv
|
conv
|
(
|
(
|
.bin_code(current_node_dest_port),
|
.bin_code(current_node_dest_port),
|
.one_hot_code(current_node_dest_port_one_hot)
|
.one_hot_code(current_node_dest_port_one_hot)
|
);
|
);
|
|
|
assign destport_encoded = (parrents_node_missmatch != {L{1'b0}}) ? /*go up*/{1'b1,current_node_dest_port_one_hot} : /*go down*/{1'b0,current_node_dest_port_one_hot};
|
assign destport_encoded = (parrents_node_missmatch != {L{1'b0}}) ? /*go up*/{1'b1,current_node_dest_port_one_hot} : /*go down*/{1'b0,current_node_dest_port_one_hot};
|
|
|
endmodule
|
endmodule
|
|
|
|
|
// ============================================================
|
// ============================================================
|
// FATTREE: Nearest Common Ancestor w/ straight port Up.
|
// FATTREE: Nearest Common Ancestor w/ straight port Up.
|
// The up port is in the same column as reciver port
|
// The up port is in the same column as reciver port
|
// ============================================================
|
// ============================================================
|
|
|
module fattree_nca_straight_up_routing #(
|
module fattree_nca_straight_up_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)
|
|
|
)
|
)
|
(
|
(
|
reset,
|
reset,
|
clk,
|
clk,
|
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);
|
|
|
|
|
|
|
input reset,clk;
|
input reset,clk;
|
|
|
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 [K :0] destport_encoded;
|
output [K :0] destport_encoded;
|
|
|
/******************
|
/******************
|
destport_encoded format in fat tree. K+1 bit
|
destport_encoded format in fat tree. K+1 bit
|
destport[K]
|
destport[K]
|
1'b0 : go down
|
1'b0 : go down
|
1'b1 : go up
|
1'b1 : go up
|
destport[K-1: 0]:
|
destport[K-1: 0]:
|
onehot coded. asserted bit show the output port locatation
|
onehot coded. asserted bit show the output port locatation
|
*******************/
|
*******************/
|
|
|
|
|
|
|
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 [Kw-1 :0] current_node_dest_port;
|
wire [Kw-1 :0] current_node_dest_port;
|
|
|
wire [L-1 : 0] parrents_node_missmatch;
|
wire [L-1 : 0] parrents_node_missmatch;
|
|
|
reg [K-1 : 0] counter; // a one hot counter. The value of the counter is used as a random destination port number when going to the up ports
|
wire [K-1 : 0] counter; // a one hot counter. The value of the counter is used as a random destination port number when going to the up ports
|
|
|
`ifdef SYNC_RESET_MODE
|
pronoc_register #(
|
always @ (posedge clk )begin
|
.W(K),
|
`else
|
.RESET_TO(1)
|
always @ (posedge clk or posedge reset)begin
|
) reg1 (
|
`endif
|
.in({counter[0],counter[K-1:1]}),
|
if(reset) begin
|
.reset(reset),
|
counter <= 1;
|
.clk(clk),
|
end
|
.out(counter)
|
else begin
|
);
|
counter <= {counter[0],counter[K-1:1]};
|
|
end
|
|
end
|
|
|
|
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
|
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}};
|
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
|
endgenerate
|
endgenerate
|
|
|
assign current_node_dest_port = dest_addr[current_level];
|
assign current_node_dest_port = dest_addr[current_level];
|
wire [K-1:0] current_node_dest_port_one_hot;
|
wire [K-1:0] current_node_dest_port_one_hot;
|
|
|
bin_to_one_hot #(
|
bin_to_one_hot #(
|
.BIN_WIDTH(Kw),
|
.BIN_WIDTH(Kw),
|
.ONE_HOT_WIDTH(K)
|
.ONE_HOT_WIDTH(K)
|
)
|
)
|
conv
|
conv
|
(
|
(
|
.bin_code(current_node_dest_port),
|
.bin_code(current_node_dest_port),
|
.one_hot_code(current_node_dest_port_one_hot)
|
.one_hot_code(current_node_dest_port_one_hot)
|
);
|
);
|
|
|
// if going up the destination port num is statis straigh. It will be filled at reciver port of the next router so leave it empty
|
// if going up the destination port num is statis straigh. It will be filled at reciver port of the next router so leave it empty
|
assign destport_encoded = (parrents_node_missmatch != {L{1'b0}}) ? /*go up*/{1'b1,{K{1'b0}}} : /*go down*/{1'b0,current_node_dest_port_one_hot};
|
assign destport_encoded = (parrents_node_missmatch != {L{1'b0}}) ? /*go up*/{1'b1,{K{1'b0}}} : /*go down*/{1'b0,current_node_dest_port_one_hot};
|
|
|
endmodule
|
endmodule
|
|
|
|
|
module fattree_destport_up_select #(
|
module fattree_destport_up_select #(
|
parameter K=3,
|
parameter K=3,
|
parameter SW_LOC=0
|
parameter SW_LOC=0
|
)(
|
)(
|
destport_in,
|
destport_in,
|
destport_o
|
destport_o
|
);
|
);
|
|
|
input [K :0] destport_in;
|
input [K :0] destport_in;
|
output [K :0] destport_o;
|
output [K :0] destport_o;
|
|
|
localparam [K-1 : 0] SW_LOC_ONHOT = 1<< SW_LOC;
|
localparam [K-1 : 0] SW_LOC_ONHOT = 1<< SW_LOC;
|
|
|
|
|
wire going_up = destport_in[K];
|
wire going_up = destport_in[K];
|
assign destport_o = (going_up)? {1'b1,SW_LOC_ONHOT[K-1 : 0]} : destport_in;
|
assign destport_o = (going_up)? {1'b1,SW_LOC_ONHOT[K-1 : 0]} : destport_in;
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
/*************************
|
/*************************
|
* fattree_conventional_routing
|
* fattree_conventional_routing
|
* **********************/
|
* **********************/
|
|
|
|
|
module fattree_conventional_routing #(
|
module fattree_conventional_routing #(
|
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)
|
)
|
)
|
(
|
(
|
reset,
|
reset,
|
clk,
|
clk,
|
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);
|
|
|
|
|
|
|
input reset,clk;
|
input reset,clk;
|
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 [K :0] destport_encoded;
|
output [K :0] destport_encoded;
|
|
|
|
|
generate
|
generate
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if( ROUTE_NAME == "NCA_RND_UP")begin :nca_rnd
|
if( ROUTE_NAME == "NCA_RND_UP")begin :nca_rnd
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
fattree_nca_random_up_routing #(
|
fattree_nca_random_up_routing #(
|
.K(K),
|
.K(K),
|
.L(L)
|
.L(L)
|
)
|
)
|
nca_random_up
|
nca_random_up
|
(
|
(
|
.reset(reset),
|
.reset(reset),
|
.clk(clk),
|
.clk(clk),
|
.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)
|
);
|
);
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
end else if ( ROUTE_NAME == "NCA_DST_UP")begin :nca_dst
|
end else if ( ROUTE_NAME == "NCA_DST_UP")begin :nca_dst
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
fattree_nca_destp_up_routing #(
|
fattree_nca_destp_up_routing #(
|
.K(K),
|
.K(K),
|
.L(L)
|
.L(L)
|
)
|
)
|
nca_random_up
|
nca_random_up
|
(
|
(
|
.reset(reset),
|
.reset(reset),
|
.clk(clk),
|
.clk(clk),
|
.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)
|
);
|
);
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
end else if ( ROUTE_NAME == "NCA_STRAIGHT_UP")begin :nca_straight
|
end else if ( ROUTE_NAME == "NCA_STRAIGHT_UP")begin :nca_straight
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
fattree_nca_straight_up_routing #(
|
fattree_nca_straight_up_routing #(
|
.K(K),
|
.K(K),
|
.L(L)
|
.L(L)
|
)
|
)
|
nca_straight_up
|
nca_straight_up
|
(
|
(
|
.reset(reset),
|
.reset(reset),
|
.clk(clk),
|
.clk(clk),
|
.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)
|
);
|
);
|
end else begin
|
end else begin
|
// synthesis translate_off
|
// synthesis translate_off
|
initial begin
|
initial begin
|
$display( "\t ERROR: %s is an undefined routing algorithm for FATTREE topology",ROUTE_NAME);
|
$display( "\t ERROR: %s is an undefined routing algorithm for FATTREE topology",ROUTE_NAME);
|
$finish;
|
$finish;
|
end
|
end
|
// synthesis translate_on
|
// synthesis translate_on
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
endmodule
|
endmodule
|
|
|
|
|
/************************************
|
/************************************
|
|
|
fattree_look_ahead_routing
|
fattree_look_ahead_routing
|
|
|
*************************************/
|
*************************************/
|
|
|
module fattree_look_ahead_routing #(
|
module fattree_look_ahead_routing #(
|
parameter ROUTE_NAME = "NCA_RND_UP",
|
parameter ROUTE_NAME = "NCA_RND_UP",
|
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;
|
|
|
input [K :0] destport_encoded;
|
input [K :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 [K: 0] lkdestport_encoded;
|
output [K: 0] lkdestport_encoded;
|
input reset,clk;
|
input reset,clk;
|
|
|
reg [K :0] destport_encoded_delayed;
|
wire [K :0] destport_encoded_delayed;
|
reg [LKw-1 :0] dest_addr_encoded_delayed;
|
wire [LKw-1 :0] dest_addr_encoded_delayed;
|
|
|
fattree_deterministic_look_ahead_routing #(
|
fattree_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
|
(
|
(
|
.reset(reset),
|
.reset(reset),
|
.clk(clk),
|
.clk(clk),
|
.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)
|
);
|
);
|
|
|
|
|
`ifdef SYNC_RESET_MODE
|
pronoc_register #(
|
always @ (posedge clk )begin
|
.W(K+1)
|
`else
|
) reg1 (
|
always @ (posedge clk or posedge reset)begin
|
.in(destport_encoded),
|
`endif
|
.reset(reset),
|
if(reset)begin
|
.clk(clk),
|
destport_encoded_delayed <= {(K+1){1'b0}};
|
.out(destport_encoded_delayed)
|
dest_addr_encoded_delayed<= {LKw{1'b0}};
|
);
|
end else begin
|
|
destport_encoded_delayed<=destport_encoded;
|
pronoc_register #(
|
dest_addr_encoded_delayed<=dest_addr_encoded;
|
.W(LKw)
|
end//else reset
|
) reg2 (
|
end//always
|
.in(dest_addr_encoded),
|
|
.reset(reset),
|
|
.clk(clk),
|
|
.out(dest_addr_encoded_delayed)
|
|
);
|
|
|
|
|
|
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************
|
/************************************************
|
|
|
deterministic_look_ahead_routing
|
deterministic_look_ahead_routing
|
**********************************************/
|
**********************************************/
|
|
|
|
|
module fattree_deterministic_look_ahead_routing #(
|
module fattree_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)
|
|
|
)
|
)
|
(
|
(
|
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;
|
|
|
input reset,clk;
|
input reset,clk;
|
input [K :0] destport_encoded;
|
input [K :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 [K: 0] lkdestport_encoded;
|
output [K: 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 [K : 0] lkdestport_encoded;
|
wire [K : 0] lkdestport_encoded;
|
wire [2*K-1 : 0] destport_decoded;
|
wire [2*K-1 : 0] destport_decoded;
|
|
|
fattree_destport_decoder #(
|
fattree_destport_decoder #(
|
.K(K)
|
.K(K)
|
)
|
)
|
fattree_destport_decoder(
|
fattree_destport_decoder(
|
.destport_encoded_i(destport_encoded),
|
.destport_encoded_i(destport_encoded),
|
.destport_decoded_o(destport_decoded)
|
.destport_decoded_o(destport_decoded)
|
);
|
);
|
|
|
|
|
next_router_addr_selector_onehot #(
|
next_router_addr_selector_onehot #(
|
.P(P),
|
.P(P),
|
.RXw(LKw),
|
.RXw(LKw),
|
.RYw(Lw)
|
.RYw(Lw)
|
)
|
)
|
addr_predictor
|
addr_predictor
|
(
|
(
|
.destport_onehot(destport_decoded[P-1 : 0]),
|
.destport_onehot(destport_decoded[P-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)
|
);
|
);
|
|
|
|
|
fattree_conventional_routing #(
|
fattree_conventional_routing #(
|
.ROUTE_NAME(ROUTE_NAME),
|
.ROUTE_NAME(ROUTE_NAME),
|
.K(K),
|
.K(K),
|
.L(L)
|
.L(L)
|
)
|
)
|
conv_routing
|
conv_routing
|
(
|
(
|
.reset(reset),
|
.reset(reset),
|
.clk(clk),
|
.clk(clk),
|
.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
|
|
|
module fattree_destport_decoder #(
|
module fattree_destport_decoder #(
|
parameter K=2
|
parameter K=2
|
|
|
)(
|
)(
|
destport_decoded_o,
|
destport_decoded_o,
|
destport_encoded_i
|
destport_encoded_i
|
);
|
);
|
|
|
input [K:0] destport_encoded_i;
|
input [K:0] destport_encoded_i;
|
output [2*K-1 : 0] destport_decoded_o;
|
output [2*K-1 : 0] destport_decoded_o;
|
|
|
assign destport_decoded_o = (destport_encoded_i[K])? /*go up*/ {destport_encoded_i[K-1:0],{K{1'b0}}}:
|
assign destport_decoded_o = (destport_encoded_i[K])? /*go up*/ {destport_encoded_i[K-1:0],{K{1'b0}}}:
|
/*go down*/ {{K{1'b0}},destport_encoded_i[K-1:0]};
|
/*go down*/ {{K{1'b0}},destport_encoded_i[K-1:0]};
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
/**********
|
/**********
|
* fattree_mask_non_assignable_destport
|
* fattree_mask_non_assignable_destport
|
* ********/
|
* ********/
|
|
|
module fattree_mask_non_assignable_destport #(
|
module fattree_mask_non_assignable_destport #(
|
parameter K=4,
|
parameter K=4,
|
parameter P=2*K,
|
parameter P=2*K,
|
parameter SW_LOC = 0
|
parameter SW_LOC = 0
|
)
|
)
|
(
|
(
|
destport_in,
|
destport_in,
|
destport_out
|
destport_out
|
);
|
);
|
|
|
input [2*K-1 : 0] destport_in;
|
input [2*K-1 : 0] destport_in;
|
output [2*K-1 : 0] destport_out;
|
output [2*K-1 : 0] destport_out;
|
|
|
generate
|
generate
|
if(P<=K)begin :root //This is a root node there is conectivety between all ports
|
if(P<=K)begin :root //This is a root node there is conectivety between all ports
|
assign destport_out = destport_in;
|
assign destport_out = destport_in;
|
end else begin: leaf
|
end else begin: leaf
|
if(SW_LOC < K) begin: down // This port located in lower side of the router. It can send packet to any destport
|
if(SW_LOC < K) begin: down // This port located in lower side of the router. It can send packet to any destport
|
assign destport_out = destport_in;
|
assign destport_out = destport_in;
|
end else begin : up // // This port located in upper side of the router. It cannot send packet to upper port anymore
|
end else begin : up // // This port located in upper side of the router. It cannot send packet to upper port anymore
|
assign destport_out[2*K-1 : K] = {K{1'b0}};
|
assign destport_out[2*K-1 : K] = {K{1'b0}};
|
assign destport_out[K-1 : 0] = destport_in [K-1 : 0];
|
assign destport_out[K-1 : 0] = destport_in [K-1 : 0];
|
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
endmodule
|
endmodule
|
|
|
/********************
|
/********************
|
|
|
distance_gen
|
distance_gen
|
|
|
********************/
|
********************/
|
|
|
module fattree_distance_gen #(
|
module fattree_distance_gen #(
|
parameter K= 4,
|
parameter K= 4,
|
parameter L= 4
|
parameter L= 4
|
)(
|
)(
|
src_addr_encoded,
|
src_addr_encoded,
|
dest_addr_encoded,
|
dest_addr_encoded,
|
distance
|
distance
|
|
|
);
|
);
|
|
|
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,
|
DISTw= log2(2*L+1);
|
DISTw= log2(2*L+1);
|
|
|
input [LKw-1 :0] src_addr_encoded;
|
input [LKw-1 :0] src_addr_encoded;
|
input [LKw-1 :0] dest_addr_encoded;
|
input [LKw-1 :0] dest_addr_encoded;
|
output reg [DISTw-1 : 0] distance;
|
output reg [DISTw-1 : 0] distance;
|
|
|
|
|
|
|
wire [Kw-1 :0] dest_addr [L-1 : 0];
|
wire [Kw-1 :0] dest_addr [L-1 : 0];
|
wire [Kw-1 :0] src_addr [L-1 : 0];
|
wire [Kw-1 :0] src_addr [L-1 : 0];
|
wire [L-1 : 0] diffrent;
|
wire [L-1 : 0] diffrent;
|
|
|
|
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for(i=0; i<L; i=i+1)begin : daddr
|
for(i=0; i<L; i=i+1)begin : daddr
|
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 src_addr [i] = src_addr_encoded[(i+1)*Kw-1 : i*Kw];
|
assign src_addr [i] = src_addr_encoded[(i+1)*Kw-1 : i*Kw];
|
assign diffrent[i] = dest_addr [i] != src_addr [i];
|
assign diffrent[i] = dest_addr [i] != src_addr [i];
|
end//for
|
end//for
|
endgenerate
|
endgenerate
|
|
|
wire [11:0] tmp;
|
wire [11:0] tmp;
|
assign tmp= {{(12-L){1'b0}},diffrent};
|
assign tmp= {{(12-L){1'b0}},diffrent};
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
always @(*)begin
|
always @(*)begin
|
if (tmp[10]) distance =21;
|
if (tmp[10]) distance =21;
|
else if (tmp[9]) distance =19;
|
else if (tmp[9]) distance =19;
|
else if (tmp[8]) distance =17;
|
else if (tmp[8]) distance =17;
|
else if (tmp[7]) distance =15;
|
else if (tmp[7]) distance =15;
|
else if (tmp[6]) distance =13;
|
else if (tmp[6]) distance =13;
|
else if (tmp[5]) distance =11;
|
else if (tmp[5]) distance =11;
|
else if (tmp[4]) distance =9;
|
else if (tmp[4]) distance =9;
|
else if (tmp[3]) distance =7;
|
else if (tmp[3]) distance =7;
|
else if (tmp[2]) distance =5;
|
else if (tmp[2]) distance =5;
|
else if (tmp[1]) distance =3;
|
else if (tmp[1]) distance =3;
|
else distance =1;
|
else distance =1;
|
end
|
end
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
|
|
|
|
|
|
|
|
endmodule
|
endmodule
|
|
|
/**************
|
/**************
|
fattree_addr_encoder
|
fattree_addr_encoder
|
most probably it is only needed for simulation purposes
|
most probably it is only needed for simulation purposes
|
***************/
|
***************/
|
|
|
module fattree_addr_encoder #(
|
module fattree_addr_encoder #(
|
parameter K=2,
|
parameter K=2,
|
parameter L=2
|
parameter L=2
|
|
|
)(
|
)(
|
id,
|
id,
|
code
|
code
|
);
|
);
|
|
|
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
|
|
|
function integer powi;
|
function integer powi;
|
input integer x,y;
|
input integer x,y;
|
integer i;begin //compute x to the y
|
integer i;begin //compute x to the y
|
powi=1;
|
powi=1;
|
for (i = 0; i <y; i=i+1 ) begin
|
for (i = 0; i <y; i=i+1 ) begin
|
powi=powi * x;
|
powi=powi * x;
|
end
|
end
|
end
|
end
|
endfunction // log2
|
endfunction // log2
|
|
|
function integer addrencode;
|
function integer addrencode;
|
input integer pos,k,n,kw;
|
input integer pos,k,n,kw;
|
integer pow,i,tmp;begin
|
integer pow,i,tmp;begin
|
addrencode=0;
|
addrencode=0;
|
pow=1;
|
pow=1;
|
for (i = 0; i <n; i=i+1 ) begin
|
for (i = 0; i <n; i=i+1 ) begin
|
tmp=(pos/pow);
|
tmp=(pos/pow);
|
tmp=tmp%k;
|
tmp=tmp%k;
|
tmp=tmp<<i*kw;
|
tmp=tmp<<i*kw;
|
addrencode=addrencode | tmp;
|
addrencode=addrencode | tmp;
|
pow=pow * k;
|
pow=pow * k;
|
end
|
end
|
end
|
end
|
endfunction // log2
|
endfunction // log2
|
|
|
|
|
localparam
|
localparam
|
NE = powi( K,L ), //total number of endpoints
|
NE = powi( K,L ), //total number of endpoints
|
NEw = log2(NE),
|
NEw = log2(NE),
|
Kw=log2(K),
|
Kw=log2(K),
|
LKw=L*Kw;
|
LKw=L*Kw;
|
|
|
|
|
input [NEw-1 :0] id;
|
input [NEw-1 :0] id;
|
output [LKw-1 : 0] code;
|
output [LKw-1 : 0] code;
|
|
|
wire [LKw-1 : 0 ] codes [NE-1 : 0];
|
wire [LKw-1 : 0 ] codes [NE-1 : 0];
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for(i=0; i< NE; i=i+1) begin : endpoints
|
for(i=0; i< NE; i=i+1) begin : endpoints
|
//Endpoint decoded address
|
//Endpoint decoded address
|
localparam [LKw-1 : 0] ENDPX= addrencode(i,K,L,Kw);
|
localparam [LKw-1 : 0] ENDPX= addrencode(i,K,L,Kw);
|
assign codes[i] = ENDPX;
|
assign codes[i] = ENDPX;
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
assign code = codes[id];
|
assign code = codes[id];
|
endmodule
|
endmodule
|
|
|
|
|
|
|
/**************
|
/**************
|
fattree_addr_decoder
|
fattree_addr_decoder
|
most probably it is only needed for simulation
|
most probably it is only needed for simulation
|
***************/
|
***************/
|
|
|
module fattree_addr_decoder #(
|
module fattree_addr_decoder #(
|
parameter K=2,
|
parameter K=2,
|
parameter L=2
|
parameter L=2
|
|
|
)(
|
)(
|
id,
|
id,
|
code
|
code
|
);
|
);
|
|
|
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
|
|
|
function integer powi;
|
function integer powi;
|
input integer x,y;
|
input integer x,y;
|
integer i;begin //compute x to the y
|
integer i;begin //compute x to the y
|
powi=1;
|
powi=1;
|
for (i = 0; i <y; i=i+1 ) begin
|
for (i = 0; i <y; i=i+1 ) begin
|
powi=powi * x;
|
powi=powi * x;
|
end
|
end
|
end
|
end
|
endfunction // log2
|
endfunction // log2
|
|
|
function integer addrencode;
|
function integer addrencode;
|
input integer pos,k,n,kw;
|
input integer pos,k,n,kw;
|
integer pow,i,tmp;begin
|
integer pow,i,tmp;begin
|
addrencode=0;
|
addrencode=0;
|
pow=1;
|
pow=1;
|
for (i = 0; i <n; i=i+1 ) begin
|
for (i = 0; i <n; i=i+1 ) begin
|
tmp=(pos/pow);
|
tmp=(pos/pow);
|
tmp=tmp%k;
|
tmp=tmp%k;
|
tmp=tmp<<i*kw;
|
tmp=tmp<<i*kw;
|
addrencode=addrencode | tmp;
|
addrencode=addrencode | tmp;
|
pow=pow * k;
|
pow=pow * k;
|
end
|
end
|
end
|
end
|
endfunction // log2
|
endfunction // log2
|
|
|
|
|
localparam
|
localparam
|
NE = powi( K,L ), //total number of endpoints
|
NE = powi( K,L ), //total number of endpoints
|
NEw = log2(NE),
|
NEw = log2(NE),
|
Kw=log2(K),
|
Kw=log2(K),
|
LKw=L*Kw;
|
LKw=L*Kw;
|
|
|
|
|
output [NEw-1 :0] id;
|
output [NEw-1 :0] id;
|
input [LKw-1 : 0] code;
|
input [LKw-1 : 0] code;
|
|
|
wire [NEw-1 : 0] codes [2**LKw-1 : 0 ];
|
wire [NEw-1 : 0] codes [2**LKw-1 : 0 ];
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for(i=0; i< NE; i=i+1) begin : endpoints
|
for(i=0; i< NE; i=i+1) begin : endpoints
|
//Endpoint decoded address
|
//Endpoint decoded address
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
localparam [LKw-1 : 0] ENDPX= addrencode(i,K,L,Kw);
|
localparam [LKw-1 : 0] ENDPX= addrencode(i,K,L,Kw);
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
assign codes[ENDPX] = i;
|
assign codes[ENDPX] = i;
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
assign id = codes[code];
|
assign id = codes[code];
|
endmodule
|
endmodule
|
|
|
/**************
|
/**************
|
* mesh_torus_ssa_check_destport_conflict
|
* mesh_torus_ssa_check_destport_conflict
|
* check if the incomming flit goes to SS port
|
* check if the incomming flit goes to SS port
|
* ************/
|
* ************/
|
|
|
module fattree_ssa_check_destport #(
|
module fattree_ssa_check_destport #(
|
parameter DSTPw = 5,
|
parameter DSTPw = 5,
|
parameter SS_PORT=0
|
parameter SS_PORT=0
|
)
|
)
|
(
|
(
|
destport_encoded, //exsited packet dest port
|
destport_encoded, //exsited packet dest port
|
destport_in_encoded, // incomming packet dest port
|
destport_in_encoded, // incomming packet dest port
|
ss_port_hdr_flit, // asserted if the header incomming flit goes to ss port
|
ss_port_hdr_flit, // asserted if the header incomming flit goes to ss port
|
ss_port_nonhdr_flit // asserted if the body or tail incomming flit goes to ss port
|
ss_port_nonhdr_flit // asserted if the body or tail incomming flit goes to ss port
|
);
|
);
|
|
|
localparam K= DSTPw-1;
|
localparam K= DSTPw-1;
|
localparam SS_LOC = (SS_PORT < K)? SS_PORT : SS_PORT-K;
|
localparam SS_LOC = (SS_PORT < K)? SS_PORT : SS_PORT-K;
|
|
|
input [DSTPw-1 : 0] destport_encoded, destport_in_encoded;
|
input [DSTPw-1 : 0] destport_encoded, destport_in_encoded;
|
output ss_port_hdr_flit, ss_port_nonhdr_flit;
|
output ss_port_hdr_flit, ss_port_nonhdr_flit;
|
|
|
|
|
/******************
|
/******************
|
destport_encoded format in fat tree. K+1 bit
|
destport_encoded format in fat tree. K+1 bit
|
destport[K]
|
destport[K]
|
1'b0 : go down
|
1'b0 : go down
|
1'b1 : go up
|
1'b1 : go up
|
destport[K-1: 0]:
|
destport[K-1: 0]:
|
onehot coded. asserted bit show the output port locatation
|
onehot coded. asserted bit show the output port locatation
|
*******************/
|
*******************/
|
|
|
wire up_flg = destport_encoded[DSTPw-1];
|
wire up_flg = destport_encoded[DSTPw-1];
|
wire up_flg_in = destport_in_encoded[DSTPw-1];
|
wire up_flg_in = destport_in_encoded[DSTPw-1];
|
wire down_flg = ~destport_encoded[DSTPw-1];
|
wire down_flg = ~destport_encoded[DSTPw-1];
|
wire down_flg_in = ~destport_in_encoded[DSTPw-1];
|
wire down_flg_in = ~destport_in_encoded[DSTPw-1];
|
|
|
|
|
generate
|
generate
|
if(SS_PORT < K) begin :SS_DOWN // the ssa port is located in down router side
|
if(SS_PORT < K) begin :SS_DOWN // the ssa port is located in down router side
|
assign ss_port_hdr_flit = destport_in_encoded [SS_LOC] & down_flg_in;
|
assign ss_port_hdr_flit = destport_in_encoded [SS_LOC] & down_flg_in;
|
assign ss_port_nonhdr_flit = destport_encoded[SS_LOC] & down_flg;
|
assign ss_port_nonhdr_flit = destport_encoded[SS_LOC] & down_flg;
|
end else begin : SS_UP
|
end else begin : SS_UP
|
assign ss_port_hdr_flit = destport_in_encoded [SS_LOC] & up_flg_in;
|
assign ss_port_hdr_flit = destport_in_encoded [SS_LOC] & up_flg_in;
|
assign ss_port_nonhdr_flit = destport_encoded[SS_LOC] & up_flg;
|
assign ss_port_nonhdr_flit = destport_encoded[SS_LOC] & up_flg;
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
endmodule
|
endmodule
|
|
|
/*
|
/*
|
module fattree_add_ss_port #(
|
module fattree_add_ss_port #(
|
parameter SW_LOC=1,
|
parameter SW_LOC=1,
|
parameter P=5
|
parameter P=5
|
)(
|
)(
|
destport_in,
|
destport_in,
|
destport_out
|
destport_out
|
);
|
);
|
localparam
|
localparam
|
P_1 = P-1,
|
P_1 = P-1,
|
DISABLED = P;
|
DISABLED = P;
|
|
|
localparam SS_PORT_FATTREE_EVEN = (SW_LOC < (P/2) )? (P/2)+ SW_LOC-1 : SW_LOC - (P/2);
|
localparam SS_PORT_FATTREE_EVEN = (SW_LOC < (P/2) )? (P/2)+ SW_LOC-1 : SW_LOC - (P/2);
|
localparam SS_PORT_FATTREE_ODD = (SW_LOC == (P-1)/2)? DISABLED:
|
localparam SS_PORT_FATTREE_ODD = (SW_LOC == (P-1)/2)? DISABLED:
|
(SW_LOC < ((P+1)/2) )? ((P+1)/2)+ SW_LOC-1 : SW_LOC - ((P+1)/2);
|
(SW_LOC < ((P+1)/2) )? ((P+1)/2)+ SW_LOC-1 : SW_LOC - ((P+1)/2);
|
|
|
localparam SS_PORT_FATTREE = (P[0]==1'b0) ? SS_PORT_FATTREE_EVEN : SS_PORT_FATTREE_ODD;
|
localparam SS_PORT_FATTREE = (P[0]==1'b0) ? SS_PORT_FATTREE_EVEN : SS_PORT_FATTREE_ODD;
|
|
|
localparam SS_PORT = SS_PORT_FATTREE;
|
localparam SS_PORT = SS_PORT_FATTREE;
|
|
|
|
|
|
|
|
|
input [P_1-1 : 0] destport_in;
|
input [P_1-1 : 0] destport_in;
|
output reg [P_1-1 : 0] destport_out;
|
output reg [P_1-1 : 0] destport_out;
|
|
|
|
|
|
|
always @(*)begin
|
always @(*)begin
|
destport_out=destport_in;
|
destport_out=destport_in;
|
if( SS_PORT != DISABLED ) begin
|
if( SS_PORT != DISABLED ) begin
|
if(destport_in=={P_1{1'b0}}) destport_out[SS_PORT]= 1'b1;
|
if(destport_in=={P_1{1'b0}}) destport_out[SS_PORT]= 1'b1;
|
end
|
end
|
end
|
end
|
|
|
|
|
endmodule
|
endmodule
|
*/
|
*/
|
module fattree_router_addr_decode #(
|
module fattree_router_addr_decode #(
|
parameter K=4,
|
parameter K=4,
|
parameter L=4
|
parameter L=4
|
)(
|
)(
|
r_addr,
|
r_addr,
|
rx,
|
rx,
|
rl
|
rl
|
//valid
|
//valid
|
);
|
);
|
|
|
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),
|
RAw= LKw + Lw;
|
RAw= LKw + Lw;
|
|
|
input [RAw-1 : 0] r_addr;
|
input [RAw-1 : 0] r_addr;
|
output [LKw-1 :0] rx;
|
output [LKw-1 :0] rx;
|
output [Lw-1 :0] rl;
|
output [Lw-1 :0] rl;
|
|
|
assign {rl,rx} = r_addr;
|
assign {rl,rx} = r_addr;
|
|
|
endmodule
|
endmodule
|
|
|
|
|
//decode and mask destport
|
//decode and mask destport
|
module fattree_destp_generator #(
|
module fattree_destp_generator #(
|
parameter K=2,
|
parameter K=2,
|
parameter P=2*K,
|
parameter P=2*K,
|
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 P_1 = (SELF_LOOP_EN == "NO")? P-1 : P;
|
localparam 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 [2*K-1 : 0] destport_decoded;
|
wire [2*K-1 : 0] destport_decoded;
|
wire [2*K-1 : 0] destport_masked;
|
wire [2*K-1 : 0] destport_masked;
|
|
|
|
|
fattree_destport_decoder #(
|
fattree_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)
|
);
|
);
|
|
|
fattree_mask_non_assignable_destport #(
|
fattree_mask_non_assignable_destport #(
|
.K(K),
|
.K(K),
|
.P(P),
|
.P(P),
|
.SW_LOC(SW_LOC)
|
.SW_LOC(SW_LOC)
|
)
|
)
|
mask
|
mask
|
(
|
(
|
.destport_in(destport_decoded),
|
.destport_in(destport_decoded),
|
.destport_out(destport_masked)
|
.destport_out(destport_masked)
|
);
|
);
|
|
|
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_masked[P-1 : 0]),
|
.destport_in(destport_masked[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_masked [P_1-1 : 0 ];
|
assign dest_port_out= destport_masked [P_1-1 : 0 ];
|
end
|
end
|
endgenerate
|
endgenerate
|
endmodule
|
endmodule
|
|
|
No newline at end of file
|
No newline at end of file
|
|
|
|
|
|
|
|
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|