OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk/mpsoc/rtl
    from Rev 50 to Rev 54
    Reverse comparison

Rev 50 → Rev 54

/arbiter.v
34,7 → 34,10
*
*
******************************************/
`include "pronoc_def.v"
 
 
 
module arbiter #(
parameter ARBITER_WIDTH =8
207,13 → 210,8
 
);
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
low_pr <= {ARBITER_BIN_WIDTH{1'b0}};
end else begin
if(any_grant) low_pr <= grant_bcd;
356,12 → 354,8
.bin_code(grant_bcd)
);
 
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
low_pr <= {ARBITER_BIN_WIDTH{1'b0}};
end else begin
if(priority_en) low_pr <= grant_bcd;
452,28 → 446,23
);
 
assign mux_out=(termo2[ARBITER_WIDTH-1])? termo2 : termo1;
assign masked_request= request & pr;
assign any_grant=termo1[ARBITER_WIDTH-1];
 
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) pr<= {ARBITER_WIDTH{1'b1}};
else begin
if(any_grant) pr<= edge_mask;
assign mux_out=(termo2[ARBITER_WIDTH-1])? termo2 : termo1;
assign masked_request= request & pr;
assign any_grant=termo1[ARBITER_WIDTH-1];
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) pr<= {ARBITER_WIDTH{1'b1}};
else begin
if(any_grant) pr<= edge_mask;
end
end
assign edge_mask= {mux_out[ARBITER_WIDTH-2:0],1'b0};
assign grant= mux_out ^ edge_mask;
 
end
 
assign edge_mask= {mux_out[ARBITER_WIDTH-2:0],1'b0};
assign grant= mux_out ^ edge_mask;
 
 
 
endmodule
530,24 → 519,19
assign masked_request= request & pr;
assign any_grant=termo1[ARBITER_WIDTH-1];
 
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) pr<= {ARBITER_WIDTH{1'b1}};
else begin
if(priority_en) pr<= edge_mask;
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) pr<= {ARBITER_WIDTH{1'b1}};
else begin
if(priority_en) pr<= edge_mask;
end
end
assign edge_mask= {mux_out[ARBITER_WIDTH-2:0],1'b0};
assign grant= mux_out ^ edge_mask;
 
end
 
assign edge_mask= {mux_out[ARBITER_WIDTH-2:0],1'b0};
assign grant= mux_out ^ edge_mask;
 
 
 
endmodule
 
871,12 → 855,12
input [ARBITER_WIDTH-1 : 0] request;
output [ARBITER_WIDTH-1 : 0] grant;
output any_grant;
/*
wire [ARBITER_WIDTH-1 : 0] cout;
reg [ARBITER_WIDTH-1 : 0] cin;
assign any_grant= | request;
assign grant = cin & request;
assign cout = cin & ~request;
885,6 → 869,34
if( HIGH_PRORITY_BIT == "HSB") cin = {1'b1, cout[ARBITER_WIDTH-1 :1]}; // hsb has highest priority
else cin = {cout[ARBITER_WIDTH-2 :0] ,1'b1}; // lsb has highest priority
end//always
*/
assign any_grant= | request;
wire [ARBITER_WIDTH-1 : 0] termo_code, edge_mask;
genvar i;
generate
if( HIGH_PRORITY_BIT == "LSB") begin :hsb
for(i=0;i<ARBITER_WIDTH;i=i+1)begin :lp
assign termo_code[i]= | request[i :0];
end
assign edge_mask= {termo_code[ARBITER_WIDTH-2:0],1'b0};
end else begin :hsb
for(i=0;i<ARBITER_WIDTH;i=i+1)begin :lp
assign termo_code[i]= | request[ARBITER_WIDTH-1 :i];
end
assign edge_mask= {1'b0, termo_code[ARBITER_WIDTH-1:1]};
end
endgenerate
assign grant= termo_code ^ edge_mask;
endmodule
 
/main_comp.v
27,13 → 27,99
** different types of multiplexors, converters and counters ...
**
**************************************************************/
`include "pronoc_def.v"
 
module pronoc_register
#(
parameter W=1,
parameter RESET_TO={W{1'b0}}
)(
input [W-1:0] in,
input reset,
input clk,
output [W-1:0] out
);
 
pronoc_register_reset_init #(
.W(W)
)reg1(
.in(in),
.reset(reset),
.clk(clk),
.out(out),
.reset_to(RESET_TO[W-1 : 0])
);
endmodule
 
 
 
module pronoc_register_reset_init
#(
parameter W=1
)(
input [W-1:0] in,
input reset,
input clk,
output reg [W-1:0] out,
input [W-1 : 0] reset_to
);
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) out<=reset_to;
else out<=in;
end
endmodule
 
 
module pronoc_register_reset_init_ld_en
#(
parameter W=1
)(
input [W-1:0] in,
input reset,
input clk,
input ld,
output reg [W-1:0] out,
input [W-1 : 0] reset_to
);
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) out<=reset_to;
else if(ld) out<=in;
end
endmodule
 
 
module pronoc_register_ld_en
#(
parameter W=1,
parameter RESET_TO={W{1'b0}}
)(
input [W-1:0] in,
input reset,
input clk,
input ld,
output [W-1:0] out
);
 
pronoc_register_reset_init_ld_en #(
.W(W)
)reg1(
.in(in),
.reset(reset),
.clk(clk),
.ld(ld),
.out(out),
.reset_to(RESET_TO[W-1 : 0])
);
endmodule
 
 
 
/*********************************
 
 
480,7 → 566,7
*******************************/
 
 
module check_single_bit_assertation #(
module is_onehot0 #(
parameter IN_WIDTH =2
)
505,6 → 591,20
wire [OUT_WIDTH-1 : 0] sum;
accumulator #(
.INw(IN_WIDTH),
.OUTw(OUT_WIDTH),
.NUM(IN_WIDTH)
)
accum
(
.in_all(in),
.out(sum)
);
/*
parallel_counter #(
.IN_WIDTH (IN_WIDTH)
)counter
512,7 → 612,8
.in(in),
.out(sum)
);
 
*/
assign result = (sum <=1)? 1'b1: 1'b0;
924,8 → 1025,8
reg [2:0] counter;
assign cnt_increase=(counter==3'd0);
always @(posedge clk or posedge reset) begin
if(reset) begin
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
start_o_reg <= {NC{1'b0}};
start_i_reg <= 1'b0;
counter <= 3'd0;
/pronoc_def.v
0,0 → 1,39
`ifndef PRONOC_DEF
`define PRONOC_DEF
 
`timescale 1ns/1ps
 
//`define SYNC_RESET_MODE /* Reset is asynchronous by default. Uncomment this line for having synchronous reset*/
//`define ACTIVE_LOW_RESET_MODE /* Reset is active high by deafult. Uncomment this line for having active low reset*/
 
 
 
`ifdef SYNC_RESET_MODE
`define pronoc_clk_reset_edge posedge clk
`else
`ifdef ACTIVE_LOW_RESET_MODE
`define pronoc_clk_reset_edge posedge clk or negedge reset
`else
`define pronoc_clk_reset_edge posedge clk or posedge reset
`endif
`endif
 
 
 
`ifdef ACTIVE_LOW_RESET_MODE
`define pronoc_reset !reset
`else
`define pronoc_reset reset
`endif
 
 
 
`ifdef USE_LIB
`uselib lib=`USE_LIB
`endif
 
 
 
`endif
 
/src_emulate/rtl/noc_emulator.sv
62,7 → 62,8
.reset(reset),
.clk(clk),
.chan_in_all(chan_in_all),
.chan_out_all(chan_out_all)
.chan_out_all(chan_out_all),
.router_event()
);
 
536,6 → 537,7
//noc
.chan_in(chan_in),
.chan_out(chan_out),
.mcast_dst_num_o()
);
/src_modelsim/filelist.f
2,5 → 2,7
#./testbench_noc.sv
./traffic_pattern.sv
./pck_injector_test.sv
./noc_sim_statistic.sv
 
 
 
/src_modelsim/multicast_injector.sv
0,0 → 1,660
`timescale 1ns/1ps
/****************************
* This module can inject and eject packets from the NoC.
* It can be used in simulation for injecting real application traces to the NoC
* *************************/
 
 
module multicast_injector
import pronoc_pkg::*;
(
//general
current_e_addr,
reset,
clk,
//noc port
chan_in,
chan_out,
//control interafce
pck_injct_in,
pck_injct_out
);
//general
input reset,clk;
input [EAw-1 :0 ] current_e_addr;
// the destination endpoint address
//NoC interface
input smartflit_chanel_t chan_in;
output smartflit_chanel_t chan_out;
//control interafce
input pck_injct_t pck_injct_in;
output pck_injct_t pck_injct_out;
wire [RAw-1 :0 ] current_r_addr;
wire [DSTPw-1 : 0 ] destport;
reg flit_wr;
assign current_r_addr = chan_in.ctrl_chanel.neighbors_r_addr;
/*
conventional_routing #(
.TOPOLOGY(TOPOLOGY),
.ROUTE_NAME(ROUTE_NAME),
.ROUTE_TYPE(ROUTE_TYPE),
.T1(T1),
.T2(T2),
.T3(T3),
.RAw(RAw),
.EAw(EAw),
.DSTPw(DSTPw),
.LOCATED_IN_NI(1)
)
routing_module
(
.reset(reset),
.clk(clk),
.current_r_addr(current_r_addr),
.dest_e_addr(pck_injct_in.endp_addr),
.src_e_addr(current_e_addr),
.destport(destport)
);
*/
 
assign destport = 7;
 
 
localparam
HDR_BYTE_NUM = HDR_MAX_DATw / 8, // = HDR_MAX_DATw / (8 - HDR_MAX_DATw %8)
HDR_DATA_w_tmp = HDR_BYTE_NUM * 8,
HDR_DATA_w = (PCK_INJ_Dw < HDR_DATA_w_tmp)? PCK_INJ_Dw : HDR_DATA_w_tmp;
 
wire [HDR_DATA_w-1 : 0] hdr_data_in = pck_injct_in.data [HDR_DATA_w-1 : 0];
wire [Fw-1 : 0] hdr_flit_out;
header_flit_generator #(
.DATA_w(HDR_DATA_w)
)
the_header_flit_generator
(
.flit_out (hdr_flit_out),
.vc_num_in (pck_injct_in.vc),
.class_in (pck_injct_in.class_num),
.dest_e_addr_in (pck_injct_in.endp_addr),
.src_e_addr_in (current_e_addr),
.weight_in (pck_injct_in.init_weight),
.destport_in (destport),
.data_in (hdr_data_in),
.be_in({BEw{1'b1}} )// Be is not used in simulation as we dont sent real data
);
localparam
REMAIN_DATw = PCK_INJ_Dw - HDR_DATA_w,
REMAIN_DAT_FLIT_I = (REMAIN_DATw / Fpay),
REMAIN_DAT_FLIT_F = (REMAIN_DATw % Fpay == 0)? 0 : 1,
REMAIN_DAT_FLIT = REMAIN_DAT_FLIT_I + REMAIN_DAT_FLIT_F,
CNTw = log2(REMAIN_DAT_FLIT),
MIN_PCK_SIZ = REMAIN_DAT_FLIT +1;
reg [PCK_SIZw-1 : 0] counter, counter_next;
reg [CNTw-1 : 0] counter2,counter2_next;
reg tail,head;
wire [Fpay -1 : 0] remain_dat [REMAIN_DAT_FLIT -1 : 0];
wire [Fpay-1 : 0] dataIn = remain_dat[counter2];
enum {HEADER, BODY,TAIL} flit_type,flit_type_next;
wire [V-1 : 0] wr_vc_send = (flit_wr)? pck_injct_in.vc : {V{1'b0}};
wire [V-1 : 0] vc_fifo_full;
wire noc_ready;
localparam
LAST_TMP =PCK_INJ_Dw - (Fpay*REMAIN_DAT_FLIT_I)-HDR_DATA_w,
LASTw=(LAST_TMP==0)? Fpay : LAST_TMP;
genvar i;
generate
for(i=0; i<REMAIN_DAT_FLIT_I; i++) begin
assign remain_dat [i] = pck_injct_in.data [Fpay*(i+1)+HDR_DATA_w-1 : (Fpay*i)+HDR_DATA_w];
end
if(REMAIN_DAT_FLIT_F ) begin
 
assign remain_dat [REMAIN_DAT_FLIT_I][LASTw-1 : 0] = pck_injct_in.data [PCK_INJ_Dw-1 : (Fpay*REMAIN_DAT_FLIT_I)+HDR_DATA_w];
end
endgenerate
one_hot_mux #(
.IN_WIDTH (V ),
.SEL_WIDTH (V ),
.OUT_WIDTH (1 )
) one_hot_mux1 (
.mux_in (~ vc_fifo_full ),
.mux_out (noc_ready ),
.sel (pck_injct_in.vc ));
always @ (*) begin
counter_next = counter;
counter2_next =counter2;
flit_type_next =flit_type;
tail=1'b0;
head=1'b0;
flit_wr=0;
if(noc_ready)begin
case(flit_type)
HEADER:begin
if(pck_injct_in.pck_wr)begin
flit_wr=1;
counter_next = pck_injct_in.size-1;
counter2_next=0;
head=1'b1;
if(pck_injct_in.size == 1)begin
tail=1'b1;
end else if (pck_injct_in.size == 2) begin
flit_type_next = TAIL;
end else begin
flit_type_next = BODY;
end
end
end
BODY: begin
flit_wr=1;
counter_next = counter -1'b1;
counter2_next =counter2 +1'b1;
if(counter == 2) begin
flit_type_next = TAIL;
end
end
TAIL: begin
flit_type_next = HEADER;
flit_wr=1;
tail=1'b1;
end
endcase
end
end
reg [V-1 : 0] credit_o;
always @ (posedge clk) begin
if(reset) begin
flit_type<=HEADER;
counter<=0;
counter2<=0;
credit_o<={V{1'b0}};
end else begin
flit_type<=flit_type_next;
counter<=counter_next;
counter2<=counter2_next;
if (chan_in.flit_chanel.flit_wr) credit_o<= chan_in.flit_chanel.flit.vc;
else credit_o<={V{1'b0}};
end
end
injector_ovc_status #(
.V(V),
.B(LB),
.CRDTw(CRDTw)
)
the_ovc_status
(
.credit_init_val_in ( chan_in.ctrl_chanel.credit_init_val),
.wr_in(wr_vc_send),
.credit_in(chan_in.flit_chanel.credit),
.full_vc(vc_fifo_full),
.nearly_full_vc( ),
.empty_vc( ),
.clk(clk),
.reset(reset)
);
wire [HDR_DATA_w-1 : 0] hdr_data_o;
hdr_flit_t hdr_flit_i;
header_flit_info
#(
.DATA_w (HDR_DATA_w )
) extractor (
.flit(chan_in.flit_chanel.flit),
.hdr_flit(hdr_flit_i),
.data_o(hdr_data_o)
);
wire [PCK_INJ_Dw-1 : 0] pck_data_o [V-1 : 0];
reg [Fpay-1 : 0] pck_data_o_gen [V-1 : 0][REMAIN_DAT_FLIT : 0];
genvar k;
reg [PCK_SIZw-1 : 0] rsv_counter [V-1 : 0];
reg [EAw-1 : 0] sender_endp_addr_reg [V-1 : 0];
logic [15:0] h2t_counter [V-1 : 0];
logic [15:0] h2t_counter_next [V-1 : 0];
//synthesis translate_off
wire [NEw-1 : 0] current_id;
wire [NEw-1 : 0] sendor_id;
endp_addr_decoder #( .TOPOLOGY(TOPOLOGY), .T1(T1), .T2(T2), .T3(T3), .EAw(EAw), .NE(NE)) encode1 ( .id(current_id), .code(current_e_addr));
endp_addr_decoder #( .TOPOLOGY(TOPOLOGY), .T1(T1), .T2(T2), .T3(T3), .EAw(EAw), .NE(NE)) encode2 ( .id(sendor_id), .code(pck_injct_out.endp_addr[EAw-1 : 0]));
//synthesis translate_on
generate
for(i=0; i<V; i++) begin: V_
always@(*) begin
h2t_counter_next[i]=h2t_counter[i]+1'b1;
if(chan_in.flit_chanel.flit.vc[i] & chan_in.flit_chanel.flit_wr & chan_in.flit_chanel.flit.hdr_flag)begin
h2t_counter_next[i]= 16'd0; // reset once header flit is received
end//hdr flit wr
end//always
always_ff @(posedge clk or posedge reset) begin
if (reset) begin
rsv_counter[i]<= {PCK_SIZw{1'b0}};
h2t_counter[i]<= 16'd0;
sender_endp_addr_reg [i]<= {EAw{1'b0}};
end else begin
h2t_counter[i]<=h2t_counter_next[i];
if(chan_in.flit_chanel.flit.vc[i] & chan_in.flit_chanel.flit_wr ) begin
if(chan_in.flit_chanel.flit.hdr_flag)begin
rsv_counter[i]<= {{(PCK_SIZw-1){1'b0}}, 1'b1};
sender_endp_addr_reg [i]<= hdr_flit_i.src_e_addr;
//synthesis translate_off
if(hdr_flit_i.dest_e_addr != current_e_addr) begin
$display("%t: ERROR: packet destination address %d does not match reciver endp address %d. %m",$time,hdr_flit_i.dest_e_addr , current_e_addr );
$finish;
end//if hdr_flit_i
//synthesis translate_on
end //if hdr_flag
else rsv_counter[i]<= rsv_counter[i]+1'b1;
end//flit wr
end//reset
end//always
 
for (k=0;k< REMAIN_DAT_FLIT+1;k++)begin : K_
always_ff @(posedge clk or posedge reset) begin
if (reset) begin
pck_data_o_gen [i][k] <= {Fpay{1'b0}};
end else begin
if(chan_in.flit_chanel.flit.vc[i] & chan_in.flit_chanel.flit_wr ) begin
if (chan_in.flit_chanel.flit.hdr_flag )begin
if ( k ==0 ) pck_data_o_gen [i][k][HDR_DATA_w-1 : 0] <= hdr_data_o;
end
else begin
if (rsv_counter[i] == k ) pck_data_o_gen [i][k] <= chan_in.flit_chanel.flit.payload;
end // else
end //if
end //else
end// always
if (k == 0 ) assign pck_data_o [i][HDR_DATA_w-1 : 0] = pck_data_o_gen [i][0][HDR_DATA_w-1 : 0];
else if (k == REMAIN_DAT_FLIT) assign pck_data_o [i][PCK_INJ_Dw-1 : (k-1)*Fpay+ HDR_DATA_w] = pck_data_o_gen [i][k][LASTw-1: 0];
else assign pck_data_o [i][(k)*Fpay+HDR_DATA_w -1 : (k-1)*Fpay+ HDR_DATA_w] = pck_data_o_gen [i][k];
end //for k
//synthesis translate_off
always @(posedge clk) begin
if((pck_injct_out.ready[i] == 1'b0 ) & pck_injct_in.vc[i] & pck_injct_in.pck_wr )begin
$display("%t: ERROR: a packet injection request is recived in core(%d), vc (%d) while packet injectore was not ready. %m",$time,current_id,i);
$finish;
end
end
//synthesis translate_on
end//for i
endgenerate
wire [V-1 : 0] vc_reg;
wire tail_flag_reg, hdr_flag_reg;
pronoc_register #(.W(V)) register1 (.in(chan_in.flit_chanel.flit.vc), .reset (reset ), .clk (clk),.out(vc_reg));
pronoc_register #(.W(1)) register2 (.in(chan_in.flit_chanel.flit.hdr_flag), .reset (reset ), .clk (clk),.out(hdr_flag_reg));
pronoc_register #(.W(1)) register3 (.in(chan_in.flit_chanel.flit.tail_flag & chan_in.flit_chanel.flit_wr ),.reset (reset ), .clk (clk),.out(tail_flag_reg));
wire [Vw-1 : 0] vc_bin;
one_hot_to_bin #(
.ONE_HOT_WIDTH (V),
.BIN_WIDTH (Vw )
) one_hot_to_bin (
.one_hot_code (vc_reg ),
.bin_code (vc_bin )
);
 
assign pck_injct_out.data = pck_data_o[vc_bin];
assign pck_injct_out.size = rsv_counter[vc_bin];
assign pck_injct_out.h2t_delay = h2t_counter[vc_bin];
assign pck_injct_out.ready = (flit_type == HEADER)? ~vc_fifo_full : {V{1'b0}};
assign pck_injct_out.endp_addr = sender_endp_addr_reg[vc_bin];
assign pck_injct_out.vc = vc_reg;
assign pck_injct_out.pck_wr = tail_flag_reg;
assign chan_out.flit_chanel.flit.hdr_flag =head;
assign chan_out.flit_chanel.flit.tail_flag=tail;
assign chan_out.flit_chanel.flit.vc=pck_injct_in.vc;
assign chan_out.flit_chanel.flit_wr=flit_wr;
 
assign chan_out.flit_chanel.flit.payload = (flit_type== HEADER)? hdr_flit_out[Fpay-1 : 0] : dataIn;
assign chan_out.smart_chanel = {SMART_CHANEL_w{1'b0}};
assign chan_out.flit_chanel.congestion = {CONGw{1'b0}};
assign chan_out.flit_chanel.credit= credit_o;
assign chan_out.ctrl_chanel.credit_init_val= LB;
assign chan_out.ctrl_chanel.endp_port =1'b1;
distance_gen #(
.TOPOLOGY(TOPOLOGY),
.T1(T1),
.T2(T2),
.T3(T3),
.EAw(EAw),
.DISTw(DISTw)
)
the_distance_gen
(
.src_e_addr(sender_endp_addr_reg[vc_bin]),
.dest_e_addr(current_e_addr),
.distance(pck_injct_out.distance)
);
//synthesis translate_off
//`define MONITOR_RSV_DAT
 
always @(posedge clk) begin
if((pck_injct_in.vc == {V{1'b0}} ) & pck_injct_in.pck_wr )begin
$display("%t: ERROR: a packet injection request is recived while vc is not set. %m",$time);
$finish;
end
if(pck_injct_in.pck_wr && (pck_injct_in.size<MIN_PCK_SIZ[PCK_SIZw-1 : 0])) begin
$display("%t: ERROR: requested %d flit packet size is smaller than minimum %d flits to send %d bits of data. %m",$time,pck_injct_in.size,MIN_PCK_SIZ, PCK_INJ_Dw );
$finish;
end
`ifdef MONITOR_RSV_DAT
if(pck_injct_in.pck_wr) begin
$display ("pck_inj(%d) send a packet: size=%d, data=%h, v=%h",current_id,
pck_injct_in.size, pck_injct_in.data,pck_injct_in.vc);
end
if(pck_injct_out.pck_wr) begin
$display ("pck_inj(%d) got a packet: source=%d, size=%d, data=%h",current_id,
sendor_id,pck_injct_out.size,pck_injct_out.data);
end
`endif
end
//synthesis translate_on
endmodule
 
 
 
 
/******************
* ovc_status
*******************/
module injector_ovc_status #(
parameter V = 4,
parameter B = 16,
parameter CRDTw =4
)
(
input [V-1 : 0] [CRDTw-1 : 0 ] credit_init_val_in,
input [V-1 :0] wr_in,
input [V-1 :0] credit_in,
output [V-1 :0] full_vc,
output [V-1 :0] nearly_full_vc,
output [V-1 :0] empty_vc,
input clk,
input reset
);
 
function integer log2;
input integer number; begin
log2=(number <=1) ? 1: 0;
while(2**log2<number) begin
log2=log2+1;
end
end
endfunction // log2
localparam DEPTH_WIDTH = log2(B+1);
reg [DEPTH_WIDTH-1 : 0] credit [V-1 : 0];
wire [V-1 : 0] cand_vc_next;
genvar i;
generate
for(i=0;i<V;i=i+1) begin : vc_loop
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset)begin
credit[i]<= credit_init_val_in[i][DEPTH_WIDTH-1:0];
end else begin
if( wr_in[i] && ~credit_in[i]) credit[i] <= credit[i]-1'b1;
if( ~wr_in[i] && credit_in[i]) credit[i] <= credit[i]+1'b1;
end //reset
end//always
 
assign full_vc[i] = (credit[i] == {DEPTH_WIDTH{1'b0}});
assign nearly_full_vc[i]= (credit[i] == 1) | full_vc[i];
assign empty_vc[i] = (credit[i] == credit_init_val_in[i][DEPTH_WIDTH-1:0]);
end//for
endgenerate
endmodule
 
 
 
 
/**************************************
*
*
* ***********************************/
 
 
 
module packet_injector_verilator
import pronoc_pkg::*;
(
//general
current_e_addr,
reset,
clk,
//noc port
chan_in,
chan_out,
//control interafce
pck_injct_in_data,
pck_injct_in_size,
pck_injct_in_endp_addr,
pck_injct_in_class_num,
pck_injct_in_init_weight,
pck_injct_in_vc,
pck_injct_in_pck_wr,
pck_injct_in_ready,
pck_injct_out_data,
pck_injct_out_size,
pck_injct_out_endp_addr,
pck_injct_out_class_num,
pck_injct_out_init_weight,
pck_injct_out_vc,
pck_injct_out_pck_wr,
pck_injct_out_ready,
pck_injct_out_distance,
pck_injct_out_h2t_delay,
min_pck_size
);
 
 
//general
input reset,clk;
input [EAw-1 :0 ] current_e_addr;
// the destination endpoint address
//NoC interface
input smartflit_chanel_t chan_in;
output smartflit_chanel_t chan_out;
//control interafce
input [PCK_INJ_Dw-1 : 0] pck_injct_in_data;
input [PCK_SIZw-1 : 0] pck_injct_in_size;
input [EAw-1 : 0] pck_injct_in_endp_addr;
input [Cw-1 : 0] pck_injct_in_class_num;
input [WEIGHTw-1 : 0] pck_injct_in_init_weight;
input [V-1 : 0] pck_injct_in_vc;
input pck_injct_in_pck_wr;
input [V-1 : 0] pck_injct_in_ready;
 
output [PCK_INJ_Dw-1 : 0] pck_injct_out_data;
output [PCK_SIZw-1 : 0] pck_injct_out_size;
output [EAw-1 : 0] pck_injct_out_endp_addr;
output [Cw-1 : 0] pck_injct_out_class_num;
output [WEIGHTw-1 : 0] pck_injct_out_init_weight;
output [V-1 : 0] pck_injct_out_vc;
output pck_injct_out_pck_wr;
output [V-1 : 0] pck_injct_out_ready;
output [DISTw-1 : 0] pck_injct_out_distance;
output [15 : 0] pck_injct_out_h2t_delay;
output [4 : 0] min_pck_size;
pck_injct_t pck_injct_in;
pck_injct_t pck_injct_out;
 
assign pck_injct_in.data = pck_injct_in_data;
assign pck_injct_in.size = pck_injct_in_size;
assign pck_injct_in.endp_addr = pck_injct_in_endp_addr;
assign pck_injct_in.class_num = pck_injct_in_class_num;
assign pck_injct_in.init_weight = pck_injct_in_init_weight;
assign pck_injct_in.vc = pck_injct_in_vc;
assign pck_injct_in.pck_wr = pck_injct_in_pck_wr;
assign pck_injct_in.ready = pck_injct_in_ready;
assign pck_injct_out_data = pck_injct_out.data;
assign pck_injct_out_size = pck_injct_out.size;
assign pck_injct_out_endp_addr = pck_injct_out.endp_addr;
assign pck_injct_out_class_num = pck_injct_out.class_num;
assign pck_injct_out_init_weight = pck_injct_out.init_weight;
assign pck_injct_out_vc = pck_injct_out.vc;
assign pck_injct_out_pck_wr = pck_injct_out.pck_wr;
assign pck_injct_out_ready = pck_injct_out.ready;
assign pck_injct_out_distance = pck_injct_out.distance;
assign pck_injct_out_h2t_delay = pck_injct_out.h2t_delay;
packet_injector injector (
.current_e_addr (current_e_addr ),
.reset (reset ),
.clk (clk ),
.chan_in (chan_in ),
.chan_out (chan_out ),
.pck_injct_in (pck_injct_in ),
.pck_injct_out (pck_injct_out ));
localparam
HDR_BYTE_NUM = HDR_MAX_DATw / 8, // = HDR_MAX_DATw / (8 - HDR_MAX_DATw %8)
HDR_DATA_w_tmp = HDR_BYTE_NUM * 8,
HDR_DATA_w = (PCK_INJ_Dw < HDR_DATA_w_tmp)? PCK_INJ_Dw : HDR_DATA_w_tmp,
REMAIN_DATw = PCK_INJ_Dw - HDR_DATA_w,
REMAIN_DAT_FLIT_I = (REMAIN_DATw / Fpay),
REMAIN_DAT_FLIT_F = (REMAIN_DATw % Fpay == 0)? 0 : 1,
REMAIN_DAT_FLIT = REMAIN_DAT_FLIT_I + REMAIN_DAT_FLIT_F,
CNTw = log2(REMAIN_DAT_FLIT),
MIN_PCK_SIZ = REMAIN_DAT_FLIT +1;
assign min_pck_size = MIN_PCK_SIZ[4:0];
 
 
// `ifdef VERILATOR
// logic endp_is_active /*verilator public_flat_rd*/ ;
//
// always @ (*) begin
// endp_is_active = 1'b0;
// if (chan_out.flit_chanel.flit_wr) endp_is_active=1'b1;
// if (chan_out.flit_chanel.credit > {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
/src_modelsim/multicast_test.sv
0,0 → 1,126
// synthesis translate_off
`timescale 1ns/1ns
 
 
module multicast_test;
import pronoc_pkg::*;
reg reset ,clk;
initial begin
clk = 1'b0;
forever clk = #10 ~clk;
end
smartflit_chanel_t chan_in_all [NE-1 : 0];
smartflit_chanel_t chan_out_all [NE-1 : 0];
pck_injct_t pck_injct_in [NE-1 : 0];
pck_injct_t pck_injct_out[NE-1 : 0];
noc_top the_noc
(
.reset(reset),
.clk(clk),
.chan_in_all(chan_in_all),
.chan_out_all(chan_out_all),
.router_event( )
);
reg [NEw-1 : 0] dest_id [NE-1 : 0];
wire [NEw-1: 0] current_e_addr [NE-1 : 0];
genvar i;
generate
for(i=0; i< NE; i=i+1) begin : endpoints
endp_addr_encoder #( .TOPOLOGY(TOPOLOGY), .T1(T1), .T2(T2), .T3(T3), .EAw(EAw), .NE(NE)) encode1 ( .id(i[NEw-1 :0]), .code(current_e_addr[i]));
multicast_injector pck_inj(
//general
.current_e_addr(current_e_addr[i]),
.reset(reset),
.clk(clk),
//noc port
.chan_in(chan_out_all[i]),
.chan_out(chan_in_all[i]),
//control interafce
.pck_injct_in(pck_injct_in[i]),
.pck_injct_out(pck_injct_out[i])
);
 
endp_addr_encoder #( .TOPOLOGY(TOPOLOGY), .T1(T1), .T2(T2), .T3(T3), .EAw(EAw), .NE(NE)) encode2 ( .id(dest_id[i]), .code(pck_injct_in[i].endp_addr[EAw-1 : 0]));
reg [31:0]k;
 
initial begin
reset = 1'b1;
k=0;
pck_injct_in[i].data =0;
#10
pck_injct_in[i].class_num=0;
pck_injct_in[i].init_weight=1;
pck_injct_in[i].vc=1;
pck_injct_in[i].pck_wr=1'b0;
#100
@(posedge clk) #1;
reset=1'b0;
#100
@(posedge clk) #1;
//if(i==1) begin
// repeat(10) begin
while (pck_injct_out[i].ready[0] == 1'b0) @(posedge clk) #1;
pck_injct_in[i].data='h123456789ABCDEFEDCBA987654321+k;
pck_injct_in[i].size=3+(k%18);
dest_id[i]=0;
pck_injct_in[i].pck_wr=1'b1;
@(posedge clk) #1 k++;
pck_injct_in[i].pck_wr=1'b0;
@(posedge clk) #1 k++;
 
// end
 
#10000
@(posedge clk) $stop;
 
//end
end
always @(posedge clk) begin
if(pck_injct_out[i].pck_wr) begin
$display ("%t:pck_inj(%d) got a packet: source=%d, size=%d, data=%h",$time,i,
pck_injct_out[i].endp_addr,pck_injct_out[i].size,pck_injct_out[i].data);
end
end
end//for
endgenerate
 
 
 
 
 
endmodule
// synthesis translate_on
 
src_modelsim/multicast_test.sv Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: src_modelsim/noc_sim_statistic.sv =================================================================== --- src_modelsim/noc_sim_statistic.sv (nonexistent) +++ src_modelsim/noc_sim_statistic.sv (revision 54) @@ -0,0 +1,128 @@ +// synthesis translate_off +`timescale 1ns/1ns +`include "pronoc_def.v" +module routers_statistic_collector + import pronoc_pkg::*; + ( + reset, + clk, + router_event, + print + ); + + + input clk,reset; + input router_event_t router_event [NR-1 : 0][MAX_P-1 : 0]; + input print; + + typedef struct { + integer pck_num_in; + integer flit_num_in; + integer pck_num_out; + integer flit_num_out; + integer flit_num_in_bypassed; + integer flit_num_in_buffered; + integer bypass_counter [SMART_NUM : 0]; + } router_stat_t; + + + + task reset_router_stat; + output router_stat_t stat_in; + integer k; + begin + stat_in.pck_num_in=0; + stat_in.flit_num_in=0; + stat_in.pck_num_out=0; + stat_in.flit_num_out=0; + stat_in.flit_num_in_bypassed=0; + stat_in.flit_num_in_buffered=0; + for (k=0;k0) for (k=0;k0) for (k=0;k
src_modelsim/noc_sim_statistic.sv Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: src_modelsim/pck_injector_test.sv =================================================================== --- src_modelsim/pck_injector_test.sv (revision 50) +++ src_modelsim/pck_injector_test.sv (revision 54) @@ -26,7 +26,8 @@ .reset(reset), .clk(clk), .chan_in_all(chan_in_all), - .chan_out_all(chan_out_all) + .chan_out_all(chan_out_all), + .router_event( ) ); reg [NEw-1 : 0] dest_id [NE-1 : 0];
/src_modelsim/testbench_noc.sv
150,17 → 150,17
 
 
reg print_router_st;
smartflit_chanel_t chan_in_all [NE-1 : 0];
smartflit_chanel_t chan_out_all [NE-1 : 0];
router_event_t router_event [NR-1 : 0] [MAX_P-1 : 0];
wire [NE-1 : 0] hdr_flit_sent;
wire [EAw-1 : 0] dest_e_addr [NE-1 :0];
wire [DAw-1 : 0] dest_e_addr [NE-1 :0];
wire [EAw-1 : 0] src_e_addr [NE-1 :0];
wire [Cw-1 : 0] pck_class_in [NE-1 :0];
wire [Cw-1 : 0] flit_out_class [NE-1 :0];
168,8 → 168,8
wire [PCK_SIZw-1: 0] pck_size_in [NE-1 :0];
wire [PCK_SIZw-1: 0] pck_size_o [NE-1 :0];
wire [NEw-1 : 0] mcast_dst_num [NE-1 :0];
// wire [NE-1 :0] report;
reg [CLK_CNTw-1 :0] clk_counter;
210,7 → 210,8
.reset(reset),
.clk(clk),
.chan_in_all(chan_in_all),
.chan_out_all(chan_out_all)
.chan_out_all(chan_out_all),
.router_event(router_event)
);
267,7 → 268,8
traffic_gen_top #(
.MAX_RATIO(100)
.MAX_RATIO(100),
.ENDP_ID(i)
)
the_traffic_gen
(
297,7 → 299,8
.start_delay(start_delay[i]),
.flit_out_class(flit_out_class[i]),
.flit_out_wr(),
.flit_in_wr()
.flit_in_wr(),
.mcast_dst_num_o(mcast_dst_num[i])
);
338,7 → 341,15
.NE(NE),
.MAX_PCK_NUM(MAX_PCK_NUM),
.TRAFFIC(TRAFFIC),
.HOTSPOT_NODE_NUM(HOTSPOT_NODE_NUM)
.HOTSPOT_NODE_NUM(HOTSPOT_NODE_NUM),
.MCAST_TRAFFIC_RATIO(MCAST_TRAFFIC_RATIO),
.MCAST_PCK_SIZ_MIN(MCAST_PCK_SIZ_MIN),
.MCAST_PCK_SIZ_MAX(MCAST_PCK_SIZ_MAX),
.PCK_SIZw(PCK_SIZw),
.MIN_PACKET_SIZE(MIN_PACKET_SIZE),
.MAX_PACKET_SIZE(MAX_PACKET_SIZE),
.PCK_SIZ_SEL(PCK_SIZ_SEL),
.DISCRETE_PCK_SIZ_NUM(DISCRETE_PCK_SIZ_NUM)
)
the_pck_dst_gen
(
351,25 → 362,13
.dest_e_addr(dest_e_addr[i]),
.valid_dst(valid_dst[i]),
.hotspot_info(hotspot_info),
.pck_size_o( pck_size_in[i]) ,
.rnd_discrete(rnd_discrete),
.custom_traffic_t(custom_traffic_t[i]), // defined in sim_param.sv
.custom_traffic_en(custom_traffic_en[i]) // defined in sim_param.sv
);
pck_size_gen #(
.PCK_SIZw(PCK_SIZw),
.MIN(MIN_PACKET_SIZE),
.MAX(MAX_PACKET_SIZE),
.PCK_SIZ_SEL(PCK_SIZ_SEL),
.DISCRETE_PCK_SIZ_NUM(DISCRETE_PCK_SIZ_NUM)
)
the_pck_siz_gen
(
.reset(reset),
.clk(clk),
.en(hdr_flit_sent[i]),
.pck_size( pck_size_in[i]) ,
.rnd_discrete(rnd_discrete)
);
end
endgenerate
394,7 → 393,7
integer sent_core_worst_delay [NE-1 : 0];
integer total_active_endp;
integer total_rsv_pck_num,total_rsv_flit_number;
integer total_sent_pck_num,total_sent_flit_number;
integer total_sent_pck_num,total_sent_flit_number,total_expect_rsv_flit_num;
integer core_num,k;
always @(posedge clk or posedge reset)begin
407,6 → 406,7
sum_clk_per_hop=0;
total_sent_flit_number=0;
total_rsv_flit_number=0;
total_expect_rsv_flit_num=0;
for (k=0;k<C;k=k+1) begin
sum_clk_pow2_per_class[k]=0;
total_rsv_pck_num_per_class[k]=0;
427,6 → 427,10
for (core_num=0; core_num<NE; core_num=core_num+1)begin
if(chan_in_all[core_num].flit_chanel.flit_wr)begin
total_sent_flit_number+=1;
if (CAST_TYPE != "UNICAST") total_expect_rsv_flit_num+=mcast_dst_num[core_num];
else total_expect_rsv_flit_num++;
if (C>1) sent_stat [core_num][flit_out_class[core_num]].flit_num++;
else sent_stat [core_num][0].flit_num++;
if(chan_in_all[core_num].flit_chanel.flit[Fw-1])begin
476,11 → 480,11
sum_clk_pow2+=time_stamp_h2h[core_num] * time_stamp_h2h[core_num];
sum_clk_pow2_per_class[pck_class_out[core_num]]+=time_stamp_h2h[core_num] * time_stamp_h2h[core_num];
`endif
sum_clk_per_hop+= $itor(time_stamp_h2h[core_num])/$itor(distance[core_num]);
if(distance[core_num] > 0) sum_clk_per_hop+= $itor(time_stamp_h2h[core_num])/$itor(distance[core_num]);
total_rsv_pck_num_per_class[pck_class_out[core_num]]+=1;
sum_clk_h2h_per_class[pck_class_out[core_num]]+=time_stamp_h2h[core_num] ;
sum_clk_h2t_per_class[pck_class_out[core_num]]+=time_stamp_h2t[core_num] ;
sum_clk_per_hop_per_class[pck_class_out[core_num]]+= $itor(time_stamp_h2h[core_num])/$itor(distance[core_num]);
if(distance[core_num]>0) sum_clk_per_hop_per_class[pck_class_out[core_num]]+= $itor(time_stamp_h2h[core_num])/$itor(distance[core_num]);
rsvd_core_total_rsv_pck_num[core_num]+=1;
if (rsvd_core_worst_delay[core_num] < time_stamp_h2t[core_num]) rsvd_core_worst_delay[core_num] = ( AVG_LATENCY_METRIC == "HEAD_2_TAIL")? time_stamp_h2t[core_num] : time_stamp_h2h[core_num];
if (sent_core_worst_delay[src_id[core_num]] < time_stamp_h2t[core_num]) sent_core_worst_delay[src_id[core_num]] = (AVG_LATENCY_METRIC == "HEAD_2_TAIL")? time_stamp_h2t[core_num] : time_stamp_h2h[core_num];
528,11 → 532,12
if(all_done_in) begin //All injectors stopped injecting packets
if(total_rsv_flit_number_old==total_rsv_flit_number) rsv_ideal_cnt<=rsv_ideal_cnt+1;//count the number of cycle when no flit is received by any injector
else rsv_ideal_cnt=0;
if(total_sent_flit_number == total_rsv_flit_number) begin // All injected packets are consumed
if(total_expect_rsv_flit_num == total_rsv_flit_number) begin // All injected packets are consumed
done<=1'b1;
end
if(rsv_ideal_cnt >= 100) begin // Injectors stopped sending packets, number of received and sent flits are not equal yet and for 100 cycles no flit is consumed.
$display ("ERROR: The number of sent (%d) & received flits (%d) were not equal at the end of simulation",total_sent_flit_number ,total_rsv_flit_number);
done<=1'b1;
#100 $display ("ERROR: The number of expected (%d) & received flits (%d) were not equal at the end of simulation",total_expect_rsv_flit_num ,total_rsv_flit_number);
$stop;
end
551,11 → 556,12
end
 
initial print_router_st=1'b0;
//report
always @( posedge done) begin
for (core_num=0; core_num<NE; core_num=core_num+1) begin
if(pck_counter[core_num]>0) total_active_endp = total_active_endp +1;
end
566,6 → 572,10
avg_latency_per_hop = sum_clk_per_hop/$itor(total_rsv_pck_num);
$display("simulation results-------------------");
$display("\tSimulation clock cycles:%0d",clk_counter);
print_router_st=1'b1;
#1
/*
$display(" total sent/received packets:%d/%d",total_sent_pck_num,total_rsv_pck_num);
$display(" total sent/received flits:%d/%d",total_sent_flit_number,total_rsv_flit_number);
579,12 → 589,12
$display(" average packet latency = %f \n average flit latency = %f ",avg_latency_pck, avg_latency_flit);
*/
$display("\n\tTotal injected packet in different size:");
for (m=0;m<=(MAX_PACKET_SIZE - MIN_PACKET_SIZE);m++) begin
$write("\tflit_size,");
$write("\tflit_size,");
for (m=0;m<=(MAX_PACKET_SIZE - MIN_PACKET_SIZE);m++) begin
if(rsv_size_array[m]>0)$write("%0d,",m+ MIN_PACKET_SIZE);
end
for (m=0;m<=(MAX_PACKET_SIZE - MIN_PACKET_SIZE);m++) begin
$write("\n\t#pck,");
$write("\n\t#pck,");
for (m=0;m<=(MAX_PACKET_SIZE - MIN_PACKET_SIZE);m++) begin
if(rsv_size_array[m]>0)$write("%0d,",rsv_size_array[m]);
end
593,16 → 603,12
//std_dev= standard_dev( sum_clk_pow2,total_rsv_pck_num, avg_latency_flit);
//$display(" standard_dev = %f",std_dev);
//`endif
 
$write("\n\n\t#node,sent_stat.pck_num,rsvd_stat.pck_num,sent_stat.flit_num,rsvd_stat.flit_num,sent_stat.worst_latency,rsvd_stat.worst_latency,sent_stat.min_latency,rsvd_stat.min_latency,avg_latency_per_hop,avg_latency_flit,avg_latency_pck,avg_throughput(%%),avg_pck_size,");
$display("\n\n\tEndpoints' statistics");
$write("\t#node,sent_stat.pck_num,rsvd_stat.pck_num,sent_stat.flit_num,rsvd_stat.flit_num,sent_stat.worst_latency,rsvd_stat.worst_latency,sent_stat.min_latency,rsvd_stat.min_latency,avg_latency_per_hop,avg_latency_flit,avg_latency_pck,avg_throughput(%%),avg_pck_size,");
`ifdef STND_DEV_EN
$write("avg.std_dev");
`endif
$write("\n");
 
 
 
$write("\n");
for (m=0; m<NE;m++)begin
for (c=0; c<STAT_NUM;c++)begin
701,41 → 707,7
 
initial begin
 
//print_parameter
$display ("NoC parameters:----------------");
$display ("\tTopology: %s",TOPOLOGY);
$display ("\tRouting algorithm: %s",ROUTE_NAME);
$display ("\tVC_per port: %0d", V);
$display ("\tNon-local port buffer_width per VC: %0d", B);
$display ("\tLocal port buffer_width per VC: %0d", LB);
if(TOPOLOGY=="MESH" || TOPOLOGY=="TORUS")begin
$display ("\tRouter num in row: %0d",T1);
$display ("\tRouter num in column: %0d",T2);
$display ("\tEndpoint num per router: %0d",T3);
end else if (TOPOLOGY=="RING" || TOPOLOGY == "LINE") begin
$display ("\tTotal Router num: %0d",T1);
$display ("\tEndpoint num per router: %0d",T3);
end else if (TOPOLOGY == "TREE" || TOPOLOGY == "FATTREE")begin
$display ("\tK: %0d",T1);
$display ("\tL: %0d",T2);
end else begin //CUSTOM
$display ("\tTotal Endpoints number: %0d",T1);
$display ("\tTotal Routers number: %0d",T2);
end
$display ("\tNumber of Class: %0d", C);
$display ("\tFlit data width: %0d", Fpay);
$display ("\tVC reallocation mechanism: %s", VC_REALLOCATION_TYPE);
$display ("\tVC/sw combination mechanism: %s", COMBINATION_TYPE);
$display ("\tAVC_ATOMIC_EN:%0d", AVC_ATOMIC_EN);
$display ("\tCongestion Index:%0d",CONGESTION_INDEX);
$display ("\tADD_PIPREG_AFTER_CROSSBAR:%0d",ADD_PIPREG_AFTER_CROSSBAR);
$display ("\tSSA_EN enabled:%s",SSA_EN);
$display ("\tSwitch allocator arbitration type:%s",SWA_ARBITER_TYPE);
$display ("\tMinimum supported packet size:%0d flit(s)",MIN_PCK_SIZE);
$display ("\tLoop back is enabled:%s",SELF_LOOP_EN);
$display ("\tNumber of multihop bypass (SMART max):%0d",SMART_MAX);
$display ("NoC parameters:----------------");
display_noc_parameters();
$display ("Simulation parameters-------------");
if(DEBUG_EN)
$display ("\tDebuging is enabled");
753,6 → 725,12
//$display ("\tHot spot percentage: %u\n", HOTSPOT_PERCENTAGE);
$display ("\tNumber of hot spot cores: %0d", HOTSPOT_NODE_NUM);
end
if (CAST_TYPE != "UNICAST")begin
$display ("\tMULTICAST traffic ratio: %d(%%), min: %d, max: %d\n", MCAST_TRAFFIC_RATIO,MCAST_PCK_SIZ_MIN,MCAST_PCK_SIZ_MAX);
end
 
//$display ("\tTotal packets sent by one router: %u\n", TOTAL_PKT_PER_ROUTER);
$display ("\tSimulation timeout =%0d", STOP_SIM_CLK);
$display ("\tSimulation ends on total packet num of =%0d", STOP_PCK_NUM);
799,7 → 777,7
rsvd_stat[core_num][0].pck_num ++;
rsvd_stat[core_num][0].sum_clk_h2h +=clk_num_h2h;
rsvd_stat[core_num][0].sum_clk_h2t +=clk_num_h2t;
rsvd_stat[core_num][0].sum_clk_per_hop+= (clk_num_h2h/$itor(distance));
if(distance>0) rsvd_stat[core_num][0].sum_clk_per_hop+= (clk_num_h2h/$itor(distance));
if (rsvd_stat[core_num][0].worst_latency < latency ) rsvd_stat[core_num][0].worst_latency=latency;
if (rsvd_stat[core_num][0].min_latency==0 ) rsvd_stat[core_num][0].min_latency =latency;
if (rsvd_stat[core_num][0].min_latency > latency ) rsvd_stat[core_num][0].min_latency =latency;
946,6 → 924,14
.start_o(start_o)
);
*/
routers_statistic_collector router_stat(
.reset(reset),
.clk(clk),
.router_event(router_event),
.print(print_router_st)
);
 
endmodule
// synthesis translate_on
/src_modelsim/traffic_pattern.sv
73,9 → 73,245
pck_dst_gen
 
*********************************/
module pck_dst_gen
import pronoc_pkg::*;
#(
parameter NE=4,
parameter TRAFFIC = "RANDOM",
parameter MAX_PCK_NUM = 10000,
parameter HOTSPOT_NODE_NUM = 4,
parameter MCAST_TRAFFIC_RATIO =50,
parameter MCAST_PCK_SIZ_MIN = 2,
parameter MCAST_PCK_SIZ_MAX = 4,
parameter PCK_SIZw=5,
parameter MIN_PACKET_SIZE=5,
parameter MAX_PACKET_SIZE=5,
parameter PCK_SIZ_SEL="random-discrete",
parameter DISCRETE_PCK_SIZ_NUM=1
)(
en,
current_e_addr,
core_num,
pck_number,
dest_e_addr,
clk,
reset,
valid_dst,
hotspot_info,
custom_traffic_t,
custom_traffic_en,
pck_size_o,
rnd_discrete
);
module pck_dst_gen
localparam ADDR_DIMENSION = (TOPOLOGY == "MESH" || TOPOLOGY == "TORUS") ? 2 : 1; // "RING" and FULLY_CONNECT
localparam NEw= log2(NE),
PCK_CNTw = log2(MAX_PCK_NUM+1),
HOTSPOT_NUM= (TRAFFIC=="HOTSPOT")? HOTSPOT_NODE_NUM : 1;
input reset,clk,en;
input [NEw-1 : 0] core_num;
input [PCK_CNTw-1 : 0] pck_number;
input [EAw-1 : 0] current_e_addr;
output [DAw-1 : 0] dest_e_addr;
output valid_dst;
input [NEw-1 : 0] custom_traffic_t;
input custom_traffic_en;
output [PCK_SIZw-1:0] pck_size_o;
input rnd_discrete_t rnd_discrete [DISCRETE_PCK_SIZ_NUM-1: 0];
input hotspot_t hotspot_info [HOTSPOT_NUM-1 : 0];
 
 
wire [EAw-1 : 0] unicast_dest_e_addr;
wire [PCK_SIZw-1 : 0] pck_size_uni;
 
pck_dst_gen_unicast #(
.NE(NE),
.TRAFFIC(TRAFFIC),
.MAX_PCK_NUM(MAX_PCK_NUM),
.HOTSPOT_NODE_NUM(HOTSPOT_NODE_NUM)
)
unicast
(
.en (en ),
.current_e_addr (current_e_addr ),
.core_num (core_num ),
.pck_number (pck_number ),
.dest_e_addr (unicast_dest_e_addr),
.clk (clk ),
.reset (reset ),
.valid_dst (valid_dst ),
.hotspot_info (hotspot_info ),
.custom_traffic_t (custom_traffic_t),
.custom_traffic_en(custom_traffic_en)
);
pck_size_gen #(
.PCK_SIZw(PCK_SIZw),
.MIN(MIN_PACKET_SIZE),
.MAX(MAX_PACKET_SIZE),
.PCK_SIZ_SEL(PCK_SIZ_SEL),
.DISCRETE_PCK_SIZ_NUM(DISCRETE_PCK_SIZ_NUM)
)
unicast_pck_size
(
.reset(reset),
.clk(clk),
.en(en),
.pck_size(pck_size_uni) ,
.rnd_discrete(rnd_discrete)
);
 
generate
if(CAST_TYPE == "UNICAST") begin :uni
assign dest_e_addr = unicast_dest_e_addr;
assign pck_size_o = pck_size_uni;
end else begin :multi
reg [DAw-1 : 0] multicast_dest_e_addr,temp;
reg [6: 0] rnd_reg;
wire [PCK_SIZw-1 : 0] pck_size_mcast;
reg [PCK_SIZw-1 : 0] pck_siz_tmp;
wire [NEw-1 : 0] unicast_id_num;
endp_addr_decoder #(
.T1(T1),
.T2(T2),
.T3(T3),
.NE(NE),
.EAw(EAw),
.TOPOLOGY(TOPOLOGY)
)enc
(
.code(unicast_dest_e_addr),
.id(unicast_id_num)
);
pck_size_gen #(
.PCK_SIZw(PCK_SIZw),
.MIN(MCAST_PCK_SIZ_MIN),
.MAX(MCAST_PCK_SIZ_MAX),
.PCK_SIZ_SEL("random-range"),
.DISCRETE_PCK_SIZ_NUM(DISCRETE_PCK_SIZ_NUM)
)
mcast_pck_size
(
.reset(reset),
.clk(clk),
.en(en),
.pck_size(pck_size_mcast) ,
.rnd_discrete(rnd_discrete)
);
always @(posedge clk ) begin
if(en | reset) begin
rnd_reg <= $urandom_range(99,0);
end
end
if(CAST_TYPE == "MULTICAST_FULL") begin :mful
always @( * ) begin
multicast_dest_e_addr = {DAw{1'b0}};
temp={DAw{1'b0}};
temp[unicast_id_num]=1'b1;
pck_siz_tmp= pck_size_uni;
if(rnd_reg >= MCAST_TRAFFIC_RATIO) begin
multicast_dest_e_addr[unicast_id_num]=1'b1;
end
else begin
multicast_dest_e_addr = $urandom();
pck_siz_tmp=pck_size_mcast;
end
if(SELF_LOOP_EN == "NO") multicast_dest_e_addr[core_num]=1'b0;
end
assign dest_e_addr = (multicast_dest_e_addr=={DAw{1'b0}} )? temp : multicast_dest_e_addr ;
assign pck_size_o = pck_siz_tmp;
end else if(CAST_TYPE == "MULTICAST_PARTIAL") begin :mpar
always @( * ) begin
multicast_dest_e_addr = {DAw{1'b0}};
temp={unicast_dest_e_addr,1'b1};
pck_siz_tmp= pck_size_uni;
if(rnd_reg >= MCAST_TRAFFIC_RATIO) begin
multicast_dest_e_addr = {unicast_dest_e_addr,1'b1};
end
else begin
multicast_dest_e_addr = $urandom();
multicast_dest_e_addr[0] =1'b0;
pck_siz_tmp=pck_size_mcast;
if(SELF_LOOP_EN == "NO") begin
if(MCAST_ENDP_LIST[core_num]==1'b1) multicast_dest_e_addr[endp_id_to_mcast_id(core_num)+1]=1'b0;
end
end
end
assign dest_e_addr = (multicast_dest_e_addr=={DAw{1'b0}} )? temp : multicast_dest_e_addr ;
assign pck_size_o = pck_siz_tmp;
end else begin //Broadcast
always @( * ) begin
multicast_dest_e_addr = {DAw{1'b0}};
pck_siz_tmp = pck_size_uni;
if(rnd_reg >= MCAST_TRAFFIC_RATIO) begin
multicast_dest_e_addr = {unicast_dest_e_addr,1'b1};
end
else begin
pck_siz_tmp=pck_size_mcast;
end
end
assign dest_e_addr = multicast_dest_e_addr ;
assign pck_size_o = pck_siz_tmp;
end
 
end endgenerate
 
endmodule
 
 
 
 
 
 
 
 
 
 
 
 
 
module pck_dst_gen_unicast
import pronoc_pkg::*;
#(
parameter NE=4,
/src_noc/comb-spec1.v
238,7 → 238,7
//synopsys translate_off
if(DEBUG_EN)begin :dbg
check_single_bit_assertation #(
is_onehot0 #(
.IN_WIDTH(P_1)
)
check_ovc_allocated
/src_noc/comb_nonspec.sv
0,0 → 1,997
`include "pronoc_def.v"
 
/**********************************************************************
** File: comb-nonspec.v
**
** Copyright (C) 2014-2017 Alireza Monemi
**
** This file is part of ProNoC
**
** ProNoC ( stands for Prototype Network-on-chip) is free software:
** you can redistribute it and/or modify it under the terms of the GNU
** Lesser General Public License as published by the Free Software Foundation,
** either version 2 of the License, or (at your option) any later version.
**
** ProNoC is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
** or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
** Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
**
**
** Description:
** VC allocator combined with non-speculative switch
** allocator where the free VC availability is checked at
** the beginning of switch allocation (comb-nonspec).
**
***********************************************************************/
 
module comb_nonspec_allocator
import pronoc_pkg::*;
#(
parameter P = 5 //port number
)
(
//VC allocator
//input
dest_port_all, // from input port
masked_ovc_request_all,
pck_is_single_flit_all,
//output
ovc_allocated_all,//to the output port
granted_ovc_num_all, // to the input port
ivc_num_getting_ovc_grant,
//switch_alloc
ivc_info,
vc_weight_is_consumed_all,
iport_weight_is_consumed_all,
//output
granted_dest_port_all,
ivc_num_getting_sw_grant,
nonspec_first_arbiter_granted_ivc_all,
any_ivc_sw_request_granted_all,
any_ovc_granted_in_outport_all,
granted_dst_is_from_a_single_flit_pck,
// global
clk,
reset
 
);
localparam
P_1 = (SELF_LOOP_EN == "NO")? P-1 : P,
PV = V * P,
VV = V * V,
VP_1 = V * P_1,
PP_1 = P_1 * P,
PVV = PV * V,
PVP_1 = PV * P_1;
 
input ivc_info_t ivc_info [P-1 : 0][V-1 : 0];
input [PVV-1 : 0] masked_ovc_request_all;
input [PVP_1-1 : 0] dest_port_all;
input [PV-1 : 0] pck_is_single_flit_all;
output [PV-1 : 0] ovc_allocated_all;
output [PVV-1 : 0] granted_ovc_num_all;
output [PV-1 : 0] ivc_num_getting_ovc_grant;
output [PP_1-1 : 0] granted_dest_port_all;
output [PV-1 : 0] ivc_num_getting_sw_grant;
output [P-1 : 0] any_ivc_sw_request_granted_all;
output [P-1 : 0] any_ovc_granted_in_outport_all;
output [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all;
// input [PVP_1-1 : 0] lk_destination_all;
input clk,reset;
input [PV-1 : 0] vc_weight_is_consumed_all;
input [P-1 : 0] iport_weight_is_consumed_all;
output [P-1 : 0] granted_dst_is_from_a_single_flit_pck;
 
 
//internal wires switch allocator
wire [PV-1 : 0] first_arbiter_granted_ivc_all;
wire [PV-1 : 0] ivc_request_masked_all;
wire [P-1 : 0] any_cand_ovc_exsit;
wire [PV-1 : 0] ivc_request_all;
wire [PV-1 : 0] ovc_is_assigned_all;
wire [PV-1 : 0] assigned_ovc_not_full_all;
assign nonspec_first_arbiter_granted_ivc_all = first_arbiter_granted_ivc_all;
//nonspeculative switch allocator
nonspec_sw_alloc #(
.V(V),
.P(P),
.FIRST_ARBITER_EXT_P_EN(FIRST_ARBITER_EXT_P_EN),
.SWA_ARBITER_TYPE (SWA_ARBITER_TYPE),
.MIN_PCK_SIZE(MIN_PCK_SIZE),
.SELF_LOOP_EN(SELF_LOOP_EN)
)
nonspeculative_sw_allocator
(
 
.ivc_granted_all (ivc_num_getting_sw_grant),
.ivc_request_masked_all (ivc_request_masked_all),
.pck_is_single_flit_all(pck_is_single_flit_all),
.granted_dst_is_from_a_single_flit_pck(granted_dst_is_from_a_single_flit_pck),
.dest_port_all (dest_port_all),
.granted_dest_port_all (granted_dest_port_all),
.first_arbiter_granted_ivc_all (first_arbiter_granted_ivc_all),
.any_ivc_granted_all (any_ivc_sw_request_granted_all),
.any_ovc_granted_all (any_ovc_granted_in_outport_all),
.vc_weight_is_consumed_all(vc_weight_is_consumed_all),
.iport_weight_is_consumed_all(iport_weight_is_consumed_all),
.clk (clk),
.reset (reset)
);
wire [PVV-1 : 0] masked_ovc_request_all;
wire [V-1 : 0] masked_non_assigned_request [PV-1 : 0] ;
wire [PV-1 : 0] masked_assigned_request;
wire [PV-1 : 0] assigned_ovc_request_all ;
wire [VV-1 : 0] masked_candidate_ovc_per_port [P-1 : 0] ;
wire [V-1 : 0] first_arbiter_granted_ivc_per_port[P-1 : 0] ;
wire [V-1 : 0] candidate_ovc_local_num [P-1 : 0] ;
wire [V-1 : 0] first_arbiter_ovc_granted [PV-1 : 0];
wire [P_1-1 : 0] granted_dest_port_per_port [P-1 : 0];
wire [VP_1-1 : 0] cand_ovc_granted [P-1 : 0];
wire [P_1-1 : 0] ovc_allocated_all_gen [PV-1 : 0];
wire [V-1 : 0] granted_ovc_local_num_per_port [P-1 : 0];
wire [V-1 : 0] ivc_local_num_getting_ovc_grant[P-1 : 0];
wire [V : 0] summ_in [PV-1 : 0];
wire [V-1 : 0] vc_pririty [PV-1 : 0] ;
assign assigned_ovc_request_all = ivc_request_all & ovc_is_assigned_all;
genvar i,j;
generate
// IVC loop
for(i=0;i< PV;i=i+1) begin :total_vc_loop
// mask unavailable ovc from requests
assign masked_non_assigned_request [i] = masked_ovc_request_all [(i+1)*V-1 : i*V ];
assign masked_assigned_request [i] = assigned_ovc_not_full_all [i] & assigned_ovc_request_all [i];
// summing assigned and non-assigned VC requests
assign summ_in[i] ={masked_non_assigned_request [i],masked_assigned_request [i]};
assign ivc_request_masked_all[i] = | summ_in[i];
//first level arbiter to candidate only one OVC
// if(VC_ARBITER_TYPE=="RRA")begin :round_robin
arbiter #(
.ARBITER_WIDTH(V)
)
ovc_arbiter
(
.clk (clk),
.reset (reset),
.request (masked_non_assigned_request [i]),
.grant (first_arbiter_ovc_granted[i]),
.any_grant ()
);
/*
end else begin :fixarb
vc_priority_based_dest_port#(
.P(P),
.V(V)
)
priority_setting
(
.dest_port(lk_destination_all [((i+1)*P_1)-1 : i*P_1]),
.vc_pririty(vc_pririty[i])
);
arbiter_ext_priority #(
.ARBITER_WIDTH (V)
)
ovc_arbiter
(
.request (masked_non_assigned_request [i]),
.priority_in(vc_pririty[i]),
.grant(first_arbiter_ovc_granted[i]),
.any_grant()
);
end
*/
end//for
wire [P-1 : 0] ovc_assigned_local;
for(i=0;i< P;i=i+1) begin :port_loop3
for(j=0;j< V;j=j+1) begin :vc_loop
//merge masked_candidate_ovc in each port
assign ivc_request_all[i*V+j] = ivc_info[i][j].ivc_req;
assign ovc_is_assigned_all[i*V+j] = ivc_info[i][j].ovc_is_assigned;
assign assigned_ovc_not_full_all[i*V+j] =ivc_info[i][j].assigned_ovc_not_full;
assign masked_candidate_ovc_per_port[i][(j+1)*V-1 : j*V] = first_arbiter_ovc_granted [i*V+j];
end//for j
assign first_arbiter_granted_ivc_per_port[i]=first_arbiter_granted_ivc_all[(i+1)*V-1 : i*V];
assign granted_dest_port_per_port[i]=granted_dest_port_all[(i+1)*P_1-1 : i*P_1];
// multiplex candidate OVC of first level switch allocatore winner
onehot_mux_1D #(
.W (V),
.N (V)
)
multiplexer2
(
.in (masked_candidate_ovc_per_port [i]),
.out (candidate_ovc_local_num [i]),
.sel (first_arbiter_granted_ivc_per_port [i])
 
);
onehot_mux_1D #(
.W (1),
.N (V)
)
multiplexer2_1
(
.in (ovc_is_assigned_all[(i+1)*V-1 : i*V]),
.out (ovc_assigned_local[i]),
.sel (first_arbiter_granted_ivc_per_port [i])
 
);
// assign any_cand_ovc_exsit[i] = | candidate_ovc_local_num [i];
//demultiplexer
one_hot_demux #(
.IN_WIDTH(V),
.SEL_WIDTH(P_1)
)
demux1
(
.demux_sel(granted_dest_port_per_port [i]),//selectore
.demux_in(candidate_ovc_local_num[i]),//repeated
.demux_out(cand_ovc_granted [i])
);
assign granted_ovc_local_num_per_port [i]=(any_ivc_sw_request_granted_all[i] )? candidate_ovc_local_num[i] : {V{1'b0}};
assign ivc_local_num_getting_ovc_grant [i]= (any_ivc_sw_request_granted_all[i] & ~ovc_assigned_local[i])? first_arbiter_granted_ivc_per_port [i] : {V{1'b0}};
assign ivc_num_getting_ovc_grant [(i+1)*V-1 : i*V] = ivc_local_num_getting_ovc_grant[i];
for(j=0;j<V; j=j+1)begin: assign_loop3
assign granted_ovc_num_all[(i*VV)+((j+1)*V)-1 : (i*VV)+(j*V)]=granted_ovc_local_num_per_port[i];
end//j
end//i
for(i=0;i< PV;i=i+1) begin :total_vc_loop2
for(j=0;j<P; j=j+1)begin: assign_loop2
if(SELF_LOOP_EN == "NO") begin :nslp
if((i/V)<j )begin: jj
assign ovc_allocated_all_gen[i][j-1] = cand_ovc_granted[j][i];
end else if((i/V)>j) begin: hh
assign ovc_allocated_all_gen[i][j] = cand_ovc_granted[j][i-V];
end
end else begin : slp
assign ovc_allocated_all_gen[i][j] = cand_ovc_granted[j][i];
end
end//j
assign ovc_allocated_all [i] = |ovc_allocated_all_gen[i];
end//i
endgenerate
endmodule
 
 
 
 
/**************************************************************
*
* comb_nonspec_v2
*
* first arbiter has been shifted after first multiplexer
*
*
*********************************************************/
 
module comb_nonspec_v2_allocator #(
parameter V = 4,
parameter P = 5,
parameter FIRST_ARBITER_EXT_P_EN = 1,
parameter SWA_ARBITER_TYPE = "WRRA",
parameter MIN_PCK_SIZE=2, //minimum packet size in flits. The minimum value is 1.
parameter SELF_LOOP_EN= "NO"
 
)(
//VC allocator
//input
dest_port_all, // from input port
ovc_is_assigned_all, //
masked_ovc_request_all,
pck_is_single_flit_all,
//output
ovc_allocated_all,//to the output port
granted_ovc_num_all, // to the input port
ivc_num_getting_ovc_grant,
//switch_alloc
ivc_request_all,
assigned_ovc_not_full_all,
vc_weight_is_consumed_all,
iport_weight_is_consumed_all,
//output
granted_dest_port_all,
ivc_num_getting_sw_grant,
nonspec_first_arbiter_granted_ivc_all,
any_ivc_sw_request_granted_all,
any_ovc_granted_in_outport_all,
granted_dst_is_from_a_single_flit_pck,
// global
clk,
reset
 
);
 
localparam
P_1 = (SELF_LOOP_EN == "NO") ? P-1 :P,
PV = V * P,
VV = V * V,
VP_1 = V * P_1,
PP_1 = P_1 * P,
PVV = PV * V,
PVP_1 = PV * P_1;
 
input [PVV-1 : 0] masked_ovc_request_all;
input [PVP_1-1 : 0] dest_port_all;
input [PV-1 : 0] ovc_is_assigned_all;
input [PV-1 : 0] pck_is_single_flit_all;
output [PV-1 : 0] ovc_allocated_all;
output [PVV-1 : 0] granted_ovc_num_all;
output [PV-1 : 0] ivc_num_getting_ovc_grant;
input [PV-1 : 0] ivc_request_all;
input [PV-1 : 0] assigned_ovc_not_full_all;
output [PP_1-1 : 0] granted_dest_port_all;
output [PV-1 : 0] ivc_num_getting_sw_grant;
output [P-1 : 0] any_ivc_sw_request_granted_all;
output [P-1 : 0] any_ovc_granted_in_outport_all;
output [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all;
input clk,reset;
input [PV-1 : 0] vc_weight_is_consumed_all;
input [P-1 : 0] iport_weight_is_consumed_all;
 
//internal wires switch allocator
wire [PV-1 : 0] first_arbiter_granted_ivc_all;
wire [PV-1 : 0] ivc_request_masked_all;
wire [P-1 : 0] any_cand_ovc_exsit;
output [P-1 : 0] granted_dst_is_from_a_single_flit_pck;
assign nonspec_first_arbiter_granted_ivc_all = first_arbiter_granted_ivc_all;
//nonspeculative switch allocator
nonspec_sw_alloc #(
.V(V),
.P(P),
.FIRST_ARBITER_EXT_P_EN(FIRST_ARBITER_EXT_P_EN),
.SWA_ARBITER_TYPE(SWA_ARBITER_TYPE),
.MIN_PCK_SIZE(MIN_PCK_SIZE)
)
nonspeculative_sw_allocator
(
 
.ivc_granted_all (ivc_num_getting_sw_grant),
.ivc_request_masked_all (ivc_request_masked_all),
.pck_is_single_flit_all(pck_is_single_flit_all),
.granted_dst_is_from_a_single_flit_pck(granted_dst_is_from_a_single_flit_pck),
.dest_port_all (dest_port_all),
.granted_dest_port_all (granted_dest_port_all),
.first_arbiter_granted_ivc_all (first_arbiter_granted_ivc_all),
//.first_arbiter_granted_port_all (first_arbiter_granted_port_all),
.any_ivc_granted_all (any_ivc_sw_request_granted_all),
.any_ovc_granted_all (any_ovc_granted_in_outport_all),
.vc_weight_is_consumed_all(vc_weight_is_consumed_all),
.iport_weight_is_consumed_all(iport_weight_is_consumed_all),
.clk (clk),
.reset (reset)
);
wire [V-1 : 0] masked_non_assigned_request [PV-1 : 0] ;
wire [PV-1 : 0] masked_assigned_request;
wire [PV-1 : 0] assigned_ovc_request_all;
wire [VV-1 : 0] masked_non_assigned_request_per_port [P-1 : 0] ;
wire [V-1 : 0] first_arbiter_granted_ivc_per_port[P-1 : 0] ;
wire [V-1 : 0] candidate_ovc_local_num [P-1 : 0] ;
wire [V-1 : 0] first_arbiter_ovc_granted [P-1:0];
wire [P_1-1 : 0] granted_dest_port_per_port [P-1 : 0];
wire [VP_1-1 : 0] cand_ovc_granted [P-1 : 0];
wire [P_1-1 : 0] ovc_allocated_all_gen [PV-1 : 0];
wire [V-1 : 0] granted_ovc_local_num_per_port [P-1 : 0];
wire [V-1 : 0] ivc_local_num_getting_ovc_grant[P-1 : 0];
wire [V : 0] summ_in [PV-1 : 0];
assign assigned_ovc_request_all = ivc_request_all & ovc_is_assigned_all;
genvar i,j;
generate
// IVC loop
for(i=0;i< PV;i=i+1) begin :total_vc_loop
// mask unavailable ovc from requests
assign masked_non_assigned_request [i] = masked_ovc_request_all [(i+1)*V-1 : i*V ];
assign masked_assigned_request [i] = assigned_ovc_not_full_all[i] & assigned_ovc_request_all[i];
// summing assigned and non-assigned VC requests
assign summ_in[i] ={masked_non_assigned_request [i],masked_assigned_request [i]};
assign ivc_request_masked_all[i] = | summ_in[i];
end//for
for(i=0;i< P;i=i+1) begin :port_loop3
for(j=0;j< V;j=j+1) begin :vc_loop
//merge masked_candidate_ovc in each port
assign masked_non_assigned_request_per_port[i][(j+1)*V-1 : j*V] = masked_non_assigned_request [i*V+j];
end//for j
assign first_arbiter_granted_ivc_per_port[i]=first_arbiter_granted_ivc_all[(i+1)*V-1 : i*V];
assign granted_dest_port_per_port[i]=granted_dest_port_all[(i+1)*P_1-1 : i*P_1];
onehot_mux_1D #(
.W (V),
.N (V)
)
multiplexer2
(
.in (masked_non_assigned_request_per_port [i]),
.out (candidate_ovc_local_num [i]),
.sel (first_arbiter_granted_ivc_per_port [i])
 
);
assign any_cand_ovc_exsit[i] = | candidate_ovc_local_num [i];
//first level arbiter to candidate only one OVC
arbiter #(
.ARBITER_WIDTH (V)
)
first_arbiter
(
.clk (clk),
.reset (reset),
.request (candidate_ovc_local_num[i]),
.grant (first_arbiter_ovc_granted[i]),
.any_grant ( )
);
//demultiplexer
one_hot_demux #(
.IN_WIDTH (V),
.SEL_WIDTH (P_1)
)
demux1
(
.demux_sel (granted_dest_port_per_port [i]),//selectore
.demux_in (first_arbiter_ovc_granted[i]),//repeated
.demux_out (cand_ovc_granted [i])
);
assign granted_ovc_local_num_per_port [i]=(any_ivc_sw_request_granted_all[i] )? first_arbiter_ovc_granted[i] : {V{1'b0}};
assign ivc_local_num_getting_ovc_grant [i]= (any_ivc_sw_request_granted_all[i] & any_cand_ovc_exsit[i])? first_arbiter_granted_ivc_per_port [i] : {V{1'b0}};
assign ivc_num_getting_ovc_grant [(i+1)*V-1 : i*V] = ivc_local_num_getting_ovc_grant[i];
for(j=0;j<V; j=j+1)begin: assign_loop3
assign granted_ovc_num_all[(i*VV)+((j+1)*V)-1 : (i*VV)+(j*V)]=granted_ovc_local_num_per_port[i];
end//j
end//i
for(i=0;i< PV;i=i+1) begin :total_vc_loop2
for(j=0;j<P; j=j+1)begin: assign_loop2
if((i/V)<j )begin: jj
assign ovc_allocated_all_gen[i][j-1] = cand_ovc_granted[j][i];
end else if((i/V)>j) begin: hh
assign ovc_allocated_all_gen[i][j] = cand_ovc_granted[j][i-V];
end
end//j
assign ovc_allocated_all [i] = |ovc_allocated_all_gen[i];
end//i
endgenerate
endmodule
 
 
/********************************************
*
* nonspeculative switch allocator
*
******************************************/
 
module nonspec_sw_alloc #(
parameter V = 4,
parameter P = 5,
parameter FIRST_ARBITER_EXT_P_EN = 1,
parameter SWA_ARBITER_TYPE = "WRRA",
parameter MIN_PCK_SIZE=2, //minimum packet size in flits. The minimum value is 1.
parameter SELF_LOOP_EN="NO"
 
)(
 
ivc_granted_all,
ivc_request_masked_all,
pck_is_single_flit_all,
granted_dst_is_from_a_single_flit_pck,
dest_port_all,
granted_dest_port_all,
first_arbiter_granted_ivc_all,
//first_arbiter_granted_port_all,
any_ivc_granted_all,
any_ovc_granted_all,
vc_weight_is_consumed_all,
iport_weight_is_consumed_all,
clk,
reset
);
 
localparam
P_1 = (SELF_LOOP_EN== "NO") ? P-1 : P,
PV = V * P,
VP_1 = V * P_1,
PP_1 = P_1 * P,
PVP_1 = PV * P_1,
PP = P*P;
 
output [PV-1 : 0] ivc_granted_all;
output [P-1 : 0] granted_dst_is_from_a_single_flit_pck;
input [PV-1 : 0] ivc_request_masked_all;
input [PV-1 : 0] pck_is_single_flit_all;
input [PVP_1-1 : 0] dest_port_all;
output [PP_1-1 : 0] granted_dest_port_all;
output [PV-1 : 0] first_arbiter_granted_ivc_all;
//output [PP_1-1 : 0] first_arbiter_granted_port_all;
output [P-1 : 0] any_ivc_granted_all; //any ivc is granted in input port [i]
output [P-1 : 0] any_ovc_granted_all; //any ovc is granted in output port [i]
input clk, reset;
input [PV-1 : 0] vc_weight_is_consumed_all;
input [P-1: 0] iport_weight_is_consumed_all;
//separte input per port
wire [V-1 : 0] ivc_granted [P-1 : 0];
wire [V-1 : 0] pck_is_single_flit [P-1 : 0];
wire [VP_1-1 : 0] dest_port_ivc [P-1 : 0];
wire [P_1-1 : 0] granted_dest_port [P-1 : 0];
wire [P_1-1 : 0] single_flit_granted_dst [P-1 : 0];
wire [PP-1 : 0] single_flit_granted_dst_all;
// internal wires
wire [V-1 : 0] ivc_masked [P-1 : 0];//output of mask and
wire [V-1 : 0] first_arbiter_grant [P-1 : 0];//output of first arbiter
wire [P-1 : 0] single_flit_pck_local_grant;
wire [P_1-1 : 0] dest_port [P-1 : 0];//output of multiplexer
wire [P_1-1 : 0] second_arbiter_request [P-1 : 0];
wire [P_1-1 : 0] second_arbiter_grant [P-1 : 0];
wire [P_1-1 : 0] second_arbiter_weight_consumed [P-1 : 0];
wire [V-1 : 0] vc_weight_is_consumed [P-1 : 0];
wire [P-1 :0] winner_weight_consumed;
genvar i,j;
generate
for(i=0;i< P;i=i+1) begin :port_loop
//assign in/out to the port based wires
//output
assign ivc_granted_all [(i+1)*V-1 : i*V] = ivc_granted [i];
assign granted_dest_port_all [(i+1)*P_1-1 : i*P_1] = granted_dest_port[i];
assign first_arbiter_granted_ivc_all[(i+1)*V-1 : i*V]= first_arbiter_grant[i];
//input
assign ivc_masked[i] = ivc_request_masked_all [(i+1)*V-1 : i*V];
assign dest_port_ivc[i] = dest_port_all [(i+1)*VP_1-1 : i*VP_1];
assign vc_weight_is_consumed[i] = vc_weight_is_consumed_all [(i+1)*V-1 : i*V];
//first level arbiter
swa_input_port_arbiter #(
.ARBITER_WIDTH(V),
.EXT_P_EN(FIRST_ARBITER_EXT_P_EN),
.ARBITER_TYPE(SWA_ARBITER_TYPE)
)
input_arbiter
(
.ext_pr_en_i(any_ivc_granted_all[i]),
.request(ivc_masked [i]),
.grant(first_arbiter_grant[i]),
.any_grant( ),
.clk(clk),
.reset(reset),
.vc_weight_is_consumed(vc_weight_is_consumed[i]),
.winner_weight_consumed(winner_weight_consumed[i])
);
//destination port multiplexer
onehot_mux_1D #(
.W (P_1),
.N (V)
)
multiplexer
(
.in (dest_port_ivc [i]),
.out (dest_port [i]),
.sel(first_arbiter_grant[i])
);
if(MIN_PCK_SIZE == 1) begin :single_flit_supported
//single_flit req multiplexer
assign pck_is_single_flit[i] = pck_is_single_flit_all [(i+1)*V-1 : i*V];
onehot_mux_1D #(
.W (1),
.N (V)
)
multiplexer2
(
.in (pck_is_single_flit [i]),
.out (single_flit_pck_local_grant[i]),
.sel (first_arbiter_grant[i])
);
assign single_flit_granted_dst[i] = (single_flit_pck_local_grant[i])? granted_dest_port[i] : {P_1{1'b0}};
if (SELF_LOOP_EN == "NO") begin :nslp
add_sw_loc_one_hot #(
.P(P),
.SW_LOC(i)
)
add_sw_loc
(
.destport_in(single_flit_granted_dst[i]),
.destport_out(single_flit_granted_dst_all[(i+1)*P-1 : i*P])
);
end else begin :slp
assign single_flit_granted_dst_all[(i+1)*P-1 : i*P] = single_flit_granted_dst[i];
end
end else begin : single_flit_notsupported
assign single_flit_pck_local_grant[i] = 1'bx;
assign single_flit_granted_dst[i] = {P_1{1'bx}};
assign single_flit_granted_dst_all[(i+1)*P-1 : i*P]={P{1'b0}};
end
//second arbiter input/output generate
 
 
for(j=0;j<P; j=j+1)begin: assign_loop
if (SELF_LOOP_EN == "NO") begin :nslp
if(i<j)begin: jj
assign second_arbiter_request[i][j-1] = dest_port[j][i];
//assign second_arbiter_weight_consumed[i][j-1] =winner_weight_consumed[j] ;
assign second_arbiter_weight_consumed[i][j-1] =iport_weight_is_consumed_all[j] ;
assign granted_dest_port[j][i] = second_arbiter_grant [i][j-1] ;
end else if(i>j)begin: hh
assign second_arbiter_request[i][j] = dest_port [j][i-1] ;
//assign second_arbiter_weight_consumed[i][j] =winner_weight_consumed[j];
assign second_arbiter_weight_consumed[i][j] =iport_weight_is_consumed_all[j];
assign granted_dest_port[j][i-1] = second_arbiter_grant [i][j] ;
end
//if(i==j) wires are left disconnected
end else begin :slp
assign second_arbiter_request[i][j] = dest_port[j][i];
assign second_arbiter_weight_consumed[i][j] =iport_weight_is_consumed_all[j] ;
assign granted_dest_port[j][i] = second_arbiter_grant [i][j] ;
end
end
//second level arbiter
swa_output_port_arbiter #(
.ARBITER_WIDTH(P_1),
.ARBITER_TYPE(SWA_ARBITER_TYPE) // RRA, WRRA
)
output_arbiter
(
.weight_consumed(second_arbiter_weight_consumed[i]), // only used for WRRA
.clk(clk),
.reset(reset),
.request(second_arbiter_request [i]),
.grant(second_arbiter_grant [i]),
.any_grant(any_ovc_granted_all [i])
);
//any ivc
assign any_ivc_granted_all[i] = | granted_dest_port[i];
assign ivc_granted[i] = (any_ivc_granted_all[i]) ? first_arbiter_grant[i] : {V{1'b0}};
 
end//for
endgenerate
 
custom_or #(
.IN_NUM(P),
.OUT_WIDTH(P)
)
or_dst
(
.or_in(single_flit_granted_dst_all),
.or_out(granted_dst_is_from_a_single_flit_pck)
);
 
endmodule
 
 
 
/*******************
* swa_input_port_arbiter
*
********************/
 
 
module swa_input_port_arbiter #(
parameter ARBITER_WIDTH =4,
parameter EXT_P_EN = 1,
parameter ARBITER_TYPE = "WRRA"// RRA, WRRA
)(
ext_pr_en_i, // it is used only if the EXT_P_EN is 1
clk,
reset,
request,
grant,
any_grant,
vc_weight_is_consumed, // only for WRRA
winner_weight_consumed // only for WRRA
);
 
 
 
 
input ext_pr_en_i;
input [ARBITER_WIDTH-1 : 0] request;
output[ARBITER_WIDTH-1 : 0] grant;
output any_grant;
input clk;
input reset;
input [ARBITER_WIDTH-1 : 0] vc_weight_is_consumed;
output winner_weight_consumed;
 
 
generate
/* verilator lint_off WIDTH */
if(ARBITER_TYPE != "RRA") begin : wrra_m
/* verilator lint_on WIDTH */
// one hot mux
onehot_mux_1D #(
.W(1),
.N(ARBITER_WIDTH)
)
mux
(
.in(vc_weight_is_consumed),
.out(winner_weight_consumed),
.sel(grant)
);
wire priority_en = (EXT_P_EN == 1) ? ext_pr_en_i & winner_weight_consumed : winner_weight_consumed;
 
//round robin arbiter with external priority
arbiter_priority_en #(
.ARBITER_WIDTH(ARBITER_WIDTH)
)
rra
(
.request(request),
.grant(grant),
.any_grant(any_grant),
.clk(clk),
.reset(reset),
.priority_en(priority_en)
);
end else begin : rra_m //RRA
assign winner_weight_consumed = 1'bx;
if(EXT_P_EN==1) begin : arbiter_ext_en
arbiter_priority_en #(
.ARBITER_WIDTH (ARBITER_WIDTH)
)
arb
(
.clk (clk),
.reset (reset),
.request (request),
.grant (grant),
.any_grant (any_grant ),
.priority_en (ext_pr_en_i)
);
end else begin: first_lvl_arbiter_internal_en
arbiter #(
.ARBITER_WIDTH (ARBITER_WIDTH)
)
arb
(
.clk (clk),
.reset (reset),
.request (request),
.grant (grant),
.any_grant (any_grant )
);
end//else
 
end
endgenerate
endmodule
 
 
 
 
/*******************
* swa_output_port_arbiter
*
********************/
 
 
module swa_output_port_arbiter #(
parameter ARBITER_WIDTH =4,
parameter ARBITER_TYPE = "WRRA" // RRA, WRRA
 
)(
weight_consumed, // only used for WRRA
clk,
reset,
request,
grant,
any_grant
);
 
 
input [ARBITER_WIDTH-1 : 0] request;
output [ARBITER_WIDTH-1 : 0] grant;
output any_grant;
input clk;
input reset;
input [ARBITER_WIDTH-1 : 0] weight_consumed;
 
 
 
generate
/* verilator lint_off WIDTH */
if(ARBITER_TYPE == "WRRA") begin : wrra_mine
/* verilator lint_on WIDTH */
// second level wrra priority is only changed if the granted request weight is consumed
wire pr_en;
onehot_mux_1D #(
.W(1),
.N(ARBITER_WIDTH)
)
multiplexer
(
.in(weight_consumed),
.out(pr_en),
.sel(grant)
);
arbiter_priority_en #(
.ARBITER_WIDTH (ARBITER_WIDTH)
)
arb
(
.clk (clk),
.reset (reset),
.request (request),
.grant (grant),
.any_grant (any_grant ),
.priority_en (pr_en)
);
/* verilator lint_off WIDTH */
end else if(ARBITER_TYPE == "WRRA_CLASSIC") begin : wrra_classic
/* verilator lint_on WIDTH */
// use classic WRRA. only for compasrion with propsoed wrra
wire [ARBITER_WIDTH-1 : 0] masked_req= request & ~weight_consumed;
wire sel = |masked_req;
wire [ARBITER_WIDTH-1 : 0] mux_req = (sel==1'b1)? masked_req : request;
arbiter #(
.ARBITER_WIDTH (ARBITER_WIDTH )
)
arb
(
.clk (clk),
.reset (reset),
.request (mux_req),
.grant (grant),
.any_grant (any_grant )
);
end else begin : rra_m
 
arbiter #(
.ARBITER_WIDTH (ARBITER_WIDTH )
)
arb
(
.clk (clk),
.reset (reset),
.request (request),
.grant (grant),
.any_grant (any_grant )
);
end
endgenerate
endmodule
 
src_noc/comb_nonspec.sv Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: src_noc/comb_spec2.v =================================================================== --- src_noc/comb_spec2.v (revision 50) +++ src_noc/comb_spec2.v (revision 54) @@ -236,7 +236,7 @@ //synthesis translate_off //synopsys translate_off if(DEBUG_EN)begin :dbg - check_single_bit_assertation #( + is_onehot0 #( .IN_WIDTH(P_1) )check_ovc_allocated
/src_noc/combined_vc_sw_alloc.sv
0,0 → 1,292
`include "pronoc_def.v"
/**********************************************************************
** File: combined_vc_sw_alloc.v
**
** Copyright (C) 2014-2017 Alireza Monemi
**
** This file is part of ProNoC
**
** ProNoC ( stands for Prototype Network-on-chip) is free software:
** you can redistribute it and/or modify it under the terms of the GNU
** Lesser General Public License as published by the Free Software Foundation,
** either version 2 of the License, or (at your option) any later version.
**
** ProNoC is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
** or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
** Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
**
**
** Description:
** combined VC/SW allocator. VC allocation is done in parallel with swich allocator
** for header flits which are successfully get sw grant
*************************************/
 
 
module combined_vc_sw_alloc
import pronoc_pkg::*;
#(
parameter P = 5 //port number
)
(
ivc_info,
dest_port_all,
masked_ovc_request_all,
ovc_allocated_all,
granted_ovc_num_all,
ivc_num_getting_ovc_grant,
ivc_num_getting_sw_grant,
spec_first_arbiter_granted_ivc_all,
nonspec_first_arbiter_granted_ivc_all,
granted_dest_port_all,
nonspec_granted_dest_port_all,
spec_granted_dest_port_all,
any_ivc_sw_request_granted_all,
any_ovc_granted_in_outport_all,
spec_ovc_num_all,
vc_weight_is_consumed_all,
iport_weight_is_consumed_all,
granted_dst_is_from_a_single_flit_pck,
clk,
reset
 
);
 
 
localparam
PV = V * P,
PVV = PV * V,
P_1 = (SELF_LOOP_EN == "NO")? P-1 : P,
PP_1 = P_1 * P,
PVP_1 = PV * P_1;
input ivc_info_t ivc_info [P-1 : 0][V-1 : 0];
input [PVP_1-1 : 0] dest_port_all;
input [PVV-1 : 0] masked_ovc_request_all;
output [PV-1 : 0] ovc_allocated_all;
output [PVV-1 : 0] granted_ovc_num_all;
output [PV-1 : 0] ivc_num_getting_ovc_grant;
output [PV-1 : 0] ivc_num_getting_sw_grant;
output [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all;
output [PV-1 : 0] spec_first_arbiter_granted_ivc_all;
output [P-1 : 0] any_ivc_sw_request_granted_all;
output [P-1 : 0] any_ovc_granted_in_outport_all;
output [PP_1-1 : 0] granted_dest_port_all;
output [PP_1-1 : 0] nonspec_granted_dest_port_all;
output [PP_1-1 : 0] spec_granted_dest_port_all;
output [PVV-1 : 0] spec_ovc_num_all;
// input [PVP_1-1 : 0] lk_destination_all;
input [PV-1 : 0] vc_weight_is_consumed_all;
input [P-1 : 0] iport_weight_is_consumed_all;
output [P-1 : 0] granted_dst_is_from_a_single_flit_pck;
input clk,reset;
 
wire [PV-1 : 0] ivc_request_all;
wire [PV-1 : 0] assigned_ovc_not_full_all;
wire [PV-1 : 0] ovc_is_assigned_all;
wire [PV-1 : 0] pck_is_single_flit_all;
genvar i;
generate
for (i=0; i<PV; i=i+1) begin : vc_loop
localparam C_PORT = i/V;
assign ivc_request_all[i] = ivc_info[C_PORT][i%V].ivc_req;
assign assigned_ovc_not_full_all[i] = ivc_info[C_PORT][i%V].assigned_ovc_not_full;
assign ovc_is_assigned_all[i] = ivc_info[C_PORT][i%V].ovc_is_assigned;
assign pck_is_single_flit_all[i] =ivc_info[C_PORT][i%V].single_flit_pck;
end//for
/* verilator lint_off WIDTH */
if(COMBINATION_TYPE == "BASELINE") begin : canonical_comb_gen
/* verilator lint_on WIDTH */
baseline_allocator #(
.V(V),
.P(P),
.TREE_ARBITER_EN(1),
.DEBUG_EN(DEBUG_EN),
.SWA_ARBITER_TYPE (SWA_ARBITER_TYPE),
.SELF_LOOP_EN(SELF_LOOP_EN)
)
the_base_line
(
.dest_port_all(dest_port_all),
.masked_ovc_request_all(masked_ovc_request_all),
.ovc_is_assigned_all(ovc_is_assigned_all),
.ivc_request_all(ivc_request_all),
.assigned_ovc_not_full_all(assigned_ovc_not_full_all),
.ovc_allocated_all(ovc_allocated_all),
.granted_ovc_num_all(granted_ovc_num_all),
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant),
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant),
.spec_first_arbiter_granted_ivc_all(spec_first_arbiter_granted_ivc_all),
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all),
.granted_dest_port_all(granted_dest_port_all),
.nonspec_granted_dest_port_all(nonspec_granted_dest_port_all),
.spec_granted_dest_port_all(spec_granted_dest_port_all),
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all),
.spec_ovc_num_all(spec_ovc_num_all),
.vc_weight_is_consumed_all(vc_weight_is_consumed_all),
.iport_weight_is_consumed_all(iport_weight_is_consumed_all),
.clk(clk),
.reset(reset)
);
/* verilator lint_off WIDTH */
end else if(COMBINATION_TYPE == "COMB_SPEC1") begin : spec1
/* verilator lint_on WIDTH */
comb_spec1_allocator #(
.V(V),
.P(P),
.DEBUG_EN(DEBUG_EN),
.SWA_ARBITER_TYPE (SWA_ARBITER_TYPE),
.MIN_PCK_SIZE(MIN_PCK_SIZE),
.SELF_LOOP_EN(SELF_LOOP_EN)
)
the_comb_spec1
(
.dest_port_all(dest_port_all),
.masked_ovc_request_all(masked_ovc_request_all),
.ovc_is_assigned_all(ovc_is_assigned_all),
.ivc_request_all(ivc_request_all),
.assigned_ovc_not_full_all(assigned_ovc_not_full_all),
.ovc_allocated_all(ovc_allocated_all),
.granted_ovc_num_all(granted_ovc_num_all),
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant),
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant),
.spec_first_arbiter_granted_ivc_all(spec_first_arbiter_granted_ivc_all),
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all),
.granted_dest_port_all(granted_dest_port_all),
.nonspec_granted_dest_port_all(nonspec_granted_dest_port_all),
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all),
.vc_weight_is_consumed_all(vc_weight_is_consumed_all),
.iport_weight_is_consumed_all(iport_weight_is_consumed_all),
.pck_is_single_flit_all(pck_is_single_flit_all),
.granted_dst_is_from_a_single_flit_pck(granted_dst_is_from_a_single_flit_pck),
.clk(clk),
.reset(reset)
);
assign spec_granted_dest_port_all = {PP_1{1'bx}};
assign spec_ovc_num_all = {PVV{1'bx}};
/* verilator lint_off WIDTH */
end else if (COMBINATION_TYPE == "COMB_SPEC2") begin :spec2
/* verilator lint_on WIDTH */
comb_spec2_allocator #(
.V(V),
.P(P),
.DEBUG_EN(DEBUG_EN),
.SWA_ARBITER_TYPE (SWA_ARBITER_TYPE),
.MIN_PCK_SIZE(MIN_PCK_SIZE),
.SELF_LOOP_EN(SELF_LOOP_EN)
)
the_comb_spec2
(
.dest_port_all(dest_port_all),
.masked_ovc_request_all(masked_ovc_request_all),
.ovc_is_assigned_all(ovc_is_assigned_all),
.ivc_request_all(ivc_request_all),
.assigned_ovc_not_full_all(assigned_ovc_not_full_all),
.ovc_allocated_all(ovc_allocated_all),
.granted_ovc_num_all(granted_ovc_num_all),
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant),
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant),
.spec_first_arbiter_granted_ivc_all(spec_first_arbiter_granted_ivc_all),
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all),
.granted_dest_port_all(granted_dest_port_all),
.nonspec_granted_dest_port_all(nonspec_granted_dest_port_all),
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all),
.vc_weight_is_consumed_all(vc_weight_is_consumed_all),
.iport_weight_is_consumed_all(iport_weight_is_consumed_all),
.pck_is_single_flit_all(pck_is_single_flit_all),
.granted_dst_is_from_a_single_flit_pck(granted_dst_is_from_a_single_flit_pck),
.clk(clk),
.reset(reset)
);
assign spec_granted_dest_port_all = {PP_1{1'bx}};
assign spec_ovc_num_all = {PVV{1'bx}};
 
end else begin : nonspec
if(V>7)begin :cmb_v2
comb_nonspec_v2_allocator #(
.V(V),
.P(P),
.FIRST_ARBITER_EXT_P_EN(FIRST_ARBITER_EXT_P_EN),
.SWA_ARBITER_TYPE (SWA_ARBITER_TYPE),
.MIN_PCK_SIZE(MIN_PCK_SIZE),
.SELF_LOOP_EN(SELF_LOOP_EN)
)
nonspec_comb
(
.dest_port_all(dest_port_all),
.masked_ovc_request_all(masked_ovc_request_all),
.ovc_is_assigned_all(ovc_is_assigned_all),
.ivc_request_all(ivc_request_all),
.assigned_ovc_not_full_all(assigned_ovc_not_full_all),
.ovc_allocated_all(ovc_allocated_all),
.granted_ovc_num_all(granted_ovc_num_all),
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant),
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant),
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all),
.granted_dest_port_all(granted_dest_port_all),
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all),
.any_ovc_granted_in_outport_all(any_ovc_granted_in_outport_all),
.vc_weight_is_consumed_all(vc_weight_is_consumed_all),
.iport_weight_is_consumed_all(iport_weight_is_consumed_all),
.pck_is_single_flit_all(pck_is_single_flit_all),
.granted_dst_is_from_a_single_flit_pck(granted_dst_is_from_a_single_flit_pck),
.clk(clk),
.reset(reset)
);
end else begin :cmb_v1
comb_nonspec_allocator #(
.P(P)
)
nonspec_comb
(
.ivc_info(ivc_info),
.dest_port_all(dest_port_all),
.masked_ovc_request_all(masked_ovc_request_all),
.ovc_allocated_all(ovc_allocated_all),
.granted_ovc_num_all(granted_ovc_num_all),
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant),
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant),
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all),
.granted_dest_port_all(granted_dest_port_all),
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all),
.any_ovc_granted_in_outport_all(any_ovc_granted_in_outport_all),
.vc_weight_is_consumed_all(vc_weight_is_consumed_all),
.iport_weight_is_consumed_all(iport_weight_is_consumed_all),
.pck_is_single_flit_all(pck_is_single_flit_all),
.granted_dst_is_from_a_single_flit_pck(granted_dst_is_from_a_single_flit_pck),
.clk(clk),
.reset(reset)
);
end
assign nonspec_granted_dest_port_all = granted_dest_port_all;
assign spec_granted_dest_port_all = {PP_1{1'bx}};
assign spec_ovc_num_all = {PVV{1'bx}};
assign spec_first_arbiter_granted_ivc_all = nonspec_first_arbiter_granted_ivc_all ;
end
endgenerate
endmodule
src_noc/combined_vc_sw_alloc.sv Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: src_noc/congestion_analyzer.v =================================================================== --- src_noc/congestion_analyzer.v (revision 50) +++ src_noc/congestion_analyzer.v (revision 54) @@ -202,7 +202,7 @@ reg [BVw-1 : 0] credit_per_port_next [P_1-1 : 0]; - reg [BVw-1 : 0] credit_per_port [P_1-1 : 0]; + wire [BVw-1 : 0] credit_per_port [P_1-1 : 0]; wire [P_1-1 : 0] credit_increased_per_port; wire [P_1-1 : 0] credit_decreased_per_port; wire [P_1-1 : 0] conjestion_cmp; @@ -228,21 +228,20 @@ end//always for(i=0; i
/src_noc/debug.v
32,7 → 32,8
 
wire [V-1 : 0] vc_num_hdr_wr, vc_num_tail_wr,vc_num_bdy_wr ;
reg [V-1 : 0] hdr_passed, hdr_passed_next;
wire [V-1 : 0] hdr_passed;
reg [V-1 : 0] hdr_passed_next;
wire [V-1 : 0] single_flit_pck;
assign vc_num_hdr_wr =(hdr_flg_in & flit_in_wr) ? vc_num_in : 0;
44,13 → 45,19
end
// synthesis translate_off
always @ (posedge clk or posedge reset) begin
if(reset) begin
hdr_passed <= 0;
end else begin
hdr_passed <= hdr_passed_next;
pronoc_register #(
.W(V)
) reg2 (
.in(hdr_passed_next),
.reset(reset),
.clk(clk),
.out(hdr_passed)
);
always @ (posedge clk ) begin
if(( hdr_passed & vc_num_hdr_wr)>0 )begin
$display("%t ERROR: a header flit is received in an active IVC %m",$time);
$finish;
73,9 → 80,8
$display("%t ERROR: A single flit packet is injected while the minimum packet size is set to %d. %m",$time,MIN_PCK_SIZE);
$finish;
end
//TODO check that the injected packet size meets the MIN_PCK_SIZE
end//else
//TODO check that the injected packet size meets the MIN_PCK_SIZE
end//always
// synthesis translate_on
endmodule
97,7 → 103,8
parameter TOPOLOGY="MESH",
parameter DSTPw=4,
parameter RAw=4,
parameter EAw=4
parameter EAw=4,
parameter DAw=EAw
)(
reset,
clk,
126,7 → 133,8
input hdr_flg_in , flit_in_wr;
input [V-1 : 0] vc_num_in, flit_is_tail, ivc_num_getting_sw_grant;
input [RAw-1 : 0] current_r_addr;
input [EAw-1 : 0] dest_e_addr_in,src_e_addr_in;
input [DAw-1 : 0] dest_e_addr_in;
input [EAw-1 : 0] src_e_addr_in;
input [DSTPw-1 : 0] destport_in;
localparam
217,29 → 225,40
if(ROUTE_TYPE == "FULL_ADAPTIVE")begin :full_adpt
/* verilator lint_on WIDTH */
reg [V-1 : 0] not_empty;
always@( posedge clk or posedge reset) begin
if(reset) begin
not_empty <=0;
end else begin
if(hdr_flg_in & flit_in_wr) begin
not_empty <= not_empty | vc_num_in;
if( ((AVC_ATOMIC_EN==1)&& (SW_LOC!= LOCAL)) || (SW_LOC== NORTH) || (SW_LOC== SOUTH) )begin
if((vc_num_in & ~ESCAP_VC_MASK)>0) begin // adaptive VCs
if( (not_empty & vc_num_in)>0) $display("%t :Error AVC allocated nonatomicly in %d port %m",$time,SW_LOC);
end
end//( AVC_ATOMIC_EN || SW_LOC== NORTH || SW_LOC== SOUTH )
if((vc_num_in & ESCAP_VC_MASK)>0 && (SW_LOC== SOUTH || SW_LOC== NORTH) ) begin // escape vc
// if (a & b) $display("%t :Error EVC allocation violate subfunction routing rules %m",$time);
if ((current_x - x_dst_in) !=0 && (current_y- y_dst_in) !=0) $display("%t :Error EVC allocation violate subfunction routing rules src_x=%d src_y=%d dst_x%d dst_y=%d %m",$time,x_src_in, y_src_in, x_dst_in,y_dst_in);
end
end//hdr_wr_in
if((flit_is_tail & ivc_num_getting_sw_grant)>0)begin
not_empty <= not_empty & ~ivc_num_getting_sw_grant;
end//tail wr out
end//reset
wire [V-1 : 0] not_empty;
reg [V-1 : 0] not_empty_next;
pronoc_register #(
.W(V)
) reg2 (
.in(not_empty_next),
.reset(reset),
.clk(clk),
.out(not_empty)
);
 
always@(*) begin
not_empty_next = not_empty;
if(hdr_flg_in & flit_in_wr) begin
not_empty_next = not_empty | vc_num_in;
end//hdr_wr_in
if((flit_is_tail & ivc_num_getting_sw_grant)>0)begin
not_empty_next = not_empty & ~ivc_num_getting_sw_grant;
end//tail wr out
end//always
always@( posedge clk ) begin
if(hdr_flg_in & flit_in_wr) begin
if( ((AVC_ATOMIC_EN==1)&& (SW_LOC!= LOCAL)) || (SW_LOC== NORTH) || (SW_LOC== SOUTH) )begin
if((vc_num_in & ~ESCAP_VC_MASK)>0) begin // adaptive VCs
if( (not_empty & vc_num_in)>0) $display("%t :Error AVC allocated nonatomicly in %d port %m",$time,SW_LOC);
end
end//( AVC_ATOMIC_EN || SW_LOC== NORTH || SW_LOC== SOUTH )
if((vc_num_in & ESCAP_VC_MASK)>0 && (SW_LOC== SOUTH || SW_LOC== NORTH) ) begin // escape vc
// if (a & b) $display("%t :Error EVC allocation violate subfunction routing rules %m",$time);
if ((current_x - x_dst_in) !=0 && (current_y- y_dst_in) !=0) $display("%t :Error EVC allocation violate subfunction routing rules src_x=%d src_y=%d dst_x%d dst_y=%d %m",$time,x_src_in, y_src_in, x_dst_in,y_dst_in);
end
end//hdr_wr_in
end//always
end //SW_LOC
 
355,7 → 374,10
parameter T3=2,
parameter T4=2,
parameter EAw=2,
parameter SELF_LOOP_EN="NO"
parameter DAw=2,
parameter SELF_LOOP_EN="NO",
parameter CAST_TYPE = "UNICAST",
parameter NE=8
)(
dest_is_valid,
dest_e_addr,
362,7 → 384,8
current_e_addr
);
input [EAw-1 : 0] dest_e_addr,current_e_addr;
input [DAw-1 : 0] dest_e_addr;
input [EAw-1 : 0] current_e_addr;
output dest_is_valid;
// general rules
371,6 → 394,21
/* verilator lint_on WIDTH */
wire valid;
generate
if(CAST_TYPE != "UNICAST") begin
wire [NE-1 : 0] dest_mcast_all_endp;
mcast_dest_list_decode decode (
.dest_e_addr(dest_e_addr),
.dest_o(dest_mcast_all_endp),
.row_has_any_dest( ),
.is_unicast()
);
//wire valid_dst_multi_r1 = (SELF_LOOP_EN == "NO") ? ~(dest_mcast_all_endp[current_e_addr] == 1'b1) : 1'b1;
wire valid_dst_multi_r2 = ~(dest_mcast_all_endp == {NE{1'b0}}); // there should be atleast one asserted destination
assign dest_is_valid = valid_dst_multi_r2;// & valid_dst_multi_r1 ;
end else
/* verilator lint_off WIDTH */
if(TOPOLOGY=="MESH" || TOPOLOGY == "TORUS" || TOPOLOGY=="RING" || TOPOLOGY == "LINE") begin : mesh
/* verilator lint_on WIDTH */
530,7 → 568,9
) addr_coder (
.id (id ),
.code (code ));
/* verilator lint_off WIDTH */
end else if (TOPOLOGY == "FMESH") begin :fmesh
/* verilator lint_on WIDTH */
fmesh_addr_coder #(
.NX(T1),
.NY(T2),
553,3 → 593,131
endmodule
 
module check_pck_size #(
parameter V=2,
parameter MIN_PCK_SIZE=2,
parameter Fw=36,
parameter DAw=4,
parameter CAST_TYPE="UNICAST",
parameter NE=4,
parameter B=4,
parameter LB=4
)(
hdr_flg_in,
flit_in_wr,
tail_flg_in,
vc_num_in,
dest_e_addr_in,
clk,
reset
 
);
 
input clk, reset;
input hdr_flg_in, tail_flg_in, flit_in_wr;
input [V-1 : 0] vc_num_in;
input [DAw-1: 0] dest_e_addr_in;
 
wire [NE-1 : 0] dest_mcast_all_endp [V-1 : 0];
wire [31 : 0] pck_size_counter [V-1: 0];
reg [31 : 0] pck_size_counter_next [V-1: 0];
wire [DAw-1 : 0] dest_e_addr [V-1:0];
wire [V-1 : 0] vc_hdr_wr_en;
wire [V-1 : 0] onehot;
 
localparam MIN_B = (B<LB)? B : LB;
genvar i;
generate
for (i=0;i<V;i=i+1) begin
always @(*) begin
pck_size_counter_next [i] = pck_size_counter [i];
if (vc_num_in == i)begin
if(flit_in_wr) begin
if(hdr_flg_in) pck_size_counter_next[i]= 1;
else pck_size_counter_next[i]=pck_size_counter[i]+1;
end
end
end
pronoc_register #(.W(32)) reg1(
.in (pck_size_counter_next[i]),
.reset (reset ),
.clk (clk ),
.out (pck_size_counter[i] ));
always @(posedge clk) begin
if (vc_num_in == i)begin
if(flit_in_wr & tail_flg_in) begin
if( pck_size_counter_next[i] < MIN_PCK_SIZE) begin
$display ( "%t\t ERROR: A packet is injected to the router with packet size (%d flits) that is smaller than MIN_PCK_SIZE (%d flits) parameter %m",$time,pck_size_counter_next[i],MIN_PCK_SIZE);
$finish;
end
end
end
end
/* verilator lint_off WIDTH */
if(CAST_TYPE!="UNICAST") begin
/* verilator lint_on WIDTH */
//Check that the size of multicast/broadcast packets <= buffer size
assign vc_hdr_wr_en [i] = flit_in_wr & hdr_flg_in & (vc_num_in == i);
pronoc_register_ld_en #(.W(DAw)) reg2(
.in (dest_e_addr_in),
.reset (reset ),
.clk (clk ),
.ld (vc_hdr_wr_en [i] ),
.out (dest_e_addr[i])
);
mcast_dest_list_decode decode (
.dest_e_addr(dest_e_addr[i]),
.dest_o(dest_mcast_all_endp[i]),
.row_has_any_dest(),
.is_unicast()
);
is_onehot0 #(
.IN_WIDTH(NE)
)
one_h
(
.in(dest_mcast_all_endp[i]),
.result(onehot[i])
);
always @(posedge clk) begin
if (vc_num_in == i)begin
if(flit_in_wr & ~onehot[i])begin
if(pck_size_counter_next[i]>MIN_B) begin
$display ( "%t\t ERROR: A multicast packet is injected to the router with packet size (%d flits) that is larger than the minimum router buffer size (%d flits) parameter %m",$time,pck_size_counter_next[i],MIN_B);
$finish;
end// size
end//flit_wr
end//vc_num
end//always
end//multicast
end //for
endgenerate
 
endmodule
 
/src_noc/fattree_noc_top.sv
1,7 → 1,4
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
 
`include "pronoc_def.v"
/**************************************
* Module: fattree
* Date:2019-01-01
24,20 → 21,21
module fattree_noc_top
import pronoc_pkg::*;
(
 
reset,
clk,
chan_in_all,
chan_out_all
chan_out_all,
router_event
);
input clk,reset;
//local ports
//Endpoints ports
input smartflit_chanel_t chan_in_all [NE-1 : 0];
output smartflit_chanel_t chan_out_all [NE-1 : 0];
//Events
output router_event_t router_event [NR-1 : 0][MAX_P-1 : 0];
//all routers port
smartflit_chanel_t router_chan_in [NR-1 :0][MAX_P-1 : 0];
smartflit_chanel_t router_chan_out [NR-1 :0][MAX_P-1 : 0];
82,20 → 80,20
 
generate
for( pos=0; pos<NRL; pos=pos+1) begin : root
localparam RID = pos;
router_top # (
.P(K)
)
the_router
(
.current_r_addr (current_r_addr [pos]),
.chan_in (router_chan_in [pos][K-1 : 0]),
.chan_out (router_chan_out[pos][K-1 : 0]),
.current_r_id (RID),
.current_r_addr (current_r_addr [RID]),
.chan_in (router_chan_in [RID][K-1 : 0]),
.chan_out (router_chan_out[RID][K-1 : 0]),
.router_event (router_event[RID][K-1 : 0]),
.clk (clk ),
.reset (reset )
);
);
end
 
//add leaves
102,15 → 100,18
 
for( level=1; level<L; level=level+1) begin :level_lp
for( pos=0; pos<NRL; pos=pos+1) begin : pos_lp
localparam RID = NRL*level+pos;
router_top # (
.P(2*K)
)
the_router
(
.current_r_addr (current_r_addr [NRL*level+pos]),
.chan_in (router_chan_in [NRL*level+pos]),
.chan_out (router_chan_out[NRL*level+pos]),
.current_r_id (RID),
.current_r_addr (current_r_addr [RID]),
.chan_in (router_chan_in [RID]),
.chan_out (router_chan_out[RID]),
.router_event (router_event[RID]),
.clk (clk ),
.reset (reset )
);
/src_noc/fattree_route.v
65,21 → 65,22
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 parrent_dest_addr [0]={Kw{1'b0}};
181,21 → 182,18
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
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
pronoc_register #(
.W(K),
.RESET_TO(1)
) reg1 (
.in({counter[0],counter[K-1:1]}),
.reset(reset),
.clk(clk),
.out(counter)
);
assign current_addr [0]={Kw{1'b0}};
assign parrent_dest_addr [0]={Kw{1'b0}};
298,20 → 296,17
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
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
pronoc_register #(
.W(K),
.RESET_TO(1)
) reg1 (
.in({counter[0],counter[K-1:1]}),
.reset(reset),
.clk(clk),
.out(counter)
);
assign current_addr [0]={Kw{1'b0}};
assign parrent_dest_addr [0]={Kw{1'b0}};
526,8 → 521,8
output [K: 0] lkdestport_encoded;
input reset,clk;
reg [K :0] destport_encoded_delayed;
reg [LKw-1 :0] dest_addr_encoded_delayed;
wire [K :0] destport_encoded_delayed;
wire [LKw-1 :0] dest_addr_encoded_delayed;
fattree_deterministic_look_ahead_routing #(
.P(P),
546,20 → 541,28
.lkdestport_encoded(lkdestport_encoded)
);
pronoc_register #(
.W(K+1)
) reg1 (
.in(destport_encoded),
.reset(reset),
.clk(clk),
.out(destport_encoded_delayed)
);
pronoc_register #(
.W(LKw)
) reg2 (
.in(dest_addr_encoded),
.reset(reset),
.clk(clk),
.out(dest_addr_encoded_delayed)
);
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset)begin
destport_encoded_delayed <= {(K+1){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
 
1115,3 → 1118,9
end
endgenerate
endmodule
 
/src_noc/flit_buffer.sv
0,0 → 1,1299
`include "pronoc_def.v"
/**********************************************************************
** File: flit_buffer.v
**
** Copyright (C) 2014-2017 Alireza Monemi
**
** This file is part of ProNoC
**
** ProNoC ( stands for Prototype Network-on-chip) is free software:
** you can redistribute it and/or modify it under the terms of the GNU
** Lesser General Public License as published by the Free Software Foundation,
** either version 2 of the License, or (at your option) any later version.
**
** ProNoC is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
** or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
** Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
**
**
** Description:
** Input buffer module. All VCs located in the same router
** input port share one single FPGA BRAM
**
**************************************************************/
 
 
module flit_buffer
import pronoc_pkg::*;
#(
parameter B =4,
parameter SSA_EN="YES" // "YES" , "NO"
)
(
din, // Data in
vc_num_wr,//write virtual channel
vc_num_rd,//read virtual channel
wr_en, // Write enable
rd_en, // Read the next word
dout, // Data out
vc_not_empty,
reset,
clk,
ssa_rd,
//for multicast
multiple_dest, // incr rd-sub
sub_rd_ptr_ld, // load rd_ptr to sub_rd_pt
flit_is_tail
);
 
localparam
Bw = (B==1)? 1 : log2(B),
BV = B * V,
BVw = log2(BV),
Vw = (V==1)? 1 : log2(V),
DEPTHw = log2(B+1),
BwV = Bw * V,
BVwV = BVw * V,
RESTw = Fw -2-V ,
PTRw = ((2**Bw)==B)? Bw : BVw, // if B is power of 2 PTRw is Bw else is BVw
ARRAYw = PTRw * V,
/* verilator lint_off WIDTH */
RAM_DATA_WIDTH = (PCK_TYPE == "MULTI_FLIT")? Fw - V : Fw - V -2;
/* verilator lint_on WIDTH */
input [Fw-1 :0] din; // Data in
input [V-1 :0] vc_num_wr;//write virtual chanel
input [V-1 :0] vc_num_rd;//read virtual chanel
input wr_en; // Write enable
input rd_en; // Read the next word
output [Fw-1 :0] dout; // Data out
output [V-1 :0] vc_not_empty;
input reset;
input clk;
input [V-1 :0] ssa_rd;
input [V-1 :0] multiple_dest;
input [V-1 :0] sub_rd_ptr_ld;
output [V-1 : 0] flit_is_tail;
//pointers
wire [PTRw- 1 : 0] rd_ptr [V-1 :0];
wire [PTRw- 1 : 0] wr_ptr [V-1 :0];
reg [PTRw- 1 : 0] rd_ptr_next [V-1 :0];
reg [PTRw- 1 : 0] wr_ptr_next [V-1 :0];
reg [PTRw- 1 : 0] sub_rd_ptr_next [V-1 :0];
wire [PTRw- 1 : 0] sub_rd_ptr [V-1 :0];
wire [PTRw-1 : 0] ptr_tmp [V-1 : 0];
wire [ARRAYw-1 : 0] rd_ptr_array;
wire [ARRAYw-1 : 0] wr_ptr_array;
wire [RAM_DATA_WIDTH-1 : 0] fifo_ram_din;
wire [RAM_DATA_WIDTH-1 : 0] fifo_ram_dout;
wire [V-1 : 0] wr;
wire [V-1 : 0] rd;
wire [DEPTHw-1 : 0] depth [V-1 :0];
reg [DEPTHw-1 : 0] depth_next [V-1 :0];
wire [DEPTHw-1 : 0] sub_depth [V-1 :0];
reg [DEPTHw-1 : 0] sub_depth_next [V-1 :0];
reg [B-1 : 0] tail_fifo [V-1 : 0];
wire [1 : 0] flgs_in, flgs_out;
wire [V-1: 0] vc_in;
wire [RESTw-1 :0 ] flit_rest_in,flit_rest_out;
wire [V-1 : 0] sub_rd;
wire [V-1 : 0] sub_restore;
assign wr = (wr_en)? vc_num_wr : {V{1'b0}};
 
genvar i;
 
generate
/* verilator lint_off WIDTH */
if (CAST_TYPE != "UNICAST") begin
/* verilator lint_on WIDTH */
assign sub_rd = (rd_en)? vc_num_rd : ssa_rd;
assign sub_restore = sub_rd_ptr_ld;
assign rd = (rd_en)? vc_num_rd & ~multiple_dest : ssa_rd & ~multiple_dest;
end else begin : unicast
assign rd = (rd_en)? vc_num_rd : ssa_rd;
end
/* verilator lint_off WIDTH */
if (PCK_TYPE == "MULTI_FLIT") begin :multi
/* verilator lint_on WIDTH */
assign {flgs_in,vc_in,flit_rest_in}=din;
assign fifo_ram_din = {flgs_in,flit_rest_in};
assign {flgs_out,flit_rest_out} = fifo_ram_dout;
assign dout = {flgs_out,{V{1'bX}},flit_rest_out};
end else begin : single
assign fifo_ram_din = din[RAM_DATA_WIDTH-1 : 0];
assign dout = {2'b11,{V{1'bX}},fifo_ram_dout};
end
for(i=0;i<V;i=i+1) begin :V_
assign wr_ptr_array[(i+1)*PTRw- 1 : i*PTRw] = wr_ptr[i];
/* verilator lint_off WIDTH */
if (CAST_TYPE != "UNICAST") begin
/* verilator lint_on WIDTH */
assign rd_ptr_array[(i+1)*PTRw- 1 : i*PTRw] = sub_rd_ptr[i];
localparam RESET_TO = ((2**Bw)==B)? 0 : B*i;
pronoc_register #(.W(PTRw),.RESET_TO(RESET_TO)) reg4 (.in(sub_rd_ptr_next[i]), .out(sub_rd_ptr[i]), .reset(reset), .clk(clk));
pronoc_register #(.W(DEPTHw)) sub_depth_reg (.in(sub_depth_next[i] ), .out(sub_depth [i]), .reset(reset), .clk(clk));
always @ (*)begin
sub_depth_next [i] = sub_depth [i];
if(sub_restore[i]) sub_depth_next [i]= depth_next[i];
else if (wr[i] & ~sub_rd[i]) sub_depth_next [i] = sub_depth[i] + 1'h1;
else if (~wr[i] & sub_rd[i]) sub_depth_next [i] = sub_depth[i] - 1'h1;
end//always
assign vc_not_empty [i] = (sub_depth[i] > 0);
end else begin : unicast
assign rd_ptr_array[(i+1)*PTRw- 1 : i*PTRw] = rd_ptr[i];
assign vc_not_empty [i] = (depth[i] > 0);
end
end//for
 
if((2**Bw)==B)begin :pow2
/*****************
Buffer width is power of 2
******************/
wire [Bw-1 : 0] vc_wr_addr;
wire [Bw-1 : 0] vc_rd_addr;
wire [Vw-1 : 0] wr_select_addr;
wire [Vw-1 : 0] rd_select_addr;
wire [Bw+Vw-1 : 0] wr_addr;
wire [Bw+Vw-1 : 0] rd_addr;
assign wr_addr = {wr_select_addr,vc_wr_addr};
assign rd_addr = {rd_select_addr,vc_rd_addr};
onehot_mux_1D #(
.W(Bw),
.N(V)
)
wr_ptr_mux
(
.in(wr_ptr_array),
.out(vc_wr_addr),
.sel(vc_num_wr)
);
onehot_mux_1D #(
.W(Bw),
.N(V)
)
rd_ptr_mux
(
.in(rd_ptr_array),
.out(vc_rd_addr),
.sel(vc_num_rd)
);
one_hot_to_bin #(
.ONE_HOT_WIDTH(V)
)
wr_vc_start_addr
(
.one_hot_code(vc_num_wr),
.bin_code(wr_select_addr)
);
one_hot_to_bin #(
.ONE_HOT_WIDTH(V)
)
rd_vc_start_addr
(
.one_hot_code(vc_num_rd),
.bin_code(rd_select_addr)
);
fifo_ram #(
.DATA_WIDTH (RAM_DATA_WIDTH),
.ADDR_WIDTH (BVw ),
.SSA_EN(SSA_EN)
)
the_queue
(
.wr_data(fifo_ram_din),
.wr_addr(wr_addr[BVw-1 : 0]),
.rd_addr(rd_addr[BVw-1 : 0]),
.wr_en(wr_en),
.rd_en(rd_en),
.clk(clk),
.rd_data(fifo_ram_dout)
);
 
for(i=0;i<V;i=i+1) begin :loop0
always @(posedge clk) begin
if(wr[i]) tail_fifo[i][wr_ptr[i]] <= din[Fw-2];
end
pronoc_register #(.W(Bw )) reg1 (.in(rd_ptr_next[i]), .out(rd_ptr[i]), .reset(reset), .clk(clk));
pronoc_register #(.W(Bw )) reg2 (.in(wr_ptr_next[i]), .out(wr_ptr[i]), .reset(reset), .clk(clk));
pronoc_register #(.W(DEPTHw)) reg3 (.in(depth_next[i] ), .out(depth [i]), .reset(reset), .clk(clk));
 
always @ (*)begin
rd_ptr_next [i] = rd_ptr [i];
wr_ptr_next [i] = wr_ptr [i];
depth_next [i] = depth [i];
if (wr[i] ) wr_ptr_next [i] = wr_ptr [i]+ 1'h1;
if (rd[i] ) rd_ptr_next [i] = rd_ptr [i]+ 1'h1;
if (wr[i] & ~rd[i]) depth_next [i] = depth[i] + 1'h1;
else if (~wr[i] & rd[i]) depth_next [i] = depth[i] - 1'h1;
end//always
 
/* verilator lint_off WIDTH */
if (CAST_TYPE != "UNICAST") begin :multicast
/* verilator lint_on WIDTH */
always @ (*)begin
sub_rd_ptr_next[i] = sub_rd_ptr[i];
if (sub_restore[i]) sub_rd_ptr_next[i] = rd_ptr_next [i];
else if(sub_rd[i]) sub_rd_ptr_next[i] = sub_rd_ptr[i]+ 1'h1;
end
/* verilator lint_off WIDTH */
assign flit_is_tail[i] = (PCK_TYPE == "MULTI_FLIT")? tail_fifo[i][sub_rd_ptr[i]] : 1'b1;
/* verilator lint_on WIDTH */
end else begin : unicast
/* verilator lint_off WIDTH */
assign flit_is_tail[i] = (PCK_TYPE == "MULTI_FLIT")? tail_fifo[i][rd_ptr[i]] : 1'b1;
/* verilator lint_on WIDTH */
end
end//for
end else begin :no_pow2
/*****************
Buffer width is not power of 2
******************/
// memory address
wire [BVw- 1 : 0] wr_addr;
wire [BVw- 1 : 0] rd_addr;
for(i=0;i<V;i=i+1) begin :V_
pronoc_register #(.W(BVw),.RESET_TO(B*i)) reg1 (.in(rd_ptr_next[i]), .out(rd_ptr[i]), .reset(reset), .clk(clk));
pronoc_register #(.W(BVw),.RESET_TO(B*i)) reg2 (.in(wr_ptr_next[i]), .out(wr_ptr[i]), .reset(reset), .clk(clk));
pronoc_register #(.W(DEPTHw) ) reg3 (.in(depth_next[i] ), .out(depth [i]), .reset(reset), .clk(clk));
always @(posedge clk) begin
/* verilator lint_off WIDTH */
if(wr[i]) tail_fifo[i][wr_ptr[i]-(B*i)] <= din[Fw-2];
/* verilator lint_on WIDTH */
end
always @ (*) begin
rd_ptr_next [i] = rd_ptr [i];
wr_ptr_next [i] = wr_ptr [i];
depth_next [i] = depth [i];
/* verilator lint_off WIDTH */
if (wr[i] ) wr_ptr_next[i] =(wr_ptr[i]==(B*(i+1))-1)? (B*i) : wr_ptr [i]+ 1'h1;
if (rd[i] ) rd_ptr_next[i] =(rd_ptr[i]==(B*(i+1))-1)? (B*i) : rd_ptr [i]+ 1'h1;
/* verilator lint_on WIDTH */
if (wr[i] & ~rd[i]) depth_next [i] = depth[i] + 1'h1;
else if (~wr[i] & rd[i]) depth_next [i] = depth[i] - 1'h1;
end//always
/* verilator lint_off WIDTH */
if (CAST_TYPE != "UNICAST") begin :multicast
/* verilator lint_on WIDTH */
always @ (*)begin
sub_rd_ptr_next[i] = sub_rd_ptr[i];
if (sub_restore[i]) sub_rd_ptr_next[i] = rd_ptr_next [i];
/* verilator lint_off WIDTH */
else if(sub_rd[i]) sub_rd_ptr_next[i] = (sub_rd_ptr[i]==(B*(i+1))-1)? (B*i) : sub_rd_ptr [i]+ 1'h1;
/* verilator lint_on WIDTH */
end
/* verilator lint_off WIDTH */
assign ptr_tmp [i] = sub_rd_ptr[i]-(B*i);
assign flit_is_tail[i] = (PCK_TYPE == "MULTI_FLIT")? tail_fifo[i][ptr_tmp [i]] :1'b1;
/* verilator lint_on WIDTH */
end else begin : unicast
/* verilator lint_off WIDTH */
assign flit_is_tail[i] = (PCK_TYPE == "MULTI_FLIT")? tail_fifo[i][rd_ptr[i]-(B*i)] : 1'b1;
/* verilator lint_on WIDTH */
end
end//FOR
onehot_mux_1D #(
.W(BVw),
.N(V)
)
wr_mux
(
.in(wr_ptr_array),
.out(wr_addr),
.sel(vc_num_wr)
);
onehot_mux_1D #(
.W(BVw),
.N(V)
)
rd_mux
(
.in(rd_ptr_array),
.out(rd_addr),
.sel(vc_num_rd)
);
fifo_ram_mem_size #(
.DATA_WIDTH (RAM_DATA_WIDTH),
.MEM_SIZE (BV ),
.SSA_EN(SSA_EN)
)
the_queue
(
.wr_data (fifo_ram_din),
.wr_addr (wr_addr),
.rd_addr (rd_addr),
.wr_en (wr_en),
.rd_en (rd_en),
.clk (clk),
.rd_data (fifo_ram_dout)
);
end
endgenerate
 
//synthesis translate_off
//synopsys translate_off
generate
if(DEBUG_EN) begin :dbg
always @(posedge clk) begin
if(wr_en && vc_num_wr == {V{1'b0}})begin
$display("%t: ERROR: Attempt to write when no wr VC is asserted: %m",$time);
$finish;
end
if(rd_en && vc_num_rd == {V{1'b0}})begin
$display("%t: ERROR: Attempt to read when no rd VC is asserted: %m",$time);
$finish;
end
end
end //DEBUG_EN
for(i=0;i<V;i=i+1) begin :loop0
/* verilator lint_off WIDTH */
if (CAST_TYPE != "UNICAST") begin :multicast
/* verilator lint_on WIDTH */
always @(posedge clk) begin
if (wr[i] && (sub_depth[i] == B [DEPTHw-1 : 0]) && !sub_rd[i]) begin
$display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,B);
$finish;
end
/* verilator lint_off WIDTH */
if (sub_rd[i] && (sub_depth[i] == {DEPTHw{1'b0}} && SSA_EN !="YES" ))begin
/* verilator lint_on WIDTH */
$display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
$finish;
end
/* verilator lint_off WIDTH */
if (sub_rd[i] && !wr[i] && (sub_depth[i] == {DEPTHw{1'b0}} && SSA_EN =="YES" ))begin
/* verilator lint_on WIDTH */
$display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
$finish;
end
end//always
end //multicast
always @(posedge clk) begin
if (wr[i] && (depth[i] == B [DEPTHw-1 : 0]) && !rd[i])begin
$display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,B);
$finish;
end
/* verilator lint_off WIDTH */
if (rd[i] && (depth[i] == {DEPTHw{1'b0}} && SSA_EN !="YES" ))begin
/* verilator lint_on WIDTH */
$display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
$finish;
end
/* verilator lint_off WIDTH */
if (rd[i] && !wr[i] && (depth[i] == {DEPTHw{1'b0}} && SSA_EN =="YES" ))begin
/* verilator lint_on WIDTH */
$display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
$finish;
end
//if (wr_en) $display($time, " %h is written on fifo ",din);
end//always
end//for
endgenerate
//synopsys translate_on
//synthesis translate_on
 
 
 
 
 
 
 
 
 
 
 
 
 
 
endmodule
 
 
 
/****************************
 
fifo_ram
 
*****************************/
 
 
 
module fifo_ram #(
parameter DATA_WIDTH = 32,
parameter ADDR_WIDTH = 8,
parameter SSA_EN="YES" // "YES" , "NO"
)
(
wr_data,
wr_addr,
rd_addr,
wr_en,
rd_en,
clk,
rd_data
);
input [DATA_WIDTH-1 : 0] wr_data;
input [ADDR_WIDTH-1 : 0] wr_addr;
input [ADDR_WIDTH-1 : 0] rd_addr;
input wr_en;
input rd_en;
input clk;
output [DATA_WIDTH-1 : 0] rd_data;
 
reg [DATA_WIDTH-1:0] memory_rd_data;
// memory
reg [DATA_WIDTH-1:0] queue [2**ADDR_WIDTH-1:0] /* synthesis ramstyle = "no_rw_check , M9K" */;
always @(posedge clk ) begin
if (wr_en)
queue[wr_addr] <= wr_data;
if (rd_en)
memory_rd_data <= queue[rd_addr];
end
 
generate
/* verilator lint_off WIDTH */
if(SSA_EN =="YES") begin :predict
/* verilator lint_on WIDTH */
//add bypass
reg [DATA_WIDTH-1:0] bypass_reg;
reg rd_en_delayed;
always @(posedge clk ) begin
bypass_reg <=wr_data;
rd_en_delayed <=rd_en;
end
assign rd_data = (rd_en_delayed)? memory_rd_data : bypass_reg;
end else begin : no_predict
assign rd_data = memory_rd_data;
end
endgenerate
endmodule
 
 
 
/*********************
*
* fifo_ram_mem_size
*
**********************/
 
 
module fifo_ram_mem_size #(
parameter DATA_WIDTH = 32,
parameter MEM_SIZE = 200,
parameter SSA_EN = "YES" // "YES" , "NO"
)
(
wr_data,
wr_addr,
rd_addr,
wr_en,
rd_en,
clk,
rd_data
);
function integer log2;
input integer number; begin
log2=(number <=1) ? 1: 0;
while(2**log2<number) begin
log2=log2+1;
end
end
endfunction // log2
 
localparam ADDR_WIDTH=log2(MEM_SIZE);
input [DATA_WIDTH-1 : 0] wr_data;
input [ADDR_WIDTH-1 : 0] wr_addr;
input [ADDR_WIDTH-1 : 0] rd_addr;
input wr_en;
input rd_en;
input clk;
output [DATA_WIDTH-1 : 0] rd_data;
reg [DATA_WIDTH-1:0] memory_rd_data;
// memory
reg [DATA_WIDTH-1:0] queue [MEM_SIZE-1:0] /* synthesis ramstyle = "no_rw_check , M9K" */;
always @(posedge clk ) begin
if (wr_en)
queue[wr_addr] <= wr_data;
if (rd_en)
memory_rd_data <= queue[rd_addr];
end
generate
/* verilator lint_off WIDTH */
if(SSA_EN =="YES") begin :predict
/* verilator lint_on WIDTH */
//add bypass
reg [DATA_WIDTH-1:0] bypass_reg;
reg rd_en_delayed;
always @(posedge clk ) begin
bypass_reg <=wr_data;
rd_en_delayed <=rd_en;
end
assign rd_data = (rd_en_delayed)? memory_rd_data : bypass_reg;
end else begin : no_predict
assign rd_data = memory_rd_data;
end
endgenerate
endmodule
 
 
 
/**********************************
 
An small First Word Fall Through FIFO. The code will use LUTs
and optimized for low LUTs utilization.
 
**********************************/
 
 
module fwft_fifo #(
parameter DATA_WIDTH = 2,
parameter MAX_DEPTH = 2,
parameter IGNORE_SAME_LOC_RD_WR_WARNING="YES" // "YES" , "NO"
)
(
input [DATA_WIDTH-1:0] din, // Data in
input wr_en, // Write enable
input rd_en, // Read the next word
output [DATA_WIDTH-1:0] dout, // Data out
output full,
output nearly_full,
output recieve_more_than_0,
output recieve_more_than_1,
input reset,
input clk
);
function integer log2;
input integer number; begin
log2=(number <=1) ? 1: 0;
while(2**log2<number) begin
log2=log2+1;
end
end
endfunction // log2
 
localparam DEPTH_DATA_WIDTH = log2(MAX_DEPTH +1);
localparam MUX_SEL_WIDTH = log2(MAX_DEPTH-1);
wire out_ld ;
wire [DATA_WIDTH-1 : 0] dout_next;
wire[DEPTH_DATA_WIDTH-1 : 0] depth;
reg [DEPTH_DATA_WIDTH-1 : 0] depth_next;
reg [DATA_WIDTH-1:0] dout_next_ld;
genvar i;
generate
if(MAX_DEPTH>2) begin :mwb2
wire [MUX_SEL_WIDTH-1 : 0] mux_sel;
wire [DEPTH_DATA_WIDTH-1 : 0] depth_2;
wire empty;
wire out_sel ;
if(DATA_WIDTH>1) begin :wb1
wire [MAX_DEPTH-2 : 0] mux_in [DATA_WIDTH-1 :0];
wire [DATA_WIDTH-1 : 0] mux_out;
reg [MAX_DEPTH-2 : 0] shiftreg [DATA_WIDTH-1 :0];
for(i=0;i<DATA_WIDTH; i=i+1) begin : lp
always @(posedge clk ) begin
//if (reset) begin
// shiftreg[i] <= {MAX_DEPTH{1'b0}};
//end else begin
if(wr_en) shiftreg[i] <= {shiftreg[i][MAX_DEPTH-3 : 0] ,din[i]};
//end
end
assign mux_in[i] = shiftreg[i];
assign mux_out[i] = mux_in[i][mux_sel];
assign dout_next[i] = (out_sel) ? mux_out[i] : din[i];
end //for
end else begin :w1
wire [MAX_DEPTH-2 : 0] mux_in;
wire mux_out;
reg [MAX_DEPTH-2 : 0] shiftreg;
always @(posedge clk ) begin
if(wr_en) shiftreg <= {shiftreg[MAX_DEPTH-3 : 0] ,din};
end
assign mux_in = shiftreg;
assign mux_out = mux_in[mux_sel];
assign dout_next = (out_sel) ? mux_out : din;
end
assign full = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1 : 0];
assign nearly_full = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1 : 0] -1'b1;
assign empty = depth == {DEPTH_DATA_WIDTH{1'b0}};
assign recieve_more_than_0 = ~ empty;
assign recieve_more_than_1 = ~( depth == {DEPTH_DATA_WIDTH{1'b0}} || depth== 1 );
assign out_sel = (recieve_more_than_1) ? 1'b1 : 1'b0;
assign out_ld = (depth !=0 )? rd_en : wr_en;
assign depth_2 = depth - 2;
assign mux_sel = depth_2[MUX_SEL_WIDTH-1 : 0] ;
end else if ( MAX_DEPTH == 2) begin :mw2
reg [DATA_WIDTH-1 : 0] register;
always @(posedge clk ) begin
if(wr_en) register <= din;
end //always
assign full = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1 : 0];
assign nearly_full = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1 : 0] -1'b1;
assign out_ld = (depth !=0 )? rd_en : wr_en;
assign recieve_more_than_0 = (depth != {DEPTH_DATA_WIDTH{1'b0}});
assign recieve_more_than_1 = ~( depth == 0 || depth== 1 );
assign dout_next = (recieve_more_than_1) ? register : din;
end else begin :mw1 // MAX_DEPTH == 1
assign out_ld = wr_en;
assign dout_next = din;
assign full = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1 : 0];
assign nearly_full= 1'b1;
assign recieve_more_than_0 = full;
assign recieve_more_than_1 = 1'b0;
end
 
 
endgenerate
pronoc_register #(.W(DEPTH_DATA_WIDTH)) reg1 (.in(depth_next), .out(depth), .reset(reset), .clk(clk));
pronoc_register #(.W(DATA_WIDTH)) reg2 (.in(dout_next_ld), .out(dout ), .reset(reset), .clk(clk));
always @ (*)begin
depth_next = depth;
dout_next_ld = dout;
if (wr_en & ~rd_en) depth_next = depth + 1'h1;
else if (~wr_en & rd_en) depth_next = depth - 1'h1;
if (out_ld) dout_next_ld = dout_next;
end//always
//synthesis translate_off
//synopsys translate_off
always @(posedge clk)
begin
if (wr_en & ~rd_en & full) begin
$display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,MAX_DEPTH);
$finish;
end
/* verilator lint_off WIDTH */
if (rd_en & !recieve_more_than_0 & IGNORE_SAME_LOC_RD_WR_WARNING == "NO") begin
$display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
$finish;
end
if (rd_en & ~wr_en & !recieve_more_than_0 & (IGNORE_SAME_LOC_RD_WR_WARNING == "YES")) begin
$display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
$finish;
end
/* verilator lint_on WIDTH */
end // always @ (posedge clk)
//synopsys translate_on
//synthesis translate_on
 
 
 
 
endmodule
 
 
 
 
 
 
 
 
 
 
/*********************
 
fwft_fifo_with_output_clear
each individual output bit has
its own clear signal
 
**********************/
 
 
 
 
 
module fwft_fifo_with_output_clear #(
parameter DATA_WIDTH = 2,
parameter MAX_DEPTH = 2,
parameter IGNORE_SAME_LOC_RD_WR_WARNING="NO" // "YES" , "NO"
)
(
din, // Data in
wr_en, // Write enable
rd_en, // Read the next word
dout, // Data out
full,
nearly_full,
recieve_more_than_0,
recieve_more_than_1,
reset,
clk,
clear
);
input [DATA_WIDTH-1:0] din;
input wr_en;
input rd_en;
output [DATA_WIDTH-1:0] dout;
output full;
output nearly_full;
output recieve_more_than_0;
output recieve_more_than_1;
input reset;
input clk;
input [DATA_WIDTH-1:0] clear;
function integer log2;
input integer number; begin
log2=(number <=1) ? 1: 0;
while(2**log2<number) begin
log2=log2+1;
end
end
endfunction // log2
localparam DEPTH_DATA_WIDTH = log2(MAX_DEPTH +1);
localparam MUX_SEL_WIDTH = log2(MAX_DEPTH-1);
wire out_ld;
wire [DATA_WIDTH-1 : 0] dout_next;
wire [DEPTH_DATA_WIDTH-1 : 0] depth;
reg [DEPTH_DATA_WIDTH-1 : 0] depth_next;
reg [DATA_WIDTH-1:0] dout_next_ld;
genvar i;
generate
if(MAX_DEPTH>2) begin :mwb2
wire [MUX_SEL_WIDTH-1 : 0] mux_sel;
wire [DEPTH_DATA_WIDTH-1 : 0] depth_2;
wire empty;
wire out_sel ;
if(DATA_WIDTH>1) begin :wb1
wire [MAX_DEPTH-2 : 0] mux_in [DATA_WIDTH-1 :0];
wire [DATA_WIDTH-1 : 0] mux_out;
reg [MAX_DEPTH-2 : 0] shiftreg [DATA_WIDTH-1 :0];
for(i=0;i<DATA_WIDTH; i=i+1) begin : lp
always @(posedge clk ) begin
//if (reset) begin
// shiftreg[i] <= {MAX_DEPTH{1'b0}};
//end else begin
if(wr_en) shiftreg[i] <= {shiftreg[i][MAX_DEPTH-3 : 0] ,din[i]};
//end
end
assign mux_in[i] = shiftreg[i];
assign mux_out[i] = mux_in[i][mux_sel];
assign dout_next[i] = (out_sel) ? mux_out[i] : din[i];
end //for
end else begin :w1
wire [MAX_DEPTH-2 : 0] mux_in;
wire mux_out;
reg [MAX_DEPTH-2 : 0] shiftreg;
always @(posedge clk ) begin
if(wr_en) shiftreg <= {shiftreg[MAX_DEPTH-3 : 0] ,din};
end
assign mux_in = shiftreg;
assign mux_out = mux_in[mux_sel];
assign dout_next = (out_sel) ? mux_out : din;
end
assign full = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1 : 0];
assign nearly_full = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1 : 0] -1'b1;
assign empty = depth == {DEPTH_DATA_WIDTH{1'b0}};
assign recieve_more_than_0 = ~ empty;
assign recieve_more_than_1 = ~( depth == {DEPTH_DATA_WIDTH{1'b0}} || depth== 1 );
assign out_sel = (recieve_more_than_1) ? 1'b1 : 1'b0;
assign out_ld = (depth !=0 )? rd_en : wr_en;
assign depth_2 = depth-'d2;
assign mux_sel = depth_2[MUX_SEL_WIDTH-1 : 0] ;
end else if ( MAX_DEPTH == 2) begin :mw2
reg [DATA_WIDTH-1 : 0] register;
always @(posedge clk ) begin
if(wr_en) register <= din;
end //always
assign full = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1 : 0];
assign nearly_full = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1 : 0] -1'b1;
assign out_ld = (depth !=0 )? rd_en : wr_en;
assign recieve_more_than_0 = (depth != {DEPTH_DATA_WIDTH{1'b0}});
assign recieve_more_than_1 = ~( depth == 0 || depth== 1 );
assign dout_next = (recieve_more_than_1) ? register : din;
end else begin :mw1 // MAX_DEPTH == 1
assign out_ld = wr_en;
assign dout_next = din;
assign full = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1 : 0];
assign nearly_full= 1'b1;
assign recieve_more_than_0 = full;
assign recieve_more_than_1 = 1'b0;
end
endgenerate
 
 
 
 
pronoc_register #(.W(DEPTH_DATA_WIDTH)) reg1 (.in(depth_next), .out(depth), .reset(reset), .clk(clk));
pronoc_register #(.W(DATA_WIDTH)) reg2 (.in(dout_next_ld), .out(dout ), .reset(reset), .clk(clk));
always @ (*)begin
depth_next = depth;
if (wr_en & ~rd_en) depth_next = depth + 1'h1;
else if (~wr_en & rd_en) depth_next = depth - 1'h1;
end//always
 
 
generate
for(i=0;i<DATA_WIDTH; i=i+1) begin : lp
always @(*)begin
dout_next_ld[i] = dout[i];
if (clear[i]) dout_next_ld[i] = 1'b0;
else if (out_ld) dout_next_ld[i] = dout_next[i];
end//always
end
endgenerate
//synthesis translate_off
//synopsys translate_off
always @(posedge clk)
 
begin
if(~reset)begin
if (wr_en && ~rd_en && full) begin
$display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,MAX_DEPTH);
$finish;
end
/* verilator lint_off WIDTH */
if (rd_en && !recieve_more_than_0 && IGNORE_SAME_LOC_RD_WR_WARNING == "NO") begin
$display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
$finish;
end
if (rd_en && ~wr_en && !recieve_more_than_0 && IGNORE_SAME_LOC_RD_WR_WARNING == "YES") begin
$display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
$finish;
end
/* verilator lint_on WIDTH */
end// ~reset
end // always @ (posedge clk)
//synopsys translate_on
//synthesis translate_on
endmodule
 
 
 
 
 
 
 
 
 
module fwft_fifo_bram #(
parameter DATA_WIDTH = 2,
parameter MAX_DEPTH = 2,
parameter IGNORE_SAME_LOC_RD_WR_WARNING="YES" // "YES" , "NO"
)
(
input [DATA_WIDTH-1:0] din, // Data in
input wr_en, // Write enable
input rd_en, // Read the next word
output [DATA_WIDTH-1:0] dout, // Data out
output full,
output nearly_full,
output recieve_more_than_0,
output recieve_more_than_1,
input reset,
input clk
);
function integer log2;
input integer number; begin
log2=(number <=1) ? 1: 0;
while(2**log2<number) begin
log2=log2+1;
end
end
endfunction // log2
 
localparam DEPTH_DATA_WIDTH = log2(MAX_DEPTH +1);
reg valid_next;
wire valid;
wire pass_din_to_out_reg, out_reg_wr_en, bram_out_is_valid_next;
wire bram_out_is_valid;
wire bram_empty, bram_rd_en, bram_wr_en;
wire [DATA_WIDTH-1 : 0] bram_dout;
wire [DATA_WIDTH-1 : 0] out_reg;
reg [DATA_WIDTH-1 : 0] out_reg_next;
assign dout = (bram_out_is_valid)? bram_dout : out_reg;
 
assign pass_din_to_out_reg = (wr_en & ~valid)| // a write has been recived while the reg_flit is not valid
(wr_en & valid & bram_empty & rd_en); //or its valid but bram is empty and its got a read request
 
assign bram_rd_en = (rd_en & ~bram_empty);
assign bram_wr_en = (pass_din_to_out_reg)? 1'b0 :wr_en ; //make sure not write on the Bram if the reg fifo is empty
assign out_reg_wr_en = pass_din_to_out_reg | bram_out_is_valid;
 
assign bram_out_is_valid_next = (bram_rd_en )? (rd_en & ~bram_empty): 1'b0;
always @(*) begin
valid_next = valid;
if(out_reg_wr_en) valid_next =1'b1;
else if( bram_empty & rd_en) valid_next =1'b0;
end
bram_based_fifo #(
.Dw(DATA_WIDTH),//data_width
.B(MAX_DEPTH)// buffer num
)bram_fifo(
.din(din),
.wr_en(bram_wr_en),
.rd_en(bram_rd_en),
.dout(bram_dout),
.full(),
.nearly_full(),
.empty(bram_empty),
.reset(reset),
.clk(clk)
);
wire [DEPTH_DATA_WIDTH-1 : 0] depth;
reg [DEPTH_DATA_WIDTH-1 : 0] depth_next;
pronoc_register #(.W(DATA_WIDTH) ) reg1 (.in(out_reg_next ), .out(out_reg), .reset(reset), .clk(clk));
pronoc_register #(.W(1) ) reg2 (.in(valid_next ), .out(valid), .reset(reset), .clk(clk));
pronoc_register #(.W(1) ) reg3 (.in(bram_out_is_valid_next ), .out(bram_out_is_valid), .reset(reset), .clk(clk));
pronoc_register #(.W(DEPTH_DATA_WIDTH)) reg4 (.in(depth_next ), .out(depth), .reset(reset), .clk(clk));
always @(*) begin
out_reg_next = out_reg;
depth_next = depth;
if (wr_en & ~rd_en) depth_next = depth + 1'h1;
else if (~wr_en & rd_en) depth_next = depth - 1'h1;
if(pass_din_to_out_reg) out_reg_next = din;
if(bram_out_is_valid) out_reg_next = bram_dout;
end
wire empty;
assign full = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1 : 0];
assign nearly_full = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1 : 0] -1'b1;
assign empty = depth == {DEPTH_DATA_WIDTH{1'b0}};
assign recieve_more_than_0 = ~ empty;
assign recieve_more_than_1 = ~( depth == {DEPTH_DATA_WIDTH{1'b0}} || depth== 1 );
//synthesis translate_off
//synopsys translate_off
always @(posedge clk)
begin
if (wr_en & ~rd_en & full) begin
$display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,MAX_DEPTH);
$finish;
end
/* verilator lint_off WIDTH */
if (rd_en & !recieve_more_than_0 & IGNORE_SAME_LOC_RD_WR_WARNING == "NO") begin
$display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
$finish;
end
if (rd_en & ~wr_en & !recieve_more_than_0 & (IGNORE_SAME_LOC_RD_WR_WARNING == "YES")) begin
$display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
$finish;
end
/* verilator lint_on WIDTH */
end // always @ (posedge clk)
//synopsys translate_on
//synthesis translate_on
 
 
 
 
endmodule
 
 
 
 
 
 
 
 
 
/**********************************
 
bram_based_fifo
 
*********************************/
 
 
module bram_based_fifo #(
parameter Dw = 72,//data_width
parameter B = 10// buffer num
)(
din,
wr_en,
rd_en,
dout,
full,
nearly_full,
empty,
reset,
clk
);
 
function integer log2;
input integer number; begin
log2=(number <=1) ? 1: 0;
while(2**log2<number) begin
log2=log2+1;
end
end
endfunction // log2
 
localparam B_1 = B-1,
Bw = log2(B),
DEPTHw=log2(B+1);
localparam [Bw-1 : 0] Bint = B_1[Bw-1 : 0];
 
input [Dw-1:0] din; // Data in
input wr_en; // Write enable
input rd_en; // Read the next word
 
output reg [Dw-1:0] dout; // Data out
output full;
output nearly_full;
output empty;
 
input reset;
input clk;
 
 
 
reg [Dw-1 : 0] queue [B-1 : 0] /* synthesis ramstyle = "no_rw_check" */;
reg [Bw- 1 : 0] rd_ptr;
reg [Bw- 1 : 0] wr_ptr;
reg [DEPTHw-1 : 0] depth;
 
// Sample the data
always @(posedge clk)
begin
if (wr_en)
queue[wr_ptr] <= din;
if (rd_en)
dout <= queue[rd_ptr];
end
 
always @(posedge clk)
begin
if (reset) begin
rd_ptr <= {Bw{1'b0}};
wr_ptr <= {Bw{1'b0}};
depth <= {DEPTHw{1'b0}};
end
else begin
if (wr_en) wr_ptr <= (wr_ptr==Bint)? {Bw{1'b0}} : wr_ptr + 1'b1;
if (rd_en) rd_ptr <= (rd_ptr==Bint)? {Bw{1'b0}} : rd_ptr + 1'b1;
if (wr_en & ~rd_en) depth <= depth + 1'b1;
else if (~wr_en & rd_en) depth <= depth - 1'b1;
end
end
 
//assign dout = queue[rd_ptr];
localparam [DEPTHw-1 : 0] Bint2 = B_1[DEPTHw-1 : 0];
 
 
assign full = depth == B [DEPTHw-1 : 0];
assign nearly_full = depth >=Bint2; // B-1
assign empty = depth == {DEPTHw{1'b0}};
 
//synthesis translate_off
//synopsys translate_off
always @(posedge clk)
begin
if(~reset)begin
if (wr_en && depth == B[DEPTHw-1 : 0] && !rd_en) begin
$display(" %t: ERROR: Attempt to write to full FIFO: %m",$time);
$finish;
end
if (rd_en && depth == {DEPTHw{1'b0}}) begin
$display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
$finish;
end
end//~reset
end
//synopsys translate_on
//synthesis translate_on
 
endmodule // fifo
 
src_noc/flit_buffer.sv Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: src_noc/flit_buffer_reg_bas.v =================================================================== --- src_noc/flit_buffer_reg_bas.v (revision 50) +++ src_noc/flit_buffer_reg_bas.v (revision 54) @@ -69,8 +69,10 @@ // input [V-1 :0] ssa_rd; wire [Fw-1 :0] dout_all [V-1 : 0]; // Data out - reg [VCw-1 : 0] class_vc [V-1 : 0]; - reg [REGFw-1 : 0] flit_regs [V-1 : 0]; // a register array save the head of each quque + wire [VCw-1 : 0] class_vc [V-1 : 0]; + reg [VCw-1 : 0] class_vc_next [V-1 : 0]; + wire [REGFw-1 : 0] flit_regs [V-1 : 0]; // a register array save the head of each quque + reg [REGFw-1 : 0] flit_regs_next [V-1 : 0]; reg [V-1 : 0] valid,valid_next; // if valid is asseted it shows the VC queue has a flit waiting to be sent wire [Fw-1 : 0] bram_dout; @@ -131,11 +133,7 @@ flit_buffer #( - .V(V), .B(B), - .PCK_TYPE(PCK_TYPE), - .Fw(Fw), - .DEBUG_EN(DEBUG_EN), .SSA_EN("NO")// should be "NO" even if SSA is enabled ) flit_buffer @@ -151,7 +149,12 @@ .vc_not_empty(bram_not_empty), .reset(reset), .clk(clk), - .ssa_rd({V{1'b0}}) + .ssa_rd({V{1'b0}}), + .multiple_dest(), + .sub_rd_ptr_ld(), + .flit_is_tail() + + ); @@ -201,28 +204,33 @@ assign class_all[(i+1)*Cw-1 : i*Cw] = class_vc[i]; + pronoc_register #( + .W(REGFw) + ) reg1 ( + .in(flit_regs_next[i]), + .reset(reset), + .clk(clk), + .out(flit_regs[i]) + ); + + + pronoc_register #( + .W(Cw) + ) reg2 ( + .in(class_vc_next[i]), + .reset(reset), + .clk(clk), + .out(class_vc[i]) + ); + + - - -`ifdef SYNC_RESET_MODE - always @ (posedge clk )begin -`else - always @ (posedge clk or posedge reset)begin -`endif - if(reset)begin - flit_regs[i]<= {REGFw{1'b0}}; - class_vc[i]<= {Cw{1'b0}}; - // dest_port_encoded_vc[i]<={DSTPw{1'b0}}; - end - else begin //1 :din, 0: bram - // if(pass_din_to_flit_reg_delaied[i] & (flit_reg_mux_sel_delay==1'b0)) $display("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"); - // if( bram_out_is_valid_delaied[i] & flit_reg_mux_sel_delay) $display("RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR"); - if(pass_din_to_flit_reg_delaied[i]) flit_regs[i] <= {din[Fw-1:Fw-2],din_reg[Fpay-1:0]} ; - if(bram_out_is_valid_delaied[i]) flit_regs[i] <= {bram_dout[Fw-1:Fw-2],bram_dout[Fpay-1:0]}; - if(flit_reg_wr_en[i] & flit_reg_mux_out[REGFw-1] ) class_vc[i]<=class_i;// writing header flit - // if(destport_clear[i]>0) dest_port_encoded_vc<= dest_port_encoded_vc & ~destport_clear[i]; - // else if(flit_reg_wr_en[i] & flit_reg_mux_out[REGFw-1] ) dest_port_encoded_vc <=destport_i; - end + always @ (*)begin + flit_regs_next[i] = flit_regs[i]; + class_vc_next[i] = class_vc[i]; + if(pass_din_to_flit_reg_delaied[i]) flit_regs_next[i] = {din[Fw-1:Fw-2],din_reg[Fpay-1:0]} ; + if(bram_out_is_valid_delaied[i]) flit_regs_next[i] = {bram_dout[Fw-1:Fw-2],bram_dout[Fpay-1:0]}; + if(flit_reg_wr_en[i] & flit_reg_mux_out[REGFw-1] ) class_vc_next[i] = class_i;// writing header flit end @@ -230,12 +238,8 @@ /* verilator lint_off WIDTH */ /* if( ROUTE_TYPE=="DETERMINISTIC") begin : dtrmn_dest -`ifdef SYNC_RESET_MODE - always @ (posedge clk )begin -`else - always @ (posedge clk or posedge reset)begin -`endif - if(reset)begin + always @ (`pronoc_clk_reset_edge )begin + if(`pronoc_reset)begin end else begin dest_port_encoded_vc[i]<= destport_in_encoded;
/src_noc/fmesh.sv
1,5 → 1,4
`timescale 1ns / 1ps
 
`include "pronoc_def.v"
/************************
* fmesh
*
/src_noc/header_flit.sv
1,5 → 1,4
`timescale 1ns / 1ps
 
`include "pronoc_def.v"
/**********************************************************************
** File: header_flit.sv
** Date:2017-07-11
78,7 → 77,7
output [Fw-1 : 0] flit_out;
input [Cw-1 : 0] class_in;
input [EAw-1 : 0] dest_e_addr_in;
input [DAw-1 : 0] dest_e_addr_in;
input [EAw-1 : 0] src_e_addr_in;
input [V-1 : 0] vc_num_in;
input [WEIGHTw-1 : 0] weight_in;
192,7 → 191,7
input flit_in_wr;
output [EAw-1 : 0] src_e_addr_o;
output [EAw-1 : 0] dest_e_addr_o;
output [DAw-1 : 0] dest_e_addr_o;
output [DSTPw-1 : 0] destport_o;
output [Cw-1 : 0] class_o;
output [W-1 : 0] weight_o;
290,11 → 289,7
VDSTPw = V * DSTPw,
VV = V * V;
localparam
E_SRC_LSB =0, E_SRC_MSB = E_SRC_LSB + EAw-1,
E_DST_LSB = E_SRC_MSB +1, E_DST_MSB = E_DST_LSB + EAw-1,
DST_P_LSB = E_DST_MSB + 1, DST_P_MSB = DST_P_LSB + DSTPw-1;
 
input [Fw-1 : 0] flit_in;
308,25 → 303,16
input [DSTPw-1 : 0] lk_dest_not_registered;
wire hdr_flag;
reg [V-1 : 0] vc_num_delayed;
logic [V-1 : 0] vc_num_delayed;
wire [V-1 : 0] ovc_num;
wire [DSTPw-1 : 0] lk_dest,dest_coded;
wire [DSTPw-1 : 0] lk_mux_out;
 
pronoc_register #(.W(V)) reg1 (.in(vc_num_in), .out(vc_num_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
vc_num_delayed <= {V{1'b0}};
//assigned_ovc_num_delayed <= {VV{1'b0}};
end else begin
vc_num_delayed<= vc_num_in;
//assigned_ovc_num_delayed <=assigned_ovc_num;
end
end
 
/* verilator lint_off WIDTH */
assign hdr_flag = ( PCK_TYPE == "MULTI_FLIT")? flit_in[Fw-1]: 1'b1;
/* verilator lint_on WIDTH */
346,20 → 332,10
/* verilator lint_off WIDTH */
if( SSA_EN == "YES" ) begin : predict // bypass the lk fifo when no ivc is granted
/* verilator lint_on WIDTH */
reg ivc_any_delayed;
 
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
ivc_any_delayed <= 1'b0;
end else begin
ivc_any_delayed <= any_ivc_sw_request_granted;
end
end
logic ivc_any_delayed;
pronoc_register #(.W(1)) reg2 (.in(any_ivc_sw_request_granted ), .out(ivc_any_delayed), .reset(reset), .clk(clk));
assign lk_dest = (ivc_any_delayed == 1'b0)? lk_dest_not_registered : lk_mux_out;
 
end else begin : no_predict
/src_noc/inout_ports.sv
1,5 → 1,4
`timescale 1ns/1ps
 
`include "pronoc_def.v"
/**********************************************************************
** File: inout_ports.v
**
67,7 → 66,6
ivc_request_all,
assigned_ovc_not_full_all,
masked_ovc_request_all,
pck_is_single_flit_all,
vc_weight_is_consumed_all,
iport_weight_is_consumed_all,
flit_is_tail_all,
139,7 → 137,6
// to vc/sw allocator
output [PVP_1-1 : 0] dest_port_all;
output [PV-1 : 0] ovc_is_assigned_all;
output [PV-1 : 0] pck_is_single_flit_all;
output [PV-1 : 0] ivc_request_all;
output [PV-1 : 0] assigned_ovc_not_full_all;
output [PVV-1: 0] masked_ovc_request_all;
157,8 → 154,8
output [PV-1 : 0] vsa_ovc_released_all;
output [PV-1 : 0] vsa_credit_decreased_all;
output ivc_info_t ivc_info [P-1 : 0][V-1 : 0];
output ovc_info_t ovc_info [P-1 : 0][V-1 : 0];
output ivc_info_t ivc_info [P-1 : 0][V-1 : 0];
output ovc_info_t ovc_info [P-1 : 0][V-1 : 0];
output oport_info_t oport_info [P-1 : 0];
input smart_ctrl_t smart_ctrl_in [P-1 : 0];
167,21 → 164,16
output [CRDTw-1 : 0 ] credit_init_val_out [P-1 : 0][V-1 : 0];
wire [PVV-1 : 0] candidate_ovc_all;
wire [PVDSTPw-1 : 0] dest_port_encoded_all;
 
wire [PPSw-1 : 0] port_pre_sel;
wire [PV-1 : 0] swap_port_presel;
wire [PV-1 : 0] reset_ivc_all;
wire [PV-1 : 0] ovc_is_assigned_all;
wire [PVV-1 : 0] assigned_ovc_num_all;
wire [PV-1 : 0] reset_ivc_all;
wire [PV-1 : 0] sel;
wire [PV-1 : 0] ovc_avalable_all;
wire [PVDSTPw-1 : 0] destport_clear_all;// clear non preferable ports in adaptive routing
wire [DSTPw-1 : 0] destport_clear [P-1 : 0][V-1 : 0]; // clear non preferable ports in adaptive routing
wire [PV-1 : 0] ivc_num_getting_sw_grant;
ssa_ctrl_t ssa_ctrl [P-1 : 0];
203,19 → 195,17
.reset_ivc_all (reset_ivc_all),
.flit_is_tail_all (flit_is_tail_all),
.ivc_request_all (ivc_request_all),
.dest_port_encoded_all (dest_port_encoded_all),
.dest_port_all(dest_port_all),
.candidate_ovcs_all (candidate_ovc_all),
.flit_out_all (flit_out_all),
.assigned_ovc_num_all (assigned_ovc_num_all),
.assigned_ovc_not_full_all(assigned_ovc_not_full_all),
.ovc_is_assigned_all(ovc_is_assigned_all),
.sel (sel),
.port_pre_sel(port_pre_sel),
.swap_port_presel(swap_port_presel),
.credit_out_all(credit_out_all),
// .lk_destination_encoded_all (lk_destination_encoded_all),
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all),
.destport_clear_all (destport_clear_all),
.destport_clear (destport_clear),
.vc_weight_is_consumed_all (vc_weight_is_consumed_all),
.iport_weight_is_consumed_all (iport_weight_is_consumed_all),
.iport_weight_all(iport_weight_all),
237,10 → 227,9
)
output_ports
(
.vsa_ovc_allocated_all (vsa_ovc_allocated_all),
.flit_is_tail_all (flit_is_tail_all),
.assigned_ovc_num_all (assigned_ovc_num_all),
.ovc_is_assigned_all (ovc_is_assigned_all),
.dest_port_all (dest_port_all),
.nonspec_granted_dest_port_all (nonspec_granted_dest_port_all),
.credit_in_all (credit_in_all),
260,6 → 249,7
.vsa_ovc_released_all (vsa_ovc_released_all),
.vsa_credit_decreased_all(vsa_credit_decreased_all),
.oport_info (oport_info),
.ivc_info(ivc_info),
.ovc_info (ovc_info),
.smart_ctrl_in(smart_ctrl_in),
.vsa_ctrl_in(vsa_ctrl_in),
273,19 → 263,17
)
vc_alloc_req_gen
(
.ovc_avalable_all(ovc_avalable_all),
.dest_port_encoded_all(dest_port_encoded_all),
.ivc_request_all(ivc_request_all),
.ovc_is_assigned_all(ovc_is_assigned_all),
.ivc_info(ivc_info),
.ovc_avalable_all(ovc_avalable_all),
.dest_port_decoded_all(dest_port_all),
.masked_ovc_request_all(masked_ovc_request_all),
.candidate_ovc_all(candidate_ovc_all),
.port_pre_sel(port_pre_sel),
.swap_port_presel(swap_port_presel),
.sel(sel),
.reset(reset),
.clk(clk),
.destport_clear_all(destport_clear_all),
.destport_clear(destport_clear),
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant),
//.ssa_ivc_num_getting_ovc_grant_all(nla_ivc_num_getting_ovc_grant_all),
.smart_ctrl_in (smart_ctrl_in),
310,18 → 298,10
.reset(reset)
);
assign pck_is_single_flit_all =
/* verilator lint_off WIDTH */
(PCK_TYPE == "SINGLE_FLIT")? {PV{1'b1}} :
/* verilator lint_on WIDTH */
(MIN_PCK_SIZE == 1)? flit_is_tail_all & ~ovc_is_assigned_all : {PV{1'b0}};
register #(.W(PV)) credit_reg (.in(ivc_num_getting_sw_grant),.reset(reset),.clk(clk),.out(credit_out_all));
genvar i;
335,16 → 315,12
)
the_ssa
(
.ivc_info(ivc_info),
.flit_in_wr_all(flit_in_wr_all),
.flit_in_all(flit_in_all),
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all),
.any_ovc_granted_in_outport_all(any_ovc_granted_in_outport_all),
.ovc_avalable_all(ovc_avalable_all),
.ivc_request_all(ivc_request_all),
.assigned_ovc_not_full_all(assigned_ovc_not_full_all),
.dest_port_encoded_all(dest_port_encoded_all),
.assigned_ovc_num_all(assigned_ovc_num_all),
.ovc_is_assigned_all(ovc_is_assigned_all),
.clk(clk),
.reset(reset),
.ssa_ctrl_o(ssa_ctrl)
417,7 → 393,7
output [V-1 :0] nearly_full_vc;
output [V-1 : 0] full_vc;
output [V-1 :0] empty_vc;
output reg [V-1 :0] cand_vc;
output [V-1 :0] cand_vc;
input cand_wr_vc_en;
input clk;
input reset;
436,7 → 412,8
localparam DEPTH_WIDTH = log2(B+1);
reg [DEPTH_WIDTH-1 : 0] credit [V-1 : 0];
logic [DEPTH_WIDTH-1 : 0] credit [V-1 : 0];
logic [DEPTH_WIDTH-1 : 0] credit_next [V-1 : 0];
wire [V-1 : 0] cand_vc_next;
wire [V-1 :0] request;
444,17 → 421,26
genvar i;
generate
for(i=0;i<V;i=i+1) begin : vc_loop
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset)begin
credit[i]<= credit_init_val_in[i][DEPTH_WIDTH-1:0];
end else begin
if( wr_in[i] && ~credit_in[i]) credit[i] <= credit[i]-1'b1;
if( ~wr_in[i] && credit_in[i]) credit[i] <= credit[i]+1'b1;
end //reset
pronoc_register_reset_init #(
.W(DEPTH_WIDTH)
)reg1(
.in(credit_next[i]),
.reset(reset),
.clk(clk),
.out(credit[i]),
.reset_to(credit_init_val_in[i][DEPTH_WIDTH-1:0])
);
 
always @ ( * )begin
credit_next[i] = credit [i];
if( wr_in[i] && ~credit_in[i]) credit_next[i] = credit[i]-1'b1;
if( ~wr_in[i] && credit_in[i]) credit_next[i] = credit[i]+1'b1;
end//always
 
assign full_vc[i] = (credit[i] == {DEPTH_WIDTH{1'b0}});
479,22 → 465,14
.any_grant ()
);
 
logic [V-1 : 0] cand_vc_ld_next;
pronoc_register #(.W(V)) reg2 (.in(cand_vc_ld_next ), .out(cand_vc), .reset(reset), .clk(clk));
always @ ( *) begin
cand_vc_ld_next = cand_vc;
if(cand_wr_vc_en) cand_vc_ld_next = cand_vc_next;
end
 
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if (reset) cand_vc <= {V{1'b0}};
else if(cand_wr_vc_en) cand_vc <= cand_vc_next;
end
 
 
 
 
 
endmodule
 
 
511,11 → 489,8
parameter P = 5
)(
ovc_avalable_all,
dest_port_encoded_all,
candidate_ovc_all,
ivc_request_all,
ovc_is_assigned_all,
ivc_info,
ovc_avalable_all,
dest_port_decoded_all,
masked_ovc_request_all,
port_pre_sel,
523,7 → 498,7
sel,
reset,
clk,
destport_clear_all,
destport_clear,
ivc_num_getting_ovc_grant,
smart_ctrl_in,
ssa_ctrl_in
535,34 → 510,46
PVP_1 = PV * P_1,
PVDSTPw= PV * DSTPw;
 
 
input [PV-1 : 0] ovc_avalable_all;
input [PVDSTPw-1 : 0] dest_port_encoded_all;
input [PV-1 : 0] ivc_request_all;
input [PV-1 : 0] ovc_is_assigned_all;
input [PVP_1-1 : 0] dest_port_decoded_all;
input [PVP_1-1 : 0] dest_port_decoded_all;
output [PVV-1 : 0] masked_ovc_request_all;
input [PVV-1 : 0] candidate_ovc_all;
input [PPSw-1 : 0] port_pre_sel;
output [PV-1 : 0] sel;
output [PV-1 : 0] swap_port_presel;
input reset;
input clk;
output [PVDSTPw-1 : 0] destport_clear_all;
output [DSTPw-1 : 0] destport_clear [P-1 : 0][V-1 : 0];
input [PV-1 : 0] ivc_num_getting_ovc_grant;
input ssa_ctrl_t ssa_ctrl_in [P-1: 0];
input smart_ctrl_t smart_ctrl_in [P-1: 0];
input ivc_info_t ivc_info [P-1 : 0][V-1 : 0];
wire [PV-1 : 0] ivc_request_all;
wire [PVDSTPw-1 : 0] dest_port_encoded_all;
wire [PVV-1 : 0] candidate_ovc_all;
wire [PV-1 : 0] ovc_is_assigned_all;
wire [PV-1 : 0] ovc_avalable_all_masked;
wire [PV-1 : 0] non_vsa_ivc_num_getting_ovc_grant_all;
wire [PV-1 : 0] non_vsa_ivc_num_getting_ovc_grant_all;
wire [PVDSTPw-1 : 0] destport_clear_all;
genvar i;
genvar i,j;
generate
for(i=0;i< P;i=i+1) begin :p_
assign ovc_avalable_all_masked [(i+1)*V-1 : i*V] = (SMART_EN)? ovc_avalable_all [(i+1)*V-1 : i*V] & ~smart_ctrl_in[i].mask_available_ovc : ovc_avalable_all [(i+1)*V-1 : i*V];
assign non_vsa_ivc_num_getting_ovc_grant_all [(i+1)*V-1 : i*V] = ssa_ctrl_in[i].ivc_num_getting_ovc_grant | smart_ctrl_in[i].ivc_num_getting_ovc_grant;
for(j=0;j< V;j=j+1) begin :V_
assign ivc_request_all[i*V+j] = ivc_info[i][j].ivc_req;
assign ovc_is_assigned_all[i*V+j] = ivc_info[i][j].ovc_is_assigned;
assign dest_port_encoded_all [(i*V+j+1)*DSTPw-1 : (i*V+j)*DSTPw]=ivc_info[i][j].dest_port_encoded;
assign candidate_ovc_all[(i*V+j+1)*V-1 : (i*V+j)*V]= ivc_info[i][j].candidate_ovc;
assign destport_clear [i][j]=destport_clear_all [(i*V+j+1)*DSTPw-1 : (i*V+j)*DSTPw];
end
end//for
574,7 → 561,8
vc_alloc_request_gen_determinstic #(
.P(P),
.V(V),
.SELF_LOOP_EN(SELF_LOOP_EN)
.SELF_LOOP_EN(SELF_LOOP_EN),
.CAST_TYPE(CAST_TYPE)
)
vc_request_gen
(
677,7 → 665,8
module vc_alloc_request_gen_determinstic #(
parameter P = 5,
parameter V = 4,
parameter SELF_LOOP_EN="NO"
parameter SELF_LOOP_EN="NO",
parameter CAST_TYPE = "UNICAST"
)(
ovc_avalable_all,
714,7 → 703,7
genvar i;
 
generate
if(SELF_LOOP_EN == "NO") begin
if(SELF_LOOP_EN == "NO" ) begin :nslp
//remove available ovc of receiver port
for(i=0;i< P;i=i+1) begin :port_loop
if(i==0) begin : first assign ovc_avalable_perport[i]=ovc_avalable_all [PV-1 : V]; end
721,7 → 710,7
else if(i==(P-1)) begin : last assign ovc_avalable_perport[i]=ovc_avalable_all [PV-V-1 : 0]; end
else begin : midle assign ovc_avalable_perport[i]={ovc_avalable_all [PV-1 : (i+1)*V],ovc_avalable_all [(i*V)-1 : 0]}; end
end
end else begin
end else begin :slp
for(i=0;i< P;i=i+1) begin :port_loop
assign ovc_avalable_perport[i]=ovc_avalable_all;
end
/src_noc/input_ports.sv
1,4 → 1,4
`timescale 1ns/1ps
`include "pronoc_def.v"
//`define MONITORE_PATH
 
/**********************************************************************
28,6 → 28,9
**
**************************************************************/
 
 
 
 
module input_ports
import pronoc_pkg::*;
#(
42,11 → 45,9
reset_ivc_all,
flit_is_tail_all,
ivc_request_all,
dest_port_encoded_all,
dest_port_all,
candidate_ovcs_all,
dest_port_all,
flit_out_all,
assigned_ovc_num_all,
assigned_ovc_not_full_all,
ovc_is_assigned_all,
sel,
53,8 → 54,9
port_pre_sel,
swap_port_presel,
nonspec_first_arbiter_granted_ivc_all,
credit_out_all,
destport_clear_all,
destport_clear,
vc_weight_is_consumed_all,
iport_weight_is_consumed_all,
iport_weight_all,
99,11 → 101,11
output [PV-1 : 0] reset_ivc_all;
output [PV-1 : 0] flit_is_tail_all;
output [PV-1 : 0] ivc_request_all;
output [PVDSTPw-1 : 0] dest_port_encoded_all;
output [PV-1 : 0] credit_out_all;
output [PVP_1-1 : 0] dest_port_all;
output [PVV-1 : 0] candidate_ovcs_all;
output [PFw-1 : 0] flit_out_all;
output [PVV-1 : 0] assigned_ovc_num_all;
input [PV-1 : 0] assigned_ovc_not_full_all;
output [PV-1 : 0] ovc_is_assigned_all;
input [PV-1 : 0] sel;
111,12 → 113,15
input [PV-1 : 0] swap_port_presel;
input [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all;
input [PVDSTPw-1 : 0] destport_clear_all;
output [WP-1 : 0] iport_weight_all;
output [PV-1 : 0] vc_weight_is_consumed_all;
output [P-1 : 0] iport_weight_is_consumed_all;
input [PP_1-1 : 0] granted_dest_port_all;
output [WPP-1 : 0] oports_weight_all;
 
output ivc_info_t ivc_info [P-1 : 0][V-1 : 0];
input vsa_ctrl_t vsa_ctrl_in [P-1: 0];
input ssa_ctrl_t ssa_ctrl_in [P-1: 0];
125,10 → 130,14
input refresh_w_counter;
input [DSTPw-1 : 0] destport_clear [P-1 : 0][V-1 : 0];
 
genvar i;
generate
for(i=0;i<P;i=i+1)begin : Port_
for(i=0;i<P;i=i+1)begin : Port_
input_queue_per_port
// iport_reg_base
138,6 → 147,7
)
the_input_queue_per_port
(
.credit_out(credit_out_all [(i+1)*V-1 : i*V]),
.current_r_addr(current_r_addr),
.neighbors_r_addr(neighbors_r_addr),
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant [(i+1)*V-1 : i*V]),// for non spec ivc_num_getting_first_sw_grant,
147,11 → 157,8
.reset_ivc(reset_ivc_all [(i+1)*V-1 : i*V]),
.flit_is_tail(flit_is_tail_all [(i+1)*V-1 : i*V]),
.ivc_request(ivc_request_all [(i+1)*V-1 : i*V]),
.dest_port_encoded(dest_port_encoded_all [(i+1)*DSTPw*V-1 : i*DSTPw*V]),
.dest_port(dest_port_all [(i+1)*P_1*V-1 : i*P_1*V]),
.candidate_ovcs(candidate_ovcs_all [(i+1) * VV -1 : i*VV]),
.flit_out(flit_out_all [(i+1)*Fw-1 : i*Fw]),
.assigned_ovc_num(assigned_ovc_num_all [(i+1)*VV-1 : i*VV]),
.assigned_ovc_not_full(assigned_ovc_not_full_all [(i+1)*V-1 : i*V]),
.ovc_is_assigned(ovc_is_assigned_all [(i+1)*V-1 : i*V]),
.sel(sel [(i+1)*V-1 : i*V]),
161,7 → 168,7
.reset(reset),
.clk(clk),
.destport_clear(destport_clear_all[(i+1)*DSTPw*V-1 : i*DSTPw*V]),
.destport_clear(destport_clear [i]),
.iport_weight(iport_weight_all[(i+1)*W-1 : i*W]),
.oports_weight(oports_weight_all[(i+1)*WP-1 : i*WP]),
.vc_weight_is_consumed(vc_weight_is_consumed_all [(i+1)*V-1 : i*V]),
195,6 → 202,7
parameter SW_LOC = 0
)(
current_r_addr,
credit_out,
neighbors_r_addr,
ivc_num_getting_sw_grant,// for non spec ivc_num_getting_first_sw_grant,
any_ivc_sw_request_granted,
203,11 → 211,8
reset_ivc,
flit_is_tail,
ivc_request,
dest_port_encoded,
dest_port,
candidate_ovcs,
flit_out,
assigned_ovc_num,
flit_out,
assigned_ovc_not_full,
ovc_is_assigned,
sel,
232,17 → 237,12
);
 
function integer log2;
input integer number; begin
log2=(number <=1) ? 1: 0;
while(2**log2<number) begin
log2=log2+1;
end
end
endfunction // log2
localparam PORT_B = port_buffer_size(SW_LOC);
localparam
PORT_B = port_buffer_size(SW_LOC),
PORT_Bw= log2(PORT_B);
272,6 → 272,7
input reset, clk;
output [V-1 : 0] credit_out;
input [RAw-1 : 0] current_r_addr;
input [PRAw-1: 0] neighbors_r_addr;
output [V-1 : 0] ivc_num_getting_sw_grant;
281,18 → 282,15
output [V-1 : 0] reset_ivc;
output [V-1 : 0] flit_is_tail;
output [V-1 : 0] ivc_request;
output [VDSTPw-1 : 0] dest_port_encoded;
output [VP_1-1 : 0] dest_port;
output [VV-1 : 0] candidate_ovcs;
output [Fw-1 : 0] flit_out;
output [VV-1 : 0] assigned_ovc_num;
input [V-1 : 0] assigned_ovc_not_full;
output [V-1 : 0] ovc_is_assigned;
input [V-1 : 0] sel;
input [V-1 : 0] nonspec_first_arbiter_granted_ivc;
input [(DSTPw*V)-1 : 0] destport_clear;
output reg [WEIGHTw-1 : 0] iport_weight;
input [DSTPw-1 : 0] destport_clear [V-1 : 0];
output [WEIGHTw-1 : 0] iport_weight;
output [V-1 : 0] vc_weight_is_consumed;
output iport_weight_is_consumed;
input refresh_w_counter;
307,16 → 305,24
input ssa_ctrl_t ssa_ctrl_in;
output [CRDTw-1 : 0 ] credit_init_val_out [V-1 : 0];
wire [DSTPw-1 : 0] dest_port_encoded [V-1 : 0];
//for multicast
wire [DSTPw-1 : 0] dest_port_multi [V-1 : 0];
wire [V-1 : 0] multiple_dest,dst_onhot0;
wire [DSTPw-1 : 0] clear_dspt_mulicast [V-1 : 0];
wire [VV-1 : 0] candidate_ovcs;
wire [Cw-1 : 0] class_in;
wire [DSTPw-1 : 0] destport_in,destport_in_encoded;
wire [VDSTPw-1 : 0] lk_destination_encoded;
wire [EAw-1 : 0] dest_e_addr_in;
wire [DAw-1 : 0] dest_e_addr_in;
wire [EAw-1 : 0] src_e_addr_in;
wire [V-1 : 0] vc_num_in;
wire [V-1 : 0] hdr_flit_wr,flit_wr;
wire [VV-1 : 0] assigned_ovc_num;
wire [DSTPw-1 : 0] lk_destination_in_encoded;
wire [WEIGHTw-1 : 0] weight_in;
wire [Fw-1 : 0] buffer_out;
338,52 → 344,66
wire [P-1 : 0] destport_one_hot [V-1 :0];
wire [V-1 : 0] mux_out[V-1 : 0];
wire [V-1 : 0] dstport_fifo_not_empty;
 
logic [WEIGHTw-1 : 0] iport_weight_next;
assign smart_hdr_en = (SMART_EN) ? smart_ctrl_in.ivc_num_getting_ovc_grant: {V{1'b0}};
assign reset_ivc = smart_ctrl_in.ivc_reset | ssa_ctrl_in.ivc_reset | vsa_ctrl_in.ivc_reset;
assign ivc_num_getting_sw_grant = ssa_ctrl_in.ivc_num_getting_sw_grant | vsa_ctrl_in.ivc_num_getting_sw_grant;
assign flit_wr =(flit_in_wr )? vc_num_in : {V{1'b0}};
assign rd_hdr_fwft_fifo = ssa_ctrl_in.ivc_reset | vsa_ctrl_in.ivc_reset | (smart_ctrl_in.ivc_reset & ~ smart_ctrl_in.ivc_single_flit_pck);
assign rd_hdr_fwft_fifo = (ssa_ctrl_in.ivc_reset | vsa_ctrl_in.ivc_reset | (smart_ctrl_in.ivc_reset & ~ smart_ctrl_in.ivc_single_flit_pck)) & ~ multiple_dest;
assign wr_hdr_fwft_fifo = hdr_flit_wr | (smart_hdr_en & ~ smart_ctrl_in.ivc_single_flit_pck);
assign ivc_request = ivc_not_empty;
wire [V-1 : 0] flit_is_tail2;
register #(.W(V)) reg1(
pronoc_register #(.W(V)) reg1(
.in (ovc_is_assigned_next),
.reset (reset ),
.clk (clk ),
.out (ovc_is_assigned ));
register #(.W(VV)) reg2(
pronoc_register #(.W(VV)) reg2(
.in (assigned_ovc_num_next),
.reset (reset ),
.clk (clk ),
.out (assigned_ovc_num ));
register #(.W(V)) reg3(
pronoc_register #(.W(V)) reg3(
.in (rd_hdr_fwft_fifo),
.reset (reset ),
.clk (clk ),
.out (rd_hdr_fwft_fifo_delay ));
register #(.W(V)) reg4(
pronoc_register #(.W(V)) reg4(
.in (wr_hdr_fwft_fifo),
.reset (reset ),
.clk (clk ),
.out (wr_hdr_fwft_fifo_delay ));
pronoc_register #(.W(WEIGHTw), .RESET_TO(1)) reg5(
.in (iport_weight_next ),
.reset (reset ),
.clk (clk ),
.out (iport_weight ));
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
iport_weight <= 1;
end else begin
if(hdr_flit_wr != {V{1'b0}}) iport_weight <= (weight_in=={WEIGHTw{1'b0}})? 1 : weight_in; // the minimum weight is 1
end
end
pronoc_register #(.W(V)) credit_reg (
.in (ivc_num_getting_sw_grant & ~ multiple_dest),
.reset (reset),
.clk (clk),
.out (credit_out));
always @ (*)begin
iport_weight_next = iport_weight;
if(hdr_flit_wr != {V{1'b0}}) iport_weight_next = (weight_in=={WEIGHTw{1'b0}})? 1 : weight_in; // the minimum weight is 1
end
 
//extract header flit info
412,7 → 432,7
genvar i;
generate
/* verilator lint_off WIDTH */
if (( TOPOLOGY == "RING" || TOPOLOGY == "LINE" || TOPOLOGY == "MESH" || TOPOLOGY == "TORUS") && (T3>1)) begin : multi_local
if (( TOPOLOGY == "RING" || TOPOLOGY == "LINE" || TOPOLOGY == "MESH" || TOPOLOGY == "TORUS") && (T3>1) && CAST_TYPE== "UNICAST") begin : multi_local
/* verilator lint_on WIDTH */
434,7 → 454,7
);
end
/* verilator lint_off WIDTH */
if ( TOPOLOGY == "FMESH") begin : fmesh
if ( TOPOLOGY == "FMESH" && CAST_TYPE== "UNICAST" ) begin : fmesh
/* verilator lint_on WIDTH */
484,7 → 504,11
.bin_code(ivc_info[i].assigned_ovc_bin)
);
assign ivc_info[i].single_flit_pck =
/* verilator lint_off WIDTH */
(PCK_TYPE == "SINGLE_FLIT")? 1'b1 :
/* verilator lint_on WIDTH */
(MIN_PCK_SIZE == 1)? flit_is_tail[i] & ~ovc_is_assigned[i] : 1'b0;
assign ivc_info[i].ivc_req = ivc_request[i];
assign ivc_info[i].class_num = class_out[i];
assign ivc_info[i].flit_is_tail = flit_is_tail[i];
492,7 → 516,7
assign ivc_info[i].candidate_ovc= candidate_ovcs [(i+1)*V-1 : i*V];
assign ivc_info[i].ovc_is_assigned = ovc_is_assigned[i];
assign ivc_info[i].assigned_ovc_num= assigned_ovc_num[(i+1)*V-1 : i*V];
assign ivc_info[i].dest_port_encoded=dest_port_encoded[(i+1)*DSTPw-1 : i*DSTPw];
assign ivc_info[i].dest_port_encoded=dest_port_encoded[i];
//assign ivc_info[i].getting_swa_first_arbiter_grant=nonspec_first_arbiter_granted_ivc[i];
//assign ivc_info[i].getting_swa_grant=ivc_num_getting_sw_grant[i];
if(P==MAX_P) begin :max_
512,6 → 536,10
end
//synthesis translate_on
class_ovc_table #(
.CVw(CVw),
.CLASS_SETTING(CLASS_SETTING),
524,7 → 552,7
.candidate_ovcs(candidate_ovcs [(i+1)*V-1 : i*V])
);
if(PCK_TYPE == "MULTI_FLIT") begin : multi
if(PCK_TYPE == "MULTI_FLIT") begin : multi_flit
always @ (*) begin
ovc_is_assigned_next[i] = ovc_is_assigned[i];
559,7 → 587,7
);
/*
//tail fifo
fwft_fifo #(
.DATA_WIDTH(1),
579,8 → 607,10
.reset (reset),
.clk (clk)
);
end else begin :single
assign flit_is_tail[i]=1'b1;
*/
end else begin :single_flit
//assign flit_is_tail[i]=1'b1;
assign ovc_is_assigned_next[i] = 1'b0;
always @(*) begin
656,6 → 686,60
assign class_out[i] = 1'b0;
end
//localparam CAST_TYPE = "UNICAST"; // multicast is not yet supported
/* verilator lint_off WIDTH */
if(CAST_TYPE!= "UNICAST") begin : muticast
/* verilator lint_on WIDTH */
// for multicast we send one packet to each direction in order. The priority is according to DoR routing dimentions
fwft_fifo_with_output_clear #(
.DATA_WIDTH(DSTPw),
.MAX_DEPTH (MAX_PCK),
.IGNORE_SAME_LOC_RD_WR_WARNING(IGNORE_SAME_LOC_RD_WR_WARNING)
)
dest_fifo
(
.din(destport_in_encoded),
.wr_en(wr_hdr_fwft_fifo[i]), // Write enable
.rd_en(rd_hdr_fwft_fifo[i]), // Read the next word
.dout(dest_port_multi[i]), // Data out
.full(),
.nearly_full(),
.recieve_more_than_0(),
.recieve_more_than_1(),
.reset(reset),
.clk(clk),
.clear(clear_dspt_mulicast [i]) // clear the destination port once it got the entire packet
);
//TODO remove multiple_dest[i] to see if it works?
assign clear_dspt_mulicast [i] = (reset_ivc[i] & multiple_dest[i]) ? dest_port_encoded[i] : {DSTPw{1'b0}};
// a fix priority arbiter.
multicast_dst_sel sel(
.destport_in(dest_port_multi[i]),
.destport_out(dest_port_encoded[i])
);
//check if we have multiple port to send a packet to
is_onehot0 #(
.IN_WIDTH(DSTPw)
)
one_h
(
.in(dest_port_multi[i]),
.result(dst_onhot0[i])
);
assign multiple_dest[i]=~dst_onhot0[i];
end else begin : unicast
assign multiple_dest[i] = 1'b0;
//lk_dst_fifo
fwft_fifo #(
.DATA_WIDTH(DSTPw),
676,86 → 760,57
.clk (clk)
);
localparam CAST_TYPE = "UNICAST"; // multicast is not yet supported
/* verilator lint_off WIDTH */
if(CAST_TYPE!= "UNICAST") begin : no_unicast
/* verilator lint_on WIDTH */
fwft_fifo_with_output_clear #(
.DATA_WIDTH(DSTPw),
.MAX_DEPTH (MAX_PCK),
.IGNORE_SAME_LOC_RD_WR_WARNING(IGNORE_SAME_LOC_RD_WR_WARNING)
)
dest_fifo
(
.din(destport_in_encoded),
.wr_en(wr_hdr_fwft_fifo[i]), // Write enable
.rd_en(rd_hdr_fwft_fifo[i]), // Read the next word
.dout(dest_port_encoded[(i+1)*DSTPw-1 : i*DSTPw]), // Data out
.full(),
.nearly_full(),
.recieve_more_than_0(),
.recieve_more_than_1(),
.reset(reset),
.clk(clk),
.clear(destport_clear[(i+1)*DSTPw-1 : i*DSTPw]) // clear the destination ports once it got its flit
);
/* verilator lint_off WIDTH */
end else if( ROUTE_TYPE=="DETERMINISTIC") begin : dtrmn_dest
/* verilator lint_on WIDTH */
//destport_fifo
fwft_fifo #(
.DATA_WIDTH(DSTPw),
.MAX_DEPTH (MAX_PCK),
.IGNORE_SAME_LOC_RD_WR_WARNING(IGNORE_SAME_LOC_RD_WR_WARNING)
)
dest_fifo
(
.din(destport_in_encoded),
.wr_en(wr_hdr_fwft_fifo[i]), // Write enable
.rd_en(rd_hdr_fwft_fifo[i]), // Read the next word
.dout(dest_port_encoded[(i+1)*DSTPw-1 : i*DSTPw]), // Data out
.full(),
.nearly_full(),
.recieve_more_than_0(),
.recieve_more_than_1(),
.reset(reset),
.clk(clk)
);
end else begin : adptv_dest
 
fwft_fifo_with_output_clear #(
.DATA_WIDTH(DSTPw),
.MAX_DEPTH (MAX_PCK),
.IGNORE_SAME_LOC_RD_WR_WARNING(IGNORE_SAME_LOC_RD_WR_WARNING)
)
dest_fifo
(
.din(destport_in_encoded),
.wr_en(wr_hdr_fwft_fifo[i]), // Write enable
.rd_en(rd_hdr_fwft_fifo[i]), // Read the next word
.dout(dest_port_encoded[(i+1)*DSTPw-1 : i*DSTPw]), // Data out
.full(),
.nearly_full(),
.recieve_more_than_0(),
.recieve_more_than_1(),
.reset(reset),
.clk(clk),
.clear(destport_clear[(i+1)*DSTPw-1 : i*DSTPw]) // clear other destination ports once one of them is selected
);
end
/* verilator lint_off WIDTH */
if( ROUTE_TYPE=="DETERMINISTIC") begin : dtrmn_dest
/* verilator lint_on WIDTH */
//destport_fifo
fwft_fifo #(
.DATA_WIDTH(DSTPw),
.MAX_DEPTH (MAX_PCK),
.IGNORE_SAME_LOC_RD_WR_WARNING(IGNORE_SAME_LOC_RD_WR_WARNING)
)
dest_fifo
(
.din(destport_in_encoded),
.wr_en(wr_hdr_fwft_fifo[i]), // Write enable
.rd_en(rd_hdr_fwft_fifo[i]), // Read the next word
.dout(dest_port_encoded[i]), // Data out
.full(),
.nearly_full(),
.recieve_more_than_0(),
.recieve_more_than_1(),
.reset(reset),
.clk(clk)
);
end else begin : adptv_dest
fwft_fifo_with_output_clear #(
.DATA_WIDTH(DSTPw),
.MAX_DEPTH (MAX_PCK),
.IGNORE_SAME_LOC_RD_WR_WARNING(IGNORE_SAME_LOC_RD_WR_WARNING)
)
dest_fifo
(
.din(destport_in_encoded),
.wr_en(wr_hdr_fwft_fifo[i]), // Write enable
.rd_en(rd_hdr_fwft_fifo[i]), // Read the next word
.dout(dest_port_encoded[i]), // Data out
.full(),
.nearly_full(),
.recieve_more_than_0(),
.recieve_more_than_1(),
.reset(reset),
.clk(clk),
.clear(destport_clear[i]) // clear other destination ports once one of them is selected
);
end
end//unicast
destp_generator #(
769,12 → 824,13
.PLw(PLw),
.PPSw(PPSw),
.SELF_LOOP_EN (SELF_LOOP_EN),
.SW_LOC(SW_LOC)
.SW_LOC(SW_LOC),
.CAST_TYPE(CAST_TYPE)
)
decoder
(
.destport_one_hot (destport_one_hot[i]),
.dest_port_encoded(dest_port_encoded[(i+1)*DSTPw-1 : i*DSTPw]),
.dest_port_encoded(dest_port_encoded[i]),
.dest_port_out(dest_port[(i+1)*P_1-1 : i*P_1]),
.endp_localp_num(endp_localp_num[(i+1)*PLw-1 : i*PLw]),
.swap_port_presel(swap_port_presel[i]),
784,7 → 840,7
/* verilator lint_off WIDTH */
if (( TOPOLOGY == "RING" || TOPOLOGY == "LINE" || TOPOLOGY == "MESH" || TOPOLOGY == "TORUS") && (T3>1)) begin : multi_local
if (( TOPOLOGY == "RING" || TOPOLOGY == "LINE" || TOPOLOGY == "MESH" || TOPOLOGY == "TORUS") && (T3>1) && (CAST_TYPE== "UNICAST")) begin : multi_local
/* verilator lint_on WIDTH */
// the router has multiple local ports. Save the destination local port
809,7 → 865,7
.clk(clk)
);
/* verilator lint_off WIDTH */
end else if ( TOPOLOGY == "FMESH") begin : fmesh
end else if ( TOPOLOGY == "FMESH" && CAST_TYPE== "UNICAST") begin : fmesh
/* verilator lint_on WIDTH */
fwft_fifo #(
903,13 → 959,22
/* verilator lint_off WIDTH */
if(COMBINATION_TYPE == "COMB_NONSPEC") begin : nonspec
/* verilator lint_on WIDTH */
/*
always @(posedge clk)
if ((ivc_not_empty & flit_is_tail2) != (ivc_not_empty & flit_is_tail))begin
$display("ERROR: %b !=%b",flit_is_tail2 , flit_is_tail ) ;
$finish;
end
*/
flit_buffer #(
.V(V),
.B(PORT_B), // buffer space :flit per VC
.PCK_TYPE(PCK_TYPE),
.Fw(Fw),
.DEBUG_EN(DEBUG_EN),
.SSA_EN(SSA_EN)
)
the_flit_buffer
924,7 → 989,10
.vc_not_empty(ivc_not_empty),
.reset(reset),
.clk(clk),
.ssa_rd(ssa_ctrl_in.ivc_num_getting_sw_grant)
.ssa_rd(ssa_ctrl_in.ivc_num_getting_sw_grant),
.multiple_dest( multiple_dest ),
.sub_rd_ptr_ld(reset_ivc) ,
.flit_is_tail(flit_is_tail)
);
end else begin :spec//not nonspec comb
931,18 → 999,14
 
flit_buffer #(
.V(V),
.B(PORT_B), // buffer space :flit per VC
.PCK_TYPE(PCK_TYPE),
.Fw(Fw),
.DEBUG_EN(DEBUG_EN),
.SSA_EN(SSA_EN)
)
the_flit_buffer
(
.din(flit_in), // Data in
.vc_num_wr(vc_num_in),//write vertual chanel
.vc_num_rd(ivc_num_getting_sw_grant),//read vertual chanel
.vc_num_wr(vc_num_in),//write virtual channel
.vc_num_rd(ivc_num_getting_sw_grant),//read virtual channel
.wr_en(flit_in_wr), // Write enable
.rd_en(any_ivc_sw_request_granted), // Read the next word
.dout(buffer_out), // Data out
949,37 → 1013,52
.vc_not_empty(ivc_not_empty),
.reset(reset),
.clk(clk),
.ssa_rd(ssa_ctrl_in.ivc_num_getting_sw_grant)
.ssa_rd(ssa_ctrl_in.ivc_num_getting_sw_grant),
.multiple_dest( multiple_dest ),
.sub_rd_ptr_ld(reset_ivc) ,
.flit_is_tail(flit_is_tail)
);
end
end
 
/* verilator lint_off WIDTH */
if(CAST_TYPE== "UNICAST") begin : unicast
/* verilator lint_on WIDTH */
look_ahead_routing #(
.T1(T1),
.T2(T2),
.T3(T3),
.T4(T4),
.P(P),
.RAw(RAw),
.EAw(EAw),
.DAw(DAw),
.DSTPw(DSTPw),
.SW_LOC(SW_LOC),
.TOPOLOGY(TOPOLOGY),
.ROUTE_NAME(ROUTE_NAME),
.ROUTE_TYPE(ROUTE_TYPE)
)
lk_routing
(
.current_r_addr(current_r_addr),
.neighbors_r_addr(neighbors_r_addr),
.dest_e_addr(dest_e_addr_in),
.src_e_addr(src_e_addr_in),
.destport_encoded(destport_in_encoded),
.lkdestport_encoded(lk_destination_in_encoded),
.reset(reset),
.clk(clk)
);
end // unicast
endgenerate
 
look_ahead_routing #(
.T1(T1),
.T2(T2),
.T3(T3),
.T4(T4),
.P(P),
.RAw(RAw),
.EAw(EAw),
.DSTPw(DSTPw),
.SW_LOC(SW_LOC),
.TOPOLOGY(TOPOLOGY),
.ROUTE_NAME(ROUTE_NAME),
.ROUTE_TYPE(ROUTE_TYPE)
)
lk_routing
(
.current_r_addr(current_r_addr),
.neighbors_r_addr(neighbors_r_addr),
.dest_e_addr(dest_e_addr_in),
.src_e_addr(src_e_addr_in),
.destport_encoded(destport_in_encoded),
.lkdestport_encoded(lk_destination_in_encoded),
.reset(reset),
.clk(clk)
);
 
header_flit_update_lk_route_ovc #(
.P(P)
1005,6 → 1084,8
generate
if(DEBUG_EN) begin :debg
always @ (posedge clk) begin
if((|vsa_ctrl_in.ivc_num_getting_sw_grant) & (|ssa_ctrl_in.ivc_num_getting_sw_grant))begin
$display("%t: ERROR: VSA/SSA conflict: an input port cannot get both sva and ssa grant at the same time %m",$time);
1025,10 → 1106,19
$finish;
end
end//always
end
always @(posedge clk) begin
if((dest_port [(i+1)*P_1-1 : i*P_1] == {P_1{1'b0}}) && (ivc_request[i]==1'b1)) begin
$display ("%t: ERROR: The destination port is not set for an active IVC request: %m \n",$time);
$finish;
end
end
end//for
/* verilator lint_off WIDTH */
if (( TOPOLOGY == "RING" || TOPOLOGY == "LINE" || TOPOLOGY == "MESH" || TOPOLOGY == "TORUS")) begin : mesh_based
if (( TOPOLOGY == "RING" || TOPOLOGY == "LINE" || TOPOLOGY == "MESH" || TOPOLOGY == "TORUS") && CAST_TYPE== "UNICAST") begin : mesh_based
/* verilator lint_on WIDTH */
 
debug_mesh_tori_route_ckeck #(
1105,7 → 1195,8
parameter PLw=1,
parameter PPSw=4,
parameter SW_LOC=0,
parameter SELF_LOOP_EN="NO"
parameter SELF_LOOP_EN="NO",
parameter CAST_TYPE = "UNICAST"
 
)
(
1128,9 → 1219,27
input odd_column;
generate
/* verilator lint_off WIDTH */
if(TOPOLOGY == "FATTREE" ) begin : fat
/* verilator lint_on WIDTH */
/* verilator lint_off WIDTH */
if(CAST_TYPE!= "UNICAST") begin : muticast
/* verilator lint_on WIDTH */
// destination port is not coded for multicast/broadcast
if( SELF_LOOP_EN=="NO") begin : nslp
remove_sw_loc_one_hot #(
.P(P),
.SW_LOC(SW_LOC)
)
remove_sw_loc
(
.destport_in(dest_port_encoded),
.destport_out(dest_port_out)
);
end else begin : slp
assign dest_port_out = dest_port_encoded;
end
/* verilator lint_off WIDTH */
end else if(TOPOLOGY == "FATTREE" ) begin : fat
/* verilator lint_on WIDTH */
fattree_destp_generator #(
.K(T1),
.P(P),
1143,9 → 1252,9
.dest_port_in_encoded(dest_port_encoded),
.dest_port_out(dest_port_out)
);
/* verilator lint_off WIDTH */
/* verilator lint_off WIDTH */
end else if (TOPOLOGY == "TREE") begin :tree
/* verilator lint_on WIDTH */
/* verilator lint_on WIDTH */
tree_destp_generator #(
.K(T1),
.P(P),
1182,7 → 1291,9
.port_pre_sel(port_pre_sel),
.odd_column(odd_column)// only needed for odd even routing
);
/* verilator lint_off WIDTH */
end else if (TOPOLOGY == "FMESH") begin :fmesh
/* verilator lint_on WIDTH */
fmesh_destp_generator #(
.ROUTE_NAME(ROUTE_NAME),
.ROUTE_TYPE(ROUTE_TYPE),
/src_noc/iport_reg_base.sv
1,4 → 1,4
`timescale 1ns/1ps
`include "pronoc_def.v"
//`define MONITORE_PATH
 
/**********************************************************************
152,7 → 152,7
input [V-1 : 0] nonspec_first_arbiter_granted_ivc;
input [V-1 : 0] ssa_ivc_num_getting_sw_grant;
input [(DSTPw*V)-1 : 0] destport_clear;
output reg [WEIGHTw-1 : 0] iport_weight;
output [WEIGHTw-1 : 0] iport_weight;
output [V-1 : 0] vc_weight_is_consumed;
output iport_weight_is_consumed;
input refresh_w_counter;
170,9 → 170,9
wire [EAw-1 : 0] src_e_addr_in;
wire [V-1 : 0] vc_num_in;
wire [V-1 : 0] hdr_flit_wr,flit_wr;
reg [V-1 : 0] hdr_flit_wr_delayed;
wire [V-1 : 0] hdr_flit_wr_delayed;
wire [V-1 : 0] class_rd_fifo,dst_rd_fifo;
reg [V-1 : 0] lk_dst_rd_fifo;
wire [V-1 : 0] lk_dst_rd_fifo;
wire [DSTPw-1 : 0] lk_destination_in_encoded;
wire [WEIGHTw-1 : 0] weight_in;
wire [Fw-1 : 0] buffer_out;
181,7 → 181,7
wire [Cw-1 : 0] class_out [V-1 : 0];
wire [VELw-1 : 0] endp_localp_num;
wire [ELw-1 : 0] endp_l_in;
logic [WEIGHTw-1 : 0] iport_weight_next;
 
//extract header flit info
extract_header_flit_info #(
231,35 → 231,31
// synthesis translate_on
// synopsys translate_on
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
iport_weight <= 1;
end else begin
if(hdr_flit_wr != {V{1'b0}}) iport_weight <= (weight_in=={WEIGHTw{1'b0}})? 1 : weight_in; // the minimum weight is 1
end
 
pronoc_register #(.W(WEIGHTw), .RESET_TO(1)) reg5(
.in (iport_weight_next ),
.reset (reset ),
.clk (clk ),
.out (iport_weight ));
always @ (*)begin
iport_weight_next = iport_weight;
if(hdr_flit_wr != {V{1'b0}}) iport_weight_next = (weight_in=={WEIGHTw{1'b0}})? 1 : weight_in; // the minimum weight is 1
end
 
 
// genrate write enable for lk_routing result with one clock cycle latency after reciveing the flit
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
hdr_flit_wr_delayed <= {V{1'b0}};
//lk_dst_rd_fifo <= {V{1'b0}};
end else begin
hdr_flit_wr_delayed <= hdr_flit_wr;
// lk_dst_rd_fifo <= dst_rd_fifo;
end
end
pronoc_register #(.W(V)) reg1(
.in (hdr_flit_wr ),
.reset (reset ),
.clk (clk ),
.out (hdr_flit_wr_delayed ));
 
 
 
 
genvar i;
generate
/* verilator lint_off WIDTH */
551,11 → 547,7
/* verilator lint_on WIDTH */
flit_buffer #(
.V(V),
.B(B), // buffer space :flit per VC
.PCK_TYPE(PCK_TYPE),
.Fw(Fw),
.DEBUG_EN(DEBUG_EN),
.SSA_EN(SSA_EN)
)
the_flit_buffer
569,7 → 561,10
.vc_not_empty(ivc_not_empty),
.reset(reset),
.clk(clk),
.ssa_rd(ssa_ivc_num_getting_sw_grant)
.ssa_rd(ssa_ivc_num_getting_sw_grant),
.multiple_dest(),
.sub_rd_ptr_ld(),
.flit_is_tail()
);
636,11 → 631,7
 
flit_buffer #(
.V(V),
.B(B), // buffer space :flit per VC
.PCK_TYPE(PCK_TYPE),
.Fw(Fw),
.DEBUG_EN(DEBUG_EN),
.SSA_EN(SSA_EN)
)
the_flit_buffer
654,7 → 645,11
.vc_not_empty(ivc_not_empty),
.reset(reset),
.clk(clk),
.ssa_rd(ssa_ivc_num_getting_sw_grant)
.ssa_rd(ssa_ivc_num_getting_sw_grant),
.multiple_dest(),
.sub_rd_ptr_ld(),
.flit_is_tail()
);
end
713,19 → 708,14
assign flit_wr =(flit_in_wr )? vc_num_in : {V{1'b0}};
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
lk_dst_rd_fifo <= {V{1'b0}};
end else begin
lk_dst_rd_fifo <= dst_rd_fifo;
end
end//always
pronoc_register #(.W(V)) reg2(
.in (dst_rd_fifo ),
.reset (reset ),
.clk (clk ),
.out (lk_dst_rd_fifo ));
 
assign dst_rd_fifo = reset_ivc;
assign class_rd_fifo = (C>1)? reset_ivc : {V{1'bx}};
assign ivc_request = ivc_not_empty;
791,4 → 781,4
//synthesis translate_on
 
 
endmodule
endmodule
/src_noc/mesh_torus.sv
0,0 → 1,1862
`include "pronoc_def.v"
 
/**********************************************************************
** File: mesh_torus.v
**
** Copyright (C) 2014-2017 Alireza Monemi
**
** This file is part of ProNoC
**
** ProNoC ( stands for Prototype Network-on-chip) is free software:
** you can redistribute it and/or modify it under the terms of the GNU
** Lesser General Public License as published by the Free Software Foundation,
** either version 2 of the License, or (at your option) any later version.
**
** ProNoC is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
** or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
** Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
**
**
** Description:
**
**
***************************************/
 
 
 
 
/*****************************************
 
pre-sel[xy]
y
1 | 3
|
-------x
0 | 2
|
 
*****************************************/
 
 
module mesh_torus_vc_alloc_request_gen_adaptive #(
parameter ROUTE_TYPE = "FULL_ADAPTIVE", // "FULL_ADAPTIVE", "PAR_ADAPTIVE"
parameter V = 4,
parameter DSTPw=4,
parameter SSA_EN ="NO",
parameter PPSw=4,
parameter [V-1 : 0] ESCAP_VC_MASK = 4'b1000 // mask scape vc, valid only for full adaptive
)(
ovc_avalable_all,
dest_port_coded_all,
candidate_ovc_all,
ivc_request_all,
ovc_is_assigned_all,
masked_ovc_request_all,
port_pre_sel,
swap_port_presel,
destport_clear_all,
ivc_num_getting_ovc_grant,
ssa_ivc_num_getting_ovc_grant_all,
sel,
reset,
clk
);
localparam P = 5;
localparam P_1 = P-1,
PV = V * P,
PVV = PV * V,
VP_1 = V * P_1,
PVDSTPw = PV * DSTPw;
localparam LOCAL = 3'd0,
EAST = 3'd1,
NORTH = 3'd2,
WEST = 3'd3,
SOUTH = 3'd4;
 
input [PV-1 : 0] ovc_avalable_all;
input [PVDSTPw-1 : 0] dest_port_coded_all;
input [PV-1 : 0] ivc_request_all;
input [PV-1 : 0] ovc_is_assigned_all;
output [PVV-1 : 0] masked_ovc_request_all;
input [PVV-1 : 0] candidate_ovc_all;
input [PPSw-1 : 0] port_pre_sel;
output [PV-1 : 0] swap_port_presel;
output [PV-1 : 0] sel;
output [PVDSTPw-1 : 0] destport_clear_all;
input [PV-1 : 0] ivc_num_getting_ovc_grant;
input [PV-1 : 0] ssa_ivc_num_getting_ovc_grant_all;
input reset,clk;
 
wire [PV-1 : 0] non_assigned_ovc_request_all;
wire [PV-1 : 0] y_evc_forbiden,x_evc_forbiden;
wire [V-1 : 0] ovc_avb_x_plus,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_y_minus,ovc_avb_local;
wire [VP_1-1 : 0] ovc_avalable_perport [P-1 : 0];
wire [PPSw-1 : 0] port_pre_sel_perport [P-1 : 0];
wire [PVV-1 : 0] candidate_ovc_x_all, candidate_ovc_y_all;
assign non_assigned_ovc_request_all = ivc_request_all & ~ovc_is_assigned_all;
assign {ovc_avb_y_minus,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_x_plus,ovc_avb_local} = ovc_avalable_all;
 
assign ovc_avalable_perport[LOCAL] = {ovc_avb_x_plus,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_y_minus};
assign ovc_avalable_perport[EAST] = {ovc_avb_local,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_y_minus};
assign ovc_avalable_perport[NORTH] = {ovc_avb_x_plus,ovc_avb_x_minus,ovc_avb_local,ovc_avb_y_minus};
assign ovc_avalable_perport[WEST] = {ovc_avb_x_plus,ovc_avb_local,ovc_avb_y_plus,ovc_avb_y_minus};
assign ovc_avalable_perport[SOUTH] = {ovc_avb_x_plus,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_local};
assign port_pre_sel_perport[LOCAL] = port_pre_sel;
assign port_pre_sel_perport[EAST] = {2'b00,port_pre_sel[1:0]};
assign port_pre_sel_perport[NORTH] = {1'b0,port_pre_sel[2],1'b0,port_pre_sel[0]};
assign port_pre_sel_perport[WEST] = {port_pre_sel[3:2],2'b0};
assign port_pre_sel_perport[SOUTH] = {port_pre_sel[3],1'b0,port_pre_sel[1],1'b0};
wire [PV-1 : 0] avc_unavailable;
genvar i;
generate
for(i=0;i< PV;i=i+1) begin :all_vc_loop
mesh_torus_adaptive_avb_ovc_mux #(
.V(V)
)
the_adaptive_avb_ovc_mux
(
.ovc_avalable (ovc_avalable_perport [i/V]),
.sel (sel [i]),
.candidate_ovc_x (candidate_ovc_x_all [((i+1)*V)-1 : i*V]),
.candidate_ovc_y (candidate_ovc_y_all [((i+1)*V)-1 : i*V]),
.non_assigned_ovc_request (non_assigned_ovc_request_all[i]),
.xydir (dest_port_coded_all [((i+1)*DSTPw)-1 : ((i+1)*DSTPw)-2]),
.masked_ovc_request (masked_ovc_request_all [((i+1)*V)-1 : i*V])
);
mesh_torus_port_selector #(
.SW_LOC (i/V),
.PPSw(PPSw)
)
the_portsel
(
.port_pre_sel (port_pre_sel_perport[i/V]),
.swap_port_presel (swap_port_presel[i]),
.sel (sel[i]),
.dest_port_in (dest_port_coded_all[((i+1)*DSTPw)-1 : i*DSTPw]),
.y_evc_forbiden (y_evc_forbiden[i]),
.x_evc_forbiden (x_evc_forbiden[i])
);
 
mesh_tori_dspt_clear_gen #(
.SSA_EN(SSA_EN),
.DSTPw(DSTPw),
.SW_LOC(i/V)
)
dspt_clear_gen
(
.destport_clear(destport_clear_all[((i+1)*DSTPw)-1 : i*DSTPw]),
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant[i]),
.sel(sel[i]),
.ssa_ivc_num_getting_ovc_grant(ssa_ivc_num_getting_ovc_grant_all[i])
);
/* verilator lint_off WIDTH */
if(ROUTE_TYPE == "FULL_ADAPTIVE") begin: full_adpt
/* verilator lint_on WIDTH */
assign candidate_ovc_y_all[((i+1)*V)-1 : i*V] = (y_evc_forbiden[i]) ? candidate_ovc_all[((i+1)*V)-1 : i*V] & (~ESCAP_VC_MASK) : candidate_ovc_all[((i+1)*V)-1 : i*V];
assign candidate_ovc_x_all[((i+1)*V)-1 : i*V] = (x_evc_forbiden[i]) ? candidate_ovc_all[((i+1)*V)-1 : i*V] & (~ESCAP_VC_MASK) : candidate_ovc_all[((i+1)*V)-1 : i*V];
assign avc_unavailable[i] = (masked_ovc_request_all [((i+1)*V)-1 : i*V] & ~ESCAP_VC_MASK) == {V{1'b0}};
mesh_torus_swap_port_presel_gen #(
.V(V),
.ESCAP_VC_MASK(ESCAP_VC_MASK),
.VC_NUM(i)
)
the_swap_port_presel
(
.avc_unavailable(avc_unavailable[i]),
.y_evc_forbiden(y_evc_forbiden[i]),
.x_evc_forbiden(x_evc_forbiden[i]),
.non_assigned_ovc_request(non_assigned_ovc_request_all[i]),
.sel(sel[i]),
.clk(clk),
.reset(reset),
.swap_port_presel(swap_port_presel[i])
);
end else begin : partial_adpt
assign candidate_ovc_y_all[((i+1)*V)-1 : i*V] = candidate_ovc_all [((i+1)*V)-1 : i*V];
assign candidate_ovc_x_all[((i+1)*V)-1 : i*V] = candidate_ovc_all [((i+1)*V)-1 : i*V];
assign swap_port_presel[i]=1'b0;
assign avc_unavailable[i]=1'b0;
end// ROUTE_TYPE
end//for
endgenerate
endmodule
 
 
 
module mesh_tori_dspt_clear_gen #(
parameter SSA_EN="YES",
parameter DSTPw =4,
parameter SW_LOC=0
 
)(
destport_clear,
ivc_num_getting_ovc_grant,
sel,
ssa_ivc_num_getting_ovc_grant
 
);
 
output [DSTPw-1 : 0] destport_clear;
input ivc_num_getting_ovc_grant;
input sel;
input ssa_ivc_num_getting_ovc_grant;
 
localparam
LOCAL = 3'd0,
EAST = 3'd1,
WEST = 3'd3;
 
generate
/* verilator lint_off WIDTH */
if ( SSA_EN=="YES" ) begin :predict_if
/* verilator lint_on WIDTH */
if (SW_LOC == LOCAL ) begin :local_if
assign destport_clear= (ivc_num_getting_ovc_grant)?{2'b00,sel,~sel} :{DSTPw{1'b0}};
end else if (SW_LOC == EAST || SW_LOC == WEST ) begin :xdir_if
assign destport_clear = (ivc_num_getting_ovc_grant)? {2'b00,sel,~sel} :
(ssa_ivc_num_getting_ovc_grant)? 4'b0001: //clear b
4'b0000;
end else begin : ydir_if
assign destport_clear = (ivc_num_getting_ovc_grant)? {2'b00,sel,~sel} :
(ssa_ivc_num_getting_ovc_grant)? 4'b0010: //clear a
4'b0000;
end
end else begin :nopredict_if
assign destport_clear = (ivc_num_getting_ovc_grant )? {2'b00,sel,~sel} :{DSTPw{1'b0}};
end// nopredict_if
endgenerate
endmodule
 
 
 
module mesh_torus_mask_non_assignable_destport #(
parameter TOPOLOGY="MESH",
parameter ROUTE_NAME="XY",
parameter SW_LOC=0,
parameter P=5,
parameter SELF_LOOP_EN="NO"
)
(
odd_column,// use only for odd even routing
dest_port_in,
dest_port_out
);
 
localparam P_1 = (SELF_LOOP_EN=="NO") ? P-1 : P;
input [P_1-1 : 0 ] dest_port_in;
output [P_1-1 : 0 ] dest_port_out;
input odd_column;
 
wire [P-2 : 0] dest_port_in_tmp,dest_port_out_tmp;
generate
if(SELF_LOOP_EN == "NO") begin :nslp
assign dest_port_in_tmp = dest_port_in;
assign dest_port_out = dest_port_out_tmp;
end else begin :slp
remove_sw_loc_one_hot #(
.P(P),
.SW_LOC(SW_LOC)
)
remove_sw_loc
(
.destport_in(dest_port_in),
.destport_out(dest_port_in_tmp)
);
//currently loop-back only can happen in local ports.
//Current supported routing algorithms does not results in loop-back in other ports
wire sw_loc_val = (SW_LOC>0 && SW_LOC<5) ? 1'b0 : dest_port_in [SW_LOC];
add_sw_loc_one_hot_val #(
.P(P),
.SW_LOC(SW_LOC)
)add_sw_loc
(
.sw_loc_val(sw_loc_val),
.destport_in (dest_port_out_tmp),
.destport_out(dest_port_out)
);
 
end
endgenerate
 
mesh_torus_mask_non_assignable_destport_no_self_loop # (
.TOPOLOGY(TOPOLOGY),
.ROUTE_NAME(ROUTE_NAME),
.SW_LOC(SW_LOC),
.P(P)
)
mask_no_self_loop
(
.dest_port_in(dest_port_in_tmp),
.dest_port_out(dest_port_out_tmp),
.odd_column(odd_column)
);
 
 
endmodule
 
module mesh_torus_mask_non_assignable_destport_no_self_loop #(
parameter TOPOLOGY="MESH",
parameter ROUTE_NAME="XY",
parameter SW_LOC=0,
parameter P=5
)
(
odd_column,// use only for odd even routing
dest_port_in,
dest_port_out
);
 
localparam
EAST = 1,
NORTH = 2,
WEST = 3,
SOUTH = 4;
 
//port number in north port
localparam
N_LOCAL = 0,
N_EAST = 1,
N_WEST = 2,
N_SOUTH = 3;
// port number in south port
localparam
S_LOCAL = 0,
S_EAST = 1,
S_NORTH = 2,
S_WEST = 3;
 
// port number in east port
localparam
E_LOCAL = 0,
E_NORTH = 1,
E_WEST = 2,
E_SOUTH = 3;
// port number in east port
localparam
W_LOCAL = 0,
W_EAST = 1,
W_NORTH = 2,
W_SOUTH = 3;
 
localparam P_1 = P-1;
input [P_1-1 : 0 ] dest_port_in;
output [P_1-1 : 0 ] dest_port_out;
input odd_column;
generate
if(P>5)begin :p5
assign dest_port_out[P_1-1:4] = dest_port_in[P_1-1:4]; //other local ports
end
 
 
/* verilator lint_off WIDTH */
if (TOPOLOGY == "RING" || TOPOLOGY == "LINE") begin : oneD // A port can send packets to all other ports in these topologies
/* verilator lint_on WIDTH */
assign dest_port_out = dest_port_in;
end else begin : towD
/*XY*/
/* verilator lint_off WIDTH */
if ( ROUTE_NAME == "XY" || ROUTE_NAME == "TRANC_XY") begin :xy
/* verilator lint_on WIDTH */
if (SW_LOC == NORTH ) begin : nort_p // The port located in y axsis does not send packets to x dimension
assign dest_port_out[N_LOCAL]= dest_port_in[N_LOCAL];
assign dest_port_out[N_EAST]= 1'b0; // mask east port
assign dest_port_out[N_WEST]= 1'b0; // mask west port
assign dest_port_out[N_SOUTH]= dest_port_in[N_SOUTH];
end else if ( SW_LOC == SOUTH) begin : south_p
assign dest_port_out[S_LOCAL]= dest_port_in[S_LOCAL];
assign dest_port_out[S_EAST]= 1'b0; // mask east port
assign dest_port_out[S_NORTH]= dest_port_in[S_NORTH];
assign dest_port_out[S_WEST]= 1'b0; // mask west port
end else begin : non_vertical
assign dest_port_out[3:0] = dest_port_in[3:0];
end
/*WEST-FIRST*/
/* verilator lint_off WIDTH */
end else if ( ROUTE_NAME == "WEST_FIRST" || ROUTE_NAME == "TRANC_WEST_FIRST") begin :west_first
/* verilator lint_on WIDTH */
// SW & NW are forbidden
if (SW_LOC == NORTH ) begin : nort_p // north port does not send packets to the west port.
assign dest_port_out[N_LOCAL]= dest_port_in[N_LOCAL];
assign dest_port_out[N_EAST]= dest_port_in[N_EAST];
assign dest_port_out[N_WEST]= 1'b0; // mask west port
assign dest_port_out[N_SOUTH]= dest_port_in[N_SOUTH];
end else if ( SW_LOC == SOUTH) begin : south_p // south port does not sends packet to west
assign dest_port_out[S_LOCAL]= dest_port_in[S_LOCAL];
assign dest_port_out[S_EAST]= dest_port_in[S_EAST];
assign dest_port_out[S_NORTH]= dest_port_in[S_NORTH];
assign dest_port_out[S_WEST]= 1'b0; // mask west port
end else begin : non_vertical
assign dest_port_out[3:0] = dest_port_in[3:0];
end
/*NORTH_LAST*/
/* verilator lint_off WIDTH */
end else if ( ROUTE_NAME == "NORTH_LAST" || ROUTE_NAME == "TRANC_NORTH_LAST") begin :north_last
/* verilator lint_on WIDTH */
//NE & NW are forbidden
if (SW_LOC == SOUTH ) begin : south_p // north port does not send packets to the east nor to the west port.
assign dest_port_out[S_LOCAL]= dest_port_in[S_LOCAL];
assign dest_port_out[S_EAST]= 1'b0; // mask east port
assign dest_port_out[S_WEST]= 1'b0; // mask west port
assign dest_port_out[S_NORTH]= dest_port_in[S_NORTH];
end else begin : other_p
assign dest_port_out[3:0] = dest_port_in[3:0];
end
/*NEGETIVE_FIRST*/
/* verilator lint_off WIDTH */
end else if ( ROUTE_NAME == "NEGETIVE_FIRST" || ROUTE_NAME == "TRANC_NEGETIVE_FIRST") begin :negetive_first
/* verilator lint_on WIDTH */
//ES & NW is forbiden
if (SW_LOC == SOUTH ) begin : south_p // south port does not send packets to the west port. NW is forbiden
assign dest_port_out[S_LOCAL]= dest_port_in[S_LOCAL];
assign dest_port_out[S_EAST]= dest_port_in[S_EAST];
assign dest_port_out[S_WEST]= 1'b0; // mask west port
assign dest_port_out[S_NORTH]= dest_port_in[S_NORTH];
end else if ( SW_LOC == WEST) begin : west_p // west port does not sends packet to south. ES is forbiden
assign dest_port_out[W_LOCAL]= dest_port_in[W_LOCAL];
assign dest_port_out[W_NORTH]= dest_port_in[W_NORTH];
assign dest_port_out[W_EAST] = dest_port_in[W_EAST];
assign dest_port_out[W_SOUTH]= 1'b0; //mask south port
end else begin : other_p
assign dest_port_out[3:0] = dest_port_in[3:0];
end
/*ODD_EVEN*/
/* verilator lint_off WIDTH */
end else if ( ROUTE_NAME == "ODD_EVEN" ) begin : odd_even
/* verilator lint_on WIDTH */
//Odd column : NW and SW turns are not allowed
//Even column: EN and ES turns are not allowed
if (SW_LOC == NORTH ) begin : nort_p // north port does not send packets to the west port in odd columns. SW is forbiden
assign dest_port_out[N_LOCAL]= dest_port_in[N_LOCAL];
assign dest_port_out[N_EAST]= dest_port_in[N_EAST];
assign dest_port_out[N_WEST]= (odd_column)? 1'b0: dest_port_in[N_WEST]; // mask west port in odd columns
assign dest_port_out[N_SOUTH]= dest_port_in[N_SOUTH];
end else if (SW_LOC == SOUTH) begin : south_p // south port does not sends packet to west in odd columns. NW is forbiden
assign dest_port_out[S_LOCAL]= dest_port_in[S_LOCAL];
assign dest_port_out[S_EAST]= dest_port_in[S_EAST];
assign dest_port_out[S_NORTH]= dest_port_in[S_NORTH];
assign dest_port_out[S_WEST]= (odd_column)? 1'b0: dest_port_in[S_WEST]; // mask west port in odd columns
end else if (SW_LOC == WEST) begin : west_p // WEST port does not sends packet to north and south ports in even columns
//ES & EN forbiden
assign dest_port_out[W_LOCAL]= dest_port_in[W_LOCAL];
assign dest_port_out[W_NORTH]= (odd_column)? dest_port_in[W_NORTH] : 1'b0; //mask north in even columns
assign dest_port_out[W_EAST] = dest_port_in[W_EAST];
assign dest_port_out[W_SOUTH]= (odd_column)? dest_port_in[W_SOUTH] : 1'b0; //mask south in even columns
end else begin: other_p
assign dest_port_out[3:0] = dest_port_in[3:0];
end
 
end else begin : f_adptv
assign dest_port_out[3:0] = dest_port_in[3:0];
end
end
endgenerate
endmodule
 
 
 
 
/**********************
 
swap_port_presel_gen
 
**********************/
 
module mesh_torus_swap_port_presel_gen #(
parameter V = 4,
parameter [V-1 : 0] ESCAP_VC_MASK = 4'b1000, // mask scape vc, valid only for full adaptive
parameter VC_NUM=0
 
)(
avc_unavailable,
swap_port_presel,
y_evc_forbiden,
x_evc_forbiden,
non_assigned_ovc_request,
sel,
clk,
reset
 
);
 
localparam LOCAL_VC_NUM= VC_NUM % V;
 
input avc_unavailable;
input y_evc_forbiden,x_evc_forbiden;
input non_assigned_ovc_request,sel;
input clk,reset;
output swap_port_presel;
wire swap_reg;
wire swap_port_presel_next;
 
wire evc_forbiden;
/************************
destination-port_in
x: 1 EAST, 0 WEST
y: 1 NORTH, 0 SOUTH
ab: 00 : LOCAL, 10: xdir, 01: ydir, 11 x&y dir
sel:
0: xdir
1: ydir
port_pre_sel
0: xdir
1: ydir
 
************************/
//For an EVC sender, if the use of EVC in destination port is restricted while the destination port has no available AVC,
//the port pre selection must swap
// generate
// check if it is an evc sender
// if(ESCAP_VC_MASK[LOCAL_VC_NUM]== 1'b0)begin
//its not EVC
// assign swap_port_presel=1'b0;
// end else begin // the sender is an EVC
assign evc_forbiden = (sel)? y_evc_forbiden : x_evc_forbiden;
assign swap_port_presel_next= non_assigned_ovc_request & evc_forbiden & avc_unavailable;
assign swap_port_presel = swap_reg;
pronoc_register #(.W(1)) reg2 (.in(swap_port_presel_next ), .out(swap_reg), .reset(reset), .clk(clk));
endmodule
 
 
 
 
/************************
 
adaptive_avb_ovc_mux
 
 
************************/
module mesh_torus_adaptive_avb_ovc_mux #(
parameter V= 4
)(
ovc_avalable,
sel,
candidate_ovc_x,
candidate_ovc_y,
non_assigned_ovc_request,
xydir,
masked_ovc_request
 
);
localparam P = 5;
localparam P_1 = P-1,
VP_1 = V * P_1;
input [VP_1-1 : 0] ovc_avalable;
input sel;
input [V-1 : 0] candidate_ovc_x;
input [V-1 : 0] candidate_ovc_y;
input non_assigned_ovc_request;
input [1 : 0] xydir;
output [V-1 : 0] masked_ovc_request;
wire x,y;
wire [V-1 : 0] ovc_avb_x_plus,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_y_minus;
wire [V-1 : 0] mux_out_x,mux_out_y;
wire [V-1 : 0] ovc_request_x,ovc_request_y,masked_ovc_request_x,masked_ovc_request_y;
assign {x,y}= xydir;
assign {ovc_avb_x_plus,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_y_minus}=ovc_avalable;
//first level mux
//assign mux_out_x = (x)? ovc_avb_x_plus : ovc_avb_x_minus;
//assign mux_out_y = (y)? ovc_avb_y_plus : ovc_avb_y_minus;
assign mux_out_x = (ovc_avb_x_plus &{V{x}}) | (ovc_avb_x_minus &{V{~x}});
assign mux_out_y = (ovc_avb_y_plus &{V{y}}) | (ovc_avb_y_minus &{V{~y}});
//assign ovc_request_x = (non_assigned_ovc_request)? candidate_ovc_x : {V{1'b0}};
//assign ovc_request_y = (non_assigned_ovc_request)? candidate_ovc_y : {V{1'b0}};
assign ovc_request_x = candidate_ovc_x & {V{non_assigned_ovc_request}};
assign ovc_request_y = candidate_ovc_y & {V{non_assigned_ovc_request}};
//mask unavailble ovc
assign masked_ovc_request_x = mux_out_x & ovc_request_x;
assign masked_ovc_request_y = mux_out_y & ovc_request_y;
//second mux
// assign masked_ovc_request = (sel)? masked_ovc_request_y: masked_ovc_request_x;
assign masked_ovc_request = (masked_ovc_request_y & {V{sel}})| (masked_ovc_request_x & {V{~sel}});
 
 
endmodule
 
 
 
 
 
/*****************************************************
 
port_selector
 
 
*****************************************************/
 
 
module mesh_torus_port_selector #(
parameter SW_LOC = 0,
parameter PPSw=4
)
(
port_pre_sel,
dest_port_in,
swap_port_presel,
sel,
y_evc_forbiden,
x_evc_forbiden
);
 
/************************
destination-port_in
x: 1 EAST, 0 WEST
y: 1 NORTH, 0 SOUTH
ab: 00 : LOCAL, 10: xdir, 01: ydir, 11 x&y dir
sel:
0: xdir
1: ydir
port_pre_sel
0: xdir
1: ydir
 
************************/
 
 
//input reset,clk;
input [PPSw-1:0] port_pre_sel;
// input port_pre_sel_ld;
output sel;
input [3:0] dest_port_in;
input swap_port_presel;
// output route_subfunc_violated;
output y_evc_forbiden, x_evc_forbiden;
wire x,y,a,b;
wire [PPSw-1:0] port_pre_sel_final;
//reg [3:0] port_pre_sel_delayed , port_pre_sel_latched;
// wire o1,o2;
 
localparam LOCAL = 0,
EAST = 1,
NORTH = 2,
WEST = 3,
SOUTH = 4;
 
localparam LOCAL_SEL = (SW_LOC == NORTH || SW_LOC == SOUTH )? 1'b1 : 1'b0;
assign port_pre_sel_final= (swap_port_presel)? ~port_pre_sel: port_pre_sel;
assign {x,y,a,b} = dest_port_in;
wire sel_in,sel_pre, overwrite;
wire [1:0] xy;
assign xy={x,y};
assign sel_pre= port_pre_sel_final[xy];
assign overwrite= a&b;
generate
if(LOCAL_SEL)begin :local_p
assign sel_in= b | ~a;
end else begin :nonlocal_p
assign sel_in= b ;
end
endgenerate
assign sel= (overwrite)? sel_pre : sel_in;
// check if EVC is allowed to be used
// Using of all EVCs located in y dimension are restricted when the packet can be sent into both x&y direction
assign y_evc_forbiden = a&b;
//there is no restriction in using EVCs located in x dimension
assign x_evc_forbiden = 1'b0;
//assign route_subfunc_violated = a&b;
/* verilator lint_off WIDTH */
endmodule
 
 
 
/*******************
mesh_torus_adaptive_lk_dest_encoder
********************/
 
 
 
module mesh_torus_adaptive_lk_dest_encoder #(
parameter V=4,
parameter P=5,
parameter DSTPw=P-1,
parameter Fw=37,
parameter DST_P_MSB=11,
parameter DST_P_LSB=8
 
)(
sel,
flit_in,
dest_coded_out,
vc_num_delayed,
lk_dest
);
input [V-1 : 0] sel;
output [DSTPw-1 : 0]dest_coded_out;
input [V-1 : 0] vc_num_delayed;
input [DSTPw-1 : 0] lk_dest;
input [Fw-1 : 0] flit_in;
 
wire [1 : 0] ab,xy;
wire sel_muxed;
 
onehot_mux_1D #(
.W(1),
.N(V)
)
sel_mux
(
.in(sel),
.out(sel_muxed),
.sel(vc_num_delayed)
);
//lkdestport = {lkdestport_x[1:0],lkdestport_y[1:0]};
// sel: 0: xdir 1: ydir
assign ab = (sel_muxed)? lk_dest[1:0] : lk_dest[3:2];
//if ab==00 change x and y direction
assign xy = (ab>0)? flit_in[DST_P_MSB : DST_P_LSB+2] : ~flit_in[DST_P_MSB : DST_P_LSB+2] ;
 
assign dest_coded_out={xy,ab};
 
endmodule
 
 
module mesh_torus_dtrmn_dest_encoder #(
parameter P=5,
parameter DSTPw=P-1,
parameter Fw=37,
parameter DST_P_MSB=11,
parameter DST_P_LSB=8
 
)(
flit_in,
dest_coded_out,
lk_dest
);
output [DSTPw-1 : 0]dest_coded_out;
input [DSTPw-1 : 0] lk_dest;
input [Fw-1 : 0] flit_in;
 
wire [1 : 0] ab,xy;
//lkdestport = {lkdestport_x[1:0],lkdestport_y[1:0]};
// sel: 0: xdir 1: ydir
assign ab = lk_dest[1:0];
//if ab==00 change x and y direction
assign xy = (ab>0)? flit_in[DST_P_MSB : DST_P_LSB+2] : ~flit_in[DST_P_MSB : DST_P_LSB+2] ;
 
assign dest_coded_out={xy,ab};
 
endmodule
 
/********************
 
distance_gen
********************/
 
module mesh_torus_distance_gen #(
parameter T1= 4, // number of node in x axis
parameter T2= 4, // number of node in y axis
parameter T3= 4,
parameter EAw=4,
parameter DISTw=4,
parameter TOPOLOGY = "MESH"
 
)(
src_e_addr,
dest_e_addr,
distance
);
 
function integer log2;
input integer number; begin
log2=(number <=1) ? 1: 0;
while(2**log2<number) begin
log2=log2+1;
end
end
endfunction // log2
localparam
Xw = log2(T1), // number of node in x axis
Yw = log2(T2); // number of node in y axis
localparam [Xw : 0] NX = T1;
localparam [Yw : 0] NY = T2;
input [EAw-1 : 0] src_e_addr;
input [EAw-1 : 0] dest_e_addr;
output[DISTw-1: 0]distance;
 
wire [Xw-1 : 0]src_x,dest_x;
wire [Yw-1 : 0]src_y,dest_y;
mesh_tori_endp_addr_decode #(
.TOPOLOGY(TOPOLOGY),
.T1(T1),
.T2(T2),
.T3(T3),
.EAw(EAw)
)
src_addr_decode
(
.e_addr(src_e_addr),
.ex(src_x),
.ey(src_y),
.el(),
.valid()
);
mesh_tori_endp_addr_decode #(
.TOPOLOGY(TOPOLOGY),
.T1(T1),
.T2(T2),
.T3(T3),
.EAw(EAw)
)
dest_addr_decode
(
.e_addr(dest_e_addr),
.ex(dest_x),
.ey(dest_y),
.el(),
.valid()
);
reg [Xw-1 : 0] x_offset;
reg [Yw-1 : 0] y_offset;
generate
/* verilator lint_off WIDTH */
if( TOPOLOGY == "MESH" || TOPOLOGY == "LINE") begin : oneD
/* verilator lint_on WIDTH */
always @(*) begin
x_offset = (src_x> dest_x)? src_x - dest_x : dest_x - src_x;
y_offset = (src_y> dest_y)? src_y - dest_y : dest_y - src_y;
end
end else begin : twoD //torus ring
wire tranc_x_plus,tranc_x_min,tranc_y_plus,tranc_y_min,same_x,same_y;
/* verilator lint_off WIDTH */
always @ (*) begin
x_offset= {Xw{1'b0}};
y_offset= {Yw{1'b0}};
//x_offset
if(same_x) x_offset= {Xw{1'b0}};
else if(tranc_x_plus) begin
if(dest_x > src_x) x_offset= dest_x-src_x;
else x_offset= (NX-src_x)+dest_x;
end
else if(tranc_x_min) begin
if(dest_x < src_x) x_offset= src_x-dest_x;
else x_offset= src_x+(NX-dest_x);
end
//y_offset
if(same_y) y_offset= {Yw{1'b0}};
else if(tranc_y_plus) begin
if(dest_y > src_y) y_offset= dest_y-src_y;
else y_offset= (NY-src_y)+dest_y;
end
else if(tranc_y_min) begin
if(dest_y < src_y) y_offset= src_y-dest_y;
else y_offset= src_y+(NY-dest_y);
end
end
/* verilator lint_on WIDTH */
tranc_dir #(
.NX(NX),
.NY(NY)
)
tranc_dir
(
.tranc_x_plus(tranc_x_plus),
.tranc_x_min(tranc_x_min),
.tranc_y_plus(tranc_y_plus),
.tranc_y_min(tranc_y_min),
.same_x(same_x),
.same_y(same_y),
.current_x(src_x),
.current_y(src_y),
.dest_x(dest_x),
.dest_y(dest_y)
);
end
endgenerate
/* verilator lint_off WIDTH */
assign distance = x_offset+y_offset+1'b1;
/* verilator lint_on WIDTH */
endmodule
module mesh_torus_ssa_check_destport #(
parameter ROUTE_TYPE="DETERMINISTIC",
parameter SW_LOC = 0,
parameter P=5,
parameter DEBUG_EN = 0,
parameter DSTPw = P-1,
parameter SS_PORT=0
)(
destport_encoded, //exsited packet dest port
destport_in_encoded, // incomming packet dest port
ss_port_hdr_flit,
ss_port_nonhdr_flit
//synthesis translate_off
//synopsys translate_off
,clk,
ivc_num_getting_sw_grant,
hdr_flg
//synopsys translate_on
//synthesis translate_on
);
 
input [DSTPw-1 : 0] destport_encoded, destport_in_encoded;
output ss_port_hdr_flit, ss_port_nonhdr_flit;
//synthesis translate_off
//synopsys translate_off
input clk, ivc_num_getting_sw_grant,hdr_flg;
//synopsys translate_on
//synthesis translate_on
 
//MESH, TORUS Topology p=5
localparam LOCAL = 0,
EAST = 1,
WEST = 3;
 
 
/************************
destination port is coded
destination-port_in
x: 1 EAST, 0 WEST
y: 1 NORTH, 0 SOUTH
ab: 00 : LOCAL, 10: xdir, 01: ydir, 11 x&y dir
sel:
0: xdir
1: ydir
port_pre_sel
0: xdir
1: ydir
 
************************/
wire a,b,aa,bb;
assign {a,b} = destport_in_encoded[1:0];
assign {aa,bb} = destport_encoded[1:0];
 
generate
if( SS_PORT == LOCAL) begin :local_p
assign ss_port_hdr_flit = 1'b0;
assign ss_port_nonhdr_flit = 1'b0;
end else if ((SS_PORT == EAST) || SS_PORT == WEST )begin :xdir
assign ss_port_hdr_flit = a;
assign ss_port_nonhdr_flit = aa;
end else begin :ydir
assign ss_port_hdr_flit = b;
assign ss_port_nonhdr_flit = bb;
end
 
//synthesis translate_off
//synopsys translate_off
 
if(DEBUG_EN) begin :dbg
always @(posedge clk) begin
//if(!reset)begin
if(ivc_num_getting_sw_grant & aa & bb & ~hdr_flg) begin
$display("%t: SSA ERROR: There are two output ports that a non-header flit can be sent to. %m",$time);
$finish;
end
//end
end
end //dbg
 
//synopsys translate_on
//synthesis translate_on
 
 
endgenerate
endmodule
 
 
module line_ring_ssa_check_destport #(
parameter ROUTE_TYPE="DETERMINISTIC",
parameter SW_LOC = 0,
parameter P=3,
parameter DEBUG_EN = 0,
parameter DSTPw = P-1,
parameter SS_PORT=0
)(
destport_encoded, //exsited packet dest port
destport_in_encoded, // incomming packet dest port
ss_port_hdr_flit,
ss_port_nonhdr_flit
 
);
 
input [DSTPw-1 : 0] destport_encoded, destport_in_encoded;
output ss_port_hdr_flit, ss_port_nonhdr_flit;
 
 
 
wire [P-1 : 0] dest_port_num,assigned_dest_port_num;
 
line_ring_decode_dstport cnv1(
.dstport_one_hot(dest_port_num),
.dstport_encoded(destport_in_encoded)
);
line_ring_decode_dstport cnv2(
.dstport_one_hot(assigned_dest_port_num),
.dstport_encoded(destport_encoded)
);
assign ss_port_hdr_flit = dest_port_num [SS_PORT];
assign ss_port_nonhdr_flit = assigned_dest_port_num[SS_PORT];
 
endmodule
 
 
/*
module mesh_torus_add_ss_port #(
parameter SW_LOC=1,
parameter P=5,
parameter SELF_LOOP_EN="NO"
)(
destport_in,
destport_out
);
localparam
P_1 = (SELF_LOOP_EN == "NO") ? P-1 : P,
LOCAL = 0,
EAST = 1,
NORTH = 2,
WEST = 3,
SOUTH = 4;
 
 
localparam NO_SELF_LOOP = (SELF_LOOP_EN == "NO") ? 1 : 0;
localparam SS_PORT_P5 = (SW_LOC== EAST )? WEST- NO_SELF_LOOP : // the sender port must be removed from destination port code
(SW_LOC== NORTH )? SOUTH- NO_SELF_LOOP: // the sender port must be removed from destination port code
(SW_LOC== WEST )? EAST :
NORTH ;
 
localparam SS_PORT_P3 = (SELF_LOOP_EN == "NO") ? 1 :
 
localparam SS_PORT = (P==5) ? SS_PORT_P5: SS_PORT_P3;
 
input [P_1-1 : 0] destport_in;
output reg [P_1-1 : 0] destport_out;
always @(*)begin
destport_out=destport_in;
if( SW_LOC != LOCAL ) begin
if(destport_in=={P_1{1'b0}}) destport_out[SS_PORT]= 1'b1;
end
end
 
endmodule
*/
 
/**************
*
* ************/
module mesh_tori_router_addr_decode #(
parameter TOPOLOGY = "MESH",
parameter T1=4,
parameter T2=4,
parameter T3=4,
parameter RAw=6
)(
r_addr,
rx,
ry,
valid
);
 
function integer log2;
input integer number; begin
log2=(number <=1) ? 1: 0;
while(2**log2<number) begin
log2=log2+1;
end
end
endfunction // log2
 
localparam
NX = T1,
NY = T2,
RXw = log2(NX), // number of node in x axis
RYw = log2(NY); // number of node in y axis
/* verilator lint_off WIDTH */
localparam [RXw-1 : 0] MAXX = (NX-1);
localparam [RYw-1 : 0] MAXY = (NY-1);
/* verilator lint_on WIDTH */
input [RAw-1 : 0] r_addr;
output [RXw-1 : 0] rx;
output [RYw-1 : 0] ry;
output valid;
generate
if ((TOPOLOGY == "RING") || (TOPOLOGY == "LINE")) begin :oneD
assign rx = r_addr;
assign ry = 1'b0;
end else begin : twoD
assign {ry,rx} = r_addr;
end
endgenerate
/* verilator lint_off CMPCONST */
assign valid = (rx<= MAXX ) & (ry <= MAXY);
/* verilator lint_on CMPCONST */
endmodule
 
module mesh_tori_endp_addr_decode #(
parameter TOPOLOGY = "MESH",
parameter T1=4,
parameter T2=4,
parameter T3=4,
parameter EAw=9
)(
e_addr,
ex,
ey,
el,
valid
);
 
function integer log2;
input integer number; begin
log2=(number <=1) ? 1: 0;
while(2**log2<number) begin
log2=log2+1;
end
end
endfunction // log2
 
localparam
NX = T1,
NY = T2,
NL = T3,
EXw = log2(NX), // number of node in x axis
EYw = log2(NY),
ELw = log2(NL); // number of node in y axis
/* verilator lint_off WIDTH */
localparam [EXw-1 : 0] MAXX = (NX-1);
localparam [EYw-1 : 0] MAXY = (NY-1);
localparam [ELw-1 : 0] MAXL = (NL-1);
/* verilator lint_on WIDTH */
input [EAw-1 : 0] e_addr;
output [EXw-1 : 0] ex;
output [EYw-1 : 0] ey;
output [ELw-1 : 0] el;
output valid;
generate
if ((TOPOLOGY == "RING") || (TOPOLOGY == "LINE")) begin :oneD
if(NL==1)begin:one_local
assign ex = e_addr;
assign ey = 1'b0;
assign el = 1'b0;
/* verilator lint_off CMPCONST */
assign valid = ex<= MAXX;
/* verilator lint_on CMPCONST */
end else begin: multi_local
assign {el,ex} = e_addr;
assign ey = 1'b0;
/* verilator lint_off CMPCONST */
assign valid = ((ex<= MAXX) & (el<=MAXL));
/* verilator lint_on CMPCONST */
end
end else begin : twoD
if(NL==1)begin:one_local
assign {ey,ex} = e_addr;
assign el = 1'b0;
/* verilator lint_off CMPCONST */
assign valid = (ex<= MAXX) & (ey <= MAXY);
/* verilator lint_on CMPCONST */
end else begin :multi_l
assign {el,ey,ex} = e_addr;
/* verilator lint_off CMPCONST */
assign valid = ( (ex<= MAXX) & (ey <= MAXY) & (el<=MAXL) );
/* verilator lint_on CMPCONST */
end
end
endgenerate
endmodule
 
 
/**************
mesh_tori_addr_encoder
most probably it is only needed for simulation purposes
***************/
 
module mesh_tori_addr_encoder #(
parameter NX=2,
parameter NY=2,
parameter NL=2,
parameter NE=16,
parameter EAw=4,
parameter TOPOLOGY="MESH"
)(
id,
code
);
function integer log2;
input integer number; begin
log2=(number <=1) ? 1: 0;
while(2**log2<number) begin
log2=log2+1;
end
end
endfunction // log2
function integer addrencode;
input integer in,nx,nxw,nl,nyw;
integer y, x, l;begin
addrencode=0;
y = ((in/nl) / nx );
x = ((in/nl) % nx );
l = (in % nl);
addrencode =(nl==1)? (y<<nxw | x) : (l<<(nxw+nyw)| (y<<nxw) | x);
end
endfunction // addrencode
localparam
NXw= log2(NX),
NYw= log2(NY),
NEw = log2(NE);
 
 
input [NEw-1 :0] id;
output [EAw-1 : 0] code;
 
wire [EAw-1 : 0 ] codes [NE-1 : 0];
genvar i;
generate
for(i=0; i< NE; i=i+1) begin : endpoints
//Endpoint decoded address
/* verilator lint_off WIDTH */
localparam [EAw-1 : 0] ENDP= addrencode(i,NX,NXw,NL,NYw);
/* verilator lint_on WIDTH */
assign codes[i] = ENDP;
end
endgenerate
 
assign code = codes[id];
endmodule
 
 
module mesh_tori_addr_coder #(
parameter NX=2,
parameter NY=2,
parameter NL=2,
parameter NE=16,
parameter EAw=4
)(
id,
code
);
function integer log2;
input integer number; begin
log2=(number <=1) ? 1: 0;
while(2**log2<number) begin
log2=log2+1;
end
end
endfunction // log2
function integer addrencode;
input integer in,nx,nxw,nl,nyw;
integer y, x, l;begin
addrencode=0;
y = ((in/nl) / nx );
x = ((in/nl) % nx );
l = (in % nl);
addrencode =(nl==1)? (y<<nxw | x) : (l<<(nxw+nyw)| (y<<nxw) | x);
end
endfunction // addrencode
localparam
NXw= log2(NX),
NYw= log2(NY),
NEw = log2(NE);
 
 
output [NEw-1 :0] id;
input [EAw-1 : 0] code;
 
wire [NEw-1 : 0] codes [(2**EAw)-1 : 0 ];
genvar i;
generate
for(i=0; i< NE; i=i+1) begin : endpoints
//Endpoint decoded address
/* verilator lint_off WIDTH */
localparam [EAw-1 : 0] ENDP= addrencode(i,NX,NXw,NL,NYw);
/* verilator lint_on WIDTH */
assign codes[ENDP] = i;
end
endgenerate
 
assign id = codes[code];
endmodule
 
 
 
module mesh_torus_destp_generator #(
parameter TOPOLOGY = "MESH",
parameter ROUTE_NAME = "XY",
parameter ROUTE_TYPE = "DETERMINISTIC",
parameter P=5,
parameter DSTPw=4,
parameter NL=1,
parameter PLw=1,
parameter PPSw=4,
parameter SW_LOC=0,
parameter SELF_LOOP_EN="NO"
)(
dest_port_out,
dest_port_coded,
endp_localp_num,
swap_port_presel,
port_pre_sel,
odd_column
);
localparam P_1 = ( SELF_LOOP_EN=="NO")? P-1 : P;
input [DSTPw-1 : 0] dest_port_coded;
input [PLw-1 : 0] endp_localp_num;
output [P_1-1 : 0] dest_port_out;
input swap_port_presel;
input [PPSw-1 : 0] port_pre_sel;
input odd_column;
wire [P_1-1 : 0] dest_port_in;
generate
/* verilator lint_off WIDTH */
if (TOPOLOGY == "RING" || TOPOLOGY == "LINE" ) begin : one_D
/* verilator lint_on WIDTH */
line_ring_destp_decoder #(
.ROUTE_TYPE(ROUTE_TYPE),
.P(P),
.DSTPw(DSTPw),
.NL(NL),
.ELw(PLw),
.PPSw(PPSw),
.SW_LOC(SW_LOC),
.SELF_LOOP_EN(SELF_LOOP_EN)
)
decoder
(
.dest_port_coded(dest_port_coded),
.dest_port_out(dest_port_in),
.endp_localp_num(endp_localp_num)
);
end else begin :two_D
mesh_torus_destp_decoder #(
.ROUTE_TYPE(ROUTE_TYPE),
.P(P),
.DSTPw(DSTPw),
.NL(NL),
.ELw(PLw),
.PPSw(PPSw),
.SW_LOC(SW_LOC),
.SELF_LOOP_EN(SELF_LOOP_EN)
)
decoder
(
.dest_port_coded(dest_port_coded),
.dest_port_out(dest_port_in),
.endp_localp_num(endp_localp_num),
.swap_port_presel(swap_port_presel),
.port_pre_sel(port_pre_sel)
);
end
endgenerate
mesh_torus_mask_non_assignable_destport #(
.TOPOLOGY(TOPOLOGY),
.ROUTE_NAME(ROUTE_NAME),
.SW_LOC(SW_LOC),
.P(P),
.SELF_LOOP_EN(SELF_LOOP_EN)
)
mask_destport
(
.dest_port_in(dest_port_in),
.dest_port_out(dest_port_out),
.odd_column(odd_column)
);
 
endmodule
 
module mesh_torus_destp_decoder #(
parameter ROUTE_TYPE="DETERMINISTIC",
parameter P=6,
parameter DSTPw=4,
parameter NL=2,
parameter ELw=1,
parameter PPSw=4,
parameter SW_LOC=0,
parameter SELF_LOOP_EN="NO"
)(
dest_port_coded,
endp_localp_num,
dest_port_out,
swap_port_presel,
port_pre_sel
);
localparam P_1 = ( SELF_LOOP_EN=="NO")? P-1 : P;
input [DSTPw-1 : 0] dest_port_coded;
input [ELw-1 : 0] endp_localp_num;
output [P_1-1 : 0] dest_port_out;
input swap_port_presel;
input [PPSw-1 : 0] port_pre_sel;
wire [NL-1 : 0] endp_localp_onehot;
reg [4:0] portout;
generate
if( ROUTE_TYPE == "DETERMINISTIC") begin :dtrmn
wire x,y,a,b;
assign {x,y,a,b} = dest_port_coded;
always @(*)begin
case({a,b})
2'b10 : portout = {1'b0,~x,1'b0,x,1'b0};
2'b01 : portout = {~y,1'b0,y,1'b0,1'b0};
2'b00 : portout = 5'b00001;
2'b11 : portout = {~y,1'b0,y,1'b0,1'b0}; //invalid condition in determinstic routing
endcase
end //always
end else begin : adpv
wire x,y,a,b;
assign {x,y,a,b} = dest_port_coded;
wire [PPSw-1:0] port_pre_sel_final;
assign port_pre_sel_final= (swap_port_presel)? ~port_pre_sel: port_pre_sel;
always @(*)begin
case({a,b})
2'b10 : portout = {1'b0,~x,1'b0,x,1'b0};
2'b01 : portout = {~y,1'b0,y,1'b0,1'b0};
2'b11 : portout = (port_pre_sel_final[{x,y}])? {~y,1'b0,y,1'b0,1'b0} : {1'b0,~x,1'b0,x,1'b0};
2'b00 : portout = 5'b00001;
endcase
end //always
end
if(NL==1) begin :slp
if(SELF_LOOP_EN == "NO") begin :nslp
remove_sw_loc_one_hot #(
.P(5),
.SW_LOC(SW_LOC)
)
conv
(
.destport_in(portout),
.destport_out(dest_port_out)
);
end else begin : slp
assign dest_port_out = portout;
end
end else begin :mlp
 
wire [P-1 : 0] destport_onehot;
bin_to_one_hot #(
.BIN_WIDTH(ELw),
.ONE_HOT_WIDTH(NL)
)
conv
(
.bin_code(endp_localp_num),
.one_hot_code(endp_localp_onehot)
);
assign destport_onehot =(portout[0])? { endp_localp_onehot[NL-1 : 1] ,{(P-NL){1'b0}},endp_localp_onehot[0]}: /*select local destination*/
{ {(NL-1){1'b0}} ,portout};
if(SELF_LOOP_EN == "NO") begin :nslp
remove_sw_loc_one_hot #(
.P(P),
.SW_LOC(SW_LOC)
)
remove_sw_loc
(
.destport_in(destport_onehot),
.destport_out(dest_port_out)
);
end else begin: slp
assign dest_port_out = destport_onehot;
end
end
endgenerate
endmodule
 
 
/**************************
* line_ring_destp_decoder
* ************************/
 
module line_ring_destp_decoder #(
parameter ROUTE_TYPE="DETERMINISTIC",
parameter P=4,
parameter DSTPw=2,
parameter NL=2,
parameter ELw=1,
parameter PPSw=4,
parameter SW_LOC=0,
parameter SELF_LOOP_EN= "NO"
)(
dest_port_coded,
endp_localp_num,
dest_port_out
);
localparam P_1 = (SELF_LOOP_EN == "NO")? P-1 : P;
input [DSTPw-1 : 0] dest_port_coded;
input [ELw-1 : 0] endp_localp_num;
output [P_1-1 : 0] dest_port_out;
wire [NL-1 : 0] endp_localp_onehot;
wire [2:0] portout;
line_ring_decode_dstport decoder(
.dstport_one_hot(portout),
.dstport_encoded(dest_port_coded)
);
generate
if(NL==1) begin :slp
if(SELF_LOOP_EN == "NO") begin :nslp
remove_sw_loc_one_hot #(
.P(3),
.SW_LOC(SW_LOC)
)
conv
(
.destport_in(portout),
.destport_out(dest_port_out)
);
end else begin : slp
assign dest_port_out = portout;
end
end else begin :mlp
 
wire [P-1 : 0] destport_onehot;
bin_to_one_hot #(
.BIN_WIDTH(ELw),
.ONE_HOT_WIDTH(NL)
)
conv
(
.bin_code(endp_localp_num),
.one_hot_code(endp_localp_onehot)
);
assign destport_onehot =(portout[0])? { endp_localp_onehot[NL-1 : 1] ,{(P-NL){1'b0}},endp_localp_onehot[0]}: /*select local destination*/
{ {(NL-1){1'b0}} ,portout};
if(SELF_LOOP_EN == "NO") begin :nslp
remove_sw_loc_one_hot #(
.P(P),
.SW_LOC(SW_LOC)
)
remove_sw_loc
(
.destport_in(destport_onehot),
.destport_out(dest_port_out)
);
end else begin :slp
assign dest_port_out = destport_onehot;
end
end
endgenerate
endmodule
 
 
 
 
/*****************
* mesh_torus_dynamic_portsel_control
*****************/
 
 
module mesh_torus_dynamic_portsel_control #(
parameter P = 5,
parameter ROUTE_TYPE = "FULL_ADAPTIVE", // "FULL_ADAPTIVE", "PAR_ADAPTIVE"
parameter V = 4,
parameter DSTPw=4,
parameter SSA_EN ="NO",
parameter PPSw=4,
parameter [V-1 : 0] ESCAP_VC_MASK = 4'b1000 // mask scape vc, valid only for full adaptive
)(
dest_port_coded_all,
ivc_request_all,
ovc_is_assigned_all,
port_pre_sel,
swap_port_presel,
destport_clear_all,
ivc_num_getting_ovc_grant,
ssa_ivc_num_getting_ovc_grant_all,
masked_ovc_request_all,
sel,
reset,
clk
);
localparam
PV = V * P,
PVV= PV * V,
PVDSTPw = PV * DSTPw;
localparam LOCAL = 0,
EAST = 1,
NORTH = 2,
WEST = 3,
SOUTH = 4;
 
input [PVDSTPw-1 : 0] dest_port_coded_all;
input [PV-1 : 0] ivc_request_all;
input [PV-1 : 0] ovc_is_assigned_all;
input [PVV-1 : 0] masked_ovc_request_all;
input [PPSw-1 : 0] port_pre_sel;
output [PV-1 : 0] swap_port_presel;
output [PV-1 : 0] sel;
output [PVDSTPw-1 : 0] destport_clear_all;
input [PV-1 : 0] ivc_num_getting_ovc_grant;
input [PV-1 : 0] ssa_ivc_num_getting_ovc_grant_all;
input reset,clk;
 
wire [PV-1 : 0] non_assigned_ovc_request_all;
wire [PV-1 : 0] y_evc_forbiden,x_evc_forbiden;
wire [PPSw-1 : 0] port_pre_sel_perport [P-1 : 0];
assign non_assigned_ovc_request_all = ivc_request_all & ~ovc_is_assigned_all;
assign port_pre_sel_perport[LOCAL] = port_pre_sel;
assign port_pre_sel_perport[EAST] = {2'b00,port_pre_sel[1:0]};
assign port_pre_sel_perport[NORTH] = {1'b0,port_pre_sel[2],1'b0,port_pre_sel[0]};
assign port_pre_sel_perport[WEST] = {port_pre_sel[3:2],2'b0};
assign port_pre_sel_perport[SOUTH] = {port_pre_sel[3],1'b0,port_pre_sel[1],1'b0};
wire [PV-1 : 0] avc_unavailable;
genvar i;
generate
for(i=0;i< PV;i=i+1) begin :all_vc_loop
localparam SW_LOC = ((i/V)<5)? i/V : LOCAL;
mesh_torus_port_selector #(
.SW_LOC (SW_LOC),
.PPSw(PPSw)
)
the_portsel
(
.port_pre_sel (port_pre_sel_perport[SW_LOC]),
.swap_port_presel (swap_port_presel[i]),
.sel (sel[i]),
.dest_port_in (dest_port_coded_all[((i+1)*DSTPw)-1 : i*DSTPw]),
.y_evc_forbiden (y_evc_forbiden[i]),
.x_evc_forbiden (x_evc_forbiden[i])
);
 
mesh_tori_dspt_clear_gen #(
.SSA_EN(SSA_EN),
.DSTPw(DSTPw),
.SW_LOC(SW_LOC)
)
dspt_clear_gen
(
.destport_clear(destport_clear_all[((i+1)*DSTPw)-1 : i*DSTPw]),
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant[i]),
.sel(sel[i]),
.ssa_ivc_num_getting_ovc_grant(ssa_ivc_num_getting_ovc_grant_all[i])
);
/* verilator lint_off WIDTH */
if(ROUTE_TYPE == "FULL_ADAPTIVE") begin: full_adpt
/* verilator lint_on WIDTH */
assign avc_unavailable[i] = (masked_ovc_request_all [((i+1)*V)-1 : i*V] & ~ESCAP_VC_MASK) == {V{1'b0}};
mesh_torus_swap_port_presel_gen #(
.V(V),
.ESCAP_VC_MASK(ESCAP_VC_MASK),
.VC_NUM(i)
)
the_swap_port_presel
(
.avc_unavailable(avc_unavailable[i]),
.y_evc_forbiden(y_evc_forbiden[i]),
.x_evc_forbiden(x_evc_forbiden[i]),
.non_assigned_ovc_request(non_assigned_ovc_request_all[i]),
.sel(sel[i]),
.clk(clk),
.reset(reset),
.swap_port_presel(swap_port_presel[i])
);
end else begin : partial_adpt
assign swap_port_presel[i]=1'b0;
assign avc_unavailable[i]=1'b0;
end// ROUTE_TYPE
end//for
endgenerate
endmodule
 
 
 
 
 
src_noc/mesh_torus.sv Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: src_noc/mesh_torus_noc_top.sv =================================================================== --- src_noc/mesh_torus_noc_top.sv (revision 50) +++ src_noc/mesh_torus_noc_top.sv (revision 54) @@ -1,6 +1,4 @@ -// synthesis translate_off -`timescale 1ns / 1ps -// synthesis translate_on +`include "pronoc_def.v" /********************************************************************** ** File: mesh_torus_noc.v @@ -42,15 +40,20 @@ reset, clk, chan_in_all, - chan_out_all + chan_out_all, + router_event ); + input clk,reset; - //local ports + //Endpoints ports input smartflit_chanel_t chan_in_all [NE-1 : 0]; output smartflit_chanel_t chan_out_all [NE-1 : 0]; + //Events + output router_event_t router_event [NR-1 : 0][MAX_P-1 : 0]; + //all routers port smartflit_chanel_t router_chan_in [NR-1 :0][MAX_P-1 : 0]; smartflit_chanel_t router_chan_out [NR-1 :0][MAX_P-1 : 0]; @@ -82,9 +85,11 @@ router_top #( .P (MAX_P ) ) the_router ( + .current_r_id (x), .current_r_addr (current_r_addr [x]), .chan_in (router_chan_in [x]), .chan_out (router_chan_out[x]), + .router_event (router_event[x]), .clk (clk ), .reset (reset )); @@ -126,15 +131,17 @@ for (y=0; y
/src_noc/mesh_torus_routting.v
50,9 → 50,9
output [P_1-1 : 0] lkdestport_encoded;
input reset,clk;
reg [Xw-1 : 0] destx_delayed;
reg [Yw-1 : 0] desty_delayed;
reg [P_1-1 : 0] destport_delayed;
wire [Xw-1 : 0] destx_delayed;
wire [Yw-1 : 0] desty_delayed;
wire [P_1-1 : 0] destport_delayed;
// routing algorithm
100,22 → 100,9
end
endgenerate
 
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset)begin
destx_delayed <= {Xw{1'b0}};
desty_delayed <= {Yw{1'b0}};
destport_delayed <= {P_1{1'b0}};
end else begin
destx_delayed <= dest_x;
desty_delayed <= dest_y;
destport_delayed <= destport_encoded;
end//else reset
end//always
pronoc_register #(.W(Xw) ) reg1 (.in(dest_x ), .out(destx_delayed), .reset(reset), .clk(clk));
pronoc_register #(.W(Yw) ) reg2 (.in(dest_y ), .out(desty_delayed), .reset(reset), .clk(clk));
pronoc_register #(.W(P_1)) reg3 (.in(destport_encoded ), .out(destport_delayed), .reset(reset), .clk(clk));
endmodule
 
/src_noc/multicast.sv
0,0 → 1,810
`include "pronoc_def.v"
 
/**************************************
* Module: router_bypass
* Date:2021-11-14
* Author: alireza
*
* Description:
* This file contains HDL modules that can be added
* to NoC router to provide multicasting
***************************************/
 
 
 
 
/************************************
 
look_ahead_routing
 
*************************************/
module multicast_routing
import pronoc_pkg::*;
#(
parameter P = 5,
parameter SW_LOC = 0
)
(
current_r_addr, //current router address
dest_e_addr, // destination endpoint address
destport
);
input [RAw-1 : 0] current_r_addr;
input [DAw-1 : 0] dest_e_addr;
output [DSTPw-1 : 0] destport;
generate
/* verilator lint_off WIDTH */
if(TOPOLOGY=="MESH") begin: mesh
/* verilator lint_on WIDTH */
multicast_routing_mesh
#(
.P(P) ,
.SW_LOC(SW_LOC)
)
routing
(
.current_r_addr(current_r_addr), //current router address
.dest_e_addr(dest_e_addr), // destination endpoint address
.destport(destport)
);
/* verilator lint_off WIDTH */
end else if (TOPOLOGY == "FMESH") begin : fmesh
/* verilator lint_on WIDTH */
multicast_routing_fmesh
#(
.P(P) ,
.SW_LOC(SW_LOC)
)
routing
(
.current_r_addr(current_r_addr), //current router address
.dest_e_addr(dest_e_addr), // destination endpoint address
.destport(destport)
);
end else begin
initial begin
$display ("ERROR: Multicast/Broadcast is not yet supported for %s Topology",TOPOLOGY);
$finish;
end
end
endgenerate
endmodule
 
module multicast_routing_mesh
import pronoc_pkg::*;
#(
parameter P = 5,
parameter SW_LOC = 0
)
(
current_r_addr, //current router address
dest_e_addr, // destination endpoint address
destport
);
input [RAw-1 : 0] current_r_addr;
input [DAw-1 : 0] dest_e_addr;
output [DSTPw-1 : 0] destport;
 
localparam
NX = T1,
NY = T2,
RXw = log2(NX),
RYw = log2(NY),
EXw = RXw,
EYw = RYw;
//mask gen. x_plus: all rows larger than current router x address are asserted.
wire [NX-1 : 0] x_plus,x_minus;
//mask generation. Only the corresponding bits to destination located in current column are asserted in each mask
wire [NE-1 : 0] y_plus,y_min;
//Only one-bit is asserted for each local_p[i]
wire [NE-1 : 0] local_p [NL-1 : 0];
wire [RXw-1 : 0] current_rx;
wire [RYw-1 : 0] current_ry;
mesh_tori_router_addr_decode #(
.TOPOLOGY(TOPOLOGY),
.T1(T1),
.T2(T2),
.T3(T3),
.RAw(RAw)
)
router_addr_decode
(
.r_addr(current_r_addr),
.rx(current_rx),
.ry(current_ry),
.valid( )
);
wire [NX-1 : 0] row_has_any_dest;
wire [NE-1 : 0] dest_mcast_all_endp;
mcast_dest_list_decode decode (
.dest_e_addr(dest_e_addr),
.dest_o(dest_mcast_all_endp),
.row_has_any_dest(row_has_any_dest),
.is_unicast()
);
genvar i,j;
generate
for(i=0; i< NX; i=i+1) begin : X_
assign x_plus[i] = (current_rx > i);
/* verilator lint_off UNSIGNED */
assign x_minus[i] = (current_rx < i);
/* verilator lint_on UNSIGNED */
end
//get all endp addresses located in the same x
for(i=0; i< NE; i=i+1) begin : endpoints
//Endpoint decoded address
localparam
Y_LOC = ((i/NL) / NX ),
X_LOC = ((i/NL) % NX ),
LL = (i % NL);
localparam [RYw-1 : 0] YY = Y_LOC [RYw-1 : 0];
localparam [RXw-1 : 0] XX = X_LOC [RXw-1 : 0];
/* verilator lint_off CMPCONST */
assign y_plus[i] = (current_rx == XX) && (current_ry > YY);
/* verilator lint_on CMPCONST */
/* verilator lint_off UNSIGNED */
assign y_min[i] = (current_rx == XX) && (current_ry < YY);
/* verilator lint_on UNSIGNED */
for(j=0;j<NL;j++)begin : lp
assign local_p[j][i] = (current_rx == XX) && (current_ry == YY) && (LL == j);
end
end //i
wire goto_north = |(y_plus & dest_mcast_all_endp);
wire goto_south = |(y_min & dest_mcast_all_endp);
wire goto_east = |(x_minus & row_has_any_dest);
wire goto_west = |(x_plus & row_has_any_dest);
wire [NL-1 : 0] goto_local;
for(i=0; i< NL; i=i+1) begin : endps
assign goto_local[i] = |(local_p[i] & dest_mcast_all_endp);// will be synthesized as single bit assign
end//for
reg [4 : 0] destport_tmp;
always @(*) begin
destport_tmp = {5{1'b0}};
destport_tmp[LOCAL]=goto_local[LOCAL];
if (SW_LOC == SOUTH) destport_tmp [NORTH] = goto_north;
else if(SW_LOC == NORTH) destport_tmp [SOUTH] = goto_south;
else if(SW_LOC == WEST)begin
destport_tmp [NORTH] = goto_north;
destport_tmp [SOUTH] = goto_south;
destport_tmp [EAST ] = goto_east;
end
else if(SW_LOC == EAST) begin
destport_tmp [NORTH] = goto_north;
destport_tmp [SOUTH] = goto_south;
destport_tmp [WEST ] = goto_west;
end
else if(SW_LOC == LOCAL || SW_LOC > SOUTH) begin
destport_tmp [NORTH] = goto_north;
destport_tmp [SOUTH] = goto_south;
destport_tmp [EAST] = goto_east;
destport_tmp [WEST] = goto_west;
end
end
localparam MSB_DSTP = (DSTPw-1 < SOUTH)? DSTPw-1: SOUTH;
assign destport [MSB_DSTP : 0] =destport_tmp;
for(i=1;i<NL;i++) begin :other_local
assign destport[MSB_DSTP+i]=goto_local[i];
end
endgenerate
endmodule
 
 
 
 
 
 
module multicast_routing_fmesh
import pronoc_pkg::*;
#(
parameter P = 5,
parameter SW_LOC = 0
)
(
current_r_addr, //current router address
dest_e_addr, // destination endpoint address
destport
);
input [RAw-1 : 0] current_r_addr;
input [DAw-1 : 0] dest_e_addr;
output [DSTPw-1 : 0] destport;
 
localparam Pw = log2(MAX_P_FMESH);
localparam
NX = T1,
NY = T2,
RXw = log2(NX),
RYw = log2(NY),
EXw = RXw,
EYw = RYw;
wire [RXw-1 : 0] current_rx;
wire [RYw-1 : 0] current_ry;
//mask gen. x_plus: all rows larger than current router x address are asserted.
wire [NX-1 : 0] x_plus,x_minus;
//mask generation. Only the corresponding bits to destination located in current column are asserted in each mask
wire [NE-1 : 0] y_plus,y_min;
//Only one-bit is asserted for each local_p[i]
wire [NE-1 : 0] local_p [MAX_P_FMESH-1 : 0];
mesh_tori_router_addr_decode #(
.TOPOLOGY(TOPOLOGY),
.T1(T1),
.T2(T2),
.T3(T3),
.RAw(RAw)
)
router_addr_decode
(
.r_addr(current_r_addr),
.rx(current_rx),
.ry(current_ry),
.valid( )
);
wire [NX-1 : 0] row_has_any_dest;
wire [NE-1 : 0] dest_mcast_all_endp;
mcast_dest_list_decode decode (
.dest_e_addr(dest_e_addr),
.dest_o(dest_mcast_all_endp),
.row_has_any_dest(row_has_any_dest),
.is_unicast()
);
genvar i,j;
generate
for(i=0; i< NX; i=i+1) begin : X_
assign x_plus[i] = (current_rx > i);
/* verilator lint_off UNSIGNED */
assign x_minus[i] = (current_rx < i);
/* verilator lint_on UNSIGNED */
end
//get all endp addresses located in the same x
for(i=0; i< NE; i=i+1) begin : endpoints
//Endpoint decoded address
localparam
ADR = fmesh_addrencode(i),
XX = ADR [NXw -1 : 0],
YY = ADR [NXw+NYw-1 : NXw],
PP = ADR [NXw+NYw+Pw-1 : NXw+NYw];
/* verilator lint_off CMPCONST */
assign y_plus[i] = (current_rx == XX) && (current_ry > YY);
/* verilator lint_on CMPCONST */
/* verilator lint_off UNSIGNED */
assign y_min[i] = (current_rx == XX) && (current_ry < YY);
/* verilator lint_on UNSIGNED */
for(j=0;j<MAX_P_FMESH;j++)begin : lp
assign local_p[j][i] = (current_rx == XX) && (current_ry == YY) && (PP == j);
end
end//for ne
wire [MAX_P_FMESH-1 : 0] goto_local;
for(i=0; i<MAX_P_FMESH ; i=i+1) begin : endps
assign goto_local[i] = |(local_p[i] & dest_mcast_all_endp);// will be synthesized as single bit assign
end//for
wire goto_north = (|(y_plus & dest_mcast_all_endp)) | goto_local[NORTH];
wire goto_south = (|(y_min & dest_mcast_all_endp)) | goto_local[SOUTH];
wire goto_east = (|(x_minus & row_has_any_dest)) | goto_local[EAST];
wire goto_west = (|(x_plus & row_has_any_dest)) | goto_local[WEST];
reg [4 : 0] destport_tmp;
always @(*) begin
destport_tmp = {DSTPw{1'b0}};
destport_tmp[LOCAL]=goto_local[LOCAL];
if (SW_LOC == SOUTH)begin
destport_tmp [NORTH] = goto_north ;
destport_tmp [EAST] = goto_east;
destport_tmp [WEST] = goto_west;
end
else if(SW_LOC == NORTH) begin
destport_tmp [SOUTH] = goto_south ;
destport_tmp [EAST] = goto_east;
destport_tmp [WEST] = goto_west;
end
else if(SW_LOC == WEST)begin
destport_tmp [NORTH] = goto_north ;
destport_tmp [SOUTH] = goto_south;
destport_tmp [EAST ] = goto_east;
end
else if(SW_LOC == EAST) begin
destport_tmp [NORTH] = goto_north;
destport_tmp [SOUTH] = goto_south;
destport_tmp [WEST ] = goto_west;
end
else if(SW_LOC == LOCAL || SW_LOC > SOUTH) begin
destport_tmp [NORTH] = goto_north;
destport_tmp [SOUTH] = goto_south;
destport_tmp [EAST] = goto_east;
destport_tmp [WEST] = goto_west;
end
end
localparam MSB_DSTP = (DSTPw-1 < SOUTH)? DSTPw-1: SOUTH;
assign destport [MSB_DSTP : 0] =destport_tmp;
for(i=1;i<NL;i++) begin :other_local
assign destport[MSB_DSTP+i]=goto_local[i];
end
endgenerate
endmodule
 
 
module mcast_dest_list_decode
import pronoc_pkg::*;
(
dest_e_addr,
dest_o,
row_has_any_dest,
is_unicast
);
input [DAw-1 :0] dest_e_addr;
output [NE-1 : 0] dest_o;
output [NX-1 : 0] row_has_any_dest;
output is_unicast;
wire [MCASTw-1 : 0] mcast_dst_coded;
assign {row_has_any_dest,mcast_dst_coded}=dest_e_addr;
genvar i;
generate
/* verilator lint_off WIDTH */
if(CAST_TYPE == "MULTICAST_FULL") begin : full
/* verilator lint_on WIDTH */
assign dest_o = mcast_dst_coded;
assign is_unicast = 1'b0;
/* verilator lint_off WIDTH */
end else if (CAST_TYPE == "MULTICAST_PARTIAL") begin : partial
/* verilator lint_on WIDTH */
wire not_in_cast_list ;
wire [EAw-1 : 0] unicast_code;
assign {unicast_code,not_in_cast_list} = mcast_dst_coded [EAw : 0];
wire [NE-1 : 0] dest_o_multi;
reg [NE-1 : 0] dest_o_uni;
wire [NEw-1 : 0] unicast_id;
assign is_unicast = not_in_cast_list;
endp_addr_decoder #(
.TOPOLOGY (TOPOLOGY),
.T1(T1),
.T2(T2),
.T3(T3),
.EAw(EAw),
.NE(NE)
)
decoder
(
.code(unicast_code),
.id(unicast_id)
);
always @(*)begin
dest_o_uni = {NE{1'b0}};
dest_o_uni[unicast_id]=1'b1;
end
for(i=0; i< NE; i=i+1) begin : endpoints
localparam MCAST_ID = endp_id_to_mcast_id(i);
assign dest_o_multi [i] = (MCAST_ENDP_LIST[i]==1'b1)? mcast_dst_coded[MCAST_ID+1] : 1'b0;
end
assign dest_o = (not_in_cast_list)? dest_o_uni : dest_o_multi;
/* verilator lint_off WIDTH */
end else if (CAST_TYPE == "BROADCAST_FULL") begin : bcast_full
/* verilator lint_on WIDTH */
wire not_broad_casted;
wire [EAw-1 : 0] unicast_code;
assign {unicast_code,not_broad_casted} = mcast_dst_coded;
assign is_unicast =not_broad_casted;
wire [NE-1 : 0] dest_o_multi;
reg [NE-1 : 0] dest_o_uni;
wire [NEw-1 : 0] unicast_id;
endp_addr_decoder #(
.TOPOLOGY (TOPOLOGY),
.T1(T1),
.T2(T2),
.T3(T3),
.EAw(EAw),
.NE(NE)
)
decoder
(
.code(unicast_code),
.id(unicast_id)
);
always @(*)begin
dest_o_uni = {NE{1'b0}};
dest_o_uni[unicast_id]=1'b1;
end
assign dest_o = (not_broad_casted)? dest_o_uni : {NE{1'b1}};
end else begin //BCAST_PARTIAL
wire not_broad_casted;
wire [EAw-1 : 0] unicast_code;
assign {unicast_code,not_broad_casted} = mcast_dst_coded;
assign is_unicast =not_broad_casted;
wire [NE-1 : 0] dest_o_multi;
reg [NE-1 : 0] dest_o_uni;
wire [NEw-1 : 0] unicast_id;
endp_addr_decoder #(
.TOPOLOGY (TOPOLOGY),
.T1(T1),
.T2(T2),
.T3(T3),
.EAw(EAw),
.NE(NE)
)
decoder
(
.code(unicast_code),
.id(unicast_id)
);
always @(*)begin
dest_o_uni = {NE{1'b0}};
dest_o_uni[unicast_id]=1'b1;
end
assign dest_o = (not_broad_casted)? dest_o_uni : MCAST_ENDP_LIST;
end
endgenerate
endmodule
 
 
 
 
module multicast_chan_in_process
import pronoc_pkg::*;
#(
parameter P = 5,
parameter SW_LOC = 0
)
(
endp_port,
current_r_addr,
chan_in,
chan_out,
clk
);
input endp_port;
input [RAw-1 : 0] current_r_addr;
input flit_chanel_t chan_in;
input clk;
output flit_chanel_t chan_out;
wire [MCASTw-1 : 0] mcast_dst_coded;
wire [NE-1 : 0] dest_mcast_all_endp;
wire [NX-1 : 0] row_has_any_dest,row_has_any_dest_in;
wire [DSTPw-1 : 0] destport,destport_o;
hdr_flit_t hdr_flit;
header_flit_info extract(
.flit(chan_in.flit),
.hdr_flit(hdr_flit),
.data_o()
);
mcast_dest_list_decode decoder
(
.dest_e_addr(hdr_flit.dest_e_addr),
.dest_o(dest_mcast_all_endp),
.row_has_any_dest(row_has_any_dest_in),
.is_unicast()
);
localparam MCASTw_= (MCASTw < DAw ) ? MCASTw : DAw;
assign mcast_dst_coded = hdr_flit.dest_e_addr[MCASTw_-1:0];
genvar i;
generate
if(TOPOLOGY == "MESH") begin : mesh_
if(SW_LOC == LOCAL || SW_LOC > SOUTH) begin :endp
wire [NE/NX-1 : 0] endp_mask [NX-1 : 0];
for(i=0; i< NE; i=i+1) begin : endpoints
//Endpoint decoded address
localparam
MCAST_ID = endp_id_to_mcast_id(i),
YY = ((i/NL) / NX ),
XX = ((i/NL) % NX ),
LL = (i % NL),
PP = YY*NL + LL;
assign endp_mask [XX] [PP] = dest_mcast_all_endp [i];
end
for(i=0;i<NX; i++) begin : X_
assign row_has_any_dest[i] =| endp_mask[i];
end
reg [DSTPw-1 : 0] destport_tmp;
always @(*) begin
destport_tmp = destport;
if(SELF_LOOP_EN == "NO") destport_tmp [ SW_LOC ] = 1'b0;
end
assign destport_o = destport_tmp;
end else begin : no_endp
assign row_has_any_dest = row_has_any_dest_in;
assign destport_o = destport;
end
end //mesh
/* verilator lint_off WIDTH */
else if (TOPOLOGY == "FMESH" ) begin :fmesh_
/* verilator lint_on WIDTH */
localparam MAX_ENDP_NUM_IN_SAME_ROW = NY * NL + NY + 2;
localparam ENDP_NUM_IN_MIDLE_ROW = NY * NL + 2;
localparam Pw = log2(MAX_P_FMESH);
wire [NX-1 : 0] row_has_any_dest_endp_port;
wire [NY*NL-1 : 0] endp_mask [NX-1 : 0];
for(i=0; i< NE; i=i+1) begin : endpoints
//Endpoint decoded address
localparam
ADR = fmesh_addrencode(i),
XX = ADR [NXw -1 : 0],
YY = ADR [NXw+NYw-1 : NXw],
PP = ADR [NXw+NYw+Pw-1 : NXw+NYw];
if(PP == LOCAL || PP > SOUTH) begin
localparam MM = (PP==LOCAL) ? YY*NL : (YY*NL) + PP - SOUTH;
assign endp_mask [XX] [MM] = dest_mcast_all_endp [i];
end
end
wire [NX-1 : 0] north_endps;
wire [NY-1 : 0] west_endps;
wire [NX-1 : 0] south_endps;
wire [NY-1 : 0] east_endps;
assign { east_endps, west_endps ,south_endps ,north_endps} = dest_mcast_all_endp [NE-1 : NY*NL*NX];
for(i=0;i<NX; i++) begin : X_
if(i==0) assign row_has_any_dest_endp_port[i] =(| endp_mask[i]) | ( |west_endps) | north_endps[i] | south_endps[i];
else if (i==NX-1) assign row_has_any_dest_endp_port[i] =(| endp_mask[i]) | ( |east_endps) | north_endps[i] | south_endps[i];
else assign row_has_any_dest_endp_port[i] =(| endp_mask[i]) | north_endps[i] | south_endps[i];
end
reg [DSTPw-1 : 0] destport_tmp;
always @(*) begin
destport_tmp = destport;
if(SELF_LOOP_EN == "NO") destport_tmp [ SW_LOC ] = 1'b0;
end
assign destport_o = (endp_port) ? destport : destport_tmp ;
assign row_has_any_dest = (endp_port) ? row_has_any_dest_endp_port : row_has_any_dest_in;
end
wire [DAw-1 : 0] dest_e_addr = {row_has_any_dest,mcast_dst_coded};
multicast_routing
#(
.P(P) ,
.SW_LOC(SW_LOC)
)
routing
(
.current_r_addr(current_r_addr), //current router address
.dest_e_addr(dest_e_addr), // destination endpoint address
.destport(destport)
);
always @(*) begin
chan_out=chan_in;
if(chan_in.flit.hdr_flag == 1'b1) begin
chan_out.flit [E_DST_MSB : E_DST_LSB] = dest_e_addr;
chan_out.flit [DST_P_MSB : DST_P_LSB] = destport_o;
end
end
//synthesis translate_off
if(DEBUG_EN) begin :debg
always @(posedge clk) begin
/* verilator lint_off WIDTH */
if(CAST_TYPE == "MULTICAST_FULL" || CAST_TYPE == "MULTICAST_PARTIAL")
/* verilator lint_on WIDTH */
if(chan_in.flit_wr == 1'b1 && chan_in.flit.hdr_flag == 1'b1 && mcast_dst_coded == {MCASTw{1'b0}}) begin
$display ("%t: ERROR: A multicast packet is injected to the NoC with zero mcast_dst_coded filed %m ",$time);
$finish;
end
if(chan_in.flit_wr == 1'b1 && chan_in.flit.hdr_flag == 1'b1 && dest_mcast_all_endp == {NE{1'b0}}) begin
$display ("%t: ERROR: A multicast packet is injected to the NoC without any set destination %m ",$time);
$finish;
end
if(chan_in.flit_wr == 1'b1 && chan_in.flit.hdr_flag == 1'b1 && destport_o == {DSTPw{1'b0}}) begin
$display ("%t: ERROR: Routing module did not set any destination port for an injected multicast packet %m ",$time);
$finish;
end
end
end//debug
//synthesis translate_on
endgenerate
endmodule
 
 
 
 
 
module multicast_dst_sel
import pronoc_pkg::*;
(
 
destport_in,
destport_out
);
 
input [DSTPw-1 : 0] destport_in;
output [DSTPw-1 : 0] destport_out;
 
 
wire [DSTPw-1 : 0] arb_in, arb_out;
function integer mesh_tori_pririty_order;
input integer x;
begin
case(x)
0 : mesh_tori_pririty_order = EAST;
1 : mesh_tori_pririty_order = WEST;
2 : mesh_tori_pririty_order = NORTH;
3 : mesh_tori_pririty_order = SOUTH;
4 : mesh_tori_pririty_order = LOCAL;
default : mesh_tori_pririty_order =x;
endcase
end
endfunction // pririty_order
function integer ring_lin_pririty_order;
input integer x;
begin
case(x)
0 : ring_lin_pririty_order = FORWARD;
1 : ring_lin_pririty_order = BACKWARD;
2 : ring_lin_pririty_order = LOCAL;
default : ring_lin_pririty_order =x;
endcase
end
endfunction // pririty_order
genvar i;
generate
for (i=0; i<DSTPw;i++) begin : lp
localparam PR =
/* verilator lint_off WIDTH */
(TOPOLOGY == "MESH" || TOPOLOGY == "TORUS" || TOPOLOGY == "FMESH" )? mesh_tori_pririty_order(i):
(TOPOLOGY == "RING" || TOPOLOGY == "LINE") ? ring_lin_pririty_order(i) : i;
/* verilator lint_on WIDTH */
assign arb_in[i] = destport_in[PR];
assign destport_out [PR] = arb_out[i];
end
endgenerate
fixed_priority_arbiter #(
.ARBITER_WIDTH (DSTPw),
.HIGH_PRORITY_BIT ("LSB")
) fixed_priority_arbiter (
.request (arb_in),
.grant (arb_out),
.any_grant ( )
);
endmodule
 
 
/src_noc/noc_filelist.f
1,4 → 1,5
+incdir+./
+incdir+./../
./pronoc_pkg.sv
./../main_comp.v
./../arbiter.v
9,7 → 10,7
./noc_top.sv
./fattree_noc_top.sv
./fattree_route.v
./comb_nonspec.v
./comb_nonspec.sv
./inout_ports.sv
./wrra.v
./input_ports.sv
16,7 → 17,7
./tree_noc_top.sv
./tree_route.v
./comb-spec1.v
./combined_vc_sw_alloc.v
./combined_vc_sw_alloc.sv
./mesh_torus_routting.v
./baseline.v
./comb_spec2.v
30,8 → 31,8
./router_two_stage.sv
./crossbar.v
./iport_reg_base.sv
./flit_buffer.v
./mesh_torus.v
./flit_buffer.sv
./mesh_torus.sv
./debug.v
./router_top.sv
./mesh_torus_noc_top.sv
38,6 → 39,7
./star_noc.sv
./fmesh.sv
./packet_injector.sv
./multicast.sv
 
 
 
/src_noc/noc_localparam.v
1,78 → 1,80
 
/**************************************************************************
** WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
** OVERWRITTEN AND LOST. Rename this file if you wish to do any modification.
** WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
** OVERWRITTEN AND LOST. Rename this file if you wish to do any modification.
****************************************************************************/
 
 
/**********************************************************************
** File: noc_localparam.v
** File: noc_localparam.v
**
** Copyright (C) 2014-2019 Alireza Monemi
** Copyright (C) 2014-2021 Alireza Monemi
**
** This file is part of ProNoC 1.9.1
** This file is part of ProNoC 2.0.0
**
** ProNoC ( stands for Prototype Network-on-chip) is free software:
** you can redistribute it and/or modify it under the terms of the GNU
** Lesser General Public License as published by the Free Software Foundation,
** either version 2 of the License, or (at your option) any later version.
** ProNoC ( stands for Prototype Network-on-chip) is free software:
** you can redistribute it and/or modify it under the terms of the GNU
** Lesser General Public License as published by the Free Software Foundation,
** either version 2 of the License, or (at your option) any later version.
**
** ProNoC is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
** or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
** Public License for more details.
** ProNoC is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
** or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
** Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
** You should have received a copy of the GNU Lesser General Public
** License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
******************************************************************************/
 
`ifdef NOC_LOCAL_PARAM
`ifdef NOC_LOCAL_PARAM
 
//NoC parameters
localparam TOPOLOGY="MESH";
localparam T1=8;
localparam T2=8;
localparam T3=1;
localparam V=2;
localparam B=4;
localparam LB=4;
localparam Fpay=32;
localparam ROUTE_NAME="XY";
localparam PCK_TYPE="MULTI_FLIT";
localparam MIN_PCK_SIZE=2;
localparam BYTE_EN=0;
localparam SSA_EN="NO";
localparam SMART_MAX=0;
localparam CONGESTION_INDEX=3;
localparam ESCAP_VC_MASK=2'b01;
localparam VC_REALLOCATION_TYPE="NONATOMIC";
localparam COMBINATION_TYPE="COMB_NONSPEC";
localparam MUX_TYPE="BINARY";
localparam C=2;
localparam DEBUG_EN=1;
localparam ADD_PIPREG_AFTER_CROSSBAR=1'b0;
localparam FIRST_ARBITER_EXT_P_EN=1;
localparam SWA_ARBITER_TYPE="RRA";
localparam WEIGHTw=4;
localparam SELF_LOOP_EN="NO";
localparam AVC_ATOMIC_EN=0;
localparam CVw=(C==0)? V : C * V;
localparam CLASS_SETTING={CVw{1'b1}};
// localparam CAST_TYPE = "UNICAST";//"MULTICAST"; not yest supported
//simulation parameter
//localparam MAX_RATIO = 1000;
localparam MAX_PCK_NUM = 1000000000;
localparam MAX_PCK_SIZ = 16383;
localparam MAX_SIM_CLKs= 1000000000;
localparam TIMSTMP_FIFO_NUM = 16;
localparam TOPOLOGY="MESH";
localparam T1=3;
localparam T2=3;
localparam T3=1;
localparam V=2;
localparam B=4;
localparam LB=4;
localparam Fpay=64;
localparam ROUTE_NAME="XY";
localparam PCK_TYPE="MULTI_FLIT";
localparam MIN_PCK_SIZE=2;
localparam BYTE_EN=0;
localparam CAST_TYPE="MULTICAST_PARTIAL";
localparam MCAST_ENDP_LIST=9'hf;
localparam SSA_EN="NO";
localparam SMART_MAX=0;
localparam CONGESTION_INDEX=3;
localparam ESCAP_VC_MASK=2'b01;
localparam VC_REALLOCATION_TYPE="NONATOMIC";
localparam COMBINATION_TYPE="COMB_NONSPEC";
localparam MUX_TYPE="BINARY";
localparam C=0;
localparam DEBUG_EN=1;
localparam ADD_PIPREG_AFTER_CROSSBAR=1'b0;
localparam FIRST_ARBITER_EXT_P_EN=1;
localparam SWA_ARBITER_TYPE="RRA";
localparam WEIGHTw=4;
localparam SELF_LOOP_EN="NO";
localparam AVC_ATOMIC_EN=0;
localparam CLASS_SETTING={V{1'b1}};
localparam CVw=(C==0)? V : C * V;
//simulation parameter
//localparam MAX_RATIO = 1000;
localparam MAX_PCK_NUM = 1000000000;
localparam MAX_PCK_SIZ = 16383;
localparam MAX_SIM_CLKs= 1000000000;
localparam TIMSTMP_FIFO_NUM = 16;
 
`endif
/src_noc/noc_top.sv
1,8 → 1,4
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
 
 
`include "pronoc_def.v"
/**********************************************************************
** File: noc_top.sv
**
37,15 → 33,17
reset,
clk,
chan_in_all,
chan_out_all
chan_out_all,
router_event
);
input clk,reset;
//local ports
//Endpoints ports
input smartflit_chanel_t chan_in_all [NE-1 : 0];
output smartflit_chanel_t chan_out_all [NE-1 : 0];
 
//Events
output router_event_t router_event [NR-1 : 0][MAX_P-1 : 0];
 
58,7 → 56,8
.reset (reset ),
.clk (clk ),
.chan_in_all (chan_in_all ),
.chan_out_all (chan_out_all )
.chan_out_all (chan_out_all ),
.router_event (router_event )
);
68,7 → 67,8
.reset (reset ),
.clk (clk ),
.chan_in_all (chan_in_all ),
.chan_out_all (chan_out_all )
.chan_out_all (chan_out_all ),
.router_event (router_event )
);
77,7 → 77,8
.reset (reset ),
.clk (clk ),
.chan_in_all (chan_in_all ),
.chan_out_all (chan_out_all )
.chan_out_all (chan_out_all ),
.router_event (router_event )
);
end else if (TOPOLOGY == "STAR") begin : star_
star_noc_top noc_top (
84,7 → 85,8
.reset (reset ),
.clk (clk ),
.chan_in_all (chan_in_all ),
.chan_out_all (chan_out_all )
.chan_out_all (chan_out_all ),
.router_event (router_event )
);
end else begin :custom_
93,7 → 95,8
.reset (reset ),
.clk (clk ),
.chan_in_all (chan_in_all ),
.chan_out_all (chan_out_all )
.chan_out_all (chan_out_all ),
.router_event (router_event )
);
 
end
106,7 → 109,7
 
 
/**********************************
The noc top module that can be caled in Verilog module.
The noc top module that can be called in Verilog module.
 
***********************************/
 
141,7 → 144,8
.reset(reset),
.clk(clk),
.chan_in_all(chan_in_all),
.chan_out_all(chan_out_all)
.chan_out_all(chan_out_all),
.router_event ( )
);
 
/src_noc/output_ports.sv
1,4 → 1,4
`timescale 1ns/1ps
`include "pronoc_def.v"
/**********************************************************************
** File: output_ports.sv
**
33,8 → 33,7
)(
vsa_ovc_allocated_all,
flit_is_tail_all,
assigned_ovc_num_all,
ovc_is_assigned_all,
dest_port_all,
nonspec_granted_dest_port_all,
credit_in_all,
53,7 → 52,8
vsa_ovc_released_all,
crossbar_flit_out_wr_all,
oport_info,
ovc_info,
ovc_info,
ivc_info,
vsa_ctrl_in,
ssa_ctrl_in,
smart_ctrl_in,
87,9 → 87,7
localparam CONG_ALw= CONGw * P; // congestion width per router;
input [PV-1 : 0] vsa_ovc_allocated_all;
input [PV-1 : 0] flit_is_tail_all;
input [PVV-1 : 0] assigned_ovc_num_all;
input [PV-1 : 0] ovc_is_assigned_all;
input [PV-1 : 0] flit_is_tail_all;
input [PVP_1-1 : 0] dest_port_all;
input [PP_1-1 : 0] nonspec_granted_dest_port_all;
input [PV-1 : 0] credit_in_all;
107,16 → 105,18
output [PV-1 : 0] vsa_ovc_released_all;
output [PV-1 : 0] vsa_credit_decreased_all;
output oport_info_t oport_info [P-1:0];
output ovc_info_t ovc_info [P-1 : 0][V-1 : 0];
input vsa_ctrl_t vsa_ctrl_in [P-1: 0];
input ssa_ctrl_t ssa_ctrl_in [P-1: 0];
output ovc_info_t ovc_info [P-1 : 0][V-1 : 0];
input ivc_info_t ivc_info [P-1 : 0][V-1 : 0];
input vsa_ctrl_t vsa_ctrl_in [P-1: 0];
input ssa_ctrl_t ssa_ctrl_in [P-1: 0];
input smart_ctrl_t smart_ctrl_in [P-1: 0];
input [CRDTw-1 : 0 ] credit_init_val_in [P-1 : 0][V-1 : 0];
reg [PV-1 : 0] ovc_status;
logic [PV-1 : 0] ovc_status;
logic [PV-1 : 0] ovc_status_next;
wire [PV-1 : 0] assigned_ovc_is_full_all;
wire [VP_1-1 : 0] credit_decreased [P-1 : 0];
wire [P_1-1 : 0] credit_decreased_gen [PV-1 : 0];
wire [VP_1-1 : 0] credit_decreased [P-1 : 0];
wire [P_1-1 : 0] credit_decreased_gen [PV-1 : 0];
wire [PV-1 : 0] credit_increased_all;
wire [VP_1-1 : 0] ovc_released [P-1 : 0];
135,13 → 135,16
wire [PV-1 : 0] ovc_allocated_all;
wire [CREDITw-1 : 0] credit_counter [PV-1 : 0];
wire [PVV-1 : 0] assigned_ovc_num_all;
wire [PV-1 : 0] ovc_is_assigned_all;
register #(.W(PV)) reg_1 ( .in(full_all_next), .reset(reset), .clk(clk), .out(full_all));
register #(.W(PV)) reg_2 ( .in(nearly_full_all_next), .reset(reset), .clk(clk), .out(nearly_full_all));
register #(.W(PV)) reg_3 ( .in(empty_all_next), .reset(reset), .clk(clk), .out(empty_all));
pronoc_register #(.W(PV)) reg_1 ( .in(full_all_next), .reset(reset), .clk(clk), .out(full_all));
pronoc_register #(.W(PV)) reg_2 ( .in(nearly_full_all_next), .reset(reset), .clk(clk), .out(nearly_full_all));
pronoc_register #(.W(PV)) reg_3 ( .in(empty_all_next), .reset(reset), .clk(clk), .out(empty_all));
integer k;
genvar i,j;
generate
174,7 → 177,7
end // for
end//always
 
register #(.W(PV)) reg2 ( .in(full_adaptive_ovc_mask_next), .reset(reset), .clk(clk), .out(full_adaptive_ovc_mask));
pronoc_register #(.W(PV)) reg2 ( .in(full_adaptive_ovc_mask_next), .reset(reset), .clk(clk), .out(full_adaptive_ovc_mask));
assign ovc_avalable_all = ~ovc_status & full_adaptive_ovc_mask;
283,6 → 286,11
for(i=0; i<PV; i=i+1) begin :PV_loop2
assign assigned_ovc_num_all[(i+1)*V-1 : i*V] = ivc_info[i/V][i%V].assigned_ovc_num;
assign ovc_is_assigned_all[i]=ivc_info[i/V][i%V].ovc_is_assigned;
credit_monitor_per_ovc #(
.SW_LOC(i/V)
)
301,7 → 309,7
sw_mask_gen #(
full_ovc_predictor #(
.OVC_ALLOC_MODE(OVC_ALLOC_MODE),
.PCK_TYPE(PCK_TYPE),
.V (V), // vc_num_per_port
325,35 → 333,31
);
end//for
for(i=0; i<PV; i=i+1) begin :reg_blk
 
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
//credit_counter[i] <= Bint;
ovc_status[i] <= 1'b0;
end else begin
/* verilator lint_off WIDTH */
if(PCK_TYPE == "SINGLE_FLIT") ovc_status[i]<=1'b0; // donot change VC status for single flit packet
/* verilator lint_on WIDTH */
else begin
if(ovc_released_all[i]) ovc_status[i]<=1'b0;
//if(ovc_allocated_all[i] & ~granted_dst_is_from_a_single_flit_pck[i/V]) ovc_status[i]<=1'b1; // donot change VC status for single flit packet
if((vsa_ctrl_in[i/V].ovc_is_allocated[i%V] & ~granted_dst_is_from_a_single_flit_pck[i/V]) |
always @ (*)begin
ovc_status_next[i] = ovc_status[i];
/* verilator lint_off WIDTH */
if(PCK_TYPE == "SINGLE_FLIT") ovc_status_next[i]=1'b0; // donot change VC status for single flit packet
/* verilator lint_on WIDTH */
else begin
if(ovc_released_all[i]) ovc_status_next[i] =1'b0;
//if(ovc_allocated_all[i] & ~granted_dst_is_from_a_single_flit_pck[i/V]) ovc_status_next[i]=1'b1; // donot change VC status for single flit packet
if((vsa_ctrl_in[i/V].ovc_is_allocated[i%V] & ~granted_dst_is_from_a_single_flit_pck[i/V]) |
(ssa_ctrl_in[i/V].ovc_is_allocated[i%V] & ~ssa_ctrl_in[i/V].ovc_single_flit_pck[i%V])|
(smart_ctrl_in[i/V].ovc_is_allocated[i%V] & ~smart_ctrl_in[i/V].ovc_single_flit_pck[i%V]))
ovc_status[i]<=1'b1; // donot change VC status for single flit packet
ovc_status_next[i]=1'b1; // donot change VC status for single flit packet
end
end//else reset
end
end//always
end//for
endgenerate
pronoc_register #(.W(PV)) reg2 (.in(ovc_status_next ), .out(ovc_status), .reset(reset), .clk(clk));
 
port_pre_sel_gen #(
.PPSw(PPSw),
385,14 → 389,8
generate
if(DEBUG_EN) begin: debug
 
`ifdef SYNC_RESET_MODE
 
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset )begin
 
end else begin
for(k=0; k<PV; k=k+1'b1) begin
if(empty_all[k] & credit_increased_all[k]) begin
$display("%t: ERROR: unexpected credit recived for empty ovc[%d]: %m",$time,k);
415,27 → 413,42
$finish;
end
end//for
end
 
end//always
localparam NUM_WIDTH = log2(PV+1);
wire [NUM_WIDTH-1 : 0] num1,num2;
parallel_counter #(
.IN_WIDTH(PV)
)cnt1
(
.in (ovc_status),
.out (num1)
);
 
parallel_counter #(
.IN_WIDTH(PV)
)cnt2
(
.in (ovc_is_assigned_all),
.out (num2)
);
/* verilator lint_off WIDTH */
if(CAST_TYPE== "UNICAST") begin : unicast
/* verilator lint_on WIDTH */
 
localparam NUM_WIDTH = log2(PV+1);
wire [NUM_WIDTH-1 : 0] num1,num2;
accumulator #(
.INw(PV),
.OUTw(NUM_WIDTH),
.NUM(PV)
)
cnt1
(
.in_all(ovc_status),
.out(num1)
);
accumulator #(
.INw(PV),
.OUTw(NUM_WIDTH),
.NUM(PV)
)
cnt2
(
.in_all(ovc_is_assigned_all),
.out(num2)
);
always @(posedge clk) begin
if(num1 != num2 )begin
$display("%t: ERROR: number of assigned IVC %d mismatch the number of occupied OVC %d: %m",$time,num1,num2);
442,7 → 455,7
$finish;
end
end
end //unicast
check_ovc #(
.V(V) , // vc_num_per_port
.P(P), // router port num
519,21 → 532,19
assign empty_all_next = (credit_counter_next == Bint);
assign full_all_next = (credit_counter_next == {DEPTHw{1'b0}});
assign nearly_full_all_next = (credit_counter_next <= 1);
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
credit_counter <= credit_init_val_i [DEPTHw-1 : 0]; // Bint;
end else begin
credit_counter <= credit_counter_next;
end
end
pronoc_register_reset_init #(
.W(DEPTHw)
)reg1(
.in(credit_counter_next),
.reset(reset),
.clk(clk),
.out(credit_counter),
.reset_to(credit_init_val_i [DEPTHw-1 : 0]) // Bint;
);
endmodule
 
 
625,11 → 636,11
 
/**********************************
 
sw_mask_gen
full_ovc_predictor
 
*********************************/
 
module sw_mask_gen #(
module full_ovc_predictor #(
parameter PCK_TYPE = "MULTI_FLIT",
parameter V = 4, // vc_num_per_port
parameter P = 5, // router port num
665,7 → 676,7
wire [VP_1-1 : 0] full_muxin1,nearly_full_muxin1;
wire [V-1 : 0] full_muxout1,nearly_full_muxout1;
wire full_muxout2,nearly_full_muxout2;
reg full_reg1,full_reg2;
wire full_reg1,full_reg2;
wire full_reg1_next,full_reg2_next;
719,24 → 730,14
assign full_reg1_next = full_muxout2;
assign full_reg2_next = nearly_full_muxout2 & ivc_getting_sw_grant;
assign assigned_ovc_is_full = (PCK_TYPE == "MULTI_FLIT")? full_reg1 | full_reg2: 1'b0;
pronoc_register #(.W(1)) reg1 (.in(full_reg1_next ), .out(full_reg1), .reset(reset), .clk(clk));
pronoc_register #(.W(1)) reg2 (.in(full_reg2_next ), .out(full_reg2), .reset(reset), .clk(clk));
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
full_reg1 <= 1'b0;
full_reg2 <= 1'b0;
end else begin
full_reg1 <= full_reg1_next;
full_reg2 <= full_reg2_next;
end
end//always
assign assigned_ovc_is_full = (PCK_TYPE == "MULTI_FLIT")? full_reg1 | full_reg2: 1'b0;
endmodule
 
 
/src_noc/packet_injector.sv
1,4 → 1,5
`timescale 1ns/1ps
`include "pronoc_def.v"
 
/****************************
* This module can inject and eject packets from the NoC.
* It can be used in simulation for injecting real application traces to the NoC
47,53 → 48,57
assign current_r_addr = chan_in.ctrl_chanel.neighbors_r_addr;
generate if(CAST_TYPE == "UNICAST") begin : uni
conventional_routing #(
.TOPOLOGY(TOPOLOGY),
.ROUTE_NAME(ROUTE_NAME),
.ROUTE_TYPE(ROUTE_TYPE),
.T1(T1),
.T2(T2),
.T3(T3),
.RAw(RAw),
.EAw(EAw),
.DSTPw(DSTPw),
.LOCATED_IN_NI(1)
)
routing_module
(
.reset(reset),
.clk(clk),
.current_r_addr(current_r_addr),
.dest_e_addr(pck_injct_in.endp_addr),
.src_e_addr(current_e_addr),
.destport(destport)
);
end endgenerate
conventional_routing #(
.TOPOLOGY(TOPOLOGY),
.ROUTE_NAME(ROUTE_NAME),
.ROUTE_TYPE(ROUTE_TYPE),
.T1(T1),
.T2(T2),
.T3(T3),
.RAw(RAw),
.EAw(EAw),
.DSTPw(DSTPw),
.LOCATED_IN_NI(1)
)
routing_module
(
.reset(reset),
.clk(clk),
.current_r_addr(current_r_addr),
.dest_e_addr(pck_injct_in.endp_addr),
.src_e_addr(current_e_addr),
.destport(destport)
);
localparam
HDR_BYTE_NUM = HDR_MAX_DATw / 8, // = HDR_MAX_DATw / (8 - HDR_MAX_DATw %8)
HDR_DATA_w_tmp = HDR_BYTE_NUM * 8,
HDR_DATA_w = (PCK_INJ_Dw < HDR_DATA_w_tmp)? PCK_INJ_Dw : HDR_DATA_w_tmp;
HDR_DATA_w =
(PCK_INJ_Dw < HDR_DATA_w_tmp)? PCK_INJ_Dw :
(HDR_DATA_w_tmp==0)? 1: HDR_DATA_w_tmp;
 
wire [HDR_DATA_w-1 : 0] hdr_data_in = pck_injct_in.data [HDR_DATA_w-1 : 0];
wire [Fw-1 : 0] hdr_flit_out;
header_flit_generator #(
.DATA_w(HDR_DATA_w)
)
the_header_flit_generator
(
.flit_out (hdr_flit_out),
.vc_num_in (pck_injct_in.vc),
.class_in (pck_injct_in.class_num),
.dest_e_addr_in (pck_injct_in.endp_addr),
.src_e_addr_in (current_e_addr),
.weight_in (pck_injct_in.init_weight),
.destport_in (destport),
.data_in (hdr_data_in),
.be_in({BEw{1'b1}} )// Be is not used in simulation as we dont sent real data
);
.DATA_w(HDR_DATA_w)
)
the_header_flit_generator
(
.flit_out (hdr_flit_out),
.vc_num_in (pck_injct_in.vc),
.class_in (pck_injct_in.class_num),
.dest_e_addr_in (pck_injct_in.endp_addr),
.src_e_addr_in (current_e_addr),
.weight_in (pck_injct_in.init_weight),
.destport_in (destport),
.data_in (hdr_data_in),
.be_in({BEw{1'b1}} )// Be is not used in simulation as we dont sent real data
);
localparam
105,13 → 110,13
MIN_PCK_SIZ = REMAIN_DAT_FLIT +1;
reg [PCK_SIZw-1 : 0] counter, counter_next;
reg [CNTw-1 : 0] counter2,counter2_next;
logic [PCK_SIZw-1 : 0] counter, counter_next;
logic [CNTw-1 : 0] counter2,counter2_next;
reg tail,head;
wire [Fpay -1 : 0] remain_dat [REMAIN_DAT_FLIT -1 : 0];
wire [Fpay-1 : 0] dataIn = remain_dat[counter2];
enum {HEADER, BODY,TAIL} flit_type,flit_type_next;
enum bit [2:0] {HEADER, BODY,TAIL} flit_type,flit_type_next;
126,10 → 131,10
LASTw=(LAST_TMP==0)? Fpay : LAST_TMP;
genvar i;
generate
for(i=0; i<REMAIN_DAT_FLIT_I; i++) begin :Rm
for(i=0; i<REMAIN_DAT_FLIT_I; i++) begin :rem
assign remain_dat [i] = pck_injct_in.data [Fpay*(i+1)+HDR_DATA_w-1 : (Fpay*i)+HDR_DATA_w];
end
if(REMAIN_DAT_FLIT_F ) begin
if(REMAIN_DAT_FLIT_F ) begin :flt
 
assign remain_dat [REMAIN_DAT_FLIT_I][LASTw-1 : 0] = pck_injct_in.data [PCK_INJ_Dw-1 : (Fpay*REMAIN_DAT_FLIT_I)+HDR_DATA_w];
end
139,11 → 144,11
one_hot_mux #(
one_hot_mux #(
.IN_WIDTH (V ),
.SEL_WIDTH (V ),
.OUT_WIDTH (1 )
) one_hot_mux1 (
) one_hot_mux1 (
.mux_in (~ vc_fifo_full ),
.mux_out (noc_ready ),
.sel (pck_injct_in.vc ));
151,84 → 156,88
always @ (*) begin
counter_next = counter;
counter2_next =counter2;
flit_type_next =flit_type;
tail=1'b0;
head=1'b0;
flit_wr=0;
if(noc_ready)begin
case(flit_type)
HEADER:begin
if(pck_injct_in.pck_wr)begin
flit_wr=1;
counter_next = pck_injct_in.size-1;
counter2_next=0;
head=1'b1;
if(pck_injct_in.size == 1)begin
tail=1'b1;
end else if (pck_injct_in.size == 2) begin
flit_type_next = TAIL;
end else begin
flit_type_next = BODY;
end
end
end
BODY: begin
always @ (*) begin
counter_next = counter;
counter2_next =counter2;
flit_type_next =flit_type;
tail=1'b0;
head=1'b0;
flit_wr=0;
if(noc_ready)begin
case(flit_type)
HEADER:begin
if(pck_injct_in.pck_wr)begin
flit_wr=1;
counter_next = counter -1'b1;
counter2_next =counter2 +1'b1;
if(counter == 2) begin
counter_next = pck_injct_in.size-1;
counter2_next=0;
head=1'b1;
if(pck_injct_in.size == 1)begin
tail=1'b1;
end else if (pck_injct_in.size == 2) begin
flit_type_next = TAIL;
end
end else begin
flit_type_next = BODY;
end
end
TAIL: begin
flit_type_next = HEADER;
flit_wr=1;
tail=1'b1;
end
BODY: begin
flit_wr=1;
counter_next = counter -1'b1;
counter2_next =counter2 +1'b1;
if(counter == 2) begin
flit_type_next = TAIL;
end
endcase
end
TAIL: begin
flit_type_next = HEADER;
flit_wr=1;
tail=1'b1;
end
default: begin
end
endcase
end
end
reg [V-1 : 0] credit_o;
end
always @ (posedge clk) begin
if(reset) begin
flit_type<=HEADER;
counter<=0;
counter2<=0;
credit_o<={V{1'b0}};
end else begin
flit_type<=flit_type_next;
counter<=counter_next;
counter2<=counter2_next;
if (chan_in.flit_chanel.flit_wr) credit_o<= chan_in.flit_chanel.flit.vc;
else credit_o<={V{1'b0}};
end
end
logic [V-1 : 0] credit_o, credit_o_next;
//pronoc_register #(.W(3),.RESET_TO(HEADER) ) reg1 (.in(flit_type_next ), .out(flit_type), .reset(reset), .clk(clk));
pronoc_register #(.W(PCK_SIZw)) reg2 (.in(counter_next ), .out(counter), .reset(reset), .clk(clk));
pronoc_register #(.W(CNTw)) reg3 (.in(counter2_next ), .out(counter2), .reset(reset), .clk(clk));
pronoc_register #(.W(V)) reg4 (.in(credit_o_next ), .out(credit_o), .reset(reset), .clk(clk));
always @ (*) begin
credit_o_next = credit_o;
if (chan_in.flit_chanel.flit_wr) credit_o_next = chan_in.flit_chanel.flit.vc;
else credit_o_next = {V{1'b0}};
end
always @(`pronoc_clk_reset_edge)begin
if(`pronoc_reset) flit_type<=HEADER;
else flit_type <= flit_type_next;
end
injector_ovc_status #(
.V(V),
.B(LB),
.CRDTw(CRDTw)
)
the_ovc_status
(
.credit_init_val_in ( chan_in.ctrl_chanel.credit_init_val),
.wr_in(wr_vc_send),
.credit_in(chan_in.flit_chanel.credit),
.full_vc(vc_fifo_full),
.nearly_full_vc( ),
.empty_vc( ),
.clk(clk),
.reset(reset)
);
.V(V),
.B(LB),
.CRDTw(CRDTw)
)
the_ovc_status
(
.credit_init_val_in ( chan_in.ctrl_chanel.credit_init_val),
.wr_in(wr_vc_send),
.credit_in(chan_in.flit_chanel.credit),
.full_vc(vc_fifo_full),
.nearly_full_vc( ),
.empty_vc( ),
.clk(clk),
.reset(reset)
);
240,13 → 249,13
hdr_flit_t hdr_flit_i;
header_flit_info
#(
.DATA_w (HDR_DATA_w )
) extractor (
.flit(chan_in.flit_chanel.flit),
.hdr_flit(hdr_flit_i),
.data_o(hdr_data_o)
);
#(
.DATA_w (HDR_DATA_w )
) extractor (
.flit(chan_in.flit_chanel.flit),
.hdr_flit(hdr_flit_i),
.data_o(hdr_data_o)
);
wire [PCK_INJ_Dw-1 : 0] pck_data_o [V-1 : 0];
reg [Fpay-1 : 0] pck_data_o_gen [V-1 : 0][REMAIN_DAT_FLIT : 0];
264,16 → 273,29
wire [NEw-1 : 0] current_id;
wire [NEw-1 : 0] sendor_id;
endp_addr_decoder #( .TOPOLOGY(TOPOLOGY), .T1(T1), .T2(T2), .T3(T3), .EAw(EAw), .NE(NE)) encode1 ( .id(current_id), .code(current_e_addr));
endp_addr_decoder #( .TOPOLOGY(TOPOLOGY), .T1(T1), .T2(T2), .T3(T3), .EAw(EAw), .NE(NE)) encode2 ( .id(sendor_id), .code(pck_injct_out.endp_addr));
endp_addr_decoder #( .TOPOLOGY(TOPOLOGY), .T1(T1), .T2(T2), .T3(T3), .EAw(EAw), .NE(NE)) encode2 ( .id(sendor_id), .code(pck_injct_out.endp_addr[EAw-1 : 0]));
//synthesis translate_on
wire [NE-1 :0] dest_mcast_all_endp;
generate
if(CAST_TYPE != "UNICAST") begin
mcast_dest_list_decode decode (
.dest_e_addr(hdr_flit_i.dest_e_addr),
.dest_o(dest_mcast_all_endp),
.row_has_any_dest(),
.is_unicast()
);
end
for(i=0; i<V; i++) begin: V_
always@(*) begin
h2t_counter_next[i]=h2t_counter[i]+1'b1;
if(chan_in.flit_chanel.flit.vc[i] & chan_in.flit_chanel.flit_wr & chan_in.flit_chanel.flit.hdr_flag)begin
h2t_counter_next[i]= 16'd0; // reset once header flit is received
h2t_counter_next[i]= 16'd0; // reset once header flit is received
end//hdr flit wr
end//always
280,8 → 302,8
always_ff @(posedge clk or posedge reset) begin
if (reset) begin
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
rsv_counter[i]<= {PCK_SIZw{1'b0}};
h2t_counter[i]<= 16'd0;
sender_endp_addr_reg [i]<= {EAw{1'b0}};
292,9 → 314,16
rsv_counter[i]<= {{(PCK_SIZw-1){1'b0}}, 1'b1};
sender_endp_addr_reg [i]<= hdr_flit_i.src_e_addr;
//synthesis translate_off
if(hdr_flit_i.dest_e_addr != current_e_addr) begin
$display("%t: ERROR: packet destination address %d does not match reciver endp address %d. %m",$time,hdr_flit_i.dest_e_addr , current_e_addr );
$finish;
if(CAST_TYPE == "UNICAST") begin
if(hdr_flit_i.dest_e_addr[EAw-1:0] != current_e_addr) begin
$display("%t: ERROR: packet destination address %d does not match reciver endp address %d. %m",$time,hdr_flit_i.dest_e_addr , current_e_addr );
$finish;
end//if hdr_flit_i
end else begin
if(dest_mcast_all_endp[current_id] !=1'b1 ) begin
$display("%t: ERROR: packet destination address %b does not match reciver endp address %d. %m",$time,hdr_flit_i.dest_e_addr , current_e_addr ,current_id );
$finish;
end
end//if hdr_flit_i
//synthesis translate_on
end //if hdr_flag
308,8 → 337,8
 
for (k=0;k< REMAIN_DAT_FLIT+1;k++)begin : K_
always_ff @(posedge clk or posedge reset) begin
if (reset) begin
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
pck_data_o_gen [i][k] <= {Fpay{1'b0}};
end else begin
318,7 → 347,7
if ( k ==0 ) pck_data_o_gen [i][k][HDR_DATA_w-1 : 0] <= hdr_data_o;
end
else begin
if (rsv_counter[i] == k ) pck_data_o_gen [i][k] <= chan_in.flit_chanel.flit.payload;
if (rsv_counter[i] == k ) pck_data_o_gen [i][k] <= chan_in.flit_chanel.flit.payload[Fpay-1 : 0];
end // else
end //if
325,9 → 354,9
end //else
end// always
if (k == 0 ) assign pck_data_o [i][HDR_DATA_w-1 : 0] = pck_data_o_gen [i][0][HDR_DATA_w-1 : 0];
else if (k == REMAIN_DAT_FLIT) assign pck_data_o [i][PCK_INJ_Dw-1 : (k-1)*Fpay+ HDR_DATA_w] = pck_data_o_gen [i][k][LASTw-1: 0];
else assign pck_data_o [i][(k)*Fpay+HDR_DATA_w -1 : (k-1)*Fpay+ HDR_DATA_w] = pck_data_o_gen [i][k];
if (k == 0 ) assign pck_data_o [i][HDR_DATA_w-1 : 0] = pck_data_o_gen [i][0][HDR_DATA_w-1 : 0];
else if (k == REMAIN_DAT_FLIT) assign pck_data_o [i][PCK_INJ_Dw-1 : (k-1)*Fpay+ HDR_DATA_w] = pck_data_o_gen [i][k][LASTw-1: 0];
else assign pck_data_o [i][(k)*Fpay+HDR_DATA_w -1 : (k-1)*Fpay+ HDR_DATA_w] = pck_data_o_gen [i][k];
end //for k
352,19 → 381,19
wire tail_flag_reg, hdr_flag_reg;
register #(.W(V)) register1 (.in(chan_in.flit_chanel.flit.vc), .reset (reset ), .clk (clk),.out(vc_reg));
register #(.W(1)) register2 (.in(chan_in.flit_chanel.flit.hdr_flag), .reset (reset ), .clk (clk),.out(hdr_flag_reg));
register #(.W(1)) register3 (.in(chan_in.flit_chanel.flit.tail_flag & chan_in.flit_chanel.flit_wr ),.reset (reset ), .clk (clk),.out(tail_flag_reg));
pronoc_register #(.W(V)) register1 (.in(chan_in.flit_chanel.flit.vc), .reset (reset ), .clk (clk),.out(vc_reg));
pronoc_register #(.W(1)) register2 (.in(chan_in.flit_chanel.flit.hdr_flag), .reset (reset ), .clk (clk),.out(hdr_flag_reg));
pronoc_register #(.W(1)) register3 (.in(chan_in.flit_chanel.flit.tail_flag & chan_in.flit_chanel.flit_wr ),.reset (reset ), .clk (clk),.out(tail_flag_reg));
wire [Vw-1 : 0] vc_bin;
one_hot_to_bin #(
.ONE_HOT_WIDTH (V),
.BIN_WIDTH (Vw )
) one_hot_to_bin (
.one_hot_code (vc_reg ),
.bin_code (vc_bin )
);
.ONE_HOT_WIDTH (V),
.BIN_WIDTH (Vw )
) one_hot_to_bin (
.one_hot_code (vc_reg ),
.bin_code (vc_bin )
);
 
assign pck_injct_out.data = pck_data_o[vc_bin];
371,7 → 400,7
assign pck_injct_out.size = rsv_counter[vc_bin];
assign pck_injct_out.h2t_delay = h2t_counter[vc_bin];
assign pck_injct_out.ready = (flit_type == HEADER)? ~vc_fifo_full : {V{1'b0}};
assign pck_injct_out.endp_addr = sender_endp_addr_reg[vc_bin];
assign pck_injct_out.endp_addr[EAw-1 : 0] = sender_endp_addr_reg[vc_bin];
assign pck_injct_out.vc = vc_reg;
assign pck_injct_out.pck_wr = tail_flag_reg;
379,12 → 408,23
assign chan_out.flit_chanel.flit.tail_flag=tail;
assign chan_out.flit_chanel.flit.vc=pck_injct_in.vc;
assign chan_out.flit_chanel.flit_wr=flit_wr;
 
assign chan_out.flit_chanel.flit.payload = (flit_type== HEADER)? hdr_flit_out[Fpay-1 : 0] : dataIn;
generate
/* verilator lint_off WIDTH */
if(PCK_TYPE == "SINGLE_FLIT" ) begin : single_f
/* verilator lint_on WIDTH */
assign chan_out.flit_chanel.flit.payload = hdr_flit_out[FPAYw-1 : 0];
end else begin
assign chan_out.flit_chanel.flit.payload = (flit_type== HEADER)? hdr_flit_out[Fpay-1 : 0] : dataIn;
end
endgenerate
assign chan_out.smart_chanel = {SMART_CHANEL_w{1'b0}};
assign chan_out.flit_chanel.congestion = {CONGw{1'b0}};
assign chan_out.flit_chanel.credit= credit_o;
assign chan_out.ctrl_chanel.credit_init_val= LB;
assign chan_out.ctrl_chanel.credit_release_en={V{1'b0}};
assign chan_out.ctrl_chanel.endp_port =1'b1;
426,15 → 466,15
`ifdef MONITOR_RSV_DAT
if(pck_injct_in.pck_wr) begin
$display ("pck_inj(%d) send a packet: size=%d, data=%h, v=%h",current_id,
pck_injct_in.size, pck_injct_in.data,pck_injct_in.vc);
end
if(pck_injct_in.pck_wr) begin
$display ("pck_inj(%d) send a packet: size=%d, data=%h, v=%h",current_id,
pck_injct_in.size, pck_injct_in.data,pck_injct_in.vc);
end
if(pck_injct_out.pck_wr) begin
$display ("pck_inj(%d) got a packet: source=%d, size=%d, data=%h",current_id,
sendor_id,pck_injct_out.size,pck_injct_out.data);
end
if(pck_injct_out.pck_wr) begin
$display ("pck_inj(%d) got a packet: source=%d, size=%d, data=%h",current_id,
sendor_id,pck_injct_out.size,pck_injct_out.data);
end
`endif
495,24 → 535,20
genvar i;
generate
for(i=0;i<V;i=i+1) begin : vc_loop
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset)begin
credit[i]<= credit_init_val_in[i][DEPTH_WIDTH-1:0];
end else begin
if( wr_in[i] && ~credit_in[i]) credit[i] <= credit[i]-1'b1;
if( ~wr_in[i] && credit_in[i]) credit[i] <= credit[i]+1'b1;
end //reset
end//always
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
credit[i]<= credit_init_val_in[i][DEPTH_WIDTH-1:0];
end else begin
if( wr_in[i] && ~credit_in[i]) credit[i] <= credit[i]-1'b1;
if( ~wr_in[i] && credit_in[i]) credit[i] <= credit[i]+1'b1;
end //reset
end//always
 
assign full_vc[i] = (credit[i] == {DEPTH_WIDTH{1'b0}});
assign nearly_full_vc[i]= (credit[i] == 1) | full_vc[i];
assign empty_vc[i] = (credit[i] == credit_init_val_in[i][DEPTH_WIDTH-1:0]);
end//for
endgenerate
assign full_vc[i] = (credit[i] == {DEPTH_WIDTH{1'b0}});
assign nearly_full_vc[i]= (credit[i] == 1) | full_vc[i];
assign empty_vc[i] = (credit[i] == credit_init_val_in[i][DEPTH_WIDTH-1:0]);
end//for
endgenerate
endmodule
 
 
526,130 → 562,132
 
 
module packet_injector_verilator
import pronoc_pkg::*;
(
//general
current_e_addr,
reset,
clk,
//noc port
chan_in,
chan_out,
//control interafce
pck_injct_in_data,
pck_injct_in_size,
pck_injct_in_endp_addr,
pck_injct_in_class_num,
pck_injct_in_init_weight,
pck_injct_in_vc,
pck_injct_in_pck_wr,
pck_injct_in_ready,
import pronoc_pkg::*;
(
//general
current_e_addr,
reset,
clk,
//noc port
chan_in,
chan_out,
//control interafce
pck_injct_in_data,
pck_injct_in_size,
pck_injct_in_endp_addr,
pck_injct_in_class_num,
pck_injct_in_init_weight,
pck_injct_in_vc,
pck_injct_in_pck_wr,
pck_injct_in_ready,
pck_injct_out_data,
pck_injct_out_size,
pck_injct_out_endp_addr,
pck_injct_out_class_num,
pck_injct_out_init_weight,
pck_injct_out_vc,
pck_injct_out_pck_wr,
pck_injct_out_ready,
pck_injct_out_distance,
pck_injct_out_h2t_delay,
min_pck_size
pck_injct_out_data,
pck_injct_out_size,
pck_injct_out_endp_addr,
pck_injct_out_class_num,
pck_injct_out_init_weight,
pck_injct_out_vc,
pck_injct_out_pck_wr,
pck_injct_out_ready,
pck_injct_out_distance,
pck_injct_out_h2t_delay,
min_pck_size
);
);
 
 
//general
input reset,clk;
input [EAw-1 :0 ] current_e_addr;
//general
input reset,clk;
input [EAw-1 :0 ] current_e_addr;
// the destination endpoint address
//NoC interface
input smartflit_chanel_t chan_in;
output smartflit_chanel_t chan_out;
//control interafce
// the destination endpoint address
//NoC interface
input smartflit_chanel_t chan_in;
output smartflit_chanel_t chan_out;
//control interafce
input [PCK_INJ_Dw-1 : 0] pck_injct_in_data;
input [PCK_SIZw-1 : 0] pck_injct_in_size;
input [EAw-1 : 0] pck_injct_in_endp_addr;
input [Cw-1 : 0] pck_injct_in_class_num;
input [WEIGHTw-1 : 0] pck_injct_in_init_weight;
input [V-1 : 0] pck_injct_in_vc;
input pck_injct_in_pck_wr;
input [V-1 : 0] pck_injct_in_ready;
input [PCK_INJ_Dw-1 : 0] pck_injct_in_data;
input [PCK_SIZw-1 : 0] pck_injct_in_size;
input [DAw-1 : 0] pck_injct_in_endp_addr;
input [Cw-1 : 0] pck_injct_in_class_num;
input [WEIGHTw-1 : 0] pck_injct_in_init_weight;
input [V-1 : 0] pck_injct_in_vc;
input pck_injct_in_pck_wr;
input [V-1 : 0] pck_injct_in_ready;
 
output [PCK_INJ_Dw-1 : 0] pck_injct_out_data;
output [PCK_SIZw-1 : 0] pck_injct_out_size;
output [EAw-1 : 0] pck_injct_out_endp_addr;
output [Cw-1 : 0] pck_injct_out_class_num;
output [WEIGHTw-1 : 0] pck_injct_out_init_weight;
output [V-1 : 0] pck_injct_out_vc;
output pck_injct_out_pck_wr;
output [V-1 : 0] pck_injct_out_ready;
output [DISTw-1 : 0] pck_injct_out_distance;
output [15 : 0] pck_injct_out_h2t_delay;
output [4 : 0] min_pck_size;
output [PCK_INJ_Dw-1 : 0] pck_injct_out_data;
output [PCK_SIZw-1 : 0] pck_injct_out_size;
output [DAw-1 : 0] pck_injct_out_endp_addr;
output [Cw-1 : 0] pck_injct_out_class_num;
output [WEIGHTw-1 : 0] pck_injct_out_init_weight;
output [V-1 : 0] pck_injct_out_vc;
output pck_injct_out_pck_wr;
output [V-1 : 0] pck_injct_out_ready;
output [DISTw-1 : 0] pck_injct_out_distance;
output [15 : 0] pck_injct_out_h2t_delay;
output [4 : 0] min_pck_size;
pck_injct_t pck_injct_in;
pck_injct_t pck_injct_out;
pck_injct_t pck_injct_in;
pck_injct_t pck_injct_out;
 
assign pck_injct_in.data = pck_injct_in_data;
assign pck_injct_in.size = pck_injct_in_size;
assign pck_injct_in.endp_addr = pck_injct_in_endp_addr;
assign pck_injct_in.class_num = pck_injct_in_class_num;
assign pck_injct_in.init_weight = pck_injct_in_init_weight;
assign pck_injct_in.vc = pck_injct_in_vc;
assign pck_injct_in.pck_wr = pck_injct_in_pck_wr;
assign pck_injct_in.ready = pck_injct_in_ready;
assign pck_injct_in.data = pck_injct_in_data;
assign pck_injct_in.size = pck_injct_in_size;
assign pck_injct_in.endp_addr = pck_injct_in_endp_addr;
assign pck_injct_in.class_num = pck_injct_in_class_num;
assign pck_injct_in.init_weight = pck_injct_in_init_weight;
assign pck_injct_in.vc = pck_injct_in_vc;
assign pck_injct_in.pck_wr = pck_injct_in_pck_wr;
assign pck_injct_in.ready = pck_injct_in_ready;
assign pck_injct_out_data = pck_injct_out.data;
assign pck_injct_out_size = pck_injct_out.size;
assign pck_injct_out_endp_addr = pck_injct_out.endp_addr;
assign pck_injct_out_class_num = pck_injct_out.class_num;
assign pck_injct_out_init_weight = pck_injct_out.init_weight;
assign pck_injct_out_vc = pck_injct_out.vc;
assign pck_injct_out_pck_wr = pck_injct_out.pck_wr;
assign pck_injct_out_ready = pck_injct_out.ready;
assign pck_injct_out_distance = pck_injct_out.distance;
assign pck_injct_out_h2t_delay = pck_injct_out.h2t_delay;
assign pck_injct_out_data = pck_injct_out.data;
assign pck_injct_out_size = pck_injct_out.size;
assign pck_injct_out_endp_addr = pck_injct_out.endp_addr;
assign pck_injct_out_class_num = pck_injct_out.class_num;
assign pck_injct_out_init_weight = pck_injct_out.init_weight;
assign pck_injct_out_vc = pck_injct_out.vc;
assign pck_injct_out_pck_wr = pck_injct_out.pck_wr;
assign pck_injct_out_ready = pck_injct_out.ready;
assign pck_injct_out_distance = pck_injct_out.distance;
assign pck_injct_out_h2t_delay = pck_injct_out.h2t_delay;
packet_injector injector (
.current_e_addr (current_e_addr ),
.reset (reset ),
.clk (clk ),
.chan_in (chan_in ),
.chan_out (chan_out ),
.pck_injct_in (pck_injct_in ),
.pck_injct_out (pck_injct_out ));
packet_injector injector (
.current_e_addr (current_e_addr ),
.reset (reset ),
.clk (clk ),
.chan_in (chan_in ),
.chan_out (chan_out ),
.pck_injct_in (pck_injct_in ),
.pck_injct_out (pck_injct_out ));
localparam
HDR_BYTE_NUM = HDR_MAX_DATw / 8, // = HDR_MAX_DATw / (8 - HDR_MAX_DATw %8)
HDR_DATA_w_tmp = HDR_BYTE_NUM * 8,
HDR_DATA_w = (PCK_INJ_Dw < HDR_DATA_w_tmp)? PCK_INJ_Dw : HDR_DATA_w_tmp,
REMAIN_DATw = PCK_INJ_Dw - HDR_DATA_w,
REMAIN_DAT_FLIT_I = (REMAIN_DATw / Fpay),
REMAIN_DAT_FLIT_F = (REMAIN_DATw % Fpay == 0)? 0 : 1,
REMAIN_DAT_FLIT = REMAIN_DAT_FLIT_I + REMAIN_DAT_FLIT_F,
CNTw = log2(REMAIN_DAT_FLIT),
MIN_PCK_SIZ = REMAIN_DAT_FLIT +1;
localparam
HDR_BYTE_NUM = HDR_MAX_DATw / 8, // = HDR_MAX_DATw / (8 - HDR_MAX_DATw %8)
HDR_DATA_w_tmp = HDR_BYTE_NUM * 8,
HDR_DATA_w =
(PCK_INJ_Dw < HDR_DATA_w_tmp)? PCK_INJ_Dw :
(HDR_DATA_w_tmp==0)? 1: HDR_DATA_w_tmp,
REMAIN_DATw = PCK_INJ_Dw - HDR_DATA_w,
REMAIN_DAT_FLIT_I = (REMAIN_DATw / Fpay),
REMAIN_DAT_FLIT_F = (REMAIN_DATw % Fpay == 0)? 0 : 1,
REMAIN_DAT_FLIT = REMAIN_DAT_FLIT_I + REMAIN_DAT_FLIT_F,
CNTw = log2(REMAIN_DAT_FLIT),
MIN_PCK_SIZ = REMAIN_DAT_FLIT +1;
assign min_pck_size = MIN_PCK_SIZ[4:0];
assign min_pck_size = MIN_PCK_SIZ[4:0];
 
 
// `ifdef VERILATOR
// logic endp_is_active /*verilator public_flat_rd*/ ;
//
// always @ (*) begin
// endp_is_active = 1'b0;
// if (chan_out.flit_chanel.flit_wr) endp_is_active=1'b1;
// if (chan_out.flit_chanel.credit > {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
// `ifdef VERILATOR
// logic endp_is_active /*verilator public_flat_rd*/ ;
//
// always @ (*) begin
// endp_is_active = 1'b0;
// if (chan_out.flit_chanel.flit_wr) endp_is_active=1'b1;
// if (chan_out.flit_chanel.credit > {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
/src_noc/pronoc_pkg.sv
1,4 → 1,4
`timescale 1ns/1ps
`include "pronoc_def.v"
/****************************************************************************
* pronoc_pkg.sv
****************************************************************************/
5,17 → 5,21
 
package pronoc_pkg;
`define NOC_LOCAL_PARAM
`include "noc_localparam.v"
 
`define INCLUDE_TOPOLOGY_LOCALPARAM
`include "topology_localparam.v"
 
 
 
localparam
Vw= log2(V),
Cw= (C==0)? 1 : log2(C),
26,8 → 30,8
SMART_NUM= (SMART_EN) ? SMART_MAX : 1,
NEV = NE * V,
T4 = 0,
BEw = (BYTE_EN)? log2(Fpay/8) : 1,
DELAYw = EAw+2; //Injector start delay counter width
BEw = (BYTE_EN)? log2(Fpay/8) : 1;
 
 
localparam CONGw= (CONGESTION_INDEX==3)? 3:
40,7 → 44,7
 
localparam
E_SRC_LSB =0, E_SRC_MSB = E_SRC_LSB + EAw-1,
E_DST_LSB = E_SRC_MSB +1, E_DST_MSB = E_DST_LSB + EAw-1,
E_DST_LSB = E_SRC_MSB +1, E_DST_MSB = E_DST_LSB + DAw-1,
DST_P_LSB = E_DST_MSB + 1, DST_P_MSB = DST_P_LSB + DSTPw-1,
CLASS_LSB = DST_P_MSB + 1, CLASS_MSB = CLASS_LSB + Cw -1,
MSB_CLASS = (C>1)? CLASS_MSB : DST_P_MSB,
178,7 → 182,8
logic flit_is_tail;
logic assigned_ovc_not_full;
logic [V-1 : 0] candidate_ovc;
logic [Cw-1 : 0] class_num;
logic [Cw-1 : 0] class_num;
logic single_flit_pck;
} ivc_info_t;
localparam IVC_INFO_w = $bits( ivc_info_t);
196,10 → 201,10
}ovc_info_t;
localparam OVC_INFO_w = $bits( ovc_info_t);
 
/*********************
* router_chanels
*********************/
206,7 → 211,7
typedef struct packed {
logic [EAw-1 : 0] src_e_addr;
logic [EAw-1 : 0] dest_e_addr;
logic [DAw-1 : 0] dest_e_addr;
logic [DSTPw-1 : 0] destport;
logic [Cw-1 : 0] message_class;
logic [WEIGHTw-1: 0] weight;
230,8 → 235,6
Fw = FLIT_w,
NEFw = NE *Fw;
typedef struct packed {
logic flit_wr;
logic [V-1 : 0] credit;
240,12 → 243,14
} flit_chanel_t;
localparam FLIT_CHANEL_w = $bits(flit_chanel_t);
localparam BYPASSw = log2(SMART_NUM+1);
typedef struct packed {
logic [SMART_NUM-1: 0] requests;
logic [V-1 : 0] ovc;
logic [EAw-1 : 0] dest_e_addr;
bit hdr_flit;
bit flit_in_bypassed;
logic [BYPASSw-1 : 0] bypassed_num;
} smart_chanel_t;
localparam SMART_CHANEL_w = $bits(smart_chanel_t);
252,11 → 257,15
 
localparam CRDTw = (B>LB) ? log2(B+1) : log2(LB+1);
typedef struct packed {
bit endp_port; // if it is one, it means the corresponding port is connected o an endpoint
logic [RAw-1: 0] neighbors_r_addr;
logic [V-1 :0] [CRDTw-1: 0] credit_init_val; // the connected port initial credit value. It is taken at reset time
logic [V-1 :0] [CRDTw-1: 0] credit_init_val; // the connected port initial credit value. It is taken at reset time
logic [V-1 :0] credit_release_en;
} ctrl_chanel_t;
localparam CTRL_CHANEL_w = $bits(ctrl_chanel_t);
typedef struct packed {
flit_chanel_t flit_chanel;
smart_chanel_t smart_chanel;
270,6 → 279,9
/***********
* simulation
* **********/
localparam DELAYw = EAw+2; //Injector start delay counter width
typedef struct packed {
integer ip_num;
bit send_enable;
290,7 → 302,7
typedef struct packed {
logic [PCK_INJ_Dw-1 : 0] data;
logic [PCK_SIZw-1 : 0] size;
logic [EAw-1 : 0] endp_addr;
logic [DAw-1 : 0] endp_addr;
logic [Cw-1 : 0] class_num;
logic [WEIGHTw-1 : 0] init_weight;
logic [V-1 : 0] vc;
301,7 → 313,16
} pck_injct_t;
localparam PCK_INJCT_w = $bits(pck_injct_t);
typedef struct packed {
logic [BYPASSw-1 : 0] bypassed_num;
bit flit_wr_i;
bit pck_wr_i;
bit flit_wr_o;
bit pck_wr_o;
bit flit_in_bypassed;
} router_event_t;
localparam ROUTER_EVENT_w = $bits(router_event_t);
endpackage : pronoc_pkg
 
/src_noc/router_bypass.sv
1,4 → 1,4
`timescale 1ns / 1ps
`include "pronoc_def.v"
 
/**************************************
* Module: router_bypass
7,7 → 7,7
*
* Description:
* This file contains HDL modules that can be added
* to a 3-stage NoC router and provide router bypassing
* to a 2-stage NoC router and provides router bypassing
***************************************/
 
/**************************
20,25 → 20,7
* lk-ahead routing, The packet can by-pass the next router once the bypassing condition are met
***************************/
 
module register #(parameter W=1)(
input [W-1:0] in,
input reset,
input clk,
output reg [W-1:0] out
);
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
out<={W{1'b0}};
end else begin
out<=in;
end
end
endmodule
`include "pronoc_def.v"
 
module reduction_or #(
115,8 → 97,45
endmodule
 
module onehot_mux_1D_reverse #(
parameter W = 5,//out width p
parameter N = 4 //sel width v
)(
input [W*N-1 : 0] in,
input [N-1 : 0] sel,
output [W-1 : 0] out
);
 
wire [N-1 : 0] in_array [W-1 : 0];
wire [W-1 : 0] in_array2[N-1 : 0];
 
genvar i,j;
generate
for (i=0;i<W;i++)begin :sep
assign in_array[i] = in[(i+1)*N-1 : i*N];
for (j=0;j<N;j++)begin :sep
assign in_array2[j][i] = in_array[i][j];
end
end
endgenerate
 
onehot_mux_2D #(
.W (N ),
.N (W )
) onehot_mux_2D (
.in (in_array2 ),
.sel (sel ),
.out (out ));
endmodule
 
 
 
 
 
 
module header_flit_info
import pronoc_pkg::*;
#(
295,7 → 314,7
assign ovc_locally_requested_next[i][j]=|mask_gen[i][j];
end//V
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]));
337,10 → 356,12
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].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}} ;
if( ADD_PIPREG_AFTER_CROSSBAR == 1 ) begin :link_reg
register #(
pronoc_register #(
.W ( SMART_CHANEL_w )
) register (
.in (smart_chanel_next[i] ),
353,12 → 374,8
end
/*
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
smart_chanel[i].dest_e_addr<= {EAw{1'b0}};
smart_chanel[i].ovc<= {V{1'b0}};
smart_chanel[i].hdr_flit<=1'b0;
448,6 → 465,7
always @(*) begin
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].bypassed_num = smart_chanel_in [i].bypassed_num +1'b1;
end
assign smart_req[i]=rq[i];
// mux out smart chanel
488,7 → 506,7
generate
/* verilator lint_off WIDTH */
if(TOPOLOGY == "MESH" || TOPOLOGY == "TORUS" ) begin :twoD
if(TOPOLOGY == "MESH" || TOPOLOGY == "TORUS" || TOPOLOGY =="FMESH" ) begin :twoD
/* verilator lint_on WIDTH */
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
618,8 → 636,8
wire smart_hdr_flit_req_next = smart_req_valid_next & smart_hdr_flit;
logic smart_hdr_flit_req;
register #(.W(1)) req1 (.in(smart_req_valid_next), .reset(reset), .clk(clk), .out(smart_req_valid));
register #(.W(1)) req2 (.in(smart_hdr_flit_req_next), .reset(reset), .clk(clk), .out(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)) req2 (.in(smart_hdr_flit_req_next), .reset(reset), .clk(clk), .out(smart_hdr_flit_req));
 
 
 
671,7 → 689,7
assign smart_mask_available_ss_ovc_o = smart_hdr_flit_req & ~ovc_locally_requested & condition2;
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
753,7 → 771,7
/* verilator lint_off WIDTH */
localparam LOCATED_IN_NI=
(TOPOLOGY=="RING" || TOPOLOGY=="LINE") ? (SW_LOC == 0 || SW_LOC>2) :
(TOPOLOGY =="MESH" || TOPOLOGY=="TORUS")? (SW_LOC == 0 || SW_LOC>4) : 0;
(TOPOLOGY =="MESH" || TOPOLOGY=="TORUS" || TOPOLOGY == "FMESH")? (SW_LOC == 0 || SW_LOC>4) : 0;
/* verilator lint_on WIDTH */
// does the route computation for the current router
777,7 → 795,7
.destport (destport)
);
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 #(
.TOPOLOGY ( TOPOLOGY ),
811,7 → 829,7
.destport (lkdestport)
);
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
assign ss_ovc_crossbar_wr = (ss_smart_chanel_new.requests[0] ) ? ss_smart_chanel_new.ovc : {V{1'b0}};
869,7 → 887,7
endgenerate
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
929,7 → 947,7
 
assign credit_out = credit_in | smart_credit_in | (counter > 0);
 
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
/src_noc/router_top.sv
1,4 → 1,4
`timescale 1ns / 1ps
`include "pronoc_def.v"
/****************************************************************************
16,13 → 16,16
# (
parameter P = 5 // router port num
)(
current_r_addr,// connected to constant parameter
current_r_id,
current_r_addr,
chan_in,
chan_out,
router_event,
clk,
reset
reset
);
30,12 → 33,16
localparam DISABLED =P;
 
input [RAw-1 : 0] current_r_addr;
input [31 : 0] current_r_id;
input smartflit_chanel_t chan_in [P-1 : 0];
output smartflit_chanel_t chan_out [P-1 : 0];
output router_event_t router_event [P-1 : 0];
input clk,reset;
genvar i,j;
57,30 → 64,52
$display("ERROR: The minimum packet size must be set as one for single-flit packet type NoC");
$finish;
end
end
if(((SSA_EN=="YES") || (SMART_EN==1'b1) ) && CAST_TYPE!="UNICAST") begin
$display("ERROR: SMART or SAA do not support muticast/braodcast packets");
$finish;
end
end
/* verilator lint_on WIDTH */
logic report_active_ivcs = 0;
generate
for (i=0; i<P; i=i+1) begin :P_
for (i=0; i<P; i=i+1) begin :P1_
for (j=0; j<V; j=j+1) begin :V_
always @ (posedge report_active_ivcs) begin
if(ivc_info[i][j].ivc_req) $display("%t : The IVC in router[%h] port[%d] VC [%d] is not empty",$time,current_r_addr,i,j);
end
end
always @ (posedge report_active_ivcs) begin
if(ivc_info[i][j].ivc_req) $display("%t : The IVC in router[%h] port[%d] VC [%d] is not empty",$time,current_r_addr,i,j);
end
end
end
endgenerate
/* verilator lint_on WIDTH */
//synopsys translate_on
//synthesis translate_on
generate
for (i=0; i<P; i=i+1) begin :P2_
assign router_event[i].flit_wr_i = chan_in[i].flit_chanel.flit_wr;
assign router_event[i].bypassed_num = chan_in[i].smart_chanel.bypassed_num;
assign router_event[i].pck_wr_i = chan_in[i].flit_chanel.flit_wr & chan_in[i].flit_chanel.flit.hdr_flag;
assign router_event[i].flit_wr_o = chan_out[i].flit_chanel.flit_wr;
assign router_event[i].pck_wr_o = chan_out[i].flit_chanel.flit_wr & chan_out[i].flit_chanel.flit.hdr_flag;
assign router_event[i].flit_in_bypassed = chan_out[i].smart_chanel.flit_in_bypassed;
end
endgenerate
flit_chanel_t r2_chan_in [P-1 : 0];
flit_chanel_t r2_chan_out [P-1 : 0];
101,6 → 130,7
for (i=0; i<P; i=i+1) begin :Pt_
assign ctrl_in [i] = chan_in[i].ctrl_chanel;
assign chan_out[i].ctrl_chanel= ctrl_out [i];
end
endgenerate
142,6 → 172,28
.flit_in_wr(chan_in[i].flit_chanel.flit_wr),
.vc_num_in(chan_in[i].flit_chanel.flit.vc)
);
check_pck_size #(
.V(V),
.MIN_PCK_SIZE(MIN_PCK_SIZE),
.Fw(Fw),
.DAw(DAw),
.CAST_TYPE(CAST_TYPE),
.NE(NE),
.B(B),
.LB(LB)
)
check_pck_siz
(
.clk(clk),
.reset(reset),
.hdr_flg_in(chan_in[i].flit_chanel.flit.hdr_flag),
.tail_flg_in(chan_in[i].flit_chanel.flit.tail_flag),
.flit_in_wr(chan_in[i].flit_chanel.flit_wr),
.vc_num_in(chan_in[i].flit_chanel.flit.vc),
.dest_e_addr_in(chan_in[i].flit_chanel.flit.payload[E_DST_MSB : E_DST_LSB])
);
end
166,6 → 218,7
.oport_info (oport_info),
.smart_ctrl_in (smart_ctrl),
.current_r_addr(current_r_addr),
.current_r_id(current_r_id),
.chan_in (r2_chan_in),
.chan_out (r2_chan_out),
.ctrl_in (ctrl_in),
229,7 → 282,7
.reset (reset ),
.current_r_addr_i (current_r_addr ),
.neighbors_r_addr_i (neighbors_r_addr ),
.smart_chanel_i (chan_in[i].smart_chanel ),
.smart_chanel_i (chan_in[i].smart_chanel ),
.flit_chanel_i (chan_in[i].flit_chanel ),
.ivc_info (ivc_info[i] ),
.ss_ovc_info (ovc_info[SS_PORT] ),
271,15 → 324,20
// synthesis translate_on
assign smart_chanel_in[i] = chan_in[i].smart_chanel;
assign chan_out[i].smart_chanel = smart_chanel_out[i];
//r2 demux
// flit_in_wr demux
always @(*) begin
chan_out[i].smart_chanel = smart_chanel_out[i];
chan_out[i].smart_chanel.flit_in_bypassed =smart_ctrl[i].smart_en & chan_in[i].flit_chanel.flit_wr ;
//mask only flit_wr if smart_en is asserted
r2_chan_in[i] = chan_in[i].flit_chanel;
//can replace destport here and remove lk rout from internal router
if (smart_ctrl[i].smart_en) r2_chan_in[i].flit_wr = 1'b0;
//send flit_in to straight out port. Replace lk destport in header flit
ss_flit_chanel[SS_PORT] = chan_in[i].flit_chanel;
350,7 → 408,7
// end
// if (not_ideal) router_is_ideal =1'b0; // delay one clock cycle if the input req exist in last clock cycle bot not on the current one
// end
// register #( .W(1)) no_ideal_register (.in(not_ideal_next), .reset (reset), .clk(clk), .out (not_ideal));
// pronoc_register #( .W(1)) no_ideal_register (.in(not_ideal_next), .reset (reset), .clk(clk), .out (not_ideal));
//`endif
366,10 → 424,13
parameter P = 5 // router port num
)(
current_r_addr,
current_r_id,
chan_in,
chan_out,
router_event,
clk,
reset
 
378,19 → 439,25
 
input [RAw-1 : 0] current_r_addr;
input [31:0] current_r_id;
input smartflit_chanel_t chan_in [P-1 : 0];
output smartflit_chanel_t chan_out [P-1 : 0];
input reset,clk;
 
input reset,clk;
output router_event_t router_event [P-1 : 0];
router_top # (
.P(P)
)
router
(
.current_r_id(current_r_id),
.current_r_addr(current_r_addr),
.chan_in (chan_in),
.chan_out(chan_out),
.chan_out(chan_out),
.router_event(router_event),
.clk(clk),
.reset(reset)
);
/src_noc/router_two_stage.sv
1,4 → 1,4
`timescale 1ns/1ps
`include "pronoc_def.v"
 
//`define MONITORE_PATH
 
36,6 → 36,7
# (
parameter P = 6 // router port num
)(
current_r_id,
current_r_addr,// connected to constant parameter
chan_in,
64,6 → 65,7
// compilation time. Note that they wont be implemented as input ports in the final synthesized code.
 
input [RAw-1 : 0] current_r_addr;
input [31:0] current_r_id;
input flit_chanel_t chan_in [P-1 : 0];
output flit_chanel_t chan_out [P-1 : 0];
97,8 → 99,8
PRAw= P * RAw;
flit_chanel_t chan_in_tmp [P-1 : 0];
 
wire [PFw-1 : 0] flit_in_all;
111,8 → 113,8
wire [PV-1 : 0] credit_in_all;
wire [CONG_ALw-1 : 0] congestion_out_all;
wire [PV-1 : 0] credit_release_out;
 
// old router verilog code
138,7 → 140,7
wire [PV-1 : 0] ivc_request_all;
wire [PV-1 : 0] assigned_ovc_not_full_all;
wire [PVV-1: 0] masked_ovc_request_all;
wire [PV-1 : 0] pck_is_single_flit_all;
wire [PV-1 : 0] vc_weight_is_consumed_all;
wire [P-1 : 0] iport_weight_is_consumed_all;
wire [PV-1 : 0] vsa_ovc_released_all;
147,7 → 149,7
// to/from the crossbar
wire [PFw-1 : 0] iport_flit_out_all;
wire [P-1 : 0] ssa_flit_wr_all;
reg [PP_1-1 : 0] granted_dest_port_all_delayed;
logic [PP_1-1 : 0] granted_dest_port_all_delayed;
wire [PFw-1 : 0] crossbar_flit_out_all;
wire [P-1 : 0] crossbar_flit_out_wr_all;
wire [PFw-1 : 0] link_flit_out_all;
168,20 → 170,46
genvar i,j;
generate for (i=0; i<P; i=i+1 ) begin :p_
generate
for (i=0; i<P; i=i+1 ) begin :p_
if(CAST_TYPE == "UNICAST") begin : uni
assign chan_in_tmp[i] = chan_in[i];
end else begin : multi
multicast_chan_in_process #(
.P(P),
.SW_LOC (i)
) multicast_process (
.endp_port (ctrl_in[i].endp_port),
.current_r_addr (current_r_addr ),
.chan_in (chan_in[i] ),
.chan_out (chan_in_tmp[i] ),
.clk (clk)
);
end
assign neighbors_r_addr [(i+1)*RAw-1: i*RAw] = ctrl_in[i].neighbors_r_addr;
assign flit_in_all [(i+1)*Fw-1: i*Fw] = chan_in[i].flit;
assign flit_in_wr_all [i] = chan_in[i].flit_wr;
assign credit_in_all [(i+1)*V-1: i*V] = chan_in[i].credit;
assign congestion_in_all [(i+1)*CONGw-1: i*CONGw] = chan_in[i].congestion;
assign flit_in_all [(i+1)*Fw-1: i*Fw] = chan_in_tmp[i].flit;
assign flit_in_wr_all [i] = chan_in_tmp[i].flit_wr;
assign credit_in_all [(i+1)*V-1: i*V] = chan_in_tmp[i].credit;
assign congestion_in_all [(i+1)*CONGw-1: i*CONGw] = chan_in_tmp[i].congestion;
assign ctrl_out[i].neighbors_r_addr = current_r_addr;
assign ctrl_out[i].endp_port =1'b0;
assign chan_out[i].flit= flit_out_all [(i+1)*Fw-1: i*Fw];
assign chan_out[i].flit_wr= flit_out_wr_all [i];
assign chan_out[i].credit= credit_out_all [(i+1)*V-1: i*V];
assign chan_out[i].credit= credit_out_all [(i+1)*V-1: i*V] | credit_release_out [(i+1)*V-1: i*V];
assign chan_out[i].congestion= congestion_out_all [(i+1)*CONGw-1: i*CONGw];
assign iport_info[i].swa_first_level_grant =nonspec_first_arbiter_granted_ivc_all[(i+1)*V-1: i*V];
assign iport_info[i].swa_grant = ivc_num_getting_sw_grant[(i+1)*V-1: i*V];
assign iport_info[i].any_ivc_get_swa_grant= any_ivc_sw_request_granted_all[i];
209,10 → 237,29
end
for (j=0;j<V;j++)begin :V_
assign credit_init_val_in[i][j] = ctrl_in[i].credit_init_val[j];
assign ctrl_out[i].credit_init_val[j] = credit_init_val_out [i][j];
//credit_release. Only activated for local ports as credit_release_en never be asserted in router to router connection.
credit_release_gen #(
.CREDIT_NUM (LB)
) credit_release_gen (
.clk (clk ),
.reset (reset ),
.en (ctrl_in[i].credit_release_en[j] ),
.credit_out (credit_release_out[i*V+j] )
);
assign ctrl_out[i].credit_release_en[j] =1'b0;
assign credit_init_val_in[i][j] = ctrl_in[i].credit_init_val[j];
assign ctrl_out[i].credit_init_val[j] = credit_init_val_out [i][j];
end
end
endgenerate
231,8 → 278,7
.flit_in_wr_all(flit_in_wr_all),
.credit_out_all(credit_out_all),
.credit_in_all(credit_in_all),
.masked_ovc_request_all(masked_ovc_request_all),
.pck_is_single_flit_all(pck_is_single_flit_all),
.masked_ovc_request_all(masked_ovc_request_all),
.granted_dst_is_from_a_single_flit_pck(granted_dst_is_from_a_single_flit_pck),
.vsa_ovc_allocated_all(ovc_allocated_all),
.granted_ovc_num_all(granted_ovc_num_all),
276,23 → 322,12
 
 
combined_vc_sw_alloc #(
.V(V),
.P(P),
.COMBINATION_TYPE(COMBINATION_TYPE),
.FIRST_ARBITER_EXT_P_EN (FIRST_ARBITER_EXT_P_EN),
.SWA_ARBITER_TYPE (SWA_ARBITER_TYPE ),
.DEBUG_EN(DEBUG_EN),
.MIN_PCK_SIZE(MIN_PCK_SIZE),
.SELF_LOOP_EN(SELF_LOOP_EN)
.P(P)
)
vsa
(
.dest_port_all(dest_port_all),
.masked_ovc_request_all(masked_ovc_request_all),
.ovc_is_assigned_all(ovc_is_assigned_all),
.ivc_request_all(ivc_request_all),
.assigned_ovc_not_full_all(assigned_ovc_not_full_all),
.pck_is_single_flit_all(pck_is_single_flit_all),
.masked_ovc_request_all(masked_ovc_request_all),
.granted_dst_is_from_a_single_flit_pck(granted_dst_is_from_a_single_flit_pck),
.ovc_allocated_all(ovc_allocated_all),
.granted_ovc_num_all(granted_ovc_num_all),
309,26 → 344,14
// .lk_destination_all(lk_destination_all),
.vc_weight_is_consumed_all(vc_weight_is_consumed_all),
.iport_weight_is_consumed_all(iport_weight_is_consumed_all),
.ivc_info(ivc_info),
.clk(clk),
.reset(reset)
);
pronoc_register #(.W(PP_1)) reg2 (.in(granted_dest_port_all ), .out(granted_dest_port_all_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
granted_dest_port_all_delayed<= {PP_1{1'b0}};
end else begin
granted_dest_port_all_delayed<= granted_dest_port_all;
end
end//always
crossbar #(
.TOPOLOGY(TOPOLOGY),
358,21 → 381,11
reg [PFw-1 : 0] flit_out_all_pipe;
reg [P-1 : 0] flit_out_wr_all_pipe;
pronoc_register #(.W(PFw)) reg1 (.in(crossbar_flit_out_all ), .out(flit_out_all_pipe), .reset(reset), .clk(clk));
pronoc_register #(.W(P) ) reg2 (.in(crossbar_flit_out_wr_all ), .out(flit_out_wr_all_pipe), .reset(reset), .clk(clk));
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset)begin
flit_out_all_pipe <= {PFw{1'b0}};
flit_out_wr_all_pipe <= {P{1'b0}};
end else begin
flit_out_all_pipe <= crossbar_flit_out_all;
flit_out_wr_all_pipe <= crossbar_flit_out_wr_all;
end
end
assign link_flit_out_all = flit_out_all_pipe;
assign link_flit_out_wr_all = flit_out_wr_all_pipe;
493,14 → 506,16
t1[i]<=1'b0;
t2[i]<=1'b0;
end else begin
if(flit_out_wr_all[i]>0 && t2[i]==0)begin
$display("%t :Out router (id=%d, addr=%h, port=%d), flitout=%h",$time,current_r_id,current_r_addr,i,flit_out_all[(i+1)*Fw-1 : i*Fw]);
t2[i]<=1;
end
if(flit_in_wr_all[i]>0 && t1[i]==0)begin
$display("%t :In router (addr=%h, port=%d), flitin=%h",$time,current_r_addr,i,flit_in_all[(i+1)*Fw-1 : i*Fw]);
$display("%t :In router (id=%d, addr=%h, port=%d), flitin=%h",$time,current_r_id,current_r_addr,i,flit_in_all[(i+1)*Fw-1 : i*Fw]);
t1[i]<=1;
end
if(flit_out_wr_all[i]>0 && t2[i]==0)begin
$display("%t :Out router (addr=%h, port=%d), flitout=%h",$time,current_r_addr,i,flit_out_all[(i+1)*Fw-1 : i*Fw]);
t2[i]<=1;
end
end
518,8 → 533,8
reg [10 : 0] counter;
reg [31 : 0] flit_counter;
always @(posedge clk or posedge reset) begin
if(reset) begin
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
flit_counter <=0;
counter <= 0;
end else begin
542,3 → 557,46
 
endmodule
 
 
 
module credit_release_gen
import pronoc_pkg::*;
#(
parameter CREDIT_NUM=4
)(
clk,
reset,
en,
credit_out
);
input clk, reset;
input en;
output reg credit_out;
localparam W=log2(CREDIT_NUM +1);
reg [W-1 : 0] counter;
wire counter_is_zero = counter=={W{1'b0}};
wire counter_is_max = counter==CREDIT_NUM;
wire counter_incr = (en & counter_is_zero ) | (~counter_is_zero & ~counter_is_max);
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
counter <= {W{1'b0}};
credit_out<=1'b0;
end else begin
if(counter_incr) begin
counter<= counter +1'b1;
credit_out<=1'b1;
end else begin
credit_out<=1'b0;
end
end
end
endmodule
 
/src_noc/routing.v
266,13 → 266,14
*************************************/
 
module look_ahead_routing #(
parameter P =5,
parameter P = 5,
parameter T1= 8,
parameter T2= 8,
parameter T3= 8,
parameter T4= 8,
parameter RAw = 3,
parameter EAw = 3,
parameter EAw = 3,
parameter DAw = 3,
parameter DSTPw=P-1,
parameter SW_LOC =0,
parameter TOPOLOGY ="MESH",//"MESH","TORUS"
312,7 → 313,7
input [PRAw-1: 0] neighbors_r_addr;
input [RAw-1 : 0] current_r_addr;
input [EAw-1 : 0] dest_e_addr;
input [DAw-1 : 0] dest_e_addr;
input [EAw-1 : 0] src_e_addr;
input [DSTPw-1 : 0] destport_encoded;
output [DSTPw-1 : 0] lkdestport_encoded;
/src_noc/ss_allocator.sv
1,4 → 1,4
`timescale 1ns / 1ps
`include "pronoc_def.v"
 
/**********************************************************************
** File: ss_allocator.v
47,12 → 47,11
any_ovc_granted_in_outport_all ,
any_ivc_sw_request_granted_all ,
ovc_avalable_all,
assigned_ovc_not_full_all,
ivc_request_all,
dest_port_encoded_all,
assigned_ovc_num_all,
ovc_is_assigned_all,
// assigned_ovc_not_full_all,
// dest_port_encoded_all,
// assigned_ovc_num_all,
// ovc_is_assigned_all,
ivc_info,
ssa_ctrl_o
);
 
85,12 → 84,10
input [P-1 : 0] any_ovc_granted_in_outport_all;
input [P-1 : 0] any_ivc_sw_request_granted_all;
input [PV-1 : 0] ovc_avalable_all;
input [PV-1 : 0] assigned_ovc_not_full_all;
input [PV-1 : 0] ivc_request_all;
input [PVDSTPw-1 : 0] dest_port_encoded_all;
input [PVV-1 : 0] assigned_ovc_num_all;
input [PV-1 : 0] ovc_is_assigned_all;
input reset,clk;
input ivc_info_t ivc_info [P-1 : 0][V-1 : 0];
output ssa_ctrl_t ssa_ctrl_o [P-1 : 0];
 
 
102,7 → 99,7
wire [PV-1 : 0] ivc_reset_all;
wire [PV-1 : 0] single_flit_pck_all,ovc_single_flit_pck_all;
wire [PV-1 : 0] decreased_credit_in_ss_ovc_all;
reg [P-1 : 0] ssa_flit_wr_all;
wire [P-1 : 0] ssa_flit_wr_all;
wire [PV-1 : 0] any_ovc_granted_in_ss_port;
112,8 → 109,12
wire [PV-1 : 0] decreased_credit_in_ss_ovc;
wire [PV-1 : 0] ivc_num_getting_sw_grantin_SS_all;
 
wire [PV-1 : 0] ivc_request_all;
wire [PV-1 : 0] assigned_ovc_not_full_all;
wire [PVDSTPw-1 : 0] dest_port_encoded_all;
wire [PVV-1 : 0] assigned_ovc_num_all;
wire [PV-1 : 0] ovc_is_assigned_all;
 
 
genvar i;
// there is no ssa for local port in 5 and 3 port routers
generate
121,6 → 122,14
localparam C_PORT = i/V;
localparam SS_PORT = strieght_port (P,C_PORT);
assign ivc_request_all[i] = ivc_info[C_PORT][i%V].ivc_req;
assign assigned_ovc_not_full_all[i] = ivc_info[C_PORT][i%V].assigned_ovc_not_full;
assign dest_port_encoded_all [(i+1)*DSTPw-1 : i*DSTPw] = ivc_info[C_PORT][i%V].dest_port_encoded;
assign assigned_ovc_num_all[(i+1)*V-1 : i*V] = ivc_info[C_PORT][i%V].assigned_ovc_num;
assign ovc_is_assigned_all[i] = ivc_info[C_PORT][i%V].ovc_is_assigned;
if (SS_PORT == DISABLED)begin : no_prefrable
188,19 → 197,16
end// vc_loop
for(i=0;i<P;i=i+1)begin: P_
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset)begin
ssa_flit_wr_all[i]<=1'b0;
end else begin
ssa_flit_wr_all[i]<= |ivc_num_getting_sw_grantin_SS_all[(i+1)*V-1 : i*V];
end //reset
end// always
for(i=0;i<P;i=i+1)begin: P_
pronoc_register #(.W(1)) reg1 (
.in(|ivc_num_getting_sw_grantin_SS_all[(i+1)*V-1 : i*V] ),
.out(ssa_flit_wr_all[i]),
.reset(reset),
.clk(clk));
 
assign ssa_ctrl_o[i].ovc_is_allocated =ovc_allocated_all [(i+1)*V-1 : i*V];
/src_noc/star_noc.sv
1,4 → 1,4
`timescale 1ns / 1ps
`include "pronoc_def.v"
 
/**************************************
* Module: tree
19,14 → 19,18
reset,
clk,
chan_in_all,
chan_out_all
chan_out_all,
router_event
);
input clk,reset;
//local ports
//Endpoints ports
input smartflit_chanel_t chan_in_all [NE-1 : 0];
output smartflit_chanel_t chan_out_all [NE-1 : 0];
//Events
output router_event_t router_event [NR-1 : 0][MAX_P-1 : 0];
router_top # (
34,9 → 38,11
)
the_router
(
.current_r_id (0),
.current_r_addr (1'b0),
.chan_in (chan_in_all),
.chan_out (chan_out_all),
.router_event (router_event[0]),
.clk (clk ),
.reset (reset )
);
/src_noc/topology_localparam.v
19,9 → 19,8
//LINE RING Topology p=3
localparam FORWARD = 1,
BACKWARD= 2;
function automatic integer log2;
input integer number; begin
log2=(number <=1) ? 1: 0;
109,12 → 108,17
end
endfunction
 
/*******************
* "RING" "LINE" "MESH" TORUS" "FMESH"
******************/
 
 
 
 
/* verilator lint_off WIDTH */
//route type
localparam
137,7 → 141,8
NR_MESH_TORI = (TOPOLOGY=="RING" || TOPOLOGY=="LINE")? NX : NX*NY,
NE_MESH_TORI = NR_MESH_TORI * NL,
MAX_P_MESH_TORI = R2R_CHANELS_MESH_TORI + R2E_CHANELS_MESH_TORI,
DSTPw_MESH_TORI = R2R_CHANELS_MESH_TORI; // P-1
DSTPw_MESH_TORI = R2R_CHANELS_MESH_TORI; // P-1
/* verilator lint_on WIDTH */
/****************
148,11 → 153,6
NR_FMESH = NR_MESH_TORI,
MAX_P_FMESH = 4 + NL,
EAw_FMESH = RAw_MESH_TORI + log2(MAX_P_FMESH);
/******************
170,7 → 170,8
NR_FATTREE = L * powi( K , L - 1 ), // total number of routers
ROUTE_TYPE_FATTREE = "DETERMINISTIC",
DSTPw_FATTREE = K+1,
MAX_P_FATTREE = 2*K;
MAX_P_FATTREE = 2*K,
DAw_MCAST_FATTREE= powi( K,L);
184,7 → 185,8
RAw_TREE = LKw + Lw,
EAw_TREE = LKw,
DSTPw_TREE = log2(K+1),
MAX_P_TREE = K+1;
MAX_P_TREE = K+1,
DAw_MCAST_TREE= DAw_MCAST_FATTREE;
 
/*********************
197,7 → 199,8
RAw_STAR = 1,
EAw_STAR = log2(NE_STAR),
DSTPw_STAR = EAw_STAR,
MAX_P_STAR = NE_STAR;
MAX_P_STAR = NE_STAR,
DAw_MCAST_STAR= NE_STAR;
/************************
* CUSTOM - made by netmaker
210,6 → 213,7
RAw_CUSTOM = log2(NR_CUSTOM),
MAX_P_CUSTOM = T3,
DSTPw_CUSTOM = log2(MAX_P_CUSTOM);
/* verilator lint_off WIDTH */
226,9 → 230,10
// destination port width in header flit
DSTPw =
// (CAST_TYPE!= "UNICAST")? MAX_P: // Each asserted bit indicats that the flit should be sent to that port
// Each asserted bit indicats that the flit should be sent to that port
(TOPOLOGY == "FATTREE")? DSTPw_FATTREE:
(TOPOLOGY == "TREE")? DSTPw_TREE:
(CAST_TYPE!= "UNICAST")? MAX_P:
(TOPOLOGY == "RING" || TOPOLOGY == "LINE" || TOPOLOGY == "MESH" || TOPOLOGY == "TORUS")? DSTPw_MESH_TORI:
(TOPOLOGY == "FMESH")? DSTPw_MESH_TORI:
(TOPOLOGY == "STAR") ? DSTPw_STAR:
248,7 → 253,7
(TOPOLOGY == "RING" || TOPOLOGY == "LINE" || TOPOLOGY == "MESH" || TOPOLOGY == "TORUS")? EAw_MESH_TORI:
(TOPOLOGY == "FMESH")? EAw_FMESH:
(TOPOLOGY == "STAR") ? EAw_STAR:
EAw_CUSTOM,
EAw_CUSTOM,
// total number of endpoints
NE =
(TOPOLOGY == "FATTREE")? NE_FATTREE:
257,6 → 262,27
(TOPOLOGY == "FMESH")? NE_FMESH:
(TOPOLOGY == "STAR")? NE_STAR:
NE_CUSTOM,
//Destination endpoint(s) address width
DAw_OFFSETw = (TOPOLOGY=="MESH" || TOPOLOGY=="TORUS" || TOPOLOGY=="FMESH")? NX : 0,
MCAST_PRTLw = mcast_partial_width( MCAST_ENDP_LIST),
MCASTw =
(CAST_TYPE == "MULTICAST_FULL") ? NE :
(CAST_TYPE == "MULTICAST_PARTIAL" && EAw >= MCAST_PRTLw) ? EAw +1 :
(CAST_TYPE == "MULTICAST_PARTIAL" && EAw < MCAST_PRTLw) ? MCAST_PRTLw +1 :
EAw +1, //broadcast
DAw =
(CAST_TYPE == "UNICAST") ? EAw:
MCASTw + DAw_OFFSETw,
//total number of routers
NR =
(TOPOLOGY == "FATTREE")? NR_FATTREE:
277,8 → 303,156
/* verilator lint_on WIDTH */
function automatic integer mcast_id_to_endp_id;
input integer mcast_id;
reg [NE-1 : 0] mcast_list;
integer k;
begin
mcast_list =MCAST_ENDP_LIST;
mcast_id_to_endp_id=0;
k=0;
/* verilator lint_off WIDTH */
if (CAST_TYPE == "MULTICAST_FULL")begin
/* verilator lint_on WIDTH */
mcast_id_to_endp_id =mcast_id;
end else begin
while( k!=mcast_id+1) begin
if( mcast_list[mcast_id_to_endp_id]==1'b1) begin
k=k+1;
end
mcast_id_to_endp_id= mcast_id_to_endp_id+1;
end
end
end
endfunction
function automatic integer endp_id_to_mcast_id;
input integer endp_id;
reg [NE-1 : 0] mcast_list;
integer i;
begin
/* verilator lint_off WIDTH */
if (CAST_TYPE == "MULTICAST_FULL") begin
/* verilator lint_on WIDTH */
endp_id_to_mcast_id = endp_id;
end else begin
mcast_list =MCAST_ENDP_LIST;
endp_id_to_mcast_id=0;
for (i=0;i<endp_id;i=i+1) begin
if( mcast_list[i]==1'b1) endp_id_to_mcast_id=endp_id_to_mcast_id+1;
end
end
end
endfunction
function automatic integer mcast_partial_width;
input [NE-1 : 0] p;
integer i;
begin
mcast_partial_width=0;
for (i=0;i<NE;i=i+1) begin
if (p [i]==1'b1) mcast_partial_width=mcast_partial_width+1;
end
end
endfunction
function automatic integer fmesh_addrencode;
input integer in;
integer y, x, l,p, diff,mul;begin
mul = NX*NY*NL;
if(in < mul) begin
y = ((in/NL) / NX );
x = ((in/NL) % NX );
l = (in % NL);
p = (l==0)? LOCAL : 4+l;
end else begin
diff = in - mul ;
if( diff < NX) begin //top mesh edge
y = 0;
x = diff;
p = NORTH;
end else if ( diff < 2* NX) begin //bottom mesh edge
y = NY-1;
x = diff-NX;
p = SOUTH;
end else if ( diff < (2* NX)+NY ) begin //left mesh edge
y = diff - (2* NX);
x = 0;
p = WEST;
end else begin //right mesh edge
y = diff - (2* NX) -NY;
x = NX-1;
p = EAST;
end
end//else
fmesh_addrencode = ( p<<(NXw+NYw) | (y<<NXw) | x);
end
endfunction // addrencode
// synthesis translate_off
/* verilator lint_off WIDTH */
task display_noc_parameters;
begin
//print_parameter
$display ("NoC parameters:----------------");
$display ("\tTopology: %s",TOPOLOGY);
$display ("\tRouting algorithm: %s",ROUTE_NAME);
$display ("\tVC_per port: %0d", V);
$display ("\tNon-local port buffer_width per VC: %0d", B);
$display ("\tLocal port buffer_width per VC: %0d", LB);
if(TOPOLOGY=="MESH" || TOPOLOGY=="TORUS" || TOPOLOGY == "FMESH")begin
$display ("\tRouter num in row: %0d",T1);
$display ("\tRouter num in column: %0d",T2);
$display ("\tEndpoint num per router: %0d",T3);
end else if (TOPOLOGY=="RING" || TOPOLOGY == "LINE") begin
$display ("\tTotal Router num: %0d",T1);
$display ("\tEndpoint num per router: %0d",T3);
end else if (TOPOLOGY == "TREE" || TOPOLOGY == "FATTREE")begin
$display ("\tK: %0d",T1);
$display ("\tL: %0d",T2);
end else begin //CUSTOM
$display ("\tTotal Endpoints number: %0d",T1);
$display ("\tTotal Routers number: %0d",T2);
end
$display ("\tNumber of Class: %0d", C);
$display ("\tFlit data width: %0d", Fpay);
$display ("\tVC reallocation mechanism: %s", VC_REALLOCATION_TYPE);
$display ("\tVC/sw combination mechanism: %s", COMBINATION_TYPE);
$display ("\tAVC_ATOMIC_EN:%0d", AVC_ATOMIC_EN);
$display ("\tCongestion Index:%0d",CONGESTION_INDEX);
$display ("\tADD_PIPREG_AFTER_CROSSBAR:%0d",ADD_PIPREG_AFTER_CROSSBAR);
$display ("\tSSA_EN enabled:%s",SSA_EN);
$display ("\tSwitch allocator arbitration type:%s",SWA_ARBITER_TYPE);
$display ("\tMinimum supported packet size:%0d flit(s)",MIN_PCK_SIZE);
$display ("\tLoop back is enabled:%s",SELF_LOOP_EN);
$display ("\tNumber of multihop bypass (SMART max):%0d",SMART_MAX);
$display ("\tCastying type:%s.",CAST_TYPE);
if (CAST_TYPE == "MULTICAST_PARTIAL" || CAST_TYPE == "BROADCAST_PARTIAL")begin
$display ("\tNumber of nodes in Cast list:%d", MCAST_PRTLw);
$display ("\tCAST LIST:%b", MCAST_ENDP_LIST);
end
$display ("NoC parameters:----------------");
end
endtask
/* verilator lint_on WIDTH */
// synthesis translate_on
`endif
 
/src_noc/traffic_gen_top.sv
1,4 → 1,4
`timescale 1ns/1ps
`include "pronoc_def.v"
 
module traffic_gen_top
import pronoc_pkg::*;
39,6 → 39,7
time_stamp_h2h,
time_stamp_h2t,
pck_size_o,
mcast_dst_num_o,
reset,
clk
78,7 → 79,7
// the current endpoint address
input [EAw-1 :0] current_e_addr;
// the destination endpoint address
input [EAw-1 :0] dest_e_addr;
input [DAw-1 :0] dest_e_addr;
output [PCK_CNTw-1 :0] pck_number;
input [PCK_SIZw-1 :0] pck_size_in;
93,6 → 94,7
// 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;
108,11 → 110,15
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;
124,7 → 130,10
assign chan_out.ctrl_chanel.credit_init_val[i]= PORT_B;
end
endgenerate
assign chan_out.ctrl_chanel.endp_port =1'b1;
assign chan_out.ctrl_chanel.credit_release_en={V{1'b0}};
//old traffic.v file
reg [2:0] ps,ns;
131,8 → 140,8
localparam IDEAL =3'b001, SENT =3'b010, WAIT=3'b100;
reg inject_en,cand_wr_vc_en,pck_rd;
reg [PCK_SIZw-1 :0] pck_size, pck_size_next;
reg [EAw-1 :0] dest_e_addr_reg;
reg [PCK_SIZw-1 :0] pck_size;
logic [DAw-1 :0] dest_e_addr_reg,dest_e_addr_o;
// synopsys translate_off
// synthesis translate_off
167,18 → 176,9
wire [HDR_Dw-1 : 0] hdr_data_in,rd_hdr_data_out;
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
dest_e_addr_reg<={EAw{1'b0}};
end else begin
dest_e_addr_reg<=dest_e_addr;
end
end
pronoc_register #(.W(DAw)) reg2 (.in(dest_e_addr ), .out(dest_e_addr_reg), .reset(reset), .clk(clk));
wire [DSTPw-1 : 0] destport;
wire [V-1 : 0] ovc_wr_in;
194,7 → 194,9
wire rd_hdr_flg,rd_tail_flg;
wire [Cw-1 : 0] rd_class_hdr;
// wire [P_1-1 : 0] rd_destport_hdr;
wire [EAw-1 : 0] rd_des_e_addr, rd_src_e_addr;
wire [DAw-1 : 0] rd_des_e_addr;
wire [EAw-1 : 0] rd_src_e_addr;
reg [CLK_CNTw-1 : 0] rsv_counter;
reg [CLK_CNTw-1 : 0] clk_counter;
wire [Vw-1 : 0] rd_vc_bin;//,wr_vc_bin;
215,8 → 217,8
logic [DELAYw-1 : 0] start_delay_counter,start_delay_counter_next;
logic start_en_next , start_en;
 
register #(.W(1)) streg1 (.reset(reset),.clk(clk), .in(start_en_next), .out(start_en) );
register #(.W(DELAYw)) streg2 (.reset(reset),.clk(clk), .in(start_delay_counter_next), .out(start_delay_counter) );
pronoc_register #(.W(1)) streg1 (.reset(reset),.clk(clk), .in(start_en_next), .out(start_en) );
pronoc_register #(.W(DELAYw)) streg2 (.reset(reset),.clk(clk), .in(start_delay_counter_next), .out(start_delay_counter) );
245,7 → 247,10
.T2(T2),
.T3(T3),
.EAw(EAw),
.SELF_LOOP_EN(SELF_LOOP_EN)
.SELF_LOOP_EN(SELF_LOOP_EN),
.DAw(DAw),
.CAST_TYPE(CAST_TYPE),
.NE(NE)
)
check_destination_addr(
.dest_e_addr(dest_e_addr),
265,7 → 270,7
pck_inject_ratio_ctrl
(
.en(inject_en),
.pck_size_in(pck_size_in),
.pck_size_in(pck_size_tmp),
.clk(clk),
.reset(reset),
.freez(buffer_full),
294,24 → 299,18
.reset (reset)
);
packet_gen #(
.P(MAX_P),
.T1(T1),
.T2(T2),
.T3(T3),
.RAw(RAw),
.EAw(EAw),
.TOPOLOGY(TOPOLOGY),
.DSTPw(DSTPw),
.ROUTE_NAME(ROUTE_NAME),
.P(MAX_P),
.PCK_TYPE(PCK_TYPE),
.ROUTE_TYPE(ROUTE_TYPE),
.MAX_PCK_NUM(MAX_PCK_NUM),
.MAX_SIM_CLKs(MAX_SIM_CLKs),
.TIMSTMP_FIFO_NUM(TIMSTMP_FIFO_NUM),
.MIN_PCK_SIZE(MIN_PCK_SIZE),
.MAX_PCK_SIZ(MAX_PCK_SIZ)
.MAX_PCK_SIZ(MAX_PCK_SIZ)
)
packet_buffer
(
323,15 → 322,19
.current_e_addr(current_e_addr),
.clk_counter(clk_counter+1'b1),//in case of zero load latency, the flit will be injected in the next clock cycle
.pck_number(pck_number),
.dest_e_addr(dest_e_addr_reg),
.dest_e_addr_in(dest_e_addr),
.dest_e_addr_o(dest_e_addr_o),
.pck_timestamp(pck_timestamp),
.buffer_full(buffer_full),
.pck_ready(pck_ready),
.valid_dst(valid_dst),
.destport(destport),
.pck_size_in(pck_size_in),
.pck_size_in(pck_size_tmp),
.pck_size_o(pck_size)
);
 
assign wr_timestamp =pck_timestamp;
366,7 → 369,7
.flit_out(hdr_flit_out),
.vc_num_in(wr_vc),
.class_in(pck_class_in),
.dest_e_addr_in(dest_e_addr_reg),
.dest_e_addr_in(dest_e_addr_o),
.src_e_addr_in(current_e_addr),
.weight_in(init_weight),
.destport_in(destport),
569,17 → 572,9
end else credit_out_next = {V{1'd0}};
end
always @ (*)begin
pck_size_next = pck_size;
if((tail_flit & flit_out_wr ) || not_yet_sent_aflit) pck_size_next = pck_size_in;
end
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
inject_en <= 1'b0;
ps <= IDEAL;
wr_vc <=1;
587,7 → 582,6
credit_out <= {V{1'd0}};
rsv_counter <= 0;
clk_counter <= 0;
//pck_size <= 0;
not_yet_sent_aflit<=1'b1;
end else begin
600,7 → 594,7
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;
//pck_size <= pck_size_next;
//sink
if(flit_in_wr) begin
639,29 → 633,130
end//always
// synopsys translate_off
// synthesis translate_off
localparam NEw=log2(NE);
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));
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
if(flit_out_wr && hdr_flit && dest_e_addr_reg == 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 );
$finish;
/* 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(flit_in_wr && rd_hdr_flg && (rd_des_e_addr != 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
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);
680,13 → 775,10
end
end
// synthesis translate_on
// synopsys translate_on
`ifdef CHECK_PCKS_CONTENT
// synopsys translate_off
// synthesis translate_off
wire [PCK_SIZw-1 : 0] rsv_flit_counter;
reg [PCK_SIZw-1 : 0] old_flit_counter [V-1 : 0];
704,18 → 796,15
integer ii;
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
for(ii=0;ii<V;ii=ii+1'b1)begin
old_flit_counter[ii]<=0;
end
end else begin
if(flit_in_wr)begin
if ( flit_in[Fw-1:Fw-2]==2'b10) begin
if ( flit_in[Fw-1:Fw-2]==2'b10) begin
old_pck_number[rd_vc_bin]<=0;
old_flit_counter[rd_vc_bin]<=0;
end else if ( flit_in[Fw-1:Fw-2]==2'b00)begin
723,10 → 812,10
old_flit_counter[rd_vc_bin]<=rsv_flit_counter;
end
end
end //flit_in_wr
end
end
end //reset
end//always
always @(posedge clk) begin
737,11 → 826,16
end
end
// synthesis translate_on
// synopsys translate_on
`endif
// synthesis translate_on
 
// `ifdef VERILATOR
// logic endp_is_active /*verilator public_flat_rd*/ ;
//
854,12 → 948,8
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if( reset) begin
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
state <= STATE_INIT;
inject <= 1'b0;
sent <= 1'b1;
893,16 → 983,11
**************************************/
 
module packet_gen #(
parameter P = 5,
parameter T1= 4,
parameter T2= 4,
parameter T3= 4,
parameter RAw = 3,
parameter EAw = 3,
parameter TOPOLOGY = "MESH",
parameter DSTPw = 4,
parameter ROUTE_NAME = "XY",
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,
909,7 → 994,6
parameter TIMSTMP_FIFO_NUM=16,
parameter MIN_PCK_SIZE=2,
parameter MAX_PCK_SIZ=100
 
)(
clk_counter,
pck_wr,
917,7 → 1001,8
current_r_addr,
current_e_addr,
pck_number,
dest_e_addr,
dest_e_addr_in,
dest_e_addr_o,
pck_timestamp,
destport,
buffer_full,
949,7 → 1034,8
input [EAw-1 : 0] current_e_addr;
input [CLK_CNTw-1 :0] clk_counter;
input [PCK_SIZw-1 :0] pck_size_in;
input [EAw-1 :0] dest_e_addr;
input [DAw-1 :0] dest_e_addr_in;
output [DAw-1 :0] dest_e_addr_o;
input valid_dst;
output [PCK_CNTw-1 :0] pck_number;
963,7 → 1049,7
assign pck_ready = ~buffer_empty & valid_dst;
generate if(CAST_TYPE == "UNICAST") begin : uni
conventional_routing #(
.TOPOLOGY(TOPOLOGY),
.ROUTE_NAME(ROUTE_NAME),
981,26 → 1067,29
.reset(reset),
.clk(clk),
.current_r_addr(current_r_addr),
.dest_e_addr(dest_e_addr),
.dest_e_addr(dest_e_addr_o),
.src_e_addr(current_e_addr),
.destport(destport)
);
 
end endgenerate
wire timestamp_fifo_nearly_full , timestamp_fifo_full;
assign buffer_full = (MIN_PCK_SIZE==1) ? timestamp_fifo_nearly_full : timestamp_fifo_full;
wire [DAw-1 :0] tmp1;
wire [PCK_SIZw-1 : 0] tmp2;
wire recieve_more_than_0;
fwft_fifo_bram #(
.DATA_WIDTH(CLK_CNTw+PCK_SIZw),
.DATA_WIDTH(CLK_CNTw+PCK_SIZw+DAw),
.MAX_DEPTH(TIMSTMP_FIFO_NUM)
)
timestamp_fifo
(
.din({pck_size_in,clk_counter}),
.din({dest_e_addr_in,pck_size_in,clk_counter}),
.wr_en(pck_wr),
.rd_en(pck_rd),
.dout({pck_size_o,pck_timestamp}),
.dout({tmp1,tmp2,pck_timestamp}),
.full(timestamp_fifo_full),
.nearly_full(timestamp_fifo_nearly_full),
.recieve_more_than_0(recieve_more_than_0),
1009,6 → 1098,12
.clk(clk)
);
//assign dest_e_addr_o = dest_e_addr_in;
assign dest_e_addr_o =tmp1;
/* verilator lint_off WIDTH */
assign pck_size_o = (PCK_TYPE == "SINGLE_FLIT" )? 1 : tmp2;
/* verilator lint_on WIDTH */
assign buffer_empty = ~recieve_more_than_0;
/*
1031,14 → 1126,9
);
*/
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
packet_counter <= {PCK_CNTw{1'b0}};
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
packet_counter <= {PCK_CNTw{1'b0}};
end else begin
if(pck_rd) begin
packet_counter <= packet_counter+1'b1;
/src_noc/tree_noc_top.sv
1,4 → 1,4
`timescale 1ns / 1ps
`include "pronoc_def.v"
 
/**************************************
* Module: tree
19,15 → 19,19
reset,
clk,
chan_in_all,
chan_out_all
chan_out_all,
router_event
);
input clk,reset;
//local ports
//Endpoints ports
input smartflit_chanel_t chan_in_all [NE-1 : 0];
output smartflit_chanel_t chan_out_all [NE-1 : 0];
//Events
output router_event_t router_event [NR-1 : 0][MAX_P-1 : 0];
//all routers port
smartflit_chanel_t router_chan_in [NR-1 :0][MAX_P-1 : 0];
smartflit_chanel_t router_chan_out [NR-1 :0][MAX_P-1 : 0];
86,9 → 90,11
)
root_router
(
.current_r_id (ROOT_ID),
.current_r_addr (current_r_addr [ROOT_ID]),
.chan_in (router_chan_in [ROOT_ID][K-1:0]),
.chan_out (router_chan_out[ROOT_ID][K-1:0]),
.router_event (router_event[ROOT_ID][K-1 : 0]),
.clk (clk ),
.reset (reset )
);
103,15 → 109,17
localparam NPOS1 = powi(K,level); // number of routers in this level
localparam NRATTOP1 = sum_powi ( K,level); // number of routers at top levels : from root until last level
for( pos=0; pos<NPOS1; pos=pos+1) begin : pos_lp
localparam RID = NRATTOP1+pos;
router_top # (
.P(K+1)// leaves have K+1 port number
)
the_router
(
.current_r_addr (current_r_addr [NRATTOP1+pos]),
.chan_in (router_chan_in [NRATTOP1+pos]),
.chan_out (router_chan_out[NRATTOP1+pos]),
.current_r_id (RID),
.current_r_addr (current_r_addr [RID]),
.chan_in (router_chan_in [RID]),
.chan_out (router_chan_out[RID]),
.router_event (router_event[RID]),
.clk (clk ),
.reset (reset )
);
/src_noc/tree_route.v
279,8 → 279,8
output [DSPw-1: 0] lkdestport_encoded;
input reset,clk;
reg [DSPw-1 :0] destport_encoded_delayed;
reg [LKw-1 :0] dest_addr_encoded_delayed;
wire [DSPw-1 :0] destport_encoded_delayed;
wire [LKw-1 :0] dest_addr_encoded_delayed;
tree_deterministic_look_ahead_routing #(
.P(P),
297,20 → 297,11
.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
 
/src_noc/wrra.v
37,6 → 37,8
** PROPOGATE_NEQ2 = (WRRA_CONFIG_INDEX==3 );
*****************************************************************/
 
`include "pronoc_def.v"
 
module wrra #(
parameter ARBITER_WIDTH = 8,
parameter WEIGHTw = 4, // maximum weight size in bits
219,7 → 221,8
output out;
wire [WEIGHTw-1 : 0] weight;
 
reg [WEIGHTw-1 : 0] counter,counter_next;
reg [WEIGHTw-1 : 0] counter_next;
wire [WEIGHTw-1 : 0] counter;
wire couner_zero, load;
assign couner_zero = counter == {WEIGHTw{1'b0}};
233,22 → 236,9
end
 
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if (reset)begin
counter<= {WEIGHTw{1'b0}};
end else begin
counter <= counter_next;
end //else
end //always
pronoc_register #(.W(WEIGHTw)) reg2 (.in(counter_next ), .out(counter), .reset(reset), .clk(clk));
 
 
endmodule
278,7 → 268,8
output out;
wire [WEIGHTw-1 : 0] weight;
 
reg [WEIGHTw-1 : 0] counter,counter_next;
reg [WEIGHTw-1 : 0] counter_next;
wire [WEIGHTw-1 : 0] counter;
wire couner_zero, load;
assign couner_zero = counter == {WEIGHTw{1'b0}};
292,21 → 283,9
end
 
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if (reset)begin
counter<= {WEIGHTw{1'b0}};
end else begin
counter <= counter_next;
end //else
end //always
pronoc_register #(.W(WEIGHTw)) reg2 (.in(counter_next ), .out(counter), .reset(reset), .clk(clk));
endmodule
 
 
415,12 → 394,9
assign oports_weight [(i+1)*W-1 : i*W] = {W{1'b0}};
end else begin :else1
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
 
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
oport_weight_counter[i]<=INIT_WEIGHT;
end else begin
if (weight_dcrease_en && counter_is_reset) oport_weight_counter[i]<= INIT_WEIGHT;
428,12 → 404,8
end
end //always
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
oport_weight[i]<={W{1'b0}};
end else begin
if (weight_dcrease_en && counter_is_reset) oport_weight[i]<= oport_weight_counter[i]; //capture oweight counters
468,12 → 440,8
assign oports_weight [(i+1)*W-1 : i*W] = {W{1'b0}};
end else begin :else1
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
oport_weight_counter[i]<= INIT_WEIGHT;
end else begin
if (weight_dcrease_en && counter_is_reset) oport_weight_counter[i]<= INIT_WEIGHT;
481,36 → 449,27
end
end //always
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
oport_weight[i]<={W{1'b0}};
end else begin
if(oport_weight[i]>iport_weight) oport_weight[i]<=iport_weight;// weight counter should always be smaller than iport weight
if(oport_weight[i]>iport_weight) oport_weight[i]<=iport_weight;// weight counter should always be smaller than iport weight
else if (weight_dcrease_en)begin
if( counter_is_reset ) begin
oport_weight[i]<= (oport_weight_counter[i]>0)? oport_weight_counter[i]: 1;
end//counter_reset
else begin
if (oport_weight_counter[i]>0 && oport_weight[i] < oport_weight_counter[i]) oport_weight[i]<= oport_weight_counter[i];
 
end
end//weight_dcr
if( counter_is_reset ) begin
oport_weight[i]<= (oport_weight_counter[i]>0)? oport_weight_counter[i]: 1;
end//counter_reset
else begin
if (oport_weight_counter[i]>0 && oport_weight[i] < oport_weight_counter[i]) oport_weight[i]<= oport_weight_counter[i];
end
end//weight_dcr
end//else reset
end //always
assign oports_weight [(i+1)*W-1 : i*W] = oport_weight[i];
end //else
end //else
end //for
end //for
end
 
 
879,12 → 838,8
for (i=0; i<P; i=i+1) begin : lp
assign flit_out_is_tail[i] = flit_out_all[(i+1)*Fw-2];
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
oport_weight_counter[i]<=INIT_WEIGHT;
end else begin
if (any_tail_is_sent && capture_o_weights) oport_weight_counter[i]<= INIT_WEIGHT;
892,17 → 847,14
end
end //always
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
limited_oport_weight[i]<={W{1'b0}};
end else begin
if (any_tail_is_sent && capture_o_weights) limited_oport_weight[i]<= oport_weight_counter[i]; //capture oweight counters
end
end //always
assign limited_oports_weight [(i+1)*W-1 : i*W] = limited_oport_weight[i];
1076,17 → 1028,16
end
end else if(ADD_PIPREG_AFTER_CROSSBAR==1)begin : add_reg
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
 
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
contention<={W{1'b0}};
end else begin
contention<= contention_in;
end
end
end//always
end else begin : no_reg
always @ (*) begin
contention= contention_in;
1123,49 → 1074,45
update
);
 
localparam W=WEIGHTw;
localparam W=WEIGHTw;
input [W-1 : 0] weight_in;
output reg [W-1 : 0] weight_out;
input clk, reset, update;
reg [W-1 : 0] counter,counter_next,weight_out_next;
wire less = weight_in < weight_out;
wire counter_is_zero = counter == {W{1'b0}};
input [W-1 : 0] weight_in;
output reg [W-1 : 0] weight_out;
input clk, reset, update;
reg [W-1 : 0] counter,counter_next,weight_out_next;
wire less = weight_in < weight_out;
wire counter_is_zero = counter == {W{1'b0}};
always @ (*)begin
counter_next = counter;
weight_out_next = weight_out;
if(update)begin
if (less ) begin // input weight is smaller than the captured one before
if(counter_is_zero) begin //
weight_out_next = weight_in;
end else begin
counter_next = counter - 1'b1;
end
end
else begin
counter_next = (weight_in[W-1] != 1'b1) ? {weight_in[W-2:0],1'b0} : {W{1'b1}};
weight_out_next = weight_in;
end
end
end
always @ (*)begin
counter_next = counter;
weight_out_next = weight_out;
if(update)begin
if (less ) begin // input weight is smaller than the captured one before
if(counter_is_zero) begin //
weight_out_next = weight_in;
end else begin
counter_next = counter - 1'b1;
end
end
else begin
counter_next = (weight_in[W-1] != 1'b1) ? {weight_in[W-2:0],1'b0} : {W{1'b1}};
weight_out_next = weight_in;
end
end
end
 
 
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) begin
counter = {WEIGHTw{1'b0}};
weight_out = {WEIGHTw{1'b0}};
end else begin
counter = counter_next;
weight_out = weight_out_next;
end
end
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
counter = {WEIGHTw{1'b0}};
weight_out = {WEIGHTw{1'b0}};
end else begin
counter = counter_next;
weight_out = weight_out_next;
end
end//always
 
endmodule
 
/src_peripheral/ni/ni_master.sv
577,10 → 577,10
assign chan_out.ctrl_chanel.endp_port =1'b1;
for (i=0;i<V; i=i+1) begin : vc_
985,26 → 985,26
wire [Fw-1 : 0] fifo_dout;
localparam LBw = log2(LB);
flit_buffer #(
.V(V),
.B(LB),
.PCK_TYPE(PCK_TYPE),
.Fw(Fw),
.DEBUG_EN(DEBUG_EN),
.SSA_EN("NO")
)
the_ififo
(
.din(flit_in), // Data in
.vc_num_wr(flit_in_vc_num),//write vertual chanel
.vc_num_wr(flit_in_vc_num),//write virtual chanel
.wr_en(flit_in_wr), // Write enable
.vc_num_rd(receive_vc_enable),//read vertual chanel
.vc_num_rd(receive_vc_enable),//read virtual chanel
.rd_en(fifo_rd), // Read the next word
.dout(fifo_dout), // Data out
.vc_not_empty(ififo_vc_not_empty),
.reset(reset),
.clk(clk),
.ssa_rd({V{1'b0}})
.ssa_rd({V{1'b0}}),
.multiple_dest(),
.sub_rd_ptr_ld()
);
extract_header_flit_info #(
/src_synfull/dpi_int_pkg.sv
0,0 → 1,20
import pronoc_pkg::*;
 
 
package dpi_int_pkg;
 
 
typedef struct packed {
logic [pronoc_pkg::NEw-1 : 0] dest ;
logic [pronoc_pkg::PCK_SIZw-1 : 0] size ;
logic [pronoc_pkg::NEw-1 : 0] src ;
logic [31:0] id ;
logic valid ;
} req_t;
 
typedef struct packed {
logic [31:0] id ;
logic valid ;
} deliver_t;
 
endpackage
/src_synfull/dpi_interface.sv
0,0 → 1,184
 
import pronoc_pkg::*;
import dpi_int_pkg::*;
 
 
localparam NE = 4*4*2 ;
 
module top_dpi_interface (
input logic clk_i, rst_i ,
input logic init_i ,
input logic startCom_i ,
input logic [NE-1:0] NE_ready_all_i ,
input deliver_t [NE-1:0] pronoc_synfull_del_all_i ,
output req_t [NE-1:0] synfull_pronoc_req_all_o ,
output logic endCom_o
);
 
 
import "DPI-C" function void c_dpi_interface (
logic startCom ,
logic getData ,
logic ejectReq ,
logic queueReq ,
output logic endCom ,
output logic newReq ,
output int source_all[NE] ,
output int destination_all[NE] ,
output int address_all[NE] ,
output int opcode_all[NE] ,
output int id_all[NE] ,
output int valid_all[NE] ,
input int rtrn_pkgid_all[NE] ,
input int rtrn_valid_all[NE] ,
input int NEready_all[NE] ,
output int size_all[NE] ,
input int enqueue_valid[NE] ,
input int enqueue_src[NE] ,
input int enqueue_dst[NE] ,
input int enqueue_id[NE] ,
input int enqueue_size[NE]
);
 
import "DPI-C" function void connection_init(
logic startCom ,
output logic ready
);
 
int destination ;
int opcode ;
int source ;
int addr ;
int pkgid ;
int NEready_all[NE] ;
int syn_source_all[NE] ;
int syn_size_all[NE] ;
int syn_opcode_all[NE] ;
int syn_destination_all[NE] ;
int syn_address_all[NE] ;
int syn_pkgid_all[NE] ;
int syn_valid_all[NE] ;
int chi_req_pkgid_all[NE] ;
int chi_req_valid_all[NE] ;
 
int enqueue_valid[NE];
int enqueue_src[NE] ;
int enqueue_dst[NE] ;
int enqueue_id[NE] ;
int enqueue_size[NE] ;
 
int _enqueue_valid[NE];
int _enqueue_src[NE] ;
int _enqueue_dst[NE] ;
int _enqueue_id[NE] ;
int _enqueue_size[NE] ;
 
logic newData ;
logic newReq ;
logic ready_connection ;
logic eject_req ;
logic queue_req ;
logic endCom ;
 
logic [NE-1:0] valid_check ;
logic [NE-1:0] queue_check ;
 
// socket connection
always_ff @(posedge clk_i) begin
connection_init(
init_i,ready_connection
);
end
 
// trace injection
always_ff @(posedge clk_i) begin
c_dpi_interface(
startCom_i&ready_connection ,
clk_i ,
eject_req ,
queue_req ,
endCom_o ,
newData ,
syn_source_all ,
syn_destination_all ,
syn_address_all ,
syn_opcode_all ,
syn_pkgid_all ,
syn_valid_all ,
chi_req_pkgid_all ,
chi_req_valid_all ,
NEready_all ,
syn_size_all ,
enqueue_valid ,
enqueue_src ,
enqueue_dst ,
enqueue_id ,
enqueue_size
);
end
 
genvar k;
generate
for(k=0;k<NE;k=k+1)begin
//to pronoc
assign synfull_pronoc_req_all_o[k].dest = syn_destination_all[k];
assign synfull_pronoc_req_all_o[k].size = syn_size_all[k];
assign synfull_pronoc_req_all_o[k].src = syn_source_all[k];
assign synfull_pronoc_req_all_o[k].id = syn_pkgid_all[k];
assign synfull_pronoc_req_all_o[k].valid = syn_valid_all[k][0] & NE_ready_all_i[k] ;
 
//from pronoc
assign chi_req_pkgid_all[k] = pronoc_synfull_del_all_i[k].id ;
assign chi_req_valid_all[k] = pronoc_synfull_del_all_i[k].valid ;
assign NEready_all[k] = NE_ready_all_i[k] ;
 
assign valid_check[k] = pronoc_synfull_del_all_i[k].valid;
assign queue_check[k] = (syn_valid_all[k][0] & !NE_ready_all_i[k]);
 
 
//to enqueue
assign enqueue_valid[k] = (syn_valid_all[k][0] & !NE_ready_all_i[k]) ? 1 : 0 ;
assign enqueue_src[k] = syn_source_all[k] ;
assign enqueue_dst[k] = syn_destination_all[k] ;
assign enqueue_id[k] = syn_pkgid_all[k] ;
assign enqueue_size[k] = syn_size_all[k] ;
 
//always @* begin
// if(syn_valid_all[k][0] & !NE_ready_all_i[k]) begin
// $display ("not injected because the router injector is not ready: %d", syn_pkgid_all[k]);
// end
//end
end
endgenerate
 
assign eject_req = !(valid_check=='0);
assign queue_req = !(queue_check=='0);
 
 
always_ff @ (posedge clk_i) begin
if (!rst_i) begin
_enqueue_valid <= '{default:'0} ;
_enqueue_src <= '{default:'0} ;
_enqueue_dst <= '{default:'0} ;
_enqueue_id <= '{default:'0} ;
_enqueue_size <= '{default:'0} ;
end
else begin
_enqueue_valid <= enqueue_valid ;
_enqueue_src <= enqueue_src ;
_enqueue_dst <= enqueue_dst ;
_enqueue_id <= enqueue_id ;
_enqueue_size <= enqueue_size ;
end
end
 
 
 
 
 
 
 
 
 
 
endmodule
/src_synfull/synfull_top.sv
0,0 → 1,259
// synthesis translate_off
`timescale 1ns/1ns
 
 
module synfull_top;
import pronoc_pkg::*;
import dpi_int_pkg::*;
reg reset ,clk;
reg print_router_st;
initial begin
clk = 1'b0;
forever clk = #10 ~clk;
end
smartflit_chanel_t chan_in_all [NE-1 : 0];
smartflit_chanel_t chan_out_all [NE-1 : 0];
router_event_t router_event [NR-1 : 0] [MAX_P-1 : 0];
pck_injct_t pck_injct_in [NE-1 : 0];
pck_injct_t _pck_injct_in [NE-1 : 0];
pck_injct_t pck_injct_out[NE-1 : 0];
 
logic [NE-1 : 0] NE_ready_all ;
logic [NE-1 : 0] init_socket ;
logic [NE-1 : 0] wakeup_synfull ;
logic [NE-1 : 0] end_injection ;
logic end_synfull ;
 
req_t [NE-1 : 0] synfull_pronoc_req_all ;
deliver_t [NE-1 : 0] pronoc_synfull_del_all ;
noc_top the_noc
(
.reset(reset),
.clk(clk),
.chan_in_all(chan_in_all),
.chan_out_all(chan_out_all),
.router_event(router_event)
);
 
 
top_dpi_interface synfull (
.clk_i(clk), .rst_i(reset),
.init_i (init_socket[0] ),
.startCom_i (wakeup_synfull[0] ),
.pronoc_synfull_del_all_i (pronoc_synfull_del_all ),
.synfull_pronoc_req_all_o (synfull_pronoc_req_all ),
.NE_ready_all_i (NE_ready_all ),
.endCom_o (end_injection[0] )
);
 
reg [NEw-1 : 0] dest_id [NE-1 : 0];
wire [NEw-1: 0] current_e_addr [NE-1 : 0];
reg [63 : 0] total_sent_pck_count;
reg [63 : 0] total_sent_flit_count;
reg [63 : 0] total_rsv_pck_count;
reg [63 : 0] total_rsv_flit_count;
reg [63 : 0] total_queued_pck_count;
reg [63 : 0] clk_count;
initial begin
 
//print_parameter
display_noc_parameters();
$display ("Simulation parameters-------------");
if(DEBUG_EN)
$display ("\tDebuging is enabled");
else
$display ("\tDebuging is disabled");
 
 
end//initial
 
wire [31:0] fifo_id [NE-1 : 0];
wire [PCK_SIZw-1 : 0] fifo_size [NE-1 :0];
wire [NEw-1 : 0] fifo_dest [NE-1 : 0];
wire [NE-1 : 0] fifo_wr,fifo_rd ,fifo_full,fifo_not_empty;
genvar i;
generate
for(i=0; i< NE; i=i+1) begin
assign fifo_wr[i] =
(pck_injct_out[i].ready == 1'b0 && synfull_pronoc_req_all[i].valid==1'b1) ||
(fifo_not_empty[i]==1'b1 && synfull_pronoc_req_all[i].valid==1'b1);
assign fifo_rd[i] =
(pck_injct_out[i].ready == 1'b1 && fifo_not_empty[i]==1'b1 );
fwft_fifo_bram #(
.DATA_WIDTH(32+PCK_SIZw+NEw),
.MAX_DEPTH(1000000),
.IGNORE_SAME_LOC_RD_WR_WARNING("NO")
)
fifo
(
.din({synfull_pronoc_req_all[i].id,synfull_pronoc_req_all[i].size,synfull_pronoc_req_all[i].dest}), // Data in
.wr_en(fifo_wr[i]), // Write enable
.rd_en(fifo_rd[i]), // Read the next word
.dout({fifo_id[i],fifo_size[i],fifo_dest[i]}), // Data out
.full( fifo_full[i]),
.nearly_full(),
.recieve_more_than_0(fifo_not_empty[i]),
.recieve_more_than_1(),
.reset(reset),
.clk (clk)
);
//from synfull
assign pck_injct_in[i].data = (fifo_not_empty[i])? fifo_id[i] : synfull_pronoc_req_all[i].id;
assign pck_injct_in[i].size = (fifo_not_empty[i])? fifo_size[i] : synfull_pronoc_req_all[i].size;
assign pck_injct_in[i].pck_wr = (fifo_not_empty[i])? fifo_rd[i] : ( synfull_pronoc_req_all[i].valid & pck_injct_out[i].ready == 1'b1);
assign pck_injct_in[i].ready = 1'b1;
assign dest_id[i] =(fifo_not_empty[i])? fifo_dest[i] : synfull_pronoc_req_all[i].dest;
//to synfull
assign pronoc_synfull_del_all[i].id = pck_injct_out[i].data ;
assign pronoc_synfull_del_all[i].valid = pck_injct_out[i].pck_wr ;
assign NE_ready_all[i] = 1'b1 ; //pck_injct_out[i].ready;
assign pck_injct_in[i].class_num = _pck_injct_in[i].class_num;
assign pck_injct_in[i].init_weight = _pck_injct_in[i].init_weight;
assign pck_injct_in[i].vc = _pck_injct_in[i].vc;
endp_addr_encoder #( .TOPOLOGY(TOPOLOGY), .T1(T1), .T2(T2), .T3(T3), .EAw(EAw), .NE(NE)) encode1 ( .id(i[NEw-1 :0]), .code(current_e_addr[i]));
packet_injector pck_inj(
//general
.current_e_addr(current_e_addr[i]),
.reset(reset),
.clk(clk),
//noc port
.chan_in(chan_out_all[i]),
.chan_out(chan_in_all[i]),
//control interafce
.pck_injct_in(pck_injct_in[i]),
.pck_injct_out(pck_injct_out[i])
);
 
endp_addr_encoder #( .TOPOLOGY(TOPOLOGY), .T1(T1), .T2(T2), .T3(T3), .EAw(EAw), .NE(NE)) encode2 ( .id(dest_id[i]), .code(pck_injct_in[i].endp_addr));
reg [31:0]k;
 
initial begin
reset = 1'b1;
k=0;
init_socket[i] = 1'b0;
wakeup_synfull[i] = 1'b0;
print_router_st=1'b0;
@(posedge clk) #1;
_pck_injct_in[i].class_num=0;
_pck_injct_in[i].init_weight=1;
_pck_injct_in[i].vc=1;
#100
@(posedge clk) #1;
reset=1'b0;
#100
init_socket[i] = 1'b1;
@(posedge clk) #1;
init_socket[i] = 1'b0;
#100
wakeup_synfull[i] = 1'b1;
@(posedge clk) #1;
while (!end_injection[0]) @(posedge clk) #1;
// if(i==0) $display ( "All packet are sent. We wait for NoC to be ideal now");
// while (total_sent_pck_count != total_rsv_pck_count) @(posedge clk) #1;
print_router_st=1;
#1
$display ( "Statistics:");
$display ( "\t simulation clk count = %d", clk_count);
$display ( "\t Total queued packets = %d",total_queued_pck_count);
$display ( "\t Total sent packets = %d", total_sent_pck_count);
$display ( "\t Total sent flits = %d", total_sent_flit_count);
$display ( "\t Total received packets = %d", total_rsv_pck_count);
$display ( "\t Total received flits = %d", total_rsv_flit_count);
$finish;
end
always @(posedge clk) begin
if(pck_injct_out[i].pck_wr) begin
$display ("%t:pck_inj(%d) got a packet: source=%d, size=%d, data=%h",$time,i,
pck_injct_out[i].endp_addr,pck_injct_out[i].size,pck_injct_out[i].data);
end
end
end//for
endgenerate
integer k;
always @(posedge clk) begin
if(reset) begin
clk_count =0;
total_sent_pck_count =0;
total_sent_flit_count=0;
total_rsv_pck_count =0;
total_rsv_flit_count =0;
total_queued_pck_count = 0;
end else begin
clk_count++;
for(k=0; k< NE; k=k+1) begin : endpoints
if(pck_injct_out[k].pck_wr) begin
total_rsv_pck_count++;
total_rsv_flit_count+=pck_injct_out[k].size;
end
if(pck_injct_in[k].pck_wr) begin
total_sent_pck_count++;
total_sent_flit_count+=pck_injct_in[k].size;
end
if(synfull_pronoc_req_all[k].valid) begin
total_queued_pck_count++;
end
end
end
 
end
routers_statistic_collector router_stat(
.reset(reset),
.clk(clk),
.router_event(router_event),
.print(print_router_st)
);
endmodule
// synthesis translate_on
 
src_synfull/synfull_top.sv Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: src_topolgy/common/custom_lkh_routing.v =================================================================== --- src_topolgy/common/custom_lkh_routing.v (revision 50) +++ src_topolgy/common/custom_lkh_routing.v (revision 54) @@ -31,6 +31,12 @@ + + + + + + //do not modify this line ===Tcustom1Rcustom=== if(TOPOLOGY == "custom1" && ROUTE_NAME== "custom" ) begin : Tcustom1Rcustom @@ -64,6 +70,12 @@ + + + + + + endmodule
/src_topolgy/common/custom_ni_routing.v
21,11 → 21,13
 
generate
//do not modify this line ===Tcustom1Rcustom===
if(TOPOLOGY == "custom1" && ROUTE_NAME== "custom" ) begin : Tcustom1Rcustom
58,7 → 60,13
 
endmodule
/src_topolgy/common/custom_noc_top.sv
1,4 → 1,4
`timescale 1ns / 1ps
`include "pronoc_def.v"
 
module custom_noc_top
import pronoc_pkg::*;
7,7 → 7,8
reset,
clk,
chan_in_all,
chan_out_all
chan_out_all,
router_event
);
 
16,13 → 17,20
input smartflit_chanel_t chan_in_all [NE-1 : 0];
output smartflit_chanel_t chan_out_all [NE-1 : 0];
//Events
output router_event_t router_event [NR-1 : 0][MAX_P-1 : 0];
 
generate
 
 
//do not modify this line ===custom1===
if(TOPOLOGY == "custom1" ) begin : Tcustom1
31,12 → 39,25
.reset(reset),
.clk(clk),
.chan_in_all(chan_in_all),
.chan_out_all(chan_out_all)
.chan_out_all(chan_out_all),
.router_event(router_event)
);
end
end
endgenerate
 
 
 
/src_topolgy/custom1/Tcustom1Rcustom_conventional_routing.v
8,9 → 8,9
/**********************************************************************
** File: /home/alireza/work/git/hca_git/ProNoC/mpsoc/rtl/src_topolgy/custom1/Tcustom1Rcustom_conventional_routing.v
**
** Copyright (C) 2014-2019 Alireza Monemi
** Copyright (C) 2014-2021 Alireza Monemi
**
** This file is part of ProNoC 1.9.1
** This file is part of ProNoC 2.0.0
**
** ProNoC ( stands for Prototype Network-on-chip) is free software:
** you can redistribute it and/or modify it under the terms of the GNU
/src_topolgy/custom1/Tcustom1Rcustom_conventional_routing_genvar.v
8,9 → 8,9
/**********************************************************************
** File: /home/alireza/work/git/hca_git/ProNoC/mpsoc/rtl/src_topolgy/custom1/Tcustom1Rcustom_conventional_routing_genvar.v
**
** Copyright (C) 2014-2019 Alireza Monemi
** Copyright (C) 2014-2021 Alireza Monemi
**
** This file is part of ProNoC 1.9.1
** This file is part of ProNoC 2.0.0
**
** ProNoC ( stands for Prototype Network-on-chip) is free software:
** you can redistribute it and/or modify it under the terms of the GNU
/src_topolgy/custom1/Tcustom1Rcustom_look_ahead_routing.v
8,9 → 8,9
/**********************************************************************
** File: /home/alireza/work/git/hca_git/ProNoC/mpsoc/rtl/src_topolgy/custom1/Tcustom1Rcustom_look_ahead_routing.v
**
** Copyright (C) 2014-2019 Alireza Monemi
** Copyright (C) 2014-2021 Alireza Monemi
**
** This file is part of ProNoC 1.9.1
** This file is part of ProNoC 2.0.0
**
** ProNoC ( stands for Prototype Network-on-chip) is free software:
** you can redistribute it and/or modify it under the terms of the GNU
26,6 → 26,8
** License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
******************************************************************************/
 
`include "pronoc_def.v"
/*******************
* Tcustom1Rcustom_look_ahead_routing
*******************/
52,8 → 54,8
reg [EAw-1 :0] dest_e_addr_delay;
reg [EAw-1 :0] src_e_addr_delay;
 
always @(posedge clk)begin
if(reset)begin
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset)begin
dest_e_addr_delay<={EAw{1'b0}};
src_e_addr_delay<={EAw{1'b0}};
end else begin
/src_topolgy/custom1/Tcustom1Rcustom_look_ahead_routing_genvar.v
8,9 → 8,9
/**********************************************************************
** File: /home/alireza/work/git/hca_git/ProNoC/mpsoc/rtl/src_topolgy/custom1/Tcustom1Rcustom_look_ahead_routing_genvar.v
**
** Copyright (C) 2014-2019 Alireza Monemi
** Copyright (C) 2014-2021 Alireza Monemi
**
** This file is part of ProNoC 1.9.1
** This file is part of ProNoC 2.0.0
**
** ProNoC ( stands for Prototype Network-on-chip) is free software:
** you can redistribute it and/or modify it under the terms of the GNU
26,6 → 26,8
** License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
******************************************************************************/
 
`include "pronoc_def.v"
/*****************************
* Tcustom1Rcustom_look_ahead_routing_genvar
******************************/
51,8 → 53,8
reg [EAw-1 :0] dest_e_addr_delay;
reg [EAw-1 :0] src_e_addr_delay;
 
always @(posedge clk)begin
if(reset)begin
always @ (`pronoc_clk_reset_edge )begin
if(`pronoc_reset) begin
dest_e_addr_delay<={EAw{1'b0}};
src_e_addr_delay<={EAw{1'b0}};
end else begin
/src_topolgy/custom1/custom1.png Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/src_topolgy/custom1/custom1_noc.sv
8,9 → 8,9
/**********************************************************************
** File: /home/alireza/work/git/hca_git/ProNoC/mpsoc/rtl/src_topolgy/custom1/custom1_noc.sv
**
** Copyright (C) 2014-2019 Alireza Monemi
** Copyright (C) 2014-2021 Alireza Monemi
**
** This file is part of ProNoC 1.9.1
** This file is part of ProNoC 2.0.0
**
** ProNoC ( stands for Prototype Network-on-chip) is free software:
** you can redistribute it and/or modify it under the terms of the GNU
26,6 → 26,8
** License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
******************************************************************************/
 
`include "pronoc_def.v"
 
module custom1_noc
import pronoc_pkg::*;
(
34,51 → 36,67
//T0,
T0_chan_in,
T0_chan_out,
T0_router_event,
//T1,
T1_chan_in,
T1_chan_out,
T1_router_event,
//T2,
T2_chan_in,
T2_chan_out,
T2_router_event,
//T3,
T3_chan_in,
T3_chan_out,
T3_router_event,
//T4,
T4_chan_in,
T4_chan_out,
T4_router_event,
//T5,
T5_chan_in,
T5_chan_out,
T5_router_event,
//T6,
T6_chan_in,
T6_chan_out,
T6_router_event,
//T7,
T7_chan_in,
T7_chan_out,
T7_router_event,
//T8,
T8_chan_in,
T8_chan_out,
T8_router_event,
//T9,
T9_chan_in,
T9_chan_out,
T9_router_event,
//T10,
T10_chan_in,
T10_chan_out,
T10_router_event,
//T11,
T11_chan_in,
T11_chan_out,
T11_router_event,
//T12,
T12_chan_in,
T12_chan_out,
T12_router_event,
//T13,
T13_chan_in,
T13_chan_out,
T13_router_event,
//T14,
T14_chan_in,
T14_chan_out,
T14_router_event,
//T15,
T15_chan_in,
T15_chan_out
T15_chan_out,
T15_router_event
);
function integer log2;
106,6 → 124,7
*******************/
input smartflit_chanel_t T0_chan_in;
output smartflit_chanel_t T0_chan_out;
output router_event_t T0_router_event;
 
/*******************
* T1
112,6 → 131,7
*******************/
input smartflit_chanel_t T1_chan_in;
output smartflit_chanel_t T1_chan_out;
output router_event_t T1_router_event;
 
/*******************
* T2
118,6 → 138,7
*******************/
input smartflit_chanel_t T2_chan_in;
output smartflit_chanel_t T2_chan_out;
output router_event_t T2_router_event;
 
/*******************
* T3
124,6 → 145,7
*******************/
input smartflit_chanel_t T3_chan_in;
output smartflit_chanel_t T3_chan_out;
output router_event_t T3_router_event;
 
/*******************
* T4
130,6 → 152,7
*******************/
input smartflit_chanel_t T4_chan_in;
output smartflit_chanel_t T4_chan_out;
output router_event_t T4_router_event;
 
/*******************
* T5
136,6 → 159,7
*******************/
input smartflit_chanel_t T5_chan_in;
output smartflit_chanel_t T5_chan_out;
output router_event_t T5_router_event;
 
/*******************
* T6
142,6 → 166,7
*******************/
input smartflit_chanel_t T6_chan_in;
output smartflit_chanel_t T6_chan_out;
output router_event_t T6_router_event;
 
/*******************
* T7
148,6 → 173,7
*******************/
input smartflit_chanel_t T7_chan_in;
output smartflit_chanel_t T7_chan_out;
output router_event_t T7_router_event;
 
/*******************
* T8
154,6 → 180,7
*******************/
input smartflit_chanel_t T8_chan_in;
output smartflit_chanel_t T8_chan_out;
output router_event_t T8_router_event;
 
/*******************
* T9
160,6 → 187,7
*******************/
input smartflit_chanel_t T9_chan_in;
output smartflit_chanel_t T9_chan_out;
output router_event_t T9_router_event;
 
/*******************
* T10
166,6 → 194,7
*******************/
input smartflit_chanel_t T10_chan_in;
output smartflit_chanel_t T10_chan_out;
output router_event_t T10_router_event;
 
/*******************
* T11
172,6 → 201,7
*******************/
input smartflit_chanel_t T11_chan_in;
output smartflit_chanel_t T11_chan_out;
output router_event_t T11_router_event;
 
/*******************
* T12
178,6 → 208,7
*******************/
input smartflit_chanel_t T12_chan_in;
output smartflit_chanel_t T12_chan_out;
output router_event_t T12_router_event;
 
/*******************
* T13
184,6 → 215,7
*******************/
input smartflit_chanel_t T13_chan_in;
output smartflit_chanel_t T13_chan_out;
output router_event_t T13_router_event;
 
/*******************
* T14
190,6 → 222,7
*******************/
input smartflit_chanel_t T14_chan_in;
output smartflit_chanel_t T14_chan_out;
output router_event_t T14_router_event;
 
/*******************
* T15
196,6 → 229,7
*******************/
input smartflit_chanel_t T15_chan_in;
output smartflit_chanel_t T15_chan_out;
output router_event_t T15_router_event;
 
/*******************
* R0
207,6 → 241,7
 
smartflit_chanel_t R0_chan_in [3-1 : 0];
smartflit_chanel_t R0_chan_out [3-1 : 0];
router_event_t R0_router_event [3-1 : 0];
 
 
/*******************
219,6 → 254,7
 
smartflit_chanel_t R1_chan_in [3-1 : 0];
smartflit_chanel_t R1_chan_out [3-1 : 0];
router_event_t R1_router_event [3-1 : 0];
 
 
/*******************
231,6 → 267,7
 
smartflit_chanel_t R2_chan_in [3-1 : 0];
smartflit_chanel_t R2_chan_out [3-1 : 0];
router_event_t R2_router_event [3-1 : 0];
 
 
/*******************
243,6 → 280,7
 
smartflit_chanel_t R3_chan_in [3-1 : 0];
smartflit_chanel_t R3_chan_out [3-1 : 0];
router_event_t R3_router_event [3-1 : 0];
 
 
/*******************
255,6 → 293,7
 
smartflit_chanel_t R4_chan_in [4-1 : 0];
smartflit_chanel_t R4_chan_out [4-1 : 0];
router_event_t R4_router_event [4-1 : 0];
 
 
/*******************
267,6 → 306,7
 
smartflit_chanel_t R5_chan_in [4-1 : 0];
smartflit_chanel_t R5_chan_out [4-1 : 0];
router_event_t R5_router_event [4-1 : 0];
 
 
/*******************
279,6 → 319,7
 
smartflit_chanel_t R6_chan_in [4-1 : 0];
smartflit_chanel_t R6_chan_out [4-1 : 0];
router_event_t R6_router_event [4-1 : 0];
 
 
/*******************
291,6 → 332,7
 
smartflit_chanel_t R7_chan_in [4-1 : 0];
smartflit_chanel_t R7_chan_out [4-1 : 0];
router_event_t R7_router_event [4-1 : 0];
 
 
/*******************
303,6 → 345,7
 
smartflit_chanel_t R12_chan_in [4-1 : 0];
smartflit_chanel_t R12_chan_out [4-1 : 0];
router_event_t R12_router_event [4-1 : 0];
 
 
/*******************
315,6 → 358,7
 
smartflit_chanel_t R13_chan_in [4-1 : 0];
smartflit_chanel_t R13_chan_out [4-1 : 0];
router_event_t R13_router_event [4-1 : 0];
 
 
/*******************
327,6 → 371,7
 
smartflit_chanel_t R14_chan_in [4-1 : 0];
smartflit_chanel_t R14_chan_out [4-1 : 0];
router_event_t R14_router_event [4-1 : 0];
 
 
/*******************
339,6 → 384,7
 
smartflit_chanel_t R15_chan_in [4-1 : 0];
smartflit_chanel_t R15_chan_out [4-1 : 0];
router_event_t R15_router_event [4-1 : 0];
 
 
/*******************
351,6 → 397,7
 
smartflit_chanel_t R8_chan_in [5-1 : 0];
smartflit_chanel_t R8_chan_out [5-1 : 0];
router_event_t R8_router_event [5-1 : 0];
 
 
/*******************
363,6 → 410,7
 
smartflit_chanel_t R9_chan_in [5-1 : 0];
smartflit_chanel_t R9_chan_out [5-1 : 0];
router_event_t R9_router_event [5-1 : 0];
 
 
/*******************
375,6 → 423,7
 
smartflit_chanel_t R10_chan_in [5-1 : 0];
smartflit_chanel_t R10_chan_out [5-1 : 0];
router_event_t R10_router_event [5-1 : 0];
 
 
/*******************
387,6 → 436,7
 
smartflit_chanel_t R11_chan_in [5-1 : 0];
smartflit_chanel_t R11_chan_out [5-1 : 0];
router_event_t R11_router_event [5-1 : 0];
 
 
401,9 → 451,11
(
.clk(R0_clk),
.reset(R0_reset),
.current_r_id(0),
.current_r_addr (R0_current_r_addr),
.chan_in (R0_chan_in),
.chan_out (R0_chan_out)
.chan_out (R0_chan_out),
.router_event (R0_router_event)
);
 
assign R0_clk = clk;
412,6 → 464,7
//Connect R0 port 0 to T0 port 0
assign R0_chan_in [0] = T0_chan_in;
assign T0_chan_out = R0_chan_out [0];
assign T0_router_event = R0_router_event [0];
//Connect R0 port 1 to R14 port 3
assign R0_chan_in [1] = R14_chan_out [3];
//Connect R0 port 2 to R13 port 3
427,9 → 480,11
(
.clk(R1_clk),
.reset(R1_reset),
.current_r_id(1),
.current_r_addr (R1_current_r_addr),
.chan_in (R1_chan_in),
.chan_out (R1_chan_out)
.chan_out (R1_chan_out),
.router_event (R1_router_event)
);
 
assign R1_clk = clk;
438,6 → 493,7
//Connect R1 port 0 to T1 port 0
assign R1_chan_in [0] = T1_chan_in;
assign T1_chan_out = R1_chan_out [0];
assign T1_router_event = R1_router_event [0];
//Connect R1 port 1 to R7 port 3
assign R1_chan_in [1] = R7_chan_out [3];
//Connect R1 port 2 to R2 port 2
453,9 → 509,11
(
.clk(R2_clk),
.reset(R2_reset),
.current_r_id(2),
.current_r_addr (R2_current_r_addr),
.chan_in (R2_chan_in),
.chan_out (R2_chan_out)
.chan_out (R2_chan_out),
.router_event (R2_router_event)
);
 
assign R2_clk = clk;
464,6 → 522,7
//Connect R2 port 0 to T2 port 0
assign R2_chan_in [0] = T2_chan_in;
assign T2_chan_out = R2_chan_out [0];
assign T2_router_event = R2_router_event [0];
//Connect R2 port 1 to R15 port 2
assign R2_chan_in [1] = R15_chan_out [2];
//Connect R2 port 2 to R1 port 2
479,9 → 538,11
(
.clk(R3_clk),
.reset(R3_reset),
.current_r_id(3),
.current_r_addr (R3_current_r_addr),
.chan_in (R3_chan_in),
.chan_out (R3_chan_out)
.chan_out (R3_chan_out),
.router_event (R3_router_event)
);
 
assign R3_clk = clk;
490,6 → 551,7
//Connect R3 port 0 to T3 port 0
assign R3_chan_in [0] = T3_chan_in;
assign T3_chan_out = R3_chan_out [0];
assign T3_router_event = R3_router_event [0];
//Connect R3 port 1 to R15 port 3
assign R3_chan_in [1] = R15_chan_out [3];
//Connect R3 port 2 to R4 port 2
505,9 → 567,11
(
.clk(R4_clk),
.reset(R4_reset),
.current_r_id(4),
.current_r_addr (R4_current_r_addr),
.chan_in (R4_chan_in),
.chan_out (R4_chan_out)
.chan_out (R4_chan_out),
.router_event (R4_router_event)
);
 
assign R4_clk = clk;
516,6 → 580,7
//Connect R4 port 0 to T4 port 0
assign R4_chan_in [0] = T4_chan_in;
assign T4_chan_out = R4_chan_out [0];
assign T4_router_event = R4_router_event [0];
//Connect R4 port 1 to R9 port 2
assign R4_chan_in [1] = R9_chan_out [2];
//Connect R4 port 2 to R3 port 2
533,9 → 598,11
(
.clk(R5_clk),
.reset(R5_reset),
.current_r_id(5),
.current_r_addr (R5_current_r_addr),
.chan_in (R5_chan_in),
.chan_out (R5_chan_out)
.chan_out (R5_chan_out),
.router_event (R5_router_event)
);
 
assign R5_clk = clk;
544,6 → 611,7
//Connect R5 port 0 to T5 port 0
assign R5_chan_in [0] = T5_chan_in;
assign T5_chan_out = R5_chan_out [0];
assign T5_router_event = R5_router_event [0];
//Connect R5 port 1 to R11 port 4
assign R5_chan_in [1] = R11_chan_out [4];
//Connect R5 port 2 to R6 port 2
561,9 → 629,11
(
.clk(R6_clk),
.reset(R6_reset),
.current_r_id(6),
.current_r_addr (R6_current_r_addr),
.chan_in (R6_chan_in),
.chan_out (R6_chan_out)
.chan_out (R6_chan_out),
.router_event (R6_router_event)
);
 
assign R6_clk = clk;
572,6 → 642,7
//Connect R6 port 0 to T6 port 0
assign R6_chan_in [0] = T6_chan_in;
assign T6_chan_out = R6_chan_out [0];
assign T6_router_event = R6_router_event [0];
//Connect R6 port 1 to R9 port 3
assign R6_chan_in [1] = R9_chan_out [3];
//Connect R6 port 2 to R5 port 2
589,9 → 660,11
(
.clk(R7_clk),
.reset(R7_reset),
.current_r_id(7),
.current_r_addr (R7_current_r_addr),
.chan_in (R7_chan_in),
.chan_out (R7_chan_out)
.chan_out (R7_chan_out),
.router_event (R7_router_event)
);
 
assign R7_clk = clk;
600,6 → 673,7
//Connect R7 port 0 to T7 port 0
assign R7_chan_in [0] = T7_chan_in;
assign T7_chan_out = R7_chan_out [0];
assign T7_router_event = R7_router_event [0];
//Connect R7 port 1 to R12 port 3
assign R7_chan_in [1] = R12_chan_out [3];
//Connect R7 port 2 to R14 port 2
617,9 → 691,11
(
.clk(R12_clk),
.reset(R12_reset),
.current_r_id(8),
.current_r_addr (R12_current_r_addr),
.chan_in (R12_chan_in),
.chan_out (R12_chan_out)
.chan_out (R12_chan_out),
.router_event (R12_router_event)
);
 
assign R12_clk = clk;
628,6 → 704,7
//Connect R12 port 0 to T8 port 0
assign R12_chan_in [0] = T8_chan_in;
assign T8_chan_out = R12_chan_out [0];
assign T8_router_event = R12_router_event [0];
//Connect R12 port 1 to R8 port 4
assign R12_chan_in [1] = R8_chan_out [4];
//Connect R12 port 2 to R10 port 3
645,9 → 722,11
(
.clk(R13_clk),
.reset(R13_reset),
.current_r_id(9),
.current_r_addr (R13_current_r_addr),
.chan_in (R13_chan_in),
.chan_out (R13_chan_out)
.chan_out (R13_chan_out),
.router_event (R13_router_event)
);
 
assign R13_clk = clk;
656,6 → 735,7
//Connect R13 port 0 to T9 port 0
assign R13_chan_in [0] = T9_chan_in;
assign T9_chan_out = R13_chan_out [0];
assign T9_router_event = R13_router_event [0];
//Connect R13 port 1 to R8 port 2
assign R13_chan_in [1] = R8_chan_out [2];
//Connect R13 port 2 to R5 port 3
673,9 → 753,11
(
.clk(R14_clk),
.reset(R14_reset),
.current_r_id(10),
.current_r_addr (R14_current_r_addr),
.chan_in (R14_chan_in),
.chan_out (R14_chan_out)
.chan_out (R14_chan_out),
.router_event (R14_router_event)
);
 
assign R14_clk = clk;
684,6 → 766,7
//Connect R14 port 0 to T10 port 0
assign R14_chan_in [0] = T10_chan_in;
assign T10_chan_out = R14_chan_out [0];
assign T10_router_event = R14_router_event [0];
//Connect R14 port 1 to R8 port 3
assign R14_chan_in [1] = R8_chan_out [3];
//Connect R14 port 2 to R7 port 2
701,9 → 784,11
(
.clk(R15_clk),
.reset(R15_reset),
.current_r_id(11),
.current_r_addr (R15_current_r_addr),
.chan_in (R15_chan_in),
.chan_out (R15_chan_out)
.chan_out (R15_chan_out),
.router_event (R15_router_event)
);
 
assign R15_clk = clk;
712,6 → 797,7
//Connect R15 port 0 to T11 port 0
assign R15_chan_in [0] = T11_chan_in;
assign T11_chan_out = R15_chan_out [0];
assign T11_router_event = R15_router_event [0];
//Connect R15 port 1 to R10 port 4
assign R15_chan_in [1] = R10_chan_out [4];
//Connect R15 port 2 to R2 port 1
729,9 → 815,11
(
.clk(R8_clk),
.reset(R8_reset),
.current_r_id(12),
.current_r_addr (R8_current_r_addr),
.chan_in (R8_chan_in),
.chan_out (R8_chan_out)
.chan_out (R8_chan_out),
.router_event (R8_router_event)
);
 
assign R8_clk = clk;
740,6 → 828,7
//Connect R8 port 0 to T12 port 0
assign R8_chan_in [0] = T12_chan_in;
assign T12_chan_out = R8_chan_out [0];
assign T12_router_event = R8_router_event [0];
//Connect R8 port 1 to R11 port 1
assign R8_chan_in [1] = R11_chan_out [1];
//Connect R8 port 2 to R13 port 1
759,9 → 848,11
(
.clk(R9_clk),
.reset(R9_reset),
.current_r_id(13),
.current_r_addr (R9_current_r_addr),
.chan_in (R9_chan_in),
.chan_out (R9_chan_out)
.chan_out (R9_chan_out),
.router_event (R9_router_event)
);
 
assign R9_clk = clk;
770,6 → 861,7
//Connect R9 port 0 to T13 port 0
assign R9_chan_in [0] = T13_chan_in;
assign T13_chan_out = R9_chan_out [0];
assign T13_router_event = R9_router_event [0];
//Connect R9 port 1 to R11 port 3
assign R9_chan_in [1] = R11_chan_out [3];
//Connect R9 port 2 to R4 port 1
789,9 → 881,11
(
.clk(R10_clk),
.reset(R10_reset),
.current_r_id(14),
.current_r_addr (R10_current_r_addr),
.chan_in (R10_chan_in),
.chan_out (R10_chan_out)
.chan_out (R10_chan_out),
.router_event (R10_router_event)
);
 
assign R10_clk = clk;
800,6 → 894,7
//Connect R10 port 0 to T14 port 0
assign R10_chan_in [0] = T14_chan_in;
assign T14_chan_out = R10_chan_out [0];
assign T14_router_event = R10_router_event [0];
//Connect R10 port 1 to R11 port 2
assign R10_chan_in [1] = R11_chan_out [2];
//Connect R10 port 2 to R9 port 4
819,9 → 914,11
(
.clk(R11_clk),
.reset(R11_reset),
.current_r_id(15),
.current_r_addr (R11_current_r_addr),
.chan_in (R11_chan_in),
.chan_out (R11_chan_out)
.chan_out (R11_chan_out),
.router_event (R11_router_event)
);
 
assign R11_clk = clk;
830,6 → 927,7
//Connect R11 port 0 to T15 port 0
assign R11_chan_in [0] = T15_chan_in;
assign T15_chan_out = R11_chan_out [0];
assign T15_router_event = R11_router_event [0];
//Connect R11 port 1 to R8 port 1
assign R11_chan_in [1] = R8_chan_out [1];
//Connect R11 port 2 to R10 port 1
/src_topolgy/custom1/custom1_noc_genvar.sv
8,9 → 8,9
/**********************************************************************
** File: /home/alireza/work/git/hca_git/ProNoC/mpsoc/rtl/src_topolgy/custom1/custom1_noc_genvar.sv
**
** Copyright (C) 2014-2019 Alireza Monemi
** Copyright (C) 2014-2021 Alireza Monemi
**
** This file is part of ProNoC 1.9.1
** This file is part of ProNoC 2.0.0
**
** ProNoC ( stands for Prototype Network-on-chip) is free software:
** you can redistribute it and/or modify it under the terms of the GNU
26,6 → 26,8
** License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
******************************************************************************/
 
`include "pronoc_def.v"
 
module custom1_noc_genvar
import pronoc_pkg::*;
(
33,7 → 35,8
reset,
clk,
chan_in_all,
chan_out_all
chan_out_all,
router_event
);
 
function integer log2;
58,10 → 61,14
input smartflit_chanel_t chan_in_all [NE-1 : 0];
output smartflit_chanel_t chan_out_all [NE-1 : 0];
 
//Events
output router_event_t router_event [NR-1 : 0][MAX_P-1 : 0];
 
//all routers port
smartflit_chanel_t router_chan_in [NR-1 :0][MAX_P-1 : 0];
smartflit_chanel_t router_chan_out [NR-1 :0][MAX_P-1 : 0];
 
 
wire [RAw-1 : 0] current_r_addr [NR-1 : 0];
 
 
76,6 → 83,8
generate
for( i=0; i<4; i=i+1) begin : router_3_port_lp
localparam RID = i;
assign current_r_addr [RID] = RID[RAw-1: 0];
 
router_top #(
.P(3)
84,9 → 93,11
(
.clk(clk),
.reset(reset),
.current_r_addr(i),
.chan_in (router_chan_in[i]),
.chan_out (router_chan_out[i])
.current_r_id(RID),
.current_r_addr(current_r_addr[RID]),
.chan_in (router_chan_in [RID] [2 : 0]),
.chan_out (router_chan_out[RID] [2 : 0]),
.router_event(router_event[RID] [2 : 0])
);
94,6 → 105,8
end
for( i=0; i<8; i=i+1) begin : router_4_port_lp
localparam RID = i+4;
assign current_r_addr [RID] = RID[RAw-1: 0];
 
router_top #(
.P(4)
102,9 → 115,11
(
.clk(clk),
.reset(reset),
.current_r_addr(i+4),
.chan_in (router_chan_in[i+4]),
.chan_out (router_chan_out[i+4])
.current_r_id(RID),
.current_r_addr(current_r_addr[RID]),
.chan_in (router_chan_in [RID] [3 : 0]),
.chan_out (router_chan_out[RID] [3 : 0]),
.router_event(router_event[RID] [3 : 0])
);
112,6 → 127,8
end
for( i=0; i<4; i=i+1) begin : router_5_port_lp
localparam RID = i+12;
assign current_r_addr [RID] = RID[RAw-1: 0];
 
router_top #(
.P(5)
120,9 → 137,11
(
.clk(clk),
.reset(reset),
.current_r_addr(i+12),
.chan_in (router_chan_in[i+12]),
.chan_out (router_chan_out[i+12])
.current_r_id(RID),
.current_r_addr(current_r_addr[RID]),
.chan_in (router_chan_in [RID] [4 : 0]),
.chan_out (router_chan_out[RID] [4 : 0]),
.router_event(router_event[RID] [4 : 0])
);
/src_topolgy/param.obj
1,9 → 1,9
#######################################################################
## File: /home/alireza/work/git/hca_git/ProNoC/mpsoc/rtl/src_topolgy/param.obj
##
## Copyright (C) 2014-2019 Alireza Monemi
## Copyright (C) 2014-2021 Alireza Monemi
##
## This file is part of ProNoC 1.9.1
## This file is part of ProNoC 2.0.0
##
## WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT
## MAY CAUSE UNEXPECTED BEHAVIOR.
11,15 → 11,12
 
$Topology = {
'"custom1"' => {
'T3' => 5,
'ROUTE_NAME' => '"custom"',
'T2' => 16,
'ROUTER_Ps' => {
'4' => 8,
'5' => 4,
'3' => 4
'3' => 4,
'5' => 4
},
'T1' => 16,
'er_addr' => [
0,
1,
37,6 → 34,36
13,
14,
15
]
],
'T1' => 16,
'ROUTE_NAME' => '"custom"',
'T3' => 5
},
'"mesh4x4"' => {
'T2' => 16,
'ROUTER_Ps' => {
'5' => 16
},
'er_addr' => [
4,
5,
6,
7,
8,
9,
10,
11,
0,
1,
2,
3,
12,
13,
14,
15
],
'ROUTE_NAME' => '"custom","m4"',
'T1' => 16,
'T3' => 5
}
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.