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 |
} |
}; |
© copyright 1999-2024
OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.