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

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

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [rtl/] [src_noc/] [router_bypass.sv] - Diff between revs 48 and 54

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 48 Rev 54
`timescale 1ns / 1ps
`include "pronoc_def.v"
 
 
/**************************************
/**************************************
* Module: router_bypass
* Module: router_bypass
* Date:2020-11-24
* Date:2020-11-24
* Author: alireza
* Author: alireza
*
*
* Description:
* Description:
*   This file contains HDL modules that can be added
*   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
***************************************/
***************************************/
/**************************
/**************************
 * SMART_flags_gen:
 * SMART_flags_gen:
 * generate SMART flags based on NoC parameter, current router's port and address,
 * generate SMART flags based on NoC parameter, current router's port and address,
 * and destination router address
 * and destination router address
 * located in router output port (port number:SPB_OPORT_NUM)
 * located in router output port (port number:SPB_OPORT_NUM)
 * smart_flag_o indicates how many more router in direct line can be bypassed
 * smart_flag_o indicates how many more router in direct line can be bypassed
 * if SPB_OPORT_NUM  is also one of the possible output port in
 * if SPB_OPORT_NUM  is also one of the possible output port in
 * lk-ahead routing, The packet can by-pass the next router once the bypassing condition are met
 * lk-ahead routing, The packet can by-pass the next router once the bypassing condition are met
 ***************************/
 ***************************/
 
 
module register #(parameter W=1)(
`include "pronoc_def.v"
                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
 
 
 
module reduction_or #(
module reduction_or #(
        parameter W = 5,//out width
        parameter W = 5,//out width
        parameter N = 4 //array lenght
        parameter N = 4 //array lenght
)(
)(
        in,
        in,
        out
        out
);
);
    input  [W-1 : 0] in [N-1 : 0];
    input  [W-1 : 0] in [N-1 : 0];
    output reg [W-1 : 0] out;
    output reg [W-1 : 0] out;
    // assign out = in.or(); //it is not synthesizable able by some compiler
    // assign out = in.or(); //it is not synthesizable able by some compiler
        always_comb begin
        always_comb begin
                out = {W{1'b0}};
                out = {W{1'b0}};
                for (int i = 0; i < N; i++)
                for (int i = 0; i < N; i++)
                        out |=   in[i];
                        out |=   in[i];
        end
        end
endmodule
endmodule
module onehot_mux_2D #(
module onehot_mux_2D #(
                parameter W = 5,//out width
                parameter W = 5,//out width
                parameter N = 4 //sel width
                parameter N = 4 //sel width
                )(
                )(
                in,
                in,
                sel,
                sel,
                out
                out
                );
                );
        input  [W-1 : 0] in [N-1 : 0];
        input  [W-1 : 0] in [N-1 : 0];
        input  [N-1 : 0] sel;
        input  [N-1 : 0] sel;
        output reg [W-1 : 0] out;
        output reg [W-1 : 0] out;
        always_comb begin
        always_comb begin
                out = {W{1'b0}};
                out = {W{1'b0}};
                for (int i = 0; i < N; i++)
                for (int i = 0; i < N; i++)
                        out |= (sel[i]) ?  in[i] :  {W{1'b0}};
                        out |= (sel[i]) ?  in[i] :  {W{1'b0}};
        end
        end
endmodule
endmodule
module onehot_mux_1D #(
module onehot_mux_1D #(
                parameter W = 5,//out width
                parameter W = 5,//out width
                parameter N = 4 //sel width
                parameter N = 4 //sel width
        )(
        )(
                input  [W*N-1 : 0] in,
                input  [W*N-1 : 0] in,
                input  [N-1 : 0] sel,
                input  [N-1 : 0] sel,
                output [W-1 : 0] out
                output [W-1 : 0] out
        );
        );
wire  [W-1 : 0] in_array [N-1 : 0];
wire  [W-1 : 0] in_array [N-1 : 0];
genvar i;
genvar i;
generate
generate
for (i=0;i
for (i=0;i
        assign in_array[i] = in[(i+1)*W-1 : i*W];
        assign in_array[i] = in[(i+1)*W-1 : i*W];
end
end
endgenerate
endgenerate
        onehot_mux_2D #(
        onehot_mux_2D #(
                .W    (W   ),
                .W    (W   ),
                .N    (N   )
                .N    (N   )
                ) onehot_mux_2D (
                ) onehot_mux_2D (
                .in   (in_array  ),
                .in   (in_array  ),
                .sel  (sel ),
                .sel  (sel ),
                .out  (out ));
                .out  (out ));
endmodule
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
 
                        assign in_array[i] = in[(i+1)*N-1 : i*N];
 
                        for (j=0;j
 
                                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
module header_flit_info
        import pronoc_pkg::*;
        import pronoc_pkg::*;
#(
#(
        parameter DATA_w = 0
        parameter DATA_w = 0
)(
)(
        flit,
        flit,
        hdr_flit,
        hdr_flit,
        data_o
        data_o
);
);
        localparam
        localparam
        Dw = (DATA_w==0)? 1 : DATA_w;
        Dw = (DATA_w==0)? 1 : DATA_w;
        input flit_t flit;
        input flit_t flit;
        output hdr_flit_t hdr_flit;
        output hdr_flit_t hdr_flit;
        output [Dw-1 : 0] data_o;
        output [Dw-1 : 0] data_o;
        localparam
        localparam
                DATA_LSB= MSB_BE+1,               DATA_MSB= (DATA_LSB + DATA_w)
                DATA_LSB= MSB_BE+1,               DATA_MSB= (DATA_LSB + DATA_w)
                OFFSETw = DATA_MSB - DATA_LSB +1;
                OFFSETw = DATA_MSB - DATA_LSB +1;
        wire [OFFSETw-1 : 0 ] offset;
        wire [OFFSETw-1 : 0 ] offset;
        assign hdr_flit.src_e_addr  = flit.payload [E_SRC_MSB : E_SRC_LSB];
        assign hdr_flit.src_e_addr  = flit.payload [E_SRC_MSB : E_SRC_LSB];
        assign hdr_flit.dest_e_addr = flit.payload [E_DST_MSB : E_DST_LSB];
        assign hdr_flit.dest_e_addr = flit.payload [E_DST_MSB : E_DST_LSB];
        assign hdr_flit.destport    = flit.payload [DST_P_MSB : DST_P_LSB];
        assign hdr_flit.destport    = flit.payload [DST_P_MSB : DST_P_LSB];
        generate
        generate
                if(C>1)begin : have_class
                if(C>1)begin : have_class
                        assign hdr_flit.message_class = flit.payload [CLASS_MSB : CLASS_LSB];
                        assign hdr_flit.message_class = flit.payload [CLASS_MSB : CLASS_LSB];
                end else begin : no_class
                end else begin : no_class
                        assign hdr_flit.message_class = {Cw{1'b0}};
                        assign hdr_flit.message_class = {Cw{1'b0}};
                end
                end
                /* verilator lint_off WIDTH */
                /* verilator lint_off WIDTH */
                if(SWA_ARBITER_TYPE != "RRA")begin  : wrra_b
                if(SWA_ARBITER_TYPE != "RRA")begin  : wrra_b
                /* verilator lint_on WIDTH */
                /* verilator lint_on WIDTH */
                        assign hdr_flit.weight =  flit.payload [WEIGHT_MSB : WEIGHT_LSB];
                        assign hdr_flit.weight =  flit.payload [WEIGHT_MSB : WEIGHT_LSB];
                end else begin : rra_b
                end else begin : rra_b
                        assign hdr_flit.weight = {WEIGHTw{1'bX}};
                        assign hdr_flit.weight = {WEIGHTw{1'bX}};
                end
                end
                if( BYTE_EN ) begin : be_1
                if( BYTE_EN ) begin : be_1
                        assign hdr_flit.be = flit.payload [BE_MSB : BE_LSB];
                        assign hdr_flit.be = flit.payload [BE_MSB : BE_LSB];
                end else begin : be_0
                end else begin : be_0
                        assign hdr_flit.be = {BEw{1'bX}};
                        assign hdr_flit.be = {BEw{1'bX}};
                end
                end
                assign offset = flit.payload [DATA_MSB : DATA_LSB];
                assign offset = flit.payload [DATA_MSB : DATA_LSB];
                if(Dw > OFFSETw) begin : if1
                if(Dw > OFFSETw) begin : if1
                        assign data_o={{(Dw-OFFSETw){1'b0}},offset};
                        assign data_o={{(Dw-OFFSETw){1'b0}},offset};
                end else begin : if2
                end else begin : if2
                        assign data_o=offset[Dw-1 : 0];
                        assign data_o=offset[Dw-1 : 0];
                end
                end
        endgenerate
        endgenerate
endmodule
endmodule
//synthesis translate_off
//synthesis translate_off
//synopsys  translate_off
//synopsys  translate_off
module smart_chanel_check
module smart_chanel_check
                import pronoc_pkg::*;
                import pronoc_pkg::*;
        (
        (
                flit_chanel,
                flit_chanel,
                smart_chanel,
                smart_chanel,
                reset,
                reset,
                clk
                clk
        );
        );
        input flit_chanel_t  flit_chanel;
        input flit_chanel_t  flit_chanel;
        input smart_chanel_t   smart_chanel;
        input smart_chanel_t   smart_chanel;
        input reset,clk;
        input reset,clk;
        smart_chanel_t   smart_chanel_delay;
        smart_chanel_t   smart_chanel_delay;
        always @(posedge clk) smart_chanel_delay<=smart_chanel;
        always @(posedge clk) smart_chanel_delay<=smart_chanel;
        hdr_flit_t hdr_flit;
        hdr_flit_t hdr_flit;
        header_flit_info extract(
        header_flit_info extract(
                        .flit(flit_chanel.flit),
                        .flit(flit_chanel.flit),
                        .hdr_flit(hdr_flit),
                        .hdr_flit(hdr_flit),
                        .data_o()
                        .data_o()
                );
                );
        always @(posedge clk) begin
        always @(posedge clk) begin
                if(flit_chanel.flit_wr) begin
                if(flit_chanel.flit_wr) begin
                        if(smart_chanel_delay.ovc!=flit_chanel.flit.vc) begin
                        if(smart_chanel_delay.ovc!=flit_chanel.flit.vc) begin
                                $display("%t: ERROR: smart ovc %d is not equal with flit ovc %d. %m",$time,smart_chanel_delay.ovc,flit_chanel.flit.vc );
                                $display("%t: ERROR: smart ovc %d is not equal with flit ovc %d. %m",$time,smart_chanel_delay.ovc,flit_chanel.flit.vc );
                                $finish;
                                $finish;
                        end
                        end
                        if(flit_chanel.flit.hdr_flag==1'b1 &&   hdr_flit.dest_e_addr != smart_chanel_delay.dest_e_addr) begin
                        if(flit_chanel.flit.hdr_flag==1'b1 &&   hdr_flit.dest_e_addr != smart_chanel_delay.dest_e_addr) begin
                                $display("%t: ERROR: smart dest_e_addr %d is not equal with flit dest_e_addr %d. %m",$time,smart_chanel_delay.dest_e_addr,hdr_flit.dest_e_addr );
                                $display("%t: ERROR: smart dest_e_addr %d is not equal with flit dest_e_addr %d. %m",$time,smart_chanel_delay.dest_e_addr,hdr_flit.dest_e_addr );
                                $finish;
                                $finish;
                        end
                        end
                        if(flit_chanel.flit.hdr_flag!=smart_chanel_delay.hdr_flit) begin
                        if(flit_chanel.flit.hdr_flag!=smart_chanel_delay.hdr_flit) begin
                                $display("%t: ERROR: smart and current hdr flag (%d!=%d) miss-match. %m",$time, smart_chanel_delay.hdr_flit, flit_chanel.flit.hdr_flag);
                                $display("%t: ERROR: smart and current hdr flag (%d!=%d) miss-match. %m",$time, smart_chanel_delay.hdr_flit, flit_chanel.flit.hdr_flag);
                                $finish;
                                $finish;
                        end
                        end
                end
                end
        end
        end
endmodule
endmodule
//synopsys  translate_on
//synopsys  translate_on
//synthesis translate_on
//synthesis translate_on
module smart_forward_ivc_info
module smart_forward_ivc_info
        import pronoc_pkg::*;
        import pronoc_pkg::*;
        #(
        #(
        parameter P=5
        parameter P=5
)(
)(
                ivc_info,
                ivc_info,
                iport_info,
                iport_info,
                oport_info,
                oport_info,
                smart_chanel,
                smart_chanel,
                ovc_locally_requested,
                ovc_locally_requested,
                reset,clk
                reset,clk
);
);
        //ivc info
        //ivc info
        input reset,clk;
        input reset,clk;
        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  iport_info_t iport_info  [P-1 : 0];
        input  iport_info_t iport_info  [P-1 : 0];
        input  oport_info_t oport_info  [P-1 : 0];
        input  oport_info_t oport_info  [P-1 : 0];
        output smart_chanel_t smart_chanel  [P-1 : 0];
        output smart_chanel_t smart_chanel  [P-1 : 0];
        output [V-1 : 0] ovc_locally_requested [P-1 : 0];
        output [V-1 : 0] ovc_locally_requested [P-1 : 0];
        smart_ivc_info_t  smart_ivc_info [P-1 : 0][V-1 : 0];
        smart_ivc_info_t  smart_ivc_info [P-1 : 0][V-1 : 0];
        smart_ivc_info_t  smart_ivc_mux  [P-1 : 0];
        smart_ivc_info_t  smart_ivc_mux  [P-1 : 0];
        smart_ivc_info_t  smart_ivc_info_all_port [P-1 : 0] [P-1 : 0];
        smart_ivc_info_t  smart_ivc_info_all_port [P-1 : 0] [P-1 : 0];
        smart_ivc_info_t  smart_vc_info_o [P-1 : 0];
        smart_ivc_info_t  smart_vc_info_o [P-1 : 0];
        wire [V-1 : 0] assigned_ovc [P-1:0];
        wire [V-1 : 0] assigned_ovc [P-1:0];
        wire [V-1 : 0] non_assigned_vc_req [P-1:0];
        wire [V-1 : 0] non_assigned_vc_req [P-1:0];
        wire [P-1 : 0] mask_gen  [P-1 : 0][V-1 :0];
        wire [P-1 : 0] mask_gen  [P-1 : 0][V-1 :0];
        wire [V-1 : 0] ovc_locally_requested_next [P-1 : 0];
        wire [V-1 : 0] ovc_locally_requested_next [P-1 : 0];
        /*
        /*
                                                P  V                   P                P  V   p
                                                P  V                   P                P  V   p
        non_assigned_vc_req[i][j] destport_one_hot[z]-->   [z][ j][i]
        non_assigned_vc_req[i][j] destport_one_hot[z]-->   [z][ j][i]
        non_assigned_vc_req[0][0] destport_one_hot[3]--> | [3][0] [0]
        non_assigned_vc_req[0][0] destport_one_hot[3]--> | [3][0] [0]
        non_assigned_vc_req[1][0] destport_one_hot[3]--> | [3][0] [1]
        non_assigned_vc_req[1][0] destport_one_hot[3]--> | [3][0] [1]
        non_assigned_vc_req[2][0] destport_one_hot[3]--> | [3][0] [2]
        non_assigned_vc_req[2][0] destport_one_hot[3]--> | [3][0] [2]
        */
        */
        smart_chanel_t smart_chanel_next  [P-1 : 0];
        smart_chanel_t smart_chanel_next  [P-1 : 0];
        genvar i,j,z;
        genvar i,j,z;
        generate
        generate
        for (i=0;i
        for (i=0;i
                for (j=0; j < V; j=j+1) begin : ivc
                for (j=0; j < V; j=j+1) begin : ivc
                        assign smart_ivc_info[i][j].dest_e_addr = ivc_info[i][j].dest_e_addr;
                        assign smart_ivc_info[i][j].dest_e_addr = ivc_info[i][j].dest_e_addr;
                        assign smart_ivc_info[i][j].ovc_is_assigned= ivc_info[i][j].ovc_is_assigned;
                        assign smart_ivc_info[i][j].ovc_is_assigned= ivc_info[i][j].ovc_is_assigned;
                        assign smart_ivc_info[i][j].assigned_ovc_bin=ivc_info[i][j].assigned_ovc_bin;
                        assign smart_ivc_info[i][j].assigned_ovc_bin=ivc_info[i][j].assigned_ovc_bin;
                        assign non_assigned_vc_req[i][j] = ~ivc_info[i][j].ovc_is_assigned & ivc_info[i][j].ivc_req;
                        assign non_assigned_vc_req[i][j] = ~ivc_info[i][j].ovc_is_assigned & ivc_info[i][j].ivc_req;
                        for (z=0; z < P; z=z+1) begin : port
                        for (z=0; z < P; z=z+1) begin : port
                                assign mask_gen[z][j][i] = non_assigned_vc_req[i][j] & ivc_info[i][j].destport_one_hot[z];
                                assign mask_gen[z][j][i] = non_assigned_vc_req[i][j] & ivc_info[i][j].destport_one_hot[z];
                        end
                        end
                        assign ovc_locally_requested_next[i][j]=|mask_gen[i][j];
                        assign ovc_locally_requested_next[i][j]=|mask_gen[i][j];
                end//V
                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]));
 
 
                onehot_mux_2D   #(.W(SMART_IVC_w),.N(V)) mux1 ( .in(smart_ivc_info[i]), .sel(iport_info[i].swa_first_level_grant), .out(smart_ivc_mux[i]));
                onehot_mux_2D   #(.W(SMART_IVC_w),.N(V)) mux1 ( .in(smart_ivc_info[i]), .sel(iport_info[i].swa_first_level_grant), .out(smart_ivc_mux[i]));
                //demux
                //demux
                for (j=0;j
                for (j=0;j
                        assign smart_ivc_info_all_port[j][i] = (iport_info[i].granted_oport_one_hot[j]==1'b1)? smart_ivc_mux[i] : {SMART_IVC_w{1'b0}};
                        assign smart_ivc_info_all_port[j][i] = (iport_info[i].granted_oport_one_hot[j]==1'b1)? smart_ivc_mux[i] : {SMART_IVC_w{1'b0}};
                end
                end
                //assign smart_vc_info_o[i] = smart_ivc_info_all_port[i].or; not synthesizable
                //assign smart_vc_info_o[i] = smart_ivc_info_all_port[i].or; not synthesizable
                // assign smart_vc_info_o[i] = smart_ivc_info_all_port[i].[0] | smart_ivc_info_all_port[i].[1] | smart_ivc_info_all_port[i].[2]  ... | smart_ivc_info_all_port[i].[p-1];
                // assign smart_vc_info_o[i] = smart_ivc_info_all_port[i].[0] | smart_ivc_info_all_port[i].[1] | smart_ivc_info_all_port[i].[2]  ... | smart_ivc_info_all_port[i].[p-1];
                reduction_or #(
                reduction_or #(
                        .W    (SMART_IVC_w   ),
                        .W    (SMART_IVC_w   ),
                        .N    (P   )
                        .N    (P   )
                ) _or (
                ) _or (
                        .in   (smart_ivc_info_all_port[i]  ),
                        .in   (smart_ivc_info_all_port[i]  ),
                        .out  (smart_vc_info_o[i] )
                        .out  (smart_vc_info_o[i] )
                );
                );
                /*
                /*
                always_comb begin
                always_comb begin
                        smart_vc_info_o[i] = {SMART_IVC_w{1'b0}};
                        smart_vc_info_o[i] = {SMART_IVC_w{1'b0}};
                        for (int ii = 0; ii < P; ii++)
                        for (int ii = 0; ii < P; ii++)
                                smart_vc_info_o[i] |= smart_ivc_info_all_port[i][ii];
                                smart_vc_info_o[i] |= smart_ivc_info_all_port[i][ii];
                end
                end
                */
                */
                bin_to_one_hot #(
                bin_to_one_hot #(
                        .BIN_WIDTH      (Vw),
                        .BIN_WIDTH      (Vw),
                        .ONE_HOT_WIDTH  (V )
                        .ONE_HOT_WIDTH  (V )
                ) conv (
                ) conv (
                        .bin_code       (smart_vc_info_o[i].assigned_ovc_bin ),
                        .bin_code       (smart_vc_info_o[i].assigned_ovc_bin ),
                        .one_hot_code   (assigned_ovc[i]  )
                        .one_hot_code   (assigned_ovc[i]  )
                );
                );
                assign smart_chanel_next[i].dest_e_addr= smart_vc_info_o[i].dest_e_addr;
                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].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].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
                if( ADD_PIPREG_AFTER_CROSSBAR == 1 ) begin :link_reg
                        register #(
                        pronoc_register #(
                                .W      ( SMART_CHANEL_w     )
                                .W      ( SMART_CHANEL_w     )
                                ) register (
                                ) register (
                                .in     (smart_chanel_next[i]   ),
                                .in     (smart_chanel_next[i]   ),
                                .reset  (reset ),
                                .reset  (reset ),
                                .clk    (clk   ),
                                .clk    (clk   ),
                                .out    (smart_chanel[i]   ));
                                .out    (smart_chanel[i]   ));
                end else begin :no_link_reg
                end else begin :no_link_reg
                                assign smart_chanel[i] = smart_chanel_next[i];
                                assign smart_chanel[i] = smart_chanel_next[i];
                end
                end
                /*
                /*
 
 
                `ifdef SYNC_RESET_MODE
                        always @ (`pronoc_clk_reset_edge )begin
                        always @ (posedge clk )begin
                                if(`pronoc_reset) begin
                `else
 
                        always @ (posedge clk or posedge reset)begin
 
                `endif
 
                                if(reset) begin
 
                                        smart_chanel[i].dest_e_addr<= {EAw{1'b0}};
                                        smart_chanel[i].dest_e_addr<= {EAw{1'b0}};
                                        smart_chanel[i].ovc<= {V{1'b0}};
                                        smart_chanel[i].ovc<= {V{1'b0}};
                                        smart_chanel[i].hdr_flit<=1'b0;
                                        smart_chanel[i].hdr_flit<=1'b0;
                                end else begin
                                end else begin
                                        smart_chanel[i].dest_e_addr<= smart_vc_info_o[i].dest_e_addr;
                                        smart_chanel[i].dest_e_addr<= smart_vc_info_o[i].dest_e_addr;
                                        smart_chanel[i].ovc<= (smart_vc_info_o[i].ovc_is_assigned)? assigned_ovc[i] : oport_info[i].non_smart_ovc_is_allocated;
                                        smart_chanel[i].ovc<= (smart_vc_info_o[i].ovc_is_assigned)? assigned_ovc[i] : oport_info[i].non_smart_ovc_is_allocated;
                                        smart_chanel[i].hdr_flit<=~smart_vc_info_o[i].ovc_is_assigned;
                                        smart_chanel[i].hdr_flit<=~smart_vc_info_o[i].ovc_is_assigned;
                                        smart_chanel[i].requests <= (oport_info[i].any_ovc_granted)? {SMART_NUM{1'b1}}:{SMART_NUM{1'b0}} ;
                                        smart_chanel[i].requests <= (oport_info[i].any_ovc_granted)? {SMART_NUM{1'b1}}:{SMART_NUM{1'b0}} ;
                                end
                                end
                        end
                        end
                */
                */
                end//port_
                end//port_
                endgenerate
                endgenerate
//      generate for (i=0; i < P; i=i+1) begin : port
//      generate for (i=0; i < P; i=i+1) begin : port
//                      assign smart_ivc_info_o[i] = (granted_dest_port[i]==1'b1)? ivc_info_mux : {SMART_IVC_w{1'b0}};
//                      assign smart_ivc_info_o[i] = (granted_dest_port[i]==1'b1)? ivc_info_mux : {SMART_IVC_w{1'b0}};
//              end endgenerate
//              end endgenerate
endmodule
endmodule
module smart_bypass_chanels
module smart_bypass_chanels
        import pronoc_pkg::*;
        import pronoc_pkg::*;
#(
#(
        parameter P=5
        parameter P=5
)(
)(
        ivc_info,
        ivc_info,
        iport_info,
        iport_info,
        oport_info,
        oport_info,
        smart_chanel_new,
        smart_chanel_new,
        smart_chanel_in,
        smart_chanel_in,
        smart_chanel_out,
        smart_chanel_out,
        smart_req,
        smart_req,
        reset,
        reset,
        clk
        clk
);
);
        input reset,clk;
        input reset,clk;
        input smart_chanel_t smart_chanel_new  [P-1 : 0];
        input smart_chanel_t smart_chanel_new  [P-1 : 0];
        input smart_chanel_t smart_chanel_in   [P-1 : 0];
        input smart_chanel_t smart_chanel_in   [P-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 iport_info_t iport_info  [P-1 : 0];
        input iport_info_t iport_info  [P-1 : 0];
        input oport_info_t oport_info  [P-1 : 0];
        input oport_info_t oport_info  [P-1 : 0];
        output [P-1 : 0] smart_req;
        output [P-1 : 0] smart_req;
        output smart_chanel_t smart_chanel_out   [P-1 : 0];
        output smart_chanel_t smart_chanel_out   [P-1 : 0];
        smart_chanel_t smart_chanel_shifted  [P-1 : 0];
        smart_chanel_t smart_chanel_shifted  [P-1 : 0];
        localparam DISABLE = P;
        localparam DISABLE = P;
        wire [V-1 : 0 ] ivc_forwardable [P-1 : 0];
        wire [V-1 : 0 ] ivc_forwardable [P-1 : 0];
        wire [P-1 :0] smart_forwardable;
        wire [P-1 :0] smart_forwardable;
        logic [P-1 :0] outport_is_granted;
        logic [P-1 :0] outport_is_granted;
        reg [P-1 : 0] rq;
        reg [P-1 : 0] rq;
        genvar i;
        genvar i;
        generate
        generate
        for (i=0;i
        for (i=0;i
                /* verilator lint_off WIDTH */
                /* verilator lint_off WIDTH */
                assign ivc_forwardable[i] =  (PCK_TYPE == "SINGLE_FLIT")?  1'b1 :~iport_info[i].ivc_req;
                assign ivc_forwardable[i] =  (PCK_TYPE == "SINGLE_FLIT")?  1'b1 :~iport_info[i].ivc_req;
                /* verilator lint_on WIDTH */
                /* verilator lint_on WIDTH */
                if( ADD_PIPREG_AFTER_CROSSBAR == 1 ) begin :link_reg
                if( ADD_PIPREG_AFTER_CROSSBAR == 1 ) begin :link_reg
                always @( posedge clk)begin
                always @( posedge clk)begin
                    outport_is_granted[i] <= oport_info[i].any_ovc_granted;
                    outport_is_granted[i] <= oport_info[i].any_ovc_granted;
                end
                end
                end else begin
                end else begin
                        assign outport_is_granted[i] = oport_info[i].any_ovc_granted;
                        assign outport_is_granted[i] = oport_info[i].any_ovc_granted;
                end
                end
                localparam SS_PORT = strieght_port (P,i); // the straight port number
                localparam SS_PORT = strieght_port (P,i); // the straight port number
                if(SS_PORT != DISABLE) begin: ssp
                if(SS_PORT != DISABLE) begin: ssp
                        //smart_chanel_shifter
                        //smart_chanel_shifter
                        assign smart_forwardable[i] = |  (ivc_forwardable[i] & smart_chanel_in[i].ovc);
                        assign smart_forwardable[i] = |  (ivc_forwardable[i] & smart_chanel_in[i].ovc);
                        always @(*) begin
                        always @(*) begin
                                smart_chanel_shifted[i] = smart_chanel_in [i];
                                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].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
                        end
                        assign smart_req[i]=rq[i];
                        assign smart_req[i]=rq[i];
                        // mux out smart chanel
                        // mux out smart chanel
                        assign smart_chanel_out[i] = (outport_is_granted[i])? smart_chanel_new[i] : smart_chanel_shifted[SS_PORT];
                        assign smart_chanel_out[i] = (outport_is_granted[i])? smart_chanel_new[i] : smart_chanel_shifted[SS_PORT];
                end else begin
                end else begin
                        assign {smart_chanel_shifted[i].requests,smart_req[i]} = {(SMART_NUM+1){1'b0}};
                        assign {smart_chanel_shifted[i].requests,smart_req[i]} = {(SMART_NUM+1){1'b0}};
                        assign smart_chanel_out[i] = {SMART_CHANEL_w{1'b0}};
                        assign smart_chanel_out[i] = {SMART_CHANEL_w{1'b0}};
                end
                end
        end
        end
        endgenerate
        endgenerate
endmodule
endmodule
module check_straight_oport #(
module check_straight_oport #(
                parameter TOPOLOGY          =   "MESH",
                parameter TOPOLOGY          =   "MESH",
                parameter ROUTE_NAME        =   "XY",
                parameter ROUTE_NAME        =   "XY",
                parameter ROUTE_TYPE        =   "DETERMINISTIC",
                parameter ROUTE_TYPE        =   "DETERMINISTIC",
                parameter DSTPw             =   4,
                parameter DSTPw             =   4,
                parameter SS_PORT_LOC     =   1
                parameter SS_PORT_LOC     =   1
                )(
                )(
                destport_coded_i,
                destport_coded_i,
                goes_straight_o
                goes_straight_o
                );
                );
        input   [DSTPw-1 : 0] destport_coded_i;
        input   [DSTPw-1 : 0] destport_coded_i;
        output  goes_straight_o;
        output  goes_straight_o;
        generate
        generate
        /* verilator lint_off WIDTH */
        /* verilator lint_off WIDTH */
                if(TOPOLOGY == "MESH" || TOPOLOGY == "TORUS"  ) begin :twoD
                if(TOPOLOGY == "MESH" || TOPOLOGY == "TORUS" || TOPOLOGY =="FMESH" ) begin :twoD
                        /* verilator lint_on WIDTH */
                        /* verilator lint_on WIDTH */
                        if (SS_PORT_LOC == 0 || SS_PORT_LOC > 4) begin : local_ports
                        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
                                assign goes_straight_o = 1'b0; // There is not a next router in this case at all
                        end
                        end
                        else begin :non_local
                        else begin :non_local
                                wire [4 : 0 ] destport_one_hot;
                                wire [4 : 0 ] destport_one_hot;
                                mesh_tori_decode_dstport decoder(
                                mesh_tori_decode_dstport decoder(
                                                .dstport_encoded(destport_coded_i),
                                                .dstport_encoded(destport_coded_i),
                                                .dstport_one_hot(destport_one_hot)
                                                .dstport_one_hot(destport_one_hot)
                                        );
                                        );
                                assign goes_straight_o = destport_one_hot [SS_PORT_LOC];
                                assign goes_straight_o = destport_one_hot [SS_PORT_LOC];
                        end//else
                        end//else
                end//mesh_tori
                end//mesh_tori
                /* verilator lint_off WIDTH */
                /* verilator lint_off WIDTH */
                else if(TOPOLOGY ==  "RING" || TOPOLOGY ==  "LINE"  ) begin :oneD
                else if(TOPOLOGY ==  "RING" || TOPOLOGY ==  "LINE"  ) begin :oneD
                        /* verilator lint_on WIDTH */
                        /* verilator lint_on WIDTH */
                        if (SS_PORT_LOC == 0 || SS_PORT_LOC > 2) begin : local_ports
                        if (SS_PORT_LOC == 0 || SS_PORT_LOC > 2) begin : local_ports
                                assign goes_straight_o = 1'b0; // There is not a next router in this case at all
                                assign goes_straight_o = 1'b0; // There is not a next router in this case at all
                        end
                        end
                        else begin :non_local
                        else begin :non_local
                                wire [2: 0 ] destport_one_hot;
                                wire [2: 0 ] destport_one_hot;
                                line_ring_decode_dstport decoder(
                                line_ring_decode_dstport decoder(
                                                .dstport_encoded(destport_coded_i),
                                                .dstport_encoded(destport_coded_i),
                                                .dstport_one_hot(destport_one_hot)
                                                .dstport_one_hot(destport_one_hot)
                                        );
                                        );
                                assign goes_straight_o = destport_one_hot [SS_PORT_LOC];
                                assign goes_straight_o = destport_one_hot [SS_PORT_LOC];
                        end     //non_local
                        end     //non_local
                end// oneD
                end// oneD
                //TODO Add fattree & custom
                //TODO Add fattree & custom
        endgenerate
        endgenerate
endmodule
endmodule
module smart_validity_check_per_ivc
module smart_validity_check_per_ivc
        import pronoc_pkg::*;
        import pronoc_pkg::*;
#(
#(
        parameter IVC_NUM = 0
        parameter IVC_NUM = 0
)(
)(
        reset                  ,
        reset                  ,
        clk                    ,
        clk                    ,
        //smart channel
        //smart channel
        goes_straight              ,
        goes_straight              ,
        smart_requests_i         ,
        smart_requests_i         ,
        smart_ivc_i              ,
        smart_ivc_i              ,
        smart_hdr_flit             ,
        smart_hdr_flit             ,
        //flit
        //flit
        flit_hdr_flag_i        ,
        flit_hdr_flag_i        ,
        flit_tail_flag_i       ,
        flit_tail_flag_i       ,
        flit_wr_i              ,
        flit_wr_i              ,
        //router ivc status
        //router ivc status
        ovc_locally_requested     ,
        ovc_locally_requested     ,
        assigned_to_ss_ovc          ,
        assigned_to_ss_ovc          ,
        assigned_ovc_not_full       ,
        assigned_ovc_not_full       ,
        ovc_is_assigned             ,
        ovc_is_assigned             ,
        ivc_request                 ,
        ivc_request                 ,
        //ss port status
        //ss port status
        ss_ovc_avalable_in_ss_port  ,
        ss_ovc_avalable_in_ss_port  ,
        ss_port_link_reg_flit_wr    ,
        ss_port_link_reg_flit_wr    ,
        ss_ovc_crossbar_wr          ,
        ss_ovc_crossbar_wr          ,
        //output
        //output
        smart_single_flit_pck_o         ,
        smart_single_flit_pck_o         ,
        smart_ivc_smart_en_o            ,
        smart_ivc_smart_en_o            ,
        smart_credit_o                  ,
        smart_credit_o                  ,
        smart_buff_space_decreased_o  ,
        smart_buff_space_decreased_o  ,
        smart_ss_ovc_is_allocated_o   ,
        smart_ss_ovc_is_allocated_o   ,
        smart_ss_ovc_is_released_o    ,
        smart_ss_ovc_is_released_o    ,
        smart_mask_available_ss_ovc_o ,
        smart_mask_available_ss_ovc_o ,
        smart_ivc_num_getting_ovc_grant_o,
        smart_ivc_num_getting_ovc_grant_o,
        smart_ivc_reset_o,
        smart_ivc_reset_o,
        smart_ivc_granted_ovc_num_o
        smart_ivc_granted_ovc_num_o
);
);
input reset, clk;
input reset, clk;
//smart channel
//smart channel
input goes_straight                ,
input goes_straight                ,
        smart_requests_i         ,
        smart_requests_i         ,
        smart_ivc_i              ,
        smart_ivc_i              ,
        smart_hdr_flit             ,
        smart_hdr_flit             ,
        //flit
        //flit
        flit_hdr_flag_i        ,
        flit_hdr_flag_i        ,
        flit_tail_flag_i       ,
        flit_tail_flag_i       ,
        flit_wr_i              ,
        flit_wr_i              ,
        //router ivc status
        //router ivc status
        ovc_locally_requested       ,
        ovc_locally_requested       ,
        assigned_to_ss_ovc          ,
        assigned_to_ss_ovc          ,
        assigned_ovc_not_full       ,
        assigned_ovc_not_full       ,
        ovc_is_assigned             ,
        ovc_is_assigned             ,
        ivc_request                 ,
        ivc_request                 ,
        //ss port status
        //ss port status
        ss_ovc_avalable_in_ss_port  ,
        ss_ovc_avalable_in_ss_port  ,
        ss_ovc_crossbar_wr,
        ss_ovc_crossbar_wr,
        ss_port_link_reg_flit_wr    ;
        ss_port_link_reg_flit_wr    ;
//output
//output
output
output
        smart_single_flit_pck_o                 ,
        smart_single_flit_pck_o                 ,
        smart_ivc_smart_en_o         ,
        smart_ivc_smart_en_o         ,
        smart_credit_o                  ,
        smart_credit_o                  ,
        smart_buff_space_decreased_o  ,
        smart_buff_space_decreased_o  ,
        smart_ss_ovc_is_allocated_o   ,
        smart_ss_ovc_is_allocated_o   ,
        smart_ss_ovc_is_released_o    ,
        smart_ss_ovc_is_released_o    ,
        smart_ivc_num_getting_ovc_grant_o,
        smart_ivc_num_getting_ovc_grant_o,
        smart_ivc_reset_o,
        smart_ivc_reset_o,
        smart_mask_available_ss_ovc_o;
        smart_mask_available_ss_ovc_o;
output reg [V-1 : 0] smart_ivc_granted_ovc_num_o;
output reg [V-1 : 0] smart_ivc_granted_ovc_num_o;
always @(*) begin
always @(*) begin
        smart_ivc_granted_ovc_num_o={V{1'b0}};
        smart_ivc_granted_ovc_num_o={V{1'b0}};
        smart_ivc_granted_ovc_num_o[IVC_NUM]=smart_ivc_num_getting_ovc_grant_o;
        smart_ivc_granted_ovc_num_o[IVC_NUM]=smart_ivc_num_getting_ovc_grant_o;
end
end
wire  smart_req_valid_next  = smart_requests_i &  smart_ivc_i & goes_straight;
wire  smart_req_valid_next  = smart_requests_i &  smart_ivc_i & goes_straight;
logic smart_req_valid;
logic smart_req_valid;
wire  smart_hdr_flit_req_next = smart_req_valid_next  & smart_hdr_flit;
wire  smart_hdr_flit_req_next = smart_req_valid_next  & smart_hdr_flit;
logic smart_hdr_flit_req;
logic smart_hdr_flit_req;
 
 
register #(.W(1)) req1 (.in(smart_req_valid_next), .reset(reset), .clk(clk), .out(smart_req_valid));
pronoc_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)) req2 (.in(smart_hdr_flit_req_next), .reset(reset), .clk(clk), .out(smart_hdr_flit_req));
 
 
// condition1: new smart vc allocation condition
// condition1: new smart vc allocation condition
wire hdr_flit_condition    = ~ovc_locally_requested & ss_ovc_avalable_in_ss_port;
wire hdr_flit_condition    = ~ovc_locally_requested & ss_ovc_avalable_in_ss_port;
wire nonhdr_flit_condition = assigned_to_ss_ovc & assigned_ovc_not_full;
wire nonhdr_flit_condition = assigned_to_ss_ovc & assigned_ovc_not_full;
wire condition1 =
wire condition1 =
        /* verilator lint_off WIDTH */
        /* verilator lint_off WIDTH */
        (PCK_TYPE == "SINGLE_FLIT")?  hdr_flit_condition :
        (PCK_TYPE == "SINGLE_FLIT")?  hdr_flit_condition :
        /* verilator lint_on WIDTH */
        /* verilator lint_on WIDTH */
        (ovc_is_assigned)? nonhdr_flit_condition : hdr_flit_condition;
        (ovc_is_assigned)? nonhdr_flit_condition : hdr_flit_condition;
wire condition2;
wire condition2;
generate
generate
/* verilator lint_off WIDTH */
/* verilator lint_off WIDTH */
wire non_empty_ivc_condition =(PCK_TYPE == "SINGLE_FLIT")?  1'b0 :ivc_request;
wire non_empty_ivc_condition =(PCK_TYPE == "SINGLE_FLIT")?  1'b0 :ivc_request;
/* verilator lint_on WIDTH */
/* verilator lint_on WIDTH */
if( ADD_PIPREG_AFTER_CROSSBAR == 1 ) begin :link_reg
if( ADD_PIPREG_AFTER_CROSSBAR == 1 ) begin :link_reg
        assign condition2= ~(non_empty_ivc_condition | ss_port_link_reg_flit_wr| ss_ovc_crossbar_wr);
        assign condition2= ~(non_empty_ivc_condition | ss_port_link_reg_flit_wr| ss_ovc_crossbar_wr);
end else begin : no_link_reg
end else begin : no_link_reg
        assign condition2= ~(non_empty_ivc_condition | ss_port_link_reg_flit_wr); // ss_port_link_reg_flit_wr are identical with ss_ovc_crossbar_wr when there is no link reg
        assign condition2= ~(non_empty_ivc_condition | ss_port_link_reg_flit_wr); // ss_port_link_reg_flit_wr are identical with ss_ovc_crossbar_wr when there is no link reg
end
end
endgenerate
endgenerate
wire conditions_met = condition1 & condition2;
wire conditions_met = condition1 & condition2;
assign smart_ivc_smart_en_o = conditions_met & smart_req_valid;
assign smart_ivc_smart_en_o = conditions_met & smart_req_valid;
assign smart_single_flit_pck_o     =
assign smart_single_flit_pck_o     =
        /* verilator lint_off WIDTH */
        /* verilator lint_off WIDTH */
        (PCK_TYPE == "SINGLE_FLIT")? 1'b1 :
        (PCK_TYPE == "SINGLE_FLIT")? 1'b1 :
        /* verilator lint_on WIDTH */
        /* verilator lint_on WIDTH */
        (MIN_PCK_SIZE==1)?  flit_tail_flag_i & flit_hdr_flag_i : 1'b0;
        (MIN_PCK_SIZE==1)?  flit_tail_flag_i & flit_hdr_flag_i : 1'b0;
assign smart_buff_space_decreased_o =  smart_ivc_smart_en_o & flit_wr_i ;
assign smart_buff_space_decreased_o =  smart_ivc_smart_en_o & flit_wr_i ;
assign smart_ivc_num_getting_ovc_grant_o  =  smart_buff_space_decreased_o & !ovc_is_assigned  & flit_hdr_flag_i;
assign smart_ivc_num_getting_ovc_grant_o  =  smart_buff_space_decreased_o & !ovc_is_assigned  & flit_hdr_flag_i;
assign smart_ivc_reset_o   =  smart_buff_space_decreased_o & flit_tail_flag_i;
assign smart_ivc_reset_o   =  smart_buff_space_decreased_o & flit_tail_flag_i;
assign smart_ss_ovc_is_released_o = smart_ivc_reset_o & ~smart_single_flit_pck_o;
assign smart_ss_ovc_is_released_o = smart_ivc_reset_o & ~smart_single_flit_pck_o;
assign smart_ss_ovc_is_allocated_o = smart_ivc_num_getting_ovc_grant_o & ~smart_single_flit_pck_o;
assign smart_ss_ovc_is_allocated_o = smart_ivc_num_getting_ovc_grant_o & ~smart_single_flit_pck_o;
//mask the available SS OVC for local requests allocation if the following conditions met
//mask the available SS OVC for local requests allocation if the following conditions met
assign smart_mask_available_ss_ovc_o = smart_hdr_flit_req & ~ovc_locally_requested & condition2;
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
endmodule
module smart_allocator_per_iport
module smart_allocator_per_iport
        import pronoc_pkg::*;
        import pronoc_pkg::*;
#(
#(
        parameter P=5,
        parameter P=5,
        parameter SW_LOC=0,
        parameter SW_LOC=0,
        parameter SS_PORT_LOC=1
        parameter SS_PORT_LOC=1
        )(
        )(
        //general
        //general
        clk,
        clk,
        reset,
        reset,
        current_r_addr_i,
        current_r_addr_i,
        neighbors_r_addr_i,
        neighbors_r_addr_i,
        //smart_chanel & flit in
        //smart_chanel & flit in
        smart_chanel_i,
        smart_chanel_i,
        flit_chanel_i,
        flit_chanel_i,
        //router status signals
        //router status signals
        ivc_info,
        ivc_info,
        ss_ovc_info,
        ss_ovc_info,
        ovc_locally_requested,//make sure no conflict is existed between local & SMART VC allocation
        ovc_locally_requested,//make sure no conflict is existed between local & SMART VC allocation
        ss_port_link_reg_flit_wr,
        ss_port_link_reg_flit_wr,
        ss_smart_chanel_new,
        ss_smart_chanel_new,
        //output
        //output
        smart_destport_o,
        smart_destport_o,
        smart_lk_destport_o,
        smart_lk_destport_o,
        smart_ivc_smart_en_o,
        smart_ivc_smart_en_o,
        smart_credit_o,
        smart_credit_o,
        smart_buff_space_decreased_o,
        smart_buff_space_decreased_o,
        smart_ss_ovc_is_allocated_o,
        smart_ss_ovc_is_allocated_o,
        smart_ss_ovc_is_released_o,
        smart_ss_ovc_is_released_o,
        smart_ivc_num_getting_ovc_grant_o,
        smart_ivc_num_getting_ovc_grant_o,
        smart_ivc_reset_o,
        smart_ivc_reset_o,
        smart_mask_available_ss_ovc_o,
        smart_mask_available_ss_ovc_o,
        smart_hdr_flit_req_o,
        smart_hdr_flit_req_o,
        smart_ivc_granted_ovc_num_o,
        smart_ivc_granted_ovc_num_o,
        smart_ivc_single_flit_pck_o,
        smart_ivc_single_flit_pck_o,
        smart_ovc_single_flit_pck_o
        smart_ovc_single_flit_pck_o
);
);
        //general
        //general
        input clk, reset;
        input clk, reset;
        input [RAw-1   :0]  current_r_addr_i;
        input [RAw-1   :0]  current_r_addr_i;
        input [RAw-1:  0]  neighbors_r_addr_i [P-1 : 0];
        input [RAw-1:  0]  neighbors_r_addr_i [P-1 : 0];
        //channels
        //channels
        input smart_chanel_t smart_chanel_i;
        input smart_chanel_t smart_chanel_i;
        input flit_chanel_t flit_chanel_i;
        input flit_chanel_t flit_chanel_i;
        //ivc
        //ivc
        input ivc_info_t ivc_info [V-1 : 0];
        input ivc_info_t ivc_info [V-1 : 0];
        input [V-1 : 0] ovc_locally_requested;
        input [V-1 : 0] ovc_locally_requested;
        //ss port
        //ss port
        input ovc_info_t   ss_ovc_info [V-1 : 0];
        input ovc_info_t   ss_ovc_info [V-1 : 0];
        input ss_port_link_reg_flit_wr;
        input ss_port_link_reg_flit_wr;
        input smart_chanel_t ss_smart_chanel_new;
        input smart_chanel_t ss_smart_chanel_new;
        //output
        //output
        output [DSTPw-1 : 0] smart_destport_o,smart_lk_destport_o;
        output [DSTPw-1 : 0] smart_destport_o,smart_lk_destport_o;
        output smart_hdr_flit_req_o;
        output smart_hdr_flit_req_o;
        output [V-1 : 0]
        output [V-1 : 0]
                smart_ivc_smart_en_o,
                smart_ivc_smart_en_o,
                smart_credit_o,
                smart_credit_o,
                smart_buff_space_decreased_o,
                smart_buff_space_decreased_o,
                smart_ss_ovc_is_allocated_o,
                smart_ss_ovc_is_allocated_o,
                smart_ss_ovc_is_released_o,
                smart_ss_ovc_is_released_o,
                smart_mask_available_ss_ovc_o,
                smart_mask_available_ss_ovc_o,
                smart_ivc_num_getting_ovc_grant_o,
                smart_ivc_num_getting_ovc_grant_o,
                smart_ivc_reset_o,
                smart_ivc_reset_o,
                smart_ivc_single_flit_pck_o,
                smart_ivc_single_flit_pck_o,
                smart_ovc_single_flit_pck_o;
                smart_ovc_single_flit_pck_o;
        output [V*V-1 : 0] smart_ivc_granted_ovc_num_o;
        output [V*V-1 : 0] smart_ivc_granted_ovc_num_o;
        assign smart_ovc_single_flit_pck_o = smart_ivc_single_flit_pck_o;
        assign smart_ovc_single_flit_pck_o = smart_ivc_single_flit_pck_o;
        wire  [DSTPw-1  :   0]  destport,lkdestport;
        wire  [DSTPw-1  :   0]  destport,lkdestport;
        wire  goes_straight;
        wire  goes_straight;
        /* verilator lint_off WIDTH */
        /* verilator lint_off WIDTH */
        localparam  LOCATED_IN_NI=
        localparam  LOCATED_IN_NI=
                (TOPOLOGY=="RING" || TOPOLOGY=="LINE") ? (SW_LOC == 0 || SW_LOC>2) :
                (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 */
        /* verilator lint_on WIDTH */
        // does the route computation for the current router
        // does the route computation for the current router
        conventional_routing #(
        conventional_routing #(
                .TOPOLOGY        (TOPOLOGY       ),
                .TOPOLOGY        (TOPOLOGY       ),
                .ROUTE_NAME      (ROUTE_NAME     ),
                .ROUTE_NAME      (ROUTE_NAME     ),
                .ROUTE_TYPE      (ROUTE_TYPE     ),
                .ROUTE_TYPE      (ROUTE_TYPE     ),
                .T1              (T1             ),
                .T1              (T1             ),
                .T2              (T2             ),
                .T2              (T2             ),
                .T3              (T3             ),
                .T3              (T3             ),
                .RAw             (RAw            ),
                .RAw             (RAw            ),
                .EAw             (EAw            ),
                .EAw             (EAw            ),
                .DSTPw           (DSTPw          ),
                .DSTPw           (DSTPw          ),
                .LOCATED_IN_NI   (LOCATED_IN_NI  )
                .LOCATED_IN_NI   (LOCATED_IN_NI  )
        ) routing (
        ) routing (
                .reset           (reset          ),
                .reset           (reset          ),
                .clk             (clk            ),
                .clk             (clk            ),
                .current_r_addr  (current_r_addr_i ),
                .current_r_addr  (current_r_addr_i ),
                .src_e_addr      (                           ),// needed only for custom routing
                .src_e_addr      (                           ),// needed only for custom routing
                .dest_e_addr     (smart_chanel_i.dest_e_addr    ),
                .dest_e_addr     (smart_chanel_i.dest_e_addr    ),
                .destport        (destport)
                .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 #(
        check_straight_oport #(
                .TOPOLOGY      ( TOPOLOGY     ),
                .TOPOLOGY      ( TOPOLOGY     ),
                .ROUTE_NAME    ( ROUTE_NAME   ),
                .ROUTE_NAME    ( ROUTE_NAME   ),
                .ROUTE_TYPE    ( ROUTE_TYPE   ),
                .ROUTE_TYPE    ( ROUTE_TYPE   ),
                .DSTPw         ( DSTPw        ),
                .DSTPw         ( DSTPw        ),
                .SS_PORT_LOC   ( SS_PORT_LOC)
                .SS_PORT_LOC   ( SS_PORT_LOC)
        ) check_straight (
        ) check_straight (
                .destport_coded_i (destport),
                .destport_coded_i (destport),
                .goes_straight_o  (goes_straight)
                .goes_straight_o  (goes_straight)
        );
        );
        //look ahead routing. take straight next router address as input
        //look ahead routing. take straight next router address as input
        conventional_routing #(
        conventional_routing #(
                        .TOPOLOGY        (TOPOLOGY       ),
                        .TOPOLOGY        (TOPOLOGY       ),
                        .ROUTE_NAME      (ROUTE_NAME     ),
                        .ROUTE_NAME      (ROUTE_NAME     ),
                        .ROUTE_TYPE      (ROUTE_TYPE     ),
                        .ROUTE_TYPE      (ROUTE_TYPE     ),
                        .T1              (T1             ),
                        .T1              (T1             ),
                        .T2              (T2             ),
                        .T2              (T2             ),
                        .T3              (T3             ),
                        .T3              (T3             ),
                        .RAw             (RAw            ),
                        .RAw             (RAw            ),
                        .EAw             (EAw            ),
                        .EAw             (EAw            ),
                        .DSTPw           (DSTPw          ),
                        .DSTPw           (DSTPw          ),
                        .LOCATED_IN_NI   (LOCATED_IN_NI  )
                        .LOCATED_IN_NI   (LOCATED_IN_NI  )
                ) lkrouting (
                ) lkrouting (
                        .reset           (reset          ),
                        .reset           (reset          ),
                        .clk             (clk            ),
                        .clk             (clk            ),
                        .current_r_addr  (neighbors_r_addr_i[SS_PORT_LOC] ),
                        .current_r_addr  (neighbors_r_addr_i[SS_PORT_LOC] ),
                        .src_e_addr      (                           ),// needed only for custom routing
                        .src_e_addr      (                           ),// needed only for custom routing
                        .dest_e_addr     (smart_chanel_i.dest_e_addr    ),
                        .dest_e_addr     (smart_chanel_i.dest_e_addr    ),
                        .destport        (lkdestport)
                        .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
        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}};
        assign ss_ovc_crossbar_wr = (ss_smart_chanel_new.requests[0] ) ? ss_smart_chanel_new.ovc : {V{1'b0}};
        //assign smart_ivc_num_getting_ovc_grant_o = smart_ss_ovc_is_allocated_o;
        //assign smart_ivc_num_getting_ovc_grant_o = smart_ss_ovc_is_allocated_o;
        //assign smart_ivc_reset_o = smart_ss_ovc_is_released_o;
        //assign smart_ivc_reset_o = smart_ss_ovc_is_released_o;
        genvar i,j;
        genvar i,j;
        generate
        generate
        for (i=0;i
        for (i=0;i
                smart_validity_check_per_ivc #(
                smart_validity_check_per_ivc #(
                                .IVC_NUM(i)
                                .IVC_NUM(i)
                )       validity_check (
                )       validity_check (
                        .reset                       (reset                             ),
                        .reset                       (reset                             ),
                        .clk                         (clk                               ),
                        .clk                         (clk                               ),
                        .goes_straight                           (goes_straight),
                        .goes_straight                           (goes_straight),
                        .smart_requests_i              (smart_chanel_i.requests[0]              ),
                        .smart_requests_i              (smart_chanel_i.requests[0]              ),
                        .smart_ivc_i                   (smart_chanel_i.ovc  [i]                 ),
                        .smart_ivc_i                   (smart_chanel_i.ovc  [i]                 ),
                        .smart_hdr_flit                          (smart_chanel_i.hdr_flit     ),
                        .smart_hdr_flit                          (smart_chanel_i.hdr_flit     ),
                        .flit_hdr_flag_i                (flit_chanel_i.flit.hdr_flag            ),
                        .flit_hdr_flag_i                (flit_chanel_i.flit.hdr_flag            ),
                        .flit_tail_flag_i               (flit_chanel_i.flit.tail_flag       ),
                        .flit_tail_flag_i               (flit_chanel_i.flit.tail_flag       ),
                        .flit_wr_i                      (flit_chanel_i.flit_wr         ),
                        .flit_wr_i                      (flit_chanel_i.flit_wr         ),
                        .ovc_locally_requested      (ovc_locally_requested[i]   ),
                        .ovc_locally_requested      (ovc_locally_requested[i]   ),
                        .assigned_to_ss_ovc          (ivc_info[i].assigned_ovc_num[i]),
                        .assigned_to_ss_ovc          (ivc_info[i].assigned_ovc_num[i]),
                        .assigned_ovc_not_full       (~ss_ovc_info[i].full),
                        .assigned_ovc_not_full       (~ss_ovc_info[i].full),
                        .ovc_is_assigned             (ivc_info[i].ovc_is_assigned),
                        .ovc_is_assigned             (ivc_info[i].ovc_is_assigned),
                        .ivc_request                 (ivc_info[i].ivc_req       ),
                        .ivc_request                 (ivc_info[i].ivc_req       ),
                        .ss_ovc_avalable_in_ss_port  (ss_ovc_info[i].avalable),
                        .ss_ovc_avalable_in_ss_port  (ss_ovc_info[i].avalable),
                        .ss_port_link_reg_flit_wr    (ss_port_link_reg_flit_wr     ),
                        .ss_port_link_reg_flit_wr    (ss_port_link_reg_flit_wr     ),
                        .ss_ovc_crossbar_wr          (ss_ovc_crossbar_wr[i]),
                        .ss_ovc_crossbar_wr          (ss_ovc_crossbar_wr[i]),
                        .smart_single_flit_pck_o       (smart_ivc_single_flit_pck_o[i]  ),
                        .smart_single_flit_pck_o       (smart_ivc_single_flit_pck_o[i]  ),
                        .smart_ivc_smart_en_o                    (smart_ivc_smart_en_o[i]       ),
                        .smart_ivc_smart_en_o                    (smart_ivc_smart_en_o[i]       ),
                        .smart_credit_o                  (smart_credit_o[i]     ),
                        .smart_credit_o                  (smart_credit_o[i]     ),
                        .smart_buff_space_decreased_o  (smart_buff_space_decreased_o[i]),
                        .smart_buff_space_decreased_o  (smart_buff_space_decreased_o[i]),
                        .smart_ss_ovc_is_allocated_o   (smart_ss_ovc_is_allocated_o[i] ),
                        .smart_ss_ovc_is_allocated_o   (smart_ss_ovc_is_allocated_o[i] ),
                        .smart_ss_ovc_is_released_o    (smart_ss_ovc_is_released_o[i]  ),
                        .smart_ss_ovc_is_released_o    (smart_ss_ovc_is_released_o[i]  ),
                        .smart_mask_available_ss_ovc_o (smart_mask_available_ss_ovc_o[i] ),
                        .smart_mask_available_ss_ovc_o (smart_mask_available_ss_ovc_o[i] ),
                        .smart_ivc_num_getting_ovc_grant_o(smart_ivc_num_getting_ovc_grant_o[i]),
                        .smart_ivc_num_getting_ovc_grant_o(smart_ivc_num_getting_ovc_grant_o[i]),
                        .smart_ivc_reset_o                       (smart_ivc_reset_o[i]),
                        .smart_ivc_reset_o                       (smart_ivc_reset_o[i]),
                        .smart_ivc_granted_ovc_num_o   (smart_ivc_granted_ovc_num_o[(i+1)*V-1 : i*V])
                        .smart_ivc_granted_ovc_num_o   (smart_ivc_granted_ovc_num_o[(i+1)*V-1 : i*V])
                );
                );
        end//for
        end//for
        endgenerate
        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
endmodule
//
//
module smart_credit_manage #(
module smart_credit_manage #(
        parameter V=4,
        parameter V=4,
        parameter B=2
        parameter B=2
        )(
        )(
                credit_in,
                credit_in,
                smart_credit_in,
                smart_credit_in,
                credit_out,
                credit_out,
                reset,
                reset,
                clk
                clk
        );
        );
        localparam Bw=$clog2(B);
        localparam Bw=$clog2(B);
        input [V-1 : 0]  credit_in, smart_credit_in;
        input [V-1 : 0]  credit_in, smart_credit_in;
        input reset,    clk;
        input reset,    clk;
        output [V-1 : 0]  credit_out;
        output [V-1 : 0]  credit_out;
        genvar i;
        genvar i;
        generate
        generate
        for (i=0;i
        for (i=0;i
                smart_credit_manage_per_vc #(
                smart_credit_manage_per_vc #(
                        .Bw(Bw)
                        .Bw(Bw)
                        )credit(
                        )credit(
                                .credit_in(credit_in[i]),
                                .credit_in(credit_in[i]),
                                .smart_credit_in(smart_credit_in[i]),
                                .smart_credit_in(smart_credit_in[i]),
                                .credit_out(credit_out[i]),
                                .credit_out(credit_out[i]),
                                .reset(reset),
                                .reset(reset),
                                .clk(clk)
                                .clk(clk)
                        );
                        );
        end
        end
        endgenerate
        endgenerate
endmodule
endmodule
module smart_credit_manage_per_vc #(
module smart_credit_manage_per_vc #(
                parameter Bw=2
                parameter Bw=2
)(
)(
        credit_in,
        credit_in,
        smart_credit_in,
        smart_credit_in,
        credit_out,
        credit_out,
        reset,
        reset,
        clk
        clk
);
);
        input credit_in, smart_credit_in,       reset,  clk;
        input credit_in, smart_credit_in,       reset,  clk;
        output credit_out;
        output credit_out;
        logic [Bw : 0] counter, counter_next;
        logic [Bw : 0] counter, counter_next;
        always @(*) begin
        always @(*) begin
                counter_next=counter;
                counter_next=counter;
                if(credit_in & 	smart_credit_in ) counter_next = counter +1'b1;
                if(credit_in & 	smart_credit_in ) counter_next = counter +1'b1;
                else if(credit_in |     smart_credit_in ) counter_next=counter;
                else if(credit_in |     smart_credit_in ) counter_next=counter;
                else if(counter > 0) counter_next = counter -1'b1;
                else if(counter > 0) counter_next = counter -1'b1;
        end
        end
        assign credit_out = credit_in |         smart_credit_in | (counter > 0);
        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
endmodule
 
 

powered by: WebSVN 2.1.0

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