`include "pronoc_def.v"
|
`include "pronoc_def.v"
|
/**********************************************************************
|
/**********************************************************************
|
** File: output_ports.sv
|
** File: output_ports.sv
|
**
|
**
|
** Copyright (C) 2014-2017 Alireza Monemi
|
** Copyright (C) 2014-2017 Alireza Monemi
|
**
|
**
|
** This file is part of ProNoC
|
** This file is part of ProNoC
|
**
|
**
|
** ProNoC ( stands for Prototype Network-on-chip) is free software:
|
** ProNoC ( stands for Prototype Network-on-chip) is free software:
|
** you can redistribute it and/or modify it under the terms of the GNU
|
** 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,
|
** Lesser General Public License as published by the Free Software Foundation,
|
** either version 2 of the License, or (at your option) any later version.
|
** 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
|
** ProNoC is distributed in the hope that it will be useful, but WITHOUT
|
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
** or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
** or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
** Public License for more details.
|
** Public License for more details.
|
**
|
**
|
** You should have received a copy of the GNU Lesser General Public
|
** You should have received a copy of the GNU Lesser General Public
|
** License along with ProNoC. If not, see .
|
** License along with ProNoC. If not, see .
|
**
|
**
|
**
|
**
|
** Description:
|
** Description:
|
** output_ports module: contain output VC (OVC) status registers and credit counters,
|
** output_ports module: contain output VC (OVC) status registers and credit counters,
|
**
|
**
|
**************************************************************/
|
**************************************************************/
|
|
|
|
|
module output_ports
|
module output_ports #(
|
import pronoc_pkg::*;
|
parameter NOC_ID=0,
|
#(
|
parameter P=5
|
parameter P = 5 // router port num
|
|
)(
|
)(
|
vsa_ovc_allocated_all,
|
vsa_ovc_allocated_all,
|
flit_is_tail_all,
|
flit_is_tail_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,
|
ovc_avalable_all,
|
ovc_avalable_all,
|
assigned_ovc_not_full_all,
|
assigned_ovc_not_full_all,
|
port_pre_sel,
|
port_pre_sel,
|
congestion_in_all,
|
congestion_in_all,
|
granted_dst_is_from_a_single_flit_pck,
|
granted_dst_is_from_a_single_flit_pck,
|
granted_ovc_num_all,
|
granted_ovc_num_all,
|
reset,
|
reset,
|
clk,
|
clk,
|
any_ovc_granted_in_outport_all,
|
any_ovc_granted_in_outport_all,
|
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,
|
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
|
);
|
);
|
|
|
|
|
|
`NOC_CONF
|
|
|
|
localparam
|
function integer log2;
|
PV = V * P,
|
input integer number; begin
|
|
log2=(number <=1) ? 1: 0;
|
|
while(2**log2
|
|
log2=log2+1;
|
|
end
|
|
end
|
|
endfunction // log2
|
|
|
|
localparam PV = V * P,
|
|
VV = V * V,
|
VV = V * V,
|
PVV = PV * V,
|
PVV = PV * V,
|
P_1 = ( SELF_LOOP_EN=="NO")? P-1 : P,
|
P_1 = ( SELF_LOOP_EN=="NO")? P-1 : P,
|
VP_1 = V * P_1,
|
VP_1 = V * P_1,
|
PP_1 = P_1 * P,
|
PP_1 = P_1 * P,
|
PVP_1 = PV * P_1;
|
PVP_1 = PV * P_1;
|
|
|
|
|
localparam NORTH = 2,
|
|
SOUTH = 4;
|
|
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 [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;
|
output [PV-1 : 0] ovc_avalable_all;
|
output [PV-1 : 0] ovc_avalable_all;
|
output [PV-1 : 0] assigned_ovc_not_full_all;
|
output [PV-1 : 0] assigned_ovc_not_full_all;
|
input reset,clk;
|
input reset,clk;
|
output [PPSw-1 : 0] port_pre_sel;
|
output [PPSw-1 : 0] port_pre_sel;
|
input [CONG_ALw-1 : 0] congestion_in_all;
|
input [CONG_ALw-1 : 0] congestion_in_all;
|
input [PVV-1 : 0] granted_ovc_num_all;
|
input [PVV-1 : 0] granted_ovc_num_all;
|
input [P-1 : 0] granted_dst_is_from_a_single_flit_pck;
|
input [P-1 : 0] granted_dst_is_from_a_single_flit_pck;
|
input [P-1 : 0] crossbar_flit_out_wr_all;
|
input [P-1 : 0] crossbar_flit_out_wr_all;
|
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 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];
|
|
|
wire [PVV-1 : 0] ssa_granted_ovc_num_all;
|
wire [PVV-1 : 0] ssa_granted_ovc_num_all;
|
|
|
logic [PV-1 : 0] ovc_status;
|
logic [PV-1 : 0] ovc_status;
|
logic [PV-1 : 0] ovc_status_next;
|
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;
|
wire [VP_1-1 : 0] ovc_released [P-1 : 0];
|
wire [VP_1-1 : 0] ovc_released [P-1 : 0];
|
wire [P_1-1 : 0] ovc_released_gen [PV-1 : 0];
|
wire [P_1-1 : 0] ovc_released_gen [PV-1 : 0];
|
|
|
wire [VP_1-1 : 0] credit_in_perport [P-1 : 0];
|
wire [VP_1-1 : 0] credit_in_perport [P-1 : 0];
|
wire [VP_1-1 : 0] full_perport [P-1 : 0];
|
wire [VP_1-1 : 0] full_perport [P-1 : 0];
|
wire [VP_1-1 : 0] nearly_full_perport [P-1 : 0];
|
wire [VP_1-1 : 0] nearly_full_perport [P-1 : 0];
|
|
|
wire [PV-1 : 0] full_all,nearly_full_all, empty_all;
|
wire [PV-1 : 0] full_all,nearly_full_all, empty_all;
|
wire [PV-1 : 0] full_all_next,nearly_full_all_next,empty_all_next;
|
wire [PV-1 : 0] full_all_next,nearly_full_all_next,empty_all_next;
|
|
|
|
|
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 [PVV-1 : 0] assigned_ovc_num_all;
|
wire [PV-1 : 0] ovc_is_assigned_all;
|
wire [PV-1 : 0] ovc_is_assigned_all;
|
|
|
|
|
pronoc_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));
|
pronoc_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));
|
pronoc_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;
|
generate
|
generate
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if(VC_REALLOCATION_TYPE=="ATOMIC") begin :atomic
|
if(VC_REALLOCATION_TYPE=="ATOMIC") begin :atomic
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
// in atomic architecture an OVC is available if its not allocated and its empty
|
// in atomic architecture an OVC is available if its not allocated and its empty
|
assign ovc_avalable_all = ~ovc_status & empty_all;
|
assign ovc_avalable_all = ~ovc_status & empty_all;
|
|
|
end else begin :nonatomic //NONATOMIC
|
end else begin :nonatomic //NONATOMIC
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if(ROUTE_TYPE == "FULL_ADAPTIVE") begin :full_adpt
|
if(ROUTE_TYPE == "FULL_ADAPTIVE") begin :full_adpt
|
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
|
|
reg [PV-1 : 0] full_adaptive_ovc_mask,full_adaptive_ovc_mask_next;
|
reg [PV-1 : 0] full_adaptive_ovc_mask,full_adaptive_ovc_mask_next;
|
|
|
always @(*) begin
|
always @(*) begin
|
for(k=0; k
|
for(k=0; k
|
//in full adaptive routing, adaptive VCs located in y axies can not be reallocated non-atomicly
|
//in full adaptive routing, adaptive VCs located in y axies can not be reallocated non-atomicly
|
if( AVC_ATOMIC_EN== 0) begin :avc_atomic
|
if( AVC_ATOMIC_EN== 0) begin :avc_atomic
|
if((((k/V) == NORTH ) || ((k/V) == SOUTH )) && ( ADAPTIVE_VC_MASK[k%V]))
|
if((((k/V) == NORTH ) || ((k/V) == SOUTH )) && ( ADAPTIVE_VC_MASK[k%V]))
|
full_adaptive_ovc_mask_next[k] = empty_all_next[k];
|
full_adaptive_ovc_mask_next[k] = empty_all_next[k];
|
else full_adaptive_ovc_mask_next[k] = (OVC_ALLOC_MODE)? ~full_all_next[k] : ~nearly_full_all_next[k];
|
else full_adaptive_ovc_mask_next[k] = (OVC_ALLOC_MODE)? ~full_all_next[k] : ~nearly_full_all_next[k];
|
end else begin :avc_nonatomic
|
end else begin :avc_nonatomic
|
if( ADAPTIVE_VC_MASK[k%V])
|
if( ADAPTIVE_VC_MASK[k%V])
|
full_adaptive_ovc_mask_next[k] = empty_all_next[k];
|
full_adaptive_ovc_mask_next[k] = empty_all_next[k];
|
else full_adaptive_ovc_mask_next[k] = (OVC_ALLOC_MODE)? ~full_all_next[k] :~nearly_full_all_next[k];
|
else full_adaptive_ovc_mask_next[k] = (OVC_ALLOC_MODE)? ~full_all_next[k] :~nearly_full_all_next[k];
|
|
|
end
|
end
|
end // for
|
end // for
|
end//always
|
end//always
|
|
|
pronoc_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);
|
|
|
end
|
end
|
end //NONATOMIC
|
end //NONATOMIC
|
endgenerate
|
endgenerate
|
|
|
|
|
assign credit_increased_all = credit_in_all;
|
assign credit_increased_all = credit_in_all;
|
assign assigned_ovc_not_full_all = ~ assigned_ovc_is_full_all;
|
assign assigned_ovc_not_full_all = ~ assigned_ovc_is_full_all;
|
|
|
// wire [PV-1 : 0] non_smart_ovc_allocated_all = ssa_ovc_allocated_all| vsa_ovc_allocated_all;
|
// wire [PV-1 : 0] non_smart_ovc_allocated_all = ssa_ovc_allocated_all| vsa_ovc_allocated_all;
|
wire [PV-1 : 0] non_smart_ovc_allocated_all;
|
wire [PV-1 : 0] non_smart_ovc_allocated_all;
|
generate
|
generate
|
for(i=0;i
|
for(i=0;i
|
assign ssa_granted_ovc_num_all[(i+1)*VV-1: i*VV] = ssa_ctrl_in[i].ivc_granted_ovc_num;
|
assign ssa_granted_ovc_num_all[(i+1)*VV-1: i*VV] = ssa_ctrl_in[i].ivc_granted_ovc_num;
|
assign credit_decreased_all [(i+1)*V-1 : i*V] = vsa_ctrl_in[i].buff_space_decreased | ssa_ctrl_in[i].buff_space_decreased | smart_ctrl_in[i].buff_space_decreased;
|
assign credit_decreased_all [(i+1)*V-1 : i*V] = vsa_ctrl_in[i].buff_space_decreased | ssa_ctrl_in[i].buff_space_decreased | smart_ctrl_in[i].buff_space_decreased;
|
assign ovc_released_all [(i+1)*V-1 : i*V] = vsa_ctrl_in[i].ovc_is_released | ssa_ctrl_in[i].ovc_is_released | smart_ctrl_in[i].ovc_is_released;
|
assign ovc_released_all [(i+1)*V-1 : i*V] = vsa_ctrl_in[i].ovc_is_released | ssa_ctrl_in[i].ovc_is_released | smart_ctrl_in[i].ovc_is_released;
|
assign ovc_allocated_all [(i+1)*V-1 : i*V] = vsa_ctrl_in[i].ovc_is_allocated | ssa_ctrl_in[i].ovc_is_allocated | smart_ctrl_in[i].ovc_is_allocated;
|
assign ovc_allocated_all [(i+1)*V-1 : i*V] = vsa_ctrl_in[i].ovc_is_allocated | ssa_ctrl_in[i].ovc_is_allocated | smart_ctrl_in[i].ovc_is_allocated;
|
//assign non_smart_ovc_allocated_all [(i+1)*V-1 : i*V] = ssa_ctrl_in[i].ovc_is_allocated | vsa_ctrl_in[i].ovc_is_allocated;
|
//assign non_smart_ovc_allocated_all [(i+1)*V-1 : i*V] = ssa_ctrl_in[i].ovc_is_allocated | vsa_ctrl_in[i].ovc_is_allocated;
|
|
|
assign non_smart_ovc_allocated_all [(i+1)*V-1 : i*V] = vsa_ctrl_in[i].ovc_is_allocated;
|
assign non_smart_ovc_allocated_all [(i+1)*V-1 : i*V] = vsa_ctrl_in[i].ovc_is_allocated;
|
|
|
|
|
assign oport_info[i].non_smart_ovc_is_allocated = non_smart_ovc_allocated_all [(i+1)*V-1 :i*V];
|
assign oport_info[i].non_smart_ovc_is_allocated = non_smart_ovc_allocated_all [(i+1)*V-1 :i*V];
|
assign oport_info[i].any_ovc_granted = any_ovc_granted_in_outport_all [i];
|
assign oport_info[i].any_ovc_granted = any_ovc_granted_in_outport_all [i];
|
|
|
|
|
oport_ovc_sig_gen #(
|
oport_ovc_sig_gen #(
|
.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)
|
)the_oport_ovc_sig_gen
|
)the_oport_ovc_sig_gen
|
(
|
(
|
.flit_is_tail (flit_is_tail_all [(i+1)*V-1 :i*V]),
|
.flit_is_tail (flit_is_tail_all [(i+1)*V-1 :i*V]),
|
.assigned_ovc_num (assigned_ovc_num_all [(i+1)*VV-1 :i*VV]),
|
.assigned_ovc_num (assigned_ovc_num_all [(i+1)*VV-1 :i*VV]),
|
.ovc_is_assigned (ovc_is_assigned_all [(i+1)*V-1 :i*V]),
|
.ovc_is_assigned (ovc_is_assigned_all [(i+1)*V-1 :i*V]),
|
.granted_dest_port (nonspec_granted_dest_port_all [(i+1)*P_1-1 :i*P_1]),
|
.granted_dest_port (nonspec_granted_dest_port_all [(i+1)*P_1-1 :i*P_1]),
|
.first_arbiter_granted_ivc (nonspec_first_arbiter_granted_ivc_all [(i+1)*V-1 :i*V]),
|
.first_arbiter_granted_ivc (nonspec_first_arbiter_granted_ivc_all [(i+1)*V-1 :i*V]),
|
.credit_decreased (credit_decreased [i]),
|
.credit_decreased (credit_decreased [i]),
|
.ovc_released (ovc_released [i])
|
.ovc_released (ovc_released [i])
|
|
|
);
|
);
|
|
|
for(j=0; j
|
for(j=0; j
|
assign ovc_info[i][j].avalable= ovc_avalable_all [i*V+j];
|
assign ovc_info[i][j].avalable= ovc_avalable_all [i*V+j];
|
assign ovc_info[i][j].status =ovc_status [i*V+j]; //1 : is allocated 0 : not_allocated
|
assign ovc_info[i][j].status =ovc_status [i*V+j]; //1 : is allocated 0 : not_allocated
|
assign ovc_info[i][j].credit = credit_counter[i*V+j];//available credit in OVC
|
assign ovc_info[i][j].credit = credit_counter[i*V+j];//available credit in OVC
|
assign ovc_info[i][j].full =full_all[i*V+j];
|
assign ovc_info[i][j].full =full_all[i*V+j];
|
assign ovc_info[i][j].nearly_full=nearly_full_all[i*V+j];
|
assign ovc_info[i][j].nearly_full=nearly_full_all[i*V+j];
|
assign ovc_info[i][j].empty=empty_all[i*V+j];
|
assign ovc_info[i][j].empty=empty_all[i*V+j];
|
end
|
end
|
|
|
end//for
|
end//for
|
|
|
|
|
for(i=0;i< PV;i=i+1) begin :total_vc_loop2
|
for(i=0;i< PV;i=i+1) begin :total_vc_loop2
|
for(j=0;j
|
for(j=0;j
|
if ( SELF_LOOP_EN=="NO") begin : nslp
|
if ( SELF_LOOP_EN=="NO") begin : nslp
|
if((i/V)
|
if((i/V)
|
assign ovc_released_gen [i][j-1] = ovc_released[j][i];
|
assign ovc_released_gen [i][j-1] = ovc_released[j][i];
|
assign credit_decreased_gen[i][j-1] = credit_decreased [j][i];
|
assign credit_decreased_gen[i][j-1] = credit_decreased [j][i];
|
end else if((i/V)>j) begin: hh
|
end else if((i/V)>j) begin: hh
|
assign ovc_released_gen [i][j] = ovc_released[j][i-V];
|
assign ovc_released_gen [i][j] = ovc_released[j][i-V];
|
assign credit_decreased_gen[i][j] = credit_decreased[j][i-V];
|
assign credit_decreased_gen[i][j] = credit_decreased[j][i-V];
|
end
|
end
|
end else begin :slp
|
end else begin :slp
|
assign ovc_released_gen [i][j] = ovc_released[j][i];
|
assign ovc_released_gen [i][j] = ovc_released[j][i];
|
assign credit_decreased_gen[i][j] = credit_decreased [j][i];
|
assign credit_decreased_gen[i][j] = credit_decreased [j][i];
|
end
|
end
|
end//j
|
end//j
|
assign vsa_ovc_released_all [i] = |ovc_released_gen[i];
|
assign vsa_ovc_released_all [i] = |ovc_released_gen[i];
|
assign vsa_credit_decreased_all [i] = (|credit_decreased_gen[i])|vsa_ovc_allocated_all[i];
|
assign vsa_credit_decreased_all [i] = (|credit_decreased_gen[i])|vsa_ovc_allocated_all[i];
|
end//i
|
end//i
|
|
|
|
|
|
|
if ( SELF_LOOP_EN=="NO") begin : nslp
|
if ( SELF_LOOP_EN=="NO") begin : nslp
|
//remove source port from the list
|
//remove source port from the list
|
for(i=0;i< P;i=i+1) begin :port_loop
|
for(i=0;i< P;i=i+1) begin :port_loop
|
if(i==0) begin :i0
|
if(i==0) begin :i0
|
assign credit_in_perport [i]=credit_in_all [PV-1 : V];
|
assign credit_in_perport [i]=credit_in_all [PV-1 : V];
|
assign full_perport [i]=full_all [PV-1 : V];
|
assign full_perport [i]=full_all [PV-1 : V];
|
assign nearly_full_perport [i]=nearly_full_all [PV-1 : V];
|
assign nearly_full_perport [i]=nearly_full_all [PV-1 : V];
|
end else if(i==(P-1)) begin :ip_1
|
end else if(i==(P-1)) begin :ip_1
|
assign credit_in_perport [i]=credit_in_all [PV-V-1 : 0];
|
assign credit_in_perport [i]=credit_in_all [PV-V-1 : 0];
|
assign full_perport [i]=full_all [PV-V-1 : 0];
|
assign full_perport [i]=full_all [PV-V-1 : 0];
|
assign nearly_full_perport [i]=nearly_full_all [PV-V-1 : 0];
|
assign nearly_full_perport [i]=nearly_full_all [PV-V-1 : 0];
|
end else begin : els
|
end else begin : els
|
assign credit_in_perport [i]={credit_in_all [PV-1 : (i+1)*V],credit_in_all [(i*V)-1 : 0]};
|
assign credit_in_perport [i]={credit_in_all [PV-1 : (i+1)*V],credit_in_all [(i*V)-1 : 0]};
|
assign full_perport [i]={full_all [PV-1 : (i+1)*V],full_all [(i*V)-1 : 0]};
|
assign full_perport [i]={full_all [PV-1 : (i+1)*V],full_all [(i*V)-1 : 0]};
|
assign nearly_full_perport [i]={nearly_full_all [PV-1 : (i+1)*V],nearly_full_all[(i*V)-1 : 0]};
|
assign nearly_full_perport [i]={nearly_full_all [PV-1 : (i+1)*V],nearly_full_all[(i*V)-1 : 0]};
|
end
|
end
|
end//for
|
end//for
|
end else begin: slp
|
end else begin: slp
|
for(i=0;i< P;i=i+1) begin :port_loop
|
for(i=0;i< P;i=i+1) begin :port_loop
|
assign credit_in_perport [i]=credit_in_all;
|
assign credit_in_perport [i]=credit_in_all;
|
assign full_perport [i]=full_all;
|
assign full_perport [i]=full_all;
|
assign nearly_full_perport [i]=nearly_full_all;
|
assign nearly_full_perport [i]=nearly_full_all;
|
end
|
end
|
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 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;
|
assign ovc_is_assigned_all[i]=ivc_info[i/V][i%V].ovc_is_assigned;
|
|
|
|
|
|
|
credit_monitor_per_ovc #(
|
credit_monitor_per_ovc #(
|
|
.NOC_ID(NOC_ID),
|
.SW_LOC(i/V)
|
.SW_LOC(i/V)
|
)
|
) credit_monitor (
|
credit_monitor
|
|
(
|
|
.credit_init_val_i(credit_init_val_in[i/V][i%V]),
|
.credit_init_val_i(credit_init_val_in[i/V][i%V]),
|
.credit_counter_o (credit_counter[i]),
|
.credit_counter_o (credit_counter[i]),
|
.credit_increased (credit_increased_all[i]),
|
.credit_increased (credit_increased_all[i]),
|
.credit_decreased(credit_decreased_all[i]),
|
.credit_decreased(credit_decreased_all[i]),
|
.empty_all_next(empty_all_next[i]),
|
.empty_all_next(empty_all_next[i]),
|
.full_all_next(full_all_next[i]),
|
.full_all_next(full_all_next[i]),
|
.nearly_full_all_next(nearly_full_all_next[i]),
|
.nearly_full_all_next(nearly_full_all_next[i]),
|
.reset(reset),
|
.reset(reset),
|
.clk(clk)
|
.clk(clk)
|
);
|
);
|
|
|
|
|
|
|
full_ovc_predictor #(
|
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)
|
|
|
)
|
)
|
sw_mask
|
sw_mask
|
(
|
(
|
.ssa_granted_ovc_num(ssa_granted_ovc_num_all[(i+1)*V-1 :i*V]),
|
.ssa_granted_ovc_num(ssa_granted_ovc_num_all[(i+1)*V-1 :i*V]),
|
.granted_ovc_num(granted_ovc_num_all[(i+1)*V-1 :i*V]),
|
.granted_ovc_num(granted_ovc_num_all[(i+1)*V-1 :i*V]),
|
.ovc_is_assigned(ovc_is_assigned_all[i]),
|
.ovc_is_assigned(ovc_is_assigned_all[i]),
|
.assigned_ovc_num (assigned_ovc_num_all[(i+1)*V-1 :i*V]),
|
.assigned_ovc_num (assigned_ovc_num_all[(i+1)*V-1 :i*V]),
|
.dest_port (dest_port_all [(i+1)*P_1-1 :i*P_1]),
|
.dest_port (dest_port_all [(i+1)*P_1-1 :i*P_1]),
|
.full (full_perport [i/V]),
|
.full (full_perport [i/V]),
|
.credit_increased (credit_in_perport [i/V]),
|
.credit_increased (credit_in_perport [i/V]),
|
.nearly_full (nearly_full_perport [i/V]),
|
.nearly_full (nearly_full_perport [i/V]),
|
.ivc_getting_sw_grant (ivc_num_getting_sw_grant[i]),
|
.ivc_getting_sw_grant (ivc_num_getting_sw_grant[i]),
|
.assigned_ovc_is_full (assigned_ovc_is_full_all[i]),
|
.assigned_ovc_is_full (assigned_ovc_is_full_all[i]),
|
.clk (clk),
|
.clk (clk),
|
.reset (reset)
|
.reset (reset)
|
);
|
);
|
end//for
|
end//for
|
|
|
|
|
|
|
|
|
|
|
|
|
for(i=0; i
|
for(i=0; i
|
always @ (*)begin
|
always @ (*)begin
|
ovc_status_next[i] = ovc_status[i];
|
ovc_status_next[i] = ovc_status[i];
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if(PCK_TYPE == "SINGLE_FLIT") ovc_status_next[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_next[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_next[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_next[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//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));
|
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),
|
.B(B),
|
.B(B),
|
.CONGESTION_INDEX(CONGESTION_INDEX),
|
.CONGESTION_INDEX(CONGESTION_INDEX),
|
.CONGw(CONGw),
|
.CONGw(CONGw),
|
.ROUTE_TYPE(ROUTE_TYPE),
|
.ROUTE_TYPE(ROUTE_TYPE),
|
.ESCAP_VC_MASK(ESCAP_VC_MASK)
|
.ESCAP_VC_MASK(ESCAP_VC_MASK)
|
|
|
)
|
)
|
port_pre_sel_top
|
port_pre_sel_top
|
(
|
(
|
.port_pre_sel(port_pre_sel),
|
.port_pre_sel(port_pre_sel),
|
.ovc_status(ovc_status),
|
.ovc_status(ovc_status),
|
.ovc_avalable_all(ovc_avalable_all),
|
.ovc_avalable_all(ovc_avalable_all),
|
.credit_decreased_all(credit_decreased_all),
|
.credit_decreased_all(credit_decreased_all),
|
.credit_increased_all(credit_increased_all),
|
.credit_increased_all(credit_increased_all),
|
.congestion_in_all(congestion_in_all),
|
.congestion_in_all(congestion_in_all),
|
.reset(reset),
|
.reset(reset),
|
.clk(clk)
|
.clk(clk)
|
|
|
);
|
);
|
|
|
|
|
//synthesis translate_off
|
//synthesis translate_off
|
//synopsys translate_off
|
//synopsys translate_off
|
generate
|
generate
|
if(DEBUG_EN) begin: debug
|
if(DEBUG_EN) begin: debug
|
|
|
|
|
always @ (posedge clk )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
|
if(full_all[k] & credit_decreased_all[k]) begin
|
if(full_all[k] & credit_decreased_all[k]) begin
|
$display("%t: ERROR: Attempt to send flit to full ovc[%d]: %m",$time,k);
|
$display("%t: ERROR: Attempt to send flit to full ovc[%d]: %m",$time,k);
|
$finish;
|
$finish;
|
end
|
end
|
if(ovc_released_all[k] & ovc_allocated_all[k]) begin
|
if(ovc_released_all[k] & ovc_allocated_all[k]) begin
|
$display("%t: ERROR: simultaneous allocation and release for an OVC[%d]: %m",$time,k);
|
$display("%t: ERROR: simultaneous allocation and release for an OVC[%d]: %m",$time,k);
|
$finish;
|
$finish;
|
end
|
end
|
if(ovc_released_all[k]==1'b1 && ovc_status[k]==1'b0) begin
|
if(ovc_released_all[k]==1'b1 && ovc_status[k]==1'b0) begin
|
$display("%t: ERROR: Attempt to release an unallocated OVC[%d]: %m",$time,k);
|
$display("%t: ERROR: Attempt to release an unallocated OVC[%d]: %m",$time,k);
|
$finish;
|
$finish;
|
end
|
end
|
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//always
|
end//always
|
|
|
|
|
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
if(CAST_TYPE== "UNICAST") begin : unicast
|
if(CAST_TYPE== "UNICAST") begin : unicast
|
/* verilator lint_on WIDTH */
|
/* 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;
|
|
|
accumulator #(
|
accumulator #(
|
.INw(PV),
|
.INw(PV),
|
.OUTw(NUM_WIDTH),
|
.OUTw(NUM_WIDTH),
|
.NUM(PV)
|
.NUM(PV)
|
)
|
)
|
cnt1
|
cnt1
|
(
|
(
|
.in_all(ovc_status),
|
.in_all(ovc_status),
|
.out(num1)
|
.out(num1)
|
);
|
);
|
|
|
accumulator #(
|
accumulator #(
|
.INw(PV),
|
.INw(PV),
|
.OUTw(NUM_WIDTH),
|
.OUTw(NUM_WIDTH),
|
.NUM(PV)
|
.NUM(PV)
|
)
|
)
|
cnt2
|
cnt2
|
(
|
(
|
.in_all(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
|
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)
|
|
|
)test
|
)test
|
(
|
(
|
.ovc_status(ovc_status),
|
.ovc_status(ovc_status),
|
.assigned_ovc_num_all(assigned_ovc_num_all),
|
.assigned_ovc_num_all(assigned_ovc_num_all),
|
.ovc_is_assigned_all(ovc_is_assigned_all),
|
.ovc_is_assigned_all(ovc_is_assigned_all),
|
.dest_port_all(dest_port_all),
|
.dest_port_all(dest_port_all),
|
.clk(clk),
|
.clk(clk),
|
.reset(reset)
|
.reset(reset)
|
);
|
);
|
|
|
end// DEBUG
|
end// DEBUG
|
endgenerate
|
endgenerate
|
//synopsys translate_on
|
//synopsys translate_on
|
//synthesis translate_on
|
//synthesis translate_on
|
endmodule
|
endmodule
|
|
|
|
|
/*********************
|
/*********************
|
* credit_monitor_per_ovc
|
* credit_monitor_per_ovc
|
********************/
|
********************/
|
|
|
module credit_monitor_per_ovc
|
module credit_monitor_per_ovc #(
|
import pronoc_pkg::*;
|
parameter NOC_ID=0,
|
#(
|
|
parameter SW_LOC=0
|
parameter SW_LOC=0
|
)(
|
) (
|
credit_init_val_i,
|
credit_init_val_i,
|
credit_increased,
|
credit_increased,
|
credit_decreased,
|
credit_decreased,
|
credit_counter_o,
|
credit_counter_o,
|
empty_all_next,
|
empty_all_next,
|
full_all_next,
|
full_all_next,
|
nearly_full_all_next,
|
nearly_full_all_next,
|
reset,
|
reset,
|
clk
|
clk
|
);
|
);
|
|
|
|
`NOC_CONF
|
|
|
localparam
|
localparam
|
PORT_B = port_buffer_size(SW_LOC),
|
PORT_B = port_buffer_size(SW_LOC),
|
DEPTHw = log2(PORT_B+1);
|
DEPTHw = log2(PORT_B+1);
|
|
|
localparam [DEPTHw-1 : 0] Bint = PORT_B [DEPTHw-1 : 0];
|
localparam [DEPTHw-1 : 0] Bint = PORT_B [DEPTHw-1 : 0];
|
|
|
input [CRDTw-1 : 0] credit_init_val_i;
|
input [CRDTw-1 : 0] credit_init_val_i;
|
input credit_increased;
|
input credit_increased;
|
input credit_decreased;
|
input credit_decreased;
|
output reg [CREDITw-1 : 0] credit_counter_o ;
|
output reg [CREDITw-1 : 0] credit_counter_o ;
|
output empty_all_next;
|
output empty_all_next;
|
output full_all_next;
|
output full_all_next;
|
output nearly_full_all_next;
|
output nearly_full_all_next;
|
input reset,clk;
|
input reset,clk;
|
|
|
reg [DEPTHw-1 : 0] credit_counter_next;
|
reg [DEPTHw-1 : 0] credit_counter_next;
|
reg [DEPTHw-1 : 0] credit_counter;
|
reg [DEPTHw-1 : 0] credit_counter;
|
|
|
always @(*) begin
|
always @(*) begin
|
credit_counter_next = credit_counter;
|
credit_counter_next = credit_counter;
|
if(credit_increased & ~credit_decreased) begin
|
if(credit_increased & ~credit_decreased) begin
|
credit_counter_next = credit_counter+1'b1;
|
credit_counter_next = credit_counter+1'b1;
|
end else if (~credit_increased & credit_decreased)begin
|
end else if (~credit_increased & credit_decreased)begin
|
credit_counter_next = credit_counter-1'b1;
|
credit_counter_next = credit_counter-1'b1;
|
end
|
end
|
credit_counter_o = {CREDITw{1'b0}};
|
credit_counter_o = {CREDITw{1'b0}};
|
credit_counter_o [DEPTHw-1 : 0] = credit_counter;
|
credit_counter_o [DEPTHw-1 : 0] = credit_counter;
|
end
|
end
|
|
|
|
|
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);
|
|
|
|
|
pronoc_register_reset_init #(
|
pronoc_register_reset_init #(
|
.W(DEPTHw)
|
.W(DEPTHw)
|
)reg1(
|
)reg1(
|
.in(credit_counter_next),
|
.in(credit_counter_next),
|
.reset(reset),
|
.reset(reset),
|
.clk(clk),
|
.clk(clk),
|
.out(credit_counter),
|
.out(credit_counter),
|
.reset_to(credit_init_val_i [DEPTHw-1 : 0]) // Bint;
|
.reset_to(credit_init_val_i [DEPTHw-1 : 0]) // Bint;
|
);
|
);
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
/************************************
|
/************************************
|
oport_ovc_sig_gen
|
oport_ovc_sig_gen
|
*************************************/
|
*************************************/
|
module oport_ovc_sig_gen #(
|
module oport_ovc_sig_gen #(
|
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 SELF_LOOP_EN = "NO"
|
parameter SELF_LOOP_EN = "NO"
|
)(
|
)(
|
flit_is_tail,
|
flit_is_tail,
|
assigned_ovc_num,
|
assigned_ovc_num,
|
ovc_is_assigned,
|
ovc_is_assigned,
|
granted_dest_port,
|
granted_dest_port,
|
first_arbiter_granted_ivc,
|
first_arbiter_granted_ivc,
|
credit_decreased,
|
credit_decreased,
|
ovc_released
|
ovc_released
|
|
|
);
|
);
|
|
|
localparam VV = V * V,
|
localparam VV = V * V,
|
P_1 = ( SELF_LOOP_EN=="NO")? P-1 : P,
|
P_1 = ( SELF_LOOP_EN=="NO")? P-1 : P,
|
VP_1 = V * P_1;
|
VP_1 = V * P_1;
|
|
|
|
|
input [V-1 : 0] flit_is_tail;
|
input [V-1 : 0] flit_is_tail;
|
input [VV-1 : 0] assigned_ovc_num;
|
input [VV-1 : 0] assigned_ovc_num;
|
input [V-1 : 0] ovc_is_assigned;
|
input [V-1 : 0] ovc_is_assigned;
|
input [P_1-1 : 0] granted_dest_port;
|
input [P_1-1 : 0] granted_dest_port;
|
input [V-1 : 0] first_arbiter_granted_ivc;
|
input [V-1 : 0] first_arbiter_granted_ivc;
|
output [VP_1-1 : 0] credit_decreased;
|
output [VP_1-1 : 0] credit_decreased;
|
output [VP_1-1 : 0] ovc_released;
|
output [VP_1-1 : 0] ovc_released;
|
|
|
|
|
|
|
wire [V-1 : 0] muxout1;
|
wire [V-1 : 0] muxout1;
|
wire muxout2;
|
wire muxout2;
|
|
|
wire [VV-1 : 0] assigned_ovc_num_masked;
|
wire [VV-1 : 0] assigned_ovc_num_masked;
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for (i=0;i
|
for (i=0;i
|
assign assigned_ovc_num_masked[(i+1)*V-1 : i*V] = ovc_is_assigned[i]? assigned_ovc_num [(i+1)*V-1 : i*V] : {V{1'b0}};
|
assign assigned_ovc_num_masked[(i+1)*V-1 : i*V] = ovc_is_assigned[i]? assigned_ovc_num [(i+1)*V-1 : i*V] : {V{1'b0}};
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
|
|
|
// assigned ovc mux
|
// assigned ovc mux
|
onehot_mux_1D #(
|
onehot_mux_1D #(
|
.W (V),
|
.W (V),
|
.N (V)
|
.N (V)
|
)assigned_ovc_mux
|
)assigned_ovc_mux
|
(
|
(
|
.in (assigned_ovc_num_masked),
|
.in (assigned_ovc_num_masked),
|
.out (muxout1),
|
.out (muxout1),
|
.sel (first_arbiter_granted_ivc)
|
.sel (first_arbiter_granted_ivc)
|
);
|
);
|
|
|
// tail mux
|
// tail mux
|
onehot_mux_1D #(
|
onehot_mux_1D #(
|
.W (1),
|
.W (1),
|
.N (V)
|
.N (V)
|
)tail_mux
|
)tail_mux
|
(
|
(
|
.in (flit_is_tail),
|
.in (flit_is_tail),
|
.out (muxout2),
|
.out (muxout2),
|
.sel (first_arbiter_granted_ivc)
|
.sel (first_arbiter_granted_ivc)
|
);
|
);
|
|
|
|
|
one_hot_demux #(
|
one_hot_demux #(
|
.IN_WIDTH (V),
|
.IN_WIDTH (V),
|
.SEL_WIDTH (P_1)
|
.SEL_WIDTH (P_1)
|
|
|
) demux
|
) demux
|
(
|
(
|
.demux_sel (granted_dest_port),//selectore
|
.demux_sel (granted_dest_port),//selectore
|
.demux_in (muxout1),//repeated
|
.demux_in (muxout1),//repeated
|
.demux_out (credit_decreased)
|
.demux_out (credit_decreased)
|
);
|
);
|
|
|
assign ovc_released = (muxout2)? credit_decreased : {VP_1{1'b0}};
|
assign ovc_released = (muxout2)? credit_decreased : {VP_1{1'b0}};
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
/**********************************
|
/**********************************
|
|
|
full_ovc_predictor
|
full_ovc_predictor
|
|
|
*********************************/
|
*********************************/
|
|
|
module full_ovc_predictor #(
|
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"
|
|
|
)(
|
)(
|
ssa_granted_ovc_num,
|
ssa_granted_ovc_num,
|
granted_ovc_num,
|
granted_ovc_num,
|
ovc_is_assigned,
|
ovc_is_assigned,
|
assigned_ovc_num,
|
assigned_ovc_num,
|
dest_port,
|
dest_port,
|
full,
|
full,
|
credit_increased,
|
credit_increased,
|
nearly_full,
|
nearly_full,
|
ivc_getting_sw_grant,
|
ivc_getting_sw_grant,
|
assigned_ovc_is_full,
|
assigned_ovc_is_full,
|
clk,
|
clk,
|
reset
|
reset
|
);
|
);
|
localparam P_1 = ( SELF_LOOP_EN=="NO")? P-1 : P,
|
localparam P_1 = ( SELF_LOOP_EN=="NO")? P-1 : P,
|
VP_1 = V * P_1;
|
VP_1 = V * P_1;
|
input clk,reset;
|
input clk,reset;
|
input ovc_is_assigned;
|
input ovc_is_assigned;
|
input [V-1 : 0] assigned_ovc_num,granted_ovc_num,ssa_granted_ovc_num;
|
input [V-1 : 0] assigned_ovc_num,granted_ovc_num,ssa_granted_ovc_num;
|
input [P_1-1 : 0] dest_port;
|
input [P_1-1 : 0] dest_port;
|
input [VP_1-1 : 0] full;
|
input [VP_1-1 : 0] full;
|
input [VP_1-1 : 0] credit_increased;
|
input [VP_1-1 : 0] credit_increased;
|
input [VP_1-1 : 0] nearly_full;
|
input [VP_1-1 : 0] nearly_full;
|
input ivc_getting_sw_grant;
|
input ivc_getting_sw_grant;
|
output assigned_ovc_is_full;
|
output assigned_ovc_is_full;
|
|
|
|
|
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;
|
wire 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);
|
|
|
|
|
// destport mux
|
// destport mux
|
onehot_mux_1D #(
|
onehot_mux_1D #(
|
.W (V),
|
.W (V),
|
.N (P_1)
|
.N (P_1)
|
)full_mux1
|
)full_mux1
|
(
|
(
|
.in (full_muxin1),
|
.in (full_muxin1),
|
.out (full_muxout1),
|
.out (full_muxout1),
|
.sel (dest_port)
|
.sel (dest_port)
|
);
|
);
|
|
|
onehot_mux_1D #(
|
onehot_mux_1D #(
|
.W (V),
|
.W (V),
|
.N (P_1)
|
.N (P_1)
|
)nearly_full_mux1
|
)nearly_full_mux1
|
(
|
(
|
.in (nearly_full_muxin1),
|
.in (nearly_full_muxin1),
|
.out (nearly_full_muxout1),
|
.out (nearly_full_muxout1),
|
.sel (dest_port)
|
.sel (dest_port)
|
);
|
);
|
|
|
// assigned ovc mux
|
// assigned ovc mux
|
onehot_mux_1D #(
|
onehot_mux_1D #(
|
.W (1),
|
.W (1),
|
.N (V)
|
.N (V)
|
)full_mux2
|
)full_mux2
|
(
|
(
|
.in (full_muxout1),
|
.in (full_muxout1),
|
.out (full_muxout2),
|
.out (full_muxout2),
|
.sel (assigned_ovc_num)
|
.sel (assigned_ovc_num)
|
);
|
);
|
|
|
wire [V-1 : 0] nearlyfull_sel = (ovc_is_assigned | ~OVC_ALLOC_MODE)? assigned_ovc_num : granted_ovc_num ;// or (granted_ovc_num | ssa_granted_ovc_num) ?
|
wire [V-1 : 0] nearlyfull_sel = (ovc_is_assigned | ~OVC_ALLOC_MODE)? assigned_ovc_num : granted_ovc_num ;// or (granted_ovc_num | ssa_granted_ovc_num) ?
|
|
|
onehot_mux_1D #(
|
onehot_mux_1D #(
|
.W (1),
|
.W (1),
|
.N (V)
|
.N (V)
|
)nearlfull_mux2
|
)nearlfull_mux2
|
(
|
(
|
.in (nearly_full_muxout1),
|
.in (nearly_full_muxout1),
|
.out (nearly_full_muxout2),
|
.out (nearly_full_muxout2),
|
.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;
|
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)) 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));
|
pronoc_register #(.W(1)) reg2 (.in(full_reg2_next ), .out(full_reg2), .reset(reset), .clk(clk));
|
|
|
|
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
//synthesis translate_off
|
//synthesis translate_off
|
//synopsys translate_off
|
//synopsys translate_off
|
module check_ovc #(
|
module check_ovc #(
|
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 SELF_LOOP_EN="NO"
|
parameter SELF_LOOP_EN="NO"
|
|
|
)(
|
)(
|
ovc_status,
|
ovc_status,
|
assigned_ovc_num_all,
|
assigned_ovc_num_all,
|
ovc_is_assigned_all,
|
ovc_is_assigned_all,
|
dest_port_all,
|
dest_port_all,
|
clk,
|
clk,
|
reset
|
reset
|
);
|
);
|
|
|
localparam PV = V * P,
|
localparam PV = V * P,
|
PVV = PV * V,
|
PVV = PV * V,
|
P_1 = ( SELF_LOOP_EN=="NO")? P-1 : P,
|
P_1 = ( SELF_LOOP_EN=="NO")? P-1 : P,
|
PVP_1 = PV * P_1;
|
PVP_1 = PV * P_1;
|
|
|
|
|
input [PV-1 : 0] ovc_status;
|
input [PV-1 : 0] ovc_status;
|
input [PVV-1 : 0] assigned_ovc_num_all;
|
input [PVV-1 : 0] assigned_ovc_num_all;
|
input [PV-1 : 0] ovc_is_assigned_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 clk,reset;
|
input clk,reset;
|
|
|
wire [V-1 : 0] assigned_ovc_num [PV-1 : 0];
|
wire [V-1 : 0] assigned_ovc_num [PV-1 : 0];
|
wire [P_1-1 : 0] destport_sel [PV-1 : 0];
|
wire [P_1-1 : 0] destport_sel [PV-1 : 0];
|
wire [P-1 : 0] destport_num [PV-1 : 0];
|
wire [P-1 : 0] destport_num [PV-1 : 0];
|
|
|
wire [PV-1 : 0] ovc_num [PV-1 : 0];
|
wire [PV-1 : 0] ovc_num [PV-1 : 0];
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for(i=0; i
|
for(i=0; i
|
assign assigned_ovc_num [i]= (ovc_is_assigned_all[i])? assigned_ovc_num_all[(i+1)*V-1 : i*V]: 0;
|
assign assigned_ovc_num [i]= (ovc_is_assigned_all[i])? assigned_ovc_num_all[(i+1)*V-1 : i*V]: 0;
|
assign destport_sel [i]= dest_port_all[(i+1)*P_1-1 : i*P_1];
|
assign destport_sel [i]= dest_port_all[(i+1)*P_1-1 : i*P_1];
|
|
|
if(SELF_LOOP_EN=="NO") begin : nslp
|
if(SELF_LOOP_EN=="NO") begin : nslp
|
add_sw_loc_one_hot #(
|
add_sw_loc_one_hot #(
|
.P(P),
|
.P(P),
|
.SW_LOC(i/V)
|
.SW_LOC(i/V)
|
)
|
)
|
add_sw_loc
|
add_sw_loc
|
(
|
(
|
.destport_in(destport_sel[i]),
|
.destport_in(destport_sel[i]),
|
.destport_out(destport_num[i])
|
.destport_out(destport_num[i])
|
);
|
);
|
end else begin :slp
|
end else begin :slp
|
assign destport_num[i] = destport_sel[i];
|
assign destport_num[i] = destport_sel[i];
|
end
|
end
|
|
|
|
|
|
|
|
|
one_hot_demux #(
|
one_hot_demux #(
|
.IN_WIDTH (V),
|
.IN_WIDTH (V),
|
.SEL_WIDTH (P)
|
.SEL_WIDTH (P)
|
|
|
) demux
|
) demux
|
(
|
(
|
.demux_sel (destport_num[i]),//selectore
|
.demux_sel (destport_num[i]),//selectore
|
.demux_in (assigned_ovc_num[i]),//repeated
|
.demux_in (assigned_ovc_num[i]),//repeated
|
.demux_out (ovc_num[i])
|
.demux_out (ovc_num[i])
|
);
|
);
|
always @(posedge clk)begin
|
always @(posedge clk)begin
|
if(ovc_status >0 && ovc_num[i] >0 && (ovc_num[i] & ovc_status)==0) $display ("%t :Error: OVC status%d missmatch:%b & %b, %m ",$time,i,ovc_num[i] , ovc_status);
|
if(ovc_status >0 && ovc_num[i] >0 && (ovc_num[i] & ovc_status)==0) $display ("%t :Error: OVC status%d missmatch:%b & %b, %m ",$time,i,ovc_num[i] , ovc_status);
|
end
|
end
|
|
|
|
|
end//for
|
end//for
|
endgenerate
|
endgenerate
|
|
|
|
|
|
|
|
|
endmodule
|
endmodule
|
//synopsys translate_on
|
//synopsys translate_on
|
//synthesis translate_on
|
//synthesis translate_on
|
|
|
|
|