Line 1... |
Line 1... |
`timescale 1ns/1ps
|
`include "pronoc_def.v"
|
/**********************************************************************
|
/**********************************************************************
|
** File: output_ports.sv
|
** File: output_ports.sv
|
**
|
**
|
** Copyright (C) 2014-2017 Alireza Monemi
|
** Copyright (C) 2014-2017 Alireza Monemi
|
**
|
**
|
Line 31... |
Line 31... |
#(
|
#(
|
parameter P = 5 // router port num
|
parameter P = 5 // router port num
|
)(
|
)(
|
vsa_ovc_allocated_all,
|
vsa_ovc_allocated_all,
|
flit_is_tail_all,
|
flit_is_tail_all,
|
assigned_ovc_num_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,
|
nonspec_first_arbiter_granted_ivc_all,
|
nonspec_first_arbiter_granted_ivc_all,
|
ivc_num_getting_sw_grant,
|
ivc_num_getting_sw_grant,
|
Line 52... |
Line 51... |
vsa_credit_decreased_all,
|
vsa_credit_decreased_all,
|
vsa_ovc_released_all,
|
vsa_ovc_released_all,
|
crossbar_flit_out_wr_all,
|
crossbar_flit_out_wr_all,
|
oport_info,
|
oport_info,
|
ovc_info,
|
ovc_info,
|
|
ivc_info,
|
vsa_ctrl_in,
|
vsa_ctrl_in,
|
ssa_ctrl_in,
|
ssa_ctrl_in,
|
smart_ctrl_in,
|
smart_ctrl_in,
|
credit_init_val_in
|
credit_init_val_in
|
);
|
);
|
Line 86... |
Line 86... |
localparam [V-1 : 0] ADAPTIVE_VC_MASK = ~ ESCAP_VC_MASK;
|
localparam [V-1 : 0] ADAPTIVE_VC_MASK = ~ ESCAP_VC_MASK;
|
localparam CONG_ALw= CONGw * P; // congestion width per router;
|
localparam CONG_ALw= CONGw * P; // congestion width per router;
|
|
|
input [PV-1 : 0] vsa_ovc_allocated_all;
|
input [PV-1 : 0] vsa_ovc_allocated_all;
|
input [PV-1 : 0] flit_is_tail_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 [PVP_1-1 : 0] dest_port_all;
|
input [PVP_1-1 : 0] dest_port_all;
|
input [PP_1-1 : 0] nonspec_granted_dest_port_all;
|
input [PP_1-1 : 0] nonspec_granted_dest_port_all;
|
input [PV-1 : 0] credit_in_all;
|
input [PV-1 : 0] credit_in_all;
|
input [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all;
|
input [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all;
|
input [PV-1 : 0] ivc_num_getting_sw_grant;
|
input [PV-1 : 0] ivc_num_getting_sw_grant;
|
Line 106... |
Line 104... |
input [P-1 : 0] any_ovc_granted_in_outport_all;
|
input [P-1 : 0] any_ovc_granted_in_outport_all;
|
output [PV-1 : 0] vsa_ovc_released_all;
|
output [PV-1 : 0] vsa_ovc_released_all;
|
output [PV-1 : 0] vsa_credit_decreased_all;
|
output [PV-1 : 0] vsa_credit_decreased_all;
|
output oport_info_t oport_info [P-1:0];
|
output oport_info_t oport_info [P-1:0];
|
output ovc_info_t ovc_info [P-1 : 0][V-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 vsa_ctrl_t vsa_ctrl_in [P-1: 0];
|
input ssa_ctrl_t ssa_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 smart_ctrl_t smart_ctrl_in [P-1: 0];
|
input [CRDTw-1 : 0 ] credit_init_val_in [P-1 : 0][V-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 [PV-1 : 0] assigned_ovc_is_full_all;
|
wire [VP_1-1 : 0] credit_decreased [P-1 : 0];
|
wire [VP_1-1 : 0] credit_decreased [P-1 : 0];
|
wire [P_1-1 : 0] credit_decreased_gen [PV-1 : 0];
|
wire [P_1-1 : 0] credit_decreased_gen [PV-1 : 0];
|
|
|
wire [PV-1 : 0] credit_increased_all;
|
wire [PV-1 : 0] credit_increased_all;
|
Line 133... |
Line 133... |
wire [PV-1 : 0] credit_decreased_all;
|
wire [PV-1 : 0] credit_decreased_all;
|
wire [PV-1 : 0] ovc_released_all;
|
wire [PV-1 : 0] ovc_released_all;
|
wire [PV-1 : 0] ovc_allocated_all;
|
wire [PV-1 : 0] ovc_allocated_all;
|
wire [CREDITw-1 : 0] credit_counter [PV-1 : 0];
|
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));
|
pronoc_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));
|
pronoc_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_3 ( .in(empty_all_next), .reset(reset), .clk(clk), .out(empty_all));
|
|
|
|
|
|
|
integer k;
|
integer k;
|
genvar i,j;
|
genvar i,j;
|
Line 172... |
Line 175... |
|
|
end
|
end
|
end // for
|
end // for
|
end//always
|
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;
|
assign ovc_avalable_all = ~ovc_status & full_adaptive_ovc_mask;
|
|
|
end else begin : par_adpt//par adaptive
|
end else begin : par_adpt//par adaptive
|
assign ovc_avalable_all = (OVC_ALLOC_MODE)? ~(ovc_status | full_all) : ~(ovc_status | nearly_full_all);
|
assign ovc_avalable_all = (OVC_ALLOC_MODE)? ~(ovc_status | full_all) : ~(ovc_status | nearly_full_all);
|
Line 281... |
Line 284... |
end
|
end
|
|
|
|
|
for(i=0; i
|
for(i=0; i
|
|
|
|
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 #(
|
credit_monitor_per_ovc #(
|
.SW_LOC(i/V)
|
.SW_LOC(i/V)
|
)
|
)
|
credit_monitor
|
credit_monitor
|
(
|
(
|
Line 299... |
Line 307... |
.clk(clk)
|
.clk(clk)
|
);
|
);
|
|
|
|
|
|
|
sw_mask_gen #(
|
full_ovc_predictor #(
|
.OVC_ALLOC_MODE(OVC_ALLOC_MODE),
|
.OVC_ALLOC_MODE(OVC_ALLOC_MODE),
|
.PCK_TYPE(PCK_TYPE),
|
.PCK_TYPE(PCK_TYPE),
|
.V (V), // vc_num_per_port
|
.V (V), // vc_num_per_port
|
.P (P), // router port num
|
.P (P), // router port num
|
.SELF_LOOP_EN (SELF_LOOP_EN)
|
.SELF_LOOP_EN (SELF_LOOP_EN)
|
Line 323... |
Line 331... |
.clk (clk),
|
.clk (clk),
|
.reset (reset)
|
.reset (reset)
|
);
|
);
|
end//for
|
end//for
|
|
|
for(i=0; i
|
|
|
|
`ifdef SYNC_RESET_MODE
|
|
always @ (posedge clk )begin
|
|
`else
|
|
always @ (posedge clk or posedge reset)begin
|
|
`endif
|
for(i=0; i
|
if(reset) begin
|
always @ (*)begin
|
//credit_counter[i] <= Bint;
|
ovc_status_next[i] = ovc_status[i];
|
ovc_status[i] <= 1'b0;
|
|
end else begin
|
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if(PCK_TYPE == "SINGLE_FLIT") ovc_status[i]<=1'b0; // donot change VC status for single flit packet
|
if(PCK_TYPE == "SINGLE_FLIT") ovc_status_next[i]=1'b0; // donot change VC status for single flit packet
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
else begin
|
else begin
|
if(ovc_released_all[i]) ovc_status[i]<=1'b0;
|
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[i]<=1'b1; // donot change VC status for single flit packet
|
//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]) |
|
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])|
|
(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]))
|
(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
|
end//else reset
|
|
end//always
|
end//always
|
end//for
|
end//for
|
endgenerate
|
endgenerate
|
|
|
|
pronoc_register #(.W(PV)) reg2 (.in(ovc_status_next ), .out(ovc_status), .reset(reset), .clk(clk));
|
|
|
port_pre_sel_gen #(
|
port_pre_sel_gen #(
|
.PPSw(PPSw),
|
.PPSw(PPSw),
|
.P(P),
|
.P(P),
|
.V(V),
|
.V(V),
|
Line 383... |
Line 387... |
//synthesis translate_off
|
//synthesis translate_off
|
//synopsys translate_off
|
//synopsys translate_off
|
generate
|
generate
|
if(DEBUG_EN) begin: debug
|
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
|
always @ (posedge clk )begin
|
for(k=0; k
|
for(k=0; k
|
if(empty_all[k] & credit_increased_all[k]) begin
|
if(empty_all[k] & credit_increased_all[k]) begin
|
$display("%t: ERROR: unexpected credit recived for empty ovc[%d]: %m",$time,k);
|
$display("%t: ERROR: unexpected credit recived for empty ovc[%d]: %m",$time,k);
|
$finish;
|
$finish;
|
end
|
end
|
Line 413... |
Line 411... |
if(ovc_allocated_all[k] & ovc_status[k]) begin
|
if(ovc_allocated_all[k] & ovc_status[k]) begin
|
$display("%t: ERROR: Attempt to allocate an allocated OVC[%d]: %m",$time,k);
|
$display("%t: ERROR: Attempt to allocate an allocated OVC[%d]: %m",$time,k);
|
$finish;
|
$finish;
|
end
|
end
|
end//for
|
end//for
|
end
|
|
end//always
|
end//always
|
|
|
|
|
|
/* verilator lint_off WIDTH */
|
|
if(CAST_TYPE== "UNICAST") begin : unicast
|
|
/* verilator lint_on WIDTH */
|
|
|
localparam NUM_WIDTH = log2(PV+1);
|
localparam NUM_WIDTH = log2(PV+1);
|
wire [NUM_WIDTH-1 : 0] num1,num2;
|
wire [NUM_WIDTH-1 : 0] num1,num2;
|
parallel_counter #(
|
|
.IN_WIDTH(PV)
|
accumulator #(
|
)cnt1
|
.INw(PV),
|
|
.OUTw(NUM_WIDTH),
|
|
.NUM(PV)
|
|
)
|
|
cnt1
|
(
|
(
|
.in (ovc_status),
|
.in_all(ovc_status),
|
.out (num1)
|
.out (num1)
|
);
|
);
|
|
|
parallel_counter #(
|
accumulator #(
|
.IN_WIDTH(PV)
|
.INw(PV),
|
)cnt2
|
.OUTw(NUM_WIDTH),
|
|
.NUM(PV)
|
|
)
|
|
cnt2
|
(
|
(
|
.in (ovc_is_assigned_all),
|
.in_all(ovc_is_assigned_all),
|
.out (num2)
|
.out (num2)
|
);
|
);
|
|
|
|
|
|
|
|
|
always @(posedge clk) begin
|
always @(posedge clk) begin
|
if(num1 != num2 )begin
|
if(num1 != num2 )begin
|
$display("%t: ERROR: number of assigned IVC %d mismatch the number of occupied OVC %d: %m",$time,num1,num2);
|
$display("%t: ERROR: number of assigned IVC %d mismatch the number of occupied OVC %d: %m",$time,num1,num2);
|
$finish;
|
$finish;
|
end
|
end
|
end
|
end
|
|
end //unicast
|
check_ovc #(
|
check_ovc #(
|
.V(V) , // vc_num_per_port
|
.V(V) , // vc_num_per_port
|
.P(P), // router port num
|
.P(P), // router port num
|
.SELF_LOOP_EN(SELF_LOOP_EN)
|
.SELF_LOOP_EN(SELF_LOOP_EN)
|
|
|
Line 519... |
Line 532... |
assign empty_all_next = (credit_counter_next == Bint);
|
assign empty_all_next = (credit_counter_next == Bint);
|
assign full_all_next = (credit_counter_next == {DEPTHw{1'b0}});
|
assign full_all_next = (credit_counter_next == {DEPTHw{1'b0}});
|
assign nearly_full_all_next = (credit_counter_next <= 1);
|
assign nearly_full_all_next = (credit_counter_next <= 1);
|
|
|
|
|
`ifdef SYNC_RESET_MODE
|
pronoc_register_reset_init #(
|
always @ (posedge clk )begin
|
.W(DEPTHw)
|
`else
|
)reg1(
|
always @ (posedge clk or posedge reset)begin
|
.in(credit_counter_next),
|
`endif
|
.reset(reset),
|
if(reset) begin
|
.clk(clk),
|
credit_counter <= credit_init_val_i [DEPTHw-1 : 0]; // Bint;
|
.out(credit_counter),
|
end else begin
|
.reset_to(credit_init_val_i [DEPTHw-1 : 0]) // Bint;
|
credit_counter <= credit_counter_next;
|
);
|
end
|
|
end
|
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
Line 623... |
Line 634... |
endmodule
|
endmodule
|
|
|
|
|
/**********************************
|
/**********************************
|
|
|
sw_mask_gen
|
full_ovc_predictor
|
|
|
*********************************/
|
*********************************/
|
|
|
module sw_mask_gen #(
|
module full_ovc_predictor #(
|
parameter PCK_TYPE = "MULTI_FLIT",
|
parameter PCK_TYPE = "MULTI_FLIT",
|
parameter V = 4, // vc_num_per_port
|
parameter V = 4, // vc_num_per_port
|
parameter P = 5, // router port num
|
parameter P = 5, // router port num
|
parameter OVC_ALLOC_MODE=1'b0,
|
parameter OVC_ALLOC_MODE=1'b0,
|
parameter SELF_LOOP_EN = "NO"
|
parameter SELF_LOOP_EN = "NO"
|
Line 663... |
Line 674... |
|
|
|
|
wire [VP_1-1 : 0] full_muxin1,nearly_full_muxin1;
|
wire [VP_1-1 : 0] full_muxin1,nearly_full_muxin1;
|
wire [V-1 : 0] full_muxout1,nearly_full_muxout1;
|
wire [V-1 : 0] full_muxout1,nearly_full_muxout1;
|
wire full_muxout2,nearly_full_muxout2;
|
wire full_muxout2,nearly_full_muxout2;
|
reg full_reg1,full_reg2;
|
wire full_reg1,full_reg2;
|
wire full_reg1_next,full_reg2_next;
|
wire full_reg1_next,full_reg2_next;
|
|
|
|
|
assign full_muxin1 = full & (~credit_increased);
|
assign full_muxin1 = full & (~credit_increased);
|
assign nearly_full_muxin1 = nearly_full & (~credit_increased);
|
assign nearly_full_muxin1 = nearly_full & (~credit_increased);
|
Line 717... |
Line 728... |
.sel (nearlyfull_sel)
|
.sel (nearlyfull_sel)
|
);
|
);
|
|
|
assign full_reg1_next = full_muxout2;
|
assign full_reg1_next = full_muxout2;
|
assign full_reg2_next = nearly_full_muxout2 & ivc_getting_sw_grant;
|
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
|
endmodule
|
|
|
|
|
//synthesis translate_off
|
//synthesis translate_off
|