`include "pronoc_def.v"
module traffic_gen_top
import pronoc_pkg::*;
#(
parameter MAX_RATIO = 1000,
parameter ENDP_ID = 10
)
(
//noc port
chan_in,
chan_out,
//input
ratio,// real injection ratio = (MAX_RATIO/100)*ratio
pck_size_in,
current_e_addr,
dest_e_addr,
pck_class_in,
start,
stop,
report,
init_weight,
start_delay,
//output
pck_number,
sent_done, // tail flit has been sent
hdr_flit_sent,
update, // update the noc_analayzer
src_e_addr,
flit_out_class,
flit_out_wr,
flit_in_wr,
distance,
pck_class_out,
time_stamp_h2h,
time_stamp_h2t,
pck_size_o,
mcast_dst_num_o,
reset,
clk
);
localparam
RATIOw= $clog2(MAX_RATIO);
// Vw = $clog2(V);
input smartflit_chanel_t chan_in;
output smartflit_chanel_t chan_out;
localparam
PCK_CNTw = log2(MAX_PCK_NUM+1),
CLK_CNTw = log2(MAX_SIM_CLKs+1),
PCK_SIZw = log2(MAX_PCK_SIZ+1),
AVG_PCK_SIZw = log2(10*MAX_PCK_SIZ+1),
/* verilator lint_off WIDTH */
DISTw = (TOPOLOGY=="FATTREE" || TOPOLOGY=="TREE" ) ? log2(2*L+1): log2(NR+1),
W=WEIGHTw,
PORT_B = (TOPOLOGY!="FMESH")? LB :
(ENDP_ID < NE_MESH_TORI)? LB :B; // in FMESH, the buffer size of endpoints connected to edge routers non-local ports are B not LB
/* verilator lint_on WIDTH */
input reset, clk;
input [RATIOw-1 :0] ratio;
input start,stop;
output update;
output [CLK_CNTw-1 :0] time_stamp_h2h,time_stamp_h2t;
output [DISTw-1 :0] distance;
output [Cw-1 :0] pck_class_out;
// the current endpoint address
input [EAw-1 :0] current_e_addr;
// the destination endpoint address
input [DAw-1 :0] dest_e_addr;
output [PCK_CNTw-1 :0] pck_number;
input [PCK_SIZw-1 :0] pck_size_in;
output reg sent_done;
output reg hdr_flit_sent;
input [Cw-1 :0] pck_class_in;
input [W-1 :0] init_weight;
input report;
input [DELAYw-1 :0] start_delay;
// the received packet source endpoint address
output [EAw-1 : 0] src_e_addr;
output [PCK_SIZw-1 : 0] pck_size_o;
output [NEw-1 : 0] mcast_dst_num_o;
logic [Fw-1 :0] flit_out;
output logic flit_out_wr;
output [Cw-1 : 0] flit_out_class;
logic [V-1 :0] credit_in;
logic [Fw-1 :0] flit_in;
output logic flit_in_wr;
logic [V-1 :0] credit_out;
// the connected router address
wire [RAw-1 :0] current_r_addr;
/* verilator lint_off WIDTH */
wire [PCK_SIZw-1 : 0] pck_size_tmp= (PCK_TYPE == "SINGLE_FLIT" )? 1 : pck_size_in;
/* verilator lint_on WIDTH */
assign chan_out.flit_chanel.flit = flit_out;
assign chan_out.flit_chanel.flit_wr = flit_out_wr;
assign chan_out.flit_chanel.credit = credit_out;
assign chan_out.smart_chanel = {SMART_CHANEL_w {1'b0}};
assign flit_in = chan_in.flit_chanel.flit;
assign flit_in_wr= chan_in.flit_chanel.flit_wr;
assign credit_in = chan_in.flit_chanel.credit;
assign current_r_addr = chan_in.ctrl_chanel.neighbors_r_addr;
genvar i;
generate
for (i=0; i1 || flit_out_hdr!=2'b11) begin
ns = SENT;
end else begin
pck_rd=1'b1;
flit_cnt_rst = 1'b1;
sent_done =1'b1;
cand_wr_vc_en =1'b1;
if(cand_vc>0) begin
wr_vc_next = cand_vc;
end else ns = WAIT;
end //else
end//wr_vc
end
end //IDEAL
SENT: begin
if(!wr_vc_is_full )begin
flit_out_wr = 1'b1;
if(flit_counter < pck_size-1) begin
flit_cnt_inc = 1'b1;
end else begin
flit_cnt_rst = 1'b1;
sent_done =1'b1;
pck_rd=1'b1;
cand_wr_vc_en =1'b1;
if(cand_vc>0) begin
wr_vc_next = cand_vc;
ns =IDEAL;
end else ns = WAIT;
end//else
end // if wr_vc_is_full
end//SENT
WAIT:begin
cand_wr_vc_en =1'b1;
if(cand_vc>0) begin
wr_vc_next = cand_vc;
ns =IDEAL;
end
end
default: begin
ns =IDEAL;
end
endcase
// packet sink
if(flit_in_wr) begin
credit_out_next = rd_vc;
end else credit_out_next = {V{1'd0}};
end
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
inject_en <= 1'b0;
ps <= IDEAL;
wr_vc <=1;
flit_counter <= {PCK_SIZw{1'b0}};
credit_out <= {V{1'd0}};
rsv_counter <= 0;
clk_counter <= 0;
not_yet_sent_aflit<=1'b1;
end else begin
//injection
not_yet_sent_aflit<=not_yet_sent_aflit_next;
inject_en <= (start_injection |inject_en) & ~stop;
ps <= ns;
clk_counter <= clk_counter+1'b1;
wr_vc <=wr_vc_next;
if (flit_cnt_rst) flit_counter <= {PCK_SIZw{1'b0}};
else if(flit_cnt_inc) flit_counter <= flit_counter + 1'b1;
credit_out <= credit_out_next;
//sink
if(flit_in_wr) begin
if (flit_in[Fw-1])begin //header flit
rsv_pck_src_e_addr[rd_vc_bin] <= rd_src_e_addr;
rsv_pck_class_in[rd_vc_bin] <= rd_class_hdr;
rsv_time_stamp[rd_vc_bin] <= clk_counter;
rsv_counter <= rsv_counter+1'b1;
rsv_pck_size[rd_vc_bin] <=2;
// distance <= {{(32-8){1'b0}},flit_in[7:0]};
`ifdef RSV_NOTIFICATION
// synopsys translate_off
// synthesis translate_off
// last_pck_time<=$time;
$display ("total of %d pcks have been recived in core (%d)", rsv_counter,current_e_addr);
// synthesis translate_on
// synopsys translate_on
`endif
end else begin
rsv_pck_size[rd_vc_bin] <=rsv_pck_size[rd_vc_bin]+1;
end
end
// synopsys translate_off
// synthesis translate_off
if(report) begin
$display ("%t,\t total of %d pcks have been recived in core (%d)",$time ,rsv_counter,current_e_addr);
end
// synthesis translate_on
// synopsys translate_on
end
end//always
wire [NE-1 :0] dest_mcast_all_endp1;
generate
/* verilator lint_off WIDTH */
if(CAST_TYPE != "UNICAST") begin :mb_cast
/* verilator lint_on WIDTH */
wire [NEw-1 : 0] sum_temp;
wire is_unicast;
mcast_dest_list_decode decode1 (
.dest_e_addr(dest_e_addr_o),
.dest_o(dest_mcast_all_endp1),
.row_has_any_dest(),
.is_unicast(is_unicast)
);
/* verilator lint_off WIDTH */
if (CAST_TYPE == "BROADCAST_FULL") begin :bcastf
assign mcast_dst_num_o = (is_unicast) ? 1 : (SELF_LOOP_EN == "NO")? NE-1 : NE;
end else if ( CAST_TYPE == "BROADCAST_PARTIAL" ) begin :bcastp
if (SELF_LOOP_EN == "NO") begin
//check if injector node is included in partial list
wire [NEw-1: 0] current_enp_id;
endp_addr_decoder #( .TOPOLOGY(TOPOLOGY), .T1(T1), .T2(T2), .T3(T3), .EAw(EAw), .NE(NE)) decod1 ( .id(current_enp_id), .code(current_e_addr));
assign mcast_dst_num_o = (is_unicast) ? 1 : (MCAST_ENDP_LIST[current_enp_id]== 1'b1)? MCAST_PRTLw-1 : MCAST_PRTLw;
end else begin
assign mcast_dst_num_o = (is_unicast)? 1 : MCAST_PRTLw;
end
/* verilator lint_on WIDTH */
end else begin : mcast
accumulator #(
.INw(NE),
.OUTw(NEw),
.NUM(NE)
)accum
(
.in_all(dest_mcast_all_endp1),
.out(sum_temp)
);
assign mcast_dst_num_o = sum_temp;
end
end
endgenerate
/***************************************************************
* simulation code
* ************************************************************/
// synthesis translate_off
wire [NEw-1: 0] src_id,dst_id,current_id;
endp_addr_decoder #( .TOPOLOGY(TOPOLOGY), .T1(T1), .T2(T2), .T3(T3), .EAw(EAw), .NE(NE)) decod1 ( .id(current_id), .code(current_e_addr));
endp_addr_decoder #( .TOPOLOGY(TOPOLOGY), .T1(T1), .T2(T2), .T3(T3), .EAw(EAw), .NE(NE)) decod2 ( .id(dst_id), .code(rd_des_e_addr[EAw-1 : 0]));// only for unicast
endp_addr_decoder #( .TOPOLOGY(TOPOLOGY), .T1(T1), .T2(T2), .T3(T3), .EAw(EAw), .NE(NE)) decod3 ( .id(src_id), .code(rd_src_e_addr));
wire [NE-1 :0] dest_mcast_all_endp2;
generate
if(CAST_TYPE != "UNICAST") begin :no_unicast
mcast_dest_list_decode decode2 (
.dest_e_addr(rd_des_e_addr),
.dest_o(dest_mcast_all_endp2),
.row_has_any_dest(),
.is_unicast()
);
end endgenerate
always @(posedge clk) begin
/* verilator lint_off WIDTH */
if(CAST_TYPE == "UNICAST") begin
/* verilator lint_on WIDTH */
if(flit_out_wr && hdr_flit && dest_e_addr_o [EAw-1 : 0] == current_e_addr && SELF_LOOP_EN == "NO") begin
$display("%t: ERROR: The self-loop is not enabled in the router while a packet is injected to the NoC with identical source and destination address in endpoint (%h).: %m",$time, dest_e_addr_o );
$finish;
end
if(flit_in_wr && rd_hdr_flg && (rd_des_e_addr[EAw-1 : 0] != current_e_addr )) begin
$display("%t: ERROR: packet with destination %d (code %h) which is sent by source %d (code %h) has been recieved in wrong destination %d (code %h). %m",$time,dst_id,rd_des_e_addr, src_id,rd_src_e_addr, current_id,current_e_addr);
$finish;
end
end else begin
/* verilator lint_off WIDTH */
if((CAST_TYPE == "MULTICAST_FULL") || (CAST_TYPE == "MULTICAST_PARTIAL")) begin
/* verilator lint_on WIDTH */
if(flit_out_wr && hdr_flit && dest_mcast_all_endp1[current_id] == 1'b1 && SELF_LOOP_EN == "NO") begin
$display("%t: ERROR: The self-loop is not enabled in the router while a packet is injected to the NoC with identical source and destination address in endpoint %d. destination nodes:0X%h. : %m",$time, current_id,dest_mcast_all_endp1 );
$finish;
end
end
if(flit_in_wr && rd_hdr_flg && (dest_mcast_all_endp2[current_id] !=1'b1 )) begin
$display("%t: ERROR: packet with destination %b which is sent by source %d (code %h) has been recieved in wrong destination %d (code %h). %m",$time, dest_mcast_all_endp2, src_id,rd_src_e_addr, current_id,current_e_addr);
$finish;
end
//check multicast packet size to be smaller than B & LB
if(flit_out_wr & hdr_flit & (mcast_dst_num_o>1) & (pck_size >B || pck_size> LB))begin
$display("%t: ERROR: A multicast packat is injected to the NoC which has larger size (%d) than router buffer width. %m",$time, pck_size);
$finish;
end
end
if(update) begin
if (hdr_flit_timestamp<= rd_timestamp) begin
$display("%t: ERROR: In destination %d packt which is sent by source %d, the time when header flit is recived (%d) should be larger than the packet timestamp %d. %m",$time, current_id ,src_e_addr, hdr_flit_timestamp, rd_timestamp);
$finish;
end
if( clk_counter <= rd_timestamp) begin
$display("%t: ERROR: ERROR: In destination %d packt which is sent by source %d,, the current time (%d) should be larger than the packet timestamp %d. %m",$time, current_id ,src_e_addr, clk_counter, rd_timestamp);
$finish;
end
end//update
if(tail_flit & flit_out_wr) begin
if(wr_timestamp > clk_counter) begin
$display("%t: ERROR: In src %d, the current time (%d) should be larger than or equal to the packet timestamp %d. %m",$time, current_id, clk_counter, wr_timestamp);
$finish;
end
end
end
`ifdef CHECK_PCKS_CONTENT
wire [PCK_SIZw-1 : 0] rsv_flit_counter;
reg [PCK_SIZw-1 : 0] old_flit_counter [V-1 : 0];
wire [PCK_CNTw-1 : 0] rsv_pck_number;
reg [PCK_CNTw-1 : 0] old_pck_number [V-1 : 0];
wire [PCK_CNTw+PCK_SIZw-1 : 0] statistics;
generate
if(PCK_CNTw+PCK_SIZw > Fw) assign statistics = {{(PCK_CNTw+PCK_SIZw-Fw){1'b0}},flit_in};
else assign statistics = flit_in[PCK_CNTw+PCK_SIZw-1 : 0];
assign {rsv_pck_number,rsv_flit_counter}=statistics;
endgenerate
integer ii;
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
for(ii=0;ii {V{1'b0}} ) endp_is_active=1'b1;
// if (chan_out.smart_chanel.requests > {SMART_NUM{1'b0}} ) endp_is_active=1'b1;
// end
// `endif
endmodule
/*****************************
injection_ratio_ctrl
*****************************/
module injection_ratio_ctrl #
(
parameter MAX_PCK_SIZ=10,
parameter MAX_RATIO=100
)(
en,
pck_size_in, // average packet size in flit x10
clk,
reset,
inject,// inject one packet
freez,
ratio // 0~100 flit injection ratio
);
function integer log2;
input integer number; begin
log2=(number <=1) ? 1: 0;
while(2**log2= pck_size-1'b1) ? {PCK_SIZw{1'b0}} : flit_counter +1'b1;
next_inject = (flit_counter=={PCK_SIZw{1'b0}});
if (next_flit_counter >= pck_size-1'b1) begin
if( next_state >= STATE_INIT ) next_sent =1'b0;
end
end
1'b0:begin
if( next_state < STATE_INIT ) next_sent = 1'b1;
next_inject= 1'b0;
/* verilator lint_off WIDTH */
next_state = state - on_clks;
/* verilator lint_on WIDTH */
end
endcase
end else begin
next_inject= 1'b0;
end
end
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
state <= STATE_INIT;
inject <= 1'b0;
sent <= 1'b1;
flit_counter<= 0;
pck_size<=2;
end else begin
if(input_changed)begin
state <= STATE_INIT;
inject <= 1'b0;
sent <= 1'b1;
flit_counter<= 0;
end
if(flit_counter=={PCK_SIZw{1'b0}}) pck_size<=pck_size_in;
state <= next_state;
if(ratio!={CNTw{1'b0}}) inject <= next_inject;
sent <= next_sent;
flit_counter<= next_flit_counter;
end
end
endmodule
/*************************************
packet_buffer
**************************************/
module packet_gen
import pronoc_pkg::*;
#(
parameter P = 5,
parameter PCK_TYPE = "SINGLE_FLIT",
parameter ROUTE_TYPE = "DETERMINISTIC",
parameter MAX_PCK_NUM = 10000,
parameter MAX_SIM_CLKs = 100000,
parameter TIMSTMP_FIFO_NUM=16,
parameter MIN_PCK_SIZE=2,
parameter MAX_PCK_SIZ=100
)(
clk_counter,
pck_wr,
pck_rd,
current_r_addr,
current_e_addr,
pck_number,
dest_e_addr_in,
dest_e_addr_o,
pck_timestamp,
destport,
buffer_full,
pck_ready,
valid_dst,
pck_size_in,
pck_size_o,
clk,
reset
);
function integer log2;
input integer number; begin
log2=(number <=1) ? 1: 0;
while(2**log2Error running this command: diff -w -U 5 "" "/tmp/qK3ymE"
diff: : No such file or directory