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/] [mesh_torus.sv] - Diff between revs 54 and 56

Only display areas with differences | Details | Blame | View Log

Rev 54 Rev 56
`include "pronoc_def.v"
`include "pronoc_def.v"
/**********************************************************************
/**********************************************************************
**      File:  mesh_torus.v
**      File:  mesh_torus.v
**
**
**      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:
**
**
**
**
***************************************/
***************************************/
/*****************************************
/*****************************************
pre-sel[xy]
pre-sel[xy]
    y
    y
1   |   3
1   |   3
    |
    |
 -------x
 -------x
0   |   2
0   |   2
    |
    |
*****************************************/
*****************************************/
module  mesh_torus_vc_alloc_request_gen_adaptive #(
module  mesh_torus_vc_alloc_request_gen_adaptive #(
    parameter ROUTE_TYPE =  "FULL_ADAPTIVE",    // "FULL_ADAPTIVE", "PAR_ADAPTIVE"
    parameter ROUTE_TYPE =  "FULL_ADAPTIVE",    // "FULL_ADAPTIVE", "PAR_ADAPTIVE"
    parameter V = 4,
    parameter V = 4,
    parameter DSTPw=4,
    parameter DSTPw=4,
    parameter SSA_EN ="NO",
    parameter SSA_EN ="NO",
    parameter PPSw=4,
    parameter PPSw=4,
    parameter [V-1  :   0] ESCAP_VC_MASK = 4'b1000   // mask scape vc, valid only for full adaptive
    parameter [V-1  :   0] ESCAP_VC_MASK = 4'b1000   // mask scape vc, valid only for full adaptive
)(
)(
    ovc_avalable_all,
    ovc_avalable_all,
    dest_port_coded_all,
    dest_port_coded_all,
    candidate_ovc_all,
    candidate_ovc_all,
    ivc_request_all,
    ivc_request_all,
    ovc_is_assigned_all,
    ovc_is_assigned_all,
    masked_ovc_request_all,
    masked_ovc_request_all,
    port_pre_sel,
    port_pre_sel,
    swap_port_presel,
    swap_port_presel,
    destport_clear_all,
    destport_clear_all,
    ivc_num_getting_ovc_grant,
    ivc_num_getting_ovc_grant,
    ssa_ivc_num_getting_ovc_grant_all,
    ssa_ivc_num_getting_ovc_grant_all,
    sel,
    sel,
    reset,
    reset,
    clk
    clk
);
);
    localparam  P = 5;
    localparam  P = 5;
    localparam  P_1     =   P-1,
    localparam  P_1     =   P-1,
                PV      =   V       *   P,
                PV      =   V       *   P,
                PVV     =   PV      *  V,
                PVV     =   PV      *  V,
                VP_1    =   V       *   P_1,
                VP_1    =   V       *   P_1,
                PVDSTPw = PV * DSTPw;
                PVDSTPw = PV * DSTPw;
     localparam LOCAL   =   3'd0,
     localparam LOCAL   =   3'd0,
                EAST    =   3'd1,
                EAST    =   3'd1,
                NORTH   =   3'd2,
                NORTH   =   3'd2,
                WEST    =   3'd3,
                WEST    =   3'd3,
                SOUTH   =   3'd4;
                SOUTH   =   3'd4;
    input   [PV-1       :   0]  ovc_avalable_all;
    input   [PV-1       :   0]  ovc_avalable_all;
    input   [PVDSTPw-1  :   0]  dest_port_coded_all;
    input   [PVDSTPw-1  :   0]  dest_port_coded_all;
    input   [PV-1       :   0]  ivc_request_all;
    input   [PV-1       :   0]  ivc_request_all;
    input   [PV-1       :   0]  ovc_is_assigned_all;
    input   [PV-1       :   0]  ovc_is_assigned_all;
    output  [PVV-1      :   0]  masked_ovc_request_all;
    output  [PVV-1      :   0]  masked_ovc_request_all;
    input   [PVV-1      :   0]  candidate_ovc_all;
    input   [PVV-1      :   0]  candidate_ovc_all;
    input   [PPSw-1     :   0]  port_pre_sel;
    input   [PPSw-1     :   0]  port_pre_sel;
    output  [PV-1       :   0]  swap_port_presel;
    output  [PV-1       :   0]  swap_port_presel;
    output  [PV-1       :   0]  sel;
    output  [PV-1       :   0]  sel;
    output  [PVDSTPw-1 : 0] destport_clear_all;
    output  [PVDSTPw-1 : 0] destport_clear_all;
    input   [PV-1 : 0] ivc_num_getting_ovc_grant;
    input   [PV-1 : 0] ivc_num_getting_ovc_grant;
    input   [PV-1 : 0] ssa_ivc_num_getting_ovc_grant_all;
    input   [PV-1 : 0] ssa_ivc_num_getting_ovc_grant_all;
    input                       reset,clk;
    input                       reset,clk;
    wire    [PV-1       :   0]  non_assigned_ovc_request_all;
    wire    [PV-1       :   0]  non_assigned_ovc_request_all;
    wire    [PV-1       :   0]  y_evc_forbiden,x_evc_forbiden;
    wire    [PV-1       :   0]  y_evc_forbiden,x_evc_forbiden;
    wire    [V-1        :   0]  ovc_avb_x_plus,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_y_minus,ovc_avb_local;
    wire    [V-1        :   0]  ovc_avb_x_plus,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_y_minus,ovc_avb_local;
    wire    [VP_1-1     :   0]  ovc_avalable_perport            [P-1    :   0];
    wire    [VP_1-1     :   0]  ovc_avalable_perport            [P-1    :   0];
    wire    [PPSw-1     :   0]  port_pre_sel_perport            [P-1    :   0];
    wire    [PPSw-1     :   0]  port_pre_sel_perport            [P-1    :   0];
    wire    [PVV-1      :   0]  candidate_ovc_x_all, candidate_ovc_y_all;
    wire    [PVV-1      :   0]  candidate_ovc_x_all, candidate_ovc_y_all;
    assign non_assigned_ovc_request_all =   ivc_request_all & ~ovc_is_assigned_all;
    assign non_assigned_ovc_request_all =   ivc_request_all & ~ovc_is_assigned_all;
    assign {ovc_avb_y_minus,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_x_plus,ovc_avb_local} = ovc_avalable_all;
    assign {ovc_avb_y_minus,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_x_plus,ovc_avb_local} = ovc_avalable_all;
        assign ovc_avalable_perport[LOCAL]  = {ovc_avb_x_plus,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_y_minus};
        assign ovc_avalable_perport[LOCAL]  = {ovc_avb_x_plus,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_y_minus};
        assign ovc_avalable_perport[EAST]   = {ovc_avb_local,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_y_minus};
        assign ovc_avalable_perport[EAST]   = {ovc_avb_local,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_y_minus};
        assign ovc_avalable_perport[NORTH]  = {ovc_avb_x_plus,ovc_avb_x_minus,ovc_avb_local,ovc_avb_y_minus};
        assign ovc_avalable_perport[NORTH]  = {ovc_avb_x_plus,ovc_avb_x_minus,ovc_avb_local,ovc_avb_y_minus};
        assign ovc_avalable_perport[WEST]   = {ovc_avb_x_plus,ovc_avb_local,ovc_avb_y_plus,ovc_avb_y_minus};
        assign ovc_avalable_perport[WEST]   = {ovc_avb_x_plus,ovc_avb_local,ovc_avb_y_plus,ovc_avb_y_minus};
        assign ovc_avalable_perport[SOUTH]  = {ovc_avb_x_plus,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_local};
        assign ovc_avalable_perport[SOUTH]  = {ovc_avb_x_plus,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_local};
    assign port_pre_sel_perport[LOCAL]   = port_pre_sel;
    assign port_pre_sel_perport[LOCAL]   = port_pre_sel;
    assign port_pre_sel_perport[EAST]    = {2'b00,port_pre_sel[1:0]};
    assign port_pre_sel_perport[EAST]    = {2'b00,port_pre_sel[1:0]};
    assign port_pre_sel_perport[NORTH]   = {1'b0,port_pre_sel[2],1'b0,port_pre_sel[0]};
    assign port_pre_sel_perport[NORTH]   = {1'b0,port_pre_sel[2],1'b0,port_pre_sel[0]};
    assign port_pre_sel_perport[WEST]    = {port_pre_sel[3:2],2'b0};
    assign port_pre_sel_perport[WEST]    = {port_pre_sel[3:2],2'b0};
    assign port_pre_sel_perport[SOUTH]   = {port_pre_sel[3],1'b0,port_pre_sel[1],1'b0};
    assign port_pre_sel_perport[SOUTH]   = {port_pre_sel[3],1'b0,port_pre_sel[1],1'b0};
    wire    [PV-1   :   0]  avc_unavailable;
    wire    [PV-1   :   0]  avc_unavailable;
    genvar i;
    genvar i;
    generate
    generate
    for(i=0;i< PV;i=i+1) begin :all_vc_loop
    for(i=0;i< PV;i=i+1) begin :all_vc_loop
       mesh_torus_adaptive_avb_ovc_mux #(
       mesh_torus_adaptive_avb_ovc_mux #(
        .V(V)
        .V(V)
       )
       )
       the_adaptive_avb_ovc_mux
       the_adaptive_avb_ovc_mux
       (
       (
        .ovc_avalable               (ovc_avalable_perport   [i/V]),
        .ovc_avalable               (ovc_avalable_perport   [i/V]),
        .sel                        (sel                    [i]),
        .sel                        (sel                    [i]),
        .candidate_ovc_x            (candidate_ovc_x_all    [((i+1)*V)-1 : i*V]),
        .candidate_ovc_x            (candidate_ovc_x_all    [((i+1)*V)-1 : i*V]),
        .candidate_ovc_y            (candidate_ovc_y_all    [((i+1)*V)-1 : i*V]),
        .candidate_ovc_y            (candidate_ovc_y_all    [((i+1)*V)-1 : i*V]),
        .non_assigned_ovc_request   (non_assigned_ovc_request_all[i]),
        .non_assigned_ovc_request   (non_assigned_ovc_request_all[i]),
        .xydir                      (dest_port_coded_all     [((i+1)*DSTPw)-1 : ((i+1)*DSTPw)-2]),
        .xydir                      (dest_port_coded_all     [((i+1)*DSTPw)-1 : ((i+1)*DSTPw)-2]),
        .masked_ovc_request         (masked_ovc_request_all [((i+1)*V)-1 : i*V])
        .masked_ovc_request         (masked_ovc_request_all [((i+1)*V)-1 : i*V])
       );
       );
        mesh_torus_port_selector #(
        mesh_torus_port_selector #(
               .SW_LOC     (i/V),
               .SW_LOC     (i/V),
               .PPSw(PPSw)
               .PPSw(PPSw)
        )
        )
        the_portsel
        the_portsel
        (
        (
               .port_pre_sel       (port_pre_sel_perport[i/V]),
               .port_pre_sel       (port_pre_sel_perport[i/V]),
               .swap_port_presel   (swap_port_presel[i]),
               .swap_port_presel   (swap_port_presel[i]),
               .sel                (sel[i]),
               .sel                (sel[i]),
               .dest_port_in       (dest_port_coded_all[((i+1)*DSTPw)-1 : i*DSTPw]),
               .dest_port_in       (dest_port_coded_all[((i+1)*DSTPw)-1 : i*DSTPw]),
               .y_evc_forbiden     (y_evc_forbiden[i]),
               .y_evc_forbiden     (y_evc_forbiden[i]),
           .x_evc_forbiden     (x_evc_forbiden[i])
           .x_evc_forbiden     (x_evc_forbiden[i])
              );
              );
        mesh_tori_dspt_clear_gen #(
        mesh_tori_dspt_clear_gen #(
                .SSA_EN(SSA_EN),
                .SSA_EN(SSA_EN),
                .DSTPw(DSTPw),
                .DSTPw(DSTPw),
                .SW_LOC(i/V)
                .SW_LOC(i/V)
        )
        )
        dspt_clear_gen
        dspt_clear_gen
        (
        (
                .destport_clear(destport_clear_all[((i+1)*DSTPw)-1 : i*DSTPw]),
                .destport_clear(destport_clear_all[((i+1)*DSTPw)-1 : i*DSTPw]),
                .ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant[i]),
                .ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant[i]),
                .sel(sel[i]),
                .sel(sel[i]),
                .ssa_ivc_num_getting_ovc_grant(ssa_ivc_num_getting_ovc_grant_all[i])
                .ssa_ivc_num_getting_ovc_grant(ssa_ivc_num_getting_ovc_grant_all[i])
        );
        );
            /* 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 */
            assign candidate_ovc_y_all[((i+1)*V)-1 : i*V] =  (y_evc_forbiden[i]) ? candidate_ovc_all[((i+1)*V)-1 : i*V] & (~ESCAP_VC_MASK) :  candidate_ovc_all[((i+1)*V)-1 : i*V];
            assign candidate_ovc_y_all[((i+1)*V)-1 : i*V] =  (y_evc_forbiden[i]) ? candidate_ovc_all[((i+1)*V)-1 : i*V] & (~ESCAP_VC_MASK) :  candidate_ovc_all[((i+1)*V)-1 : i*V];
            assign candidate_ovc_x_all[((i+1)*V)-1 : i*V] =  (x_evc_forbiden[i]) ? candidate_ovc_all[((i+1)*V)-1 : i*V] & (~ESCAP_VC_MASK) :  candidate_ovc_all[((i+1)*V)-1 : i*V];
            assign candidate_ovc_x_all[((i+1)*V)-1 : i*V] =  (x_evc_forbiden[i]) ? candidate_ovc_all[((i+1)*V)-1 : i*V] & (~ESCAP_VC_MASK) :  candidate_ovc_all[((i+1)*V)-1 : i*V];
            assign avc_unavailable[i] = (masked_ovc_request_all [((i+1)*V)-1 : i*V] & ~ESCAP_VC_MASK) == {V{1'b0}};
            assign avc_unavailable[i] = (masked_ovc_request_all [((i+1)*V)-1 : i*V] & ~ESCAP_VC_MASK) == {V{1'b0}};
            mesh_torus_swap_port_presel_gen #(
            mesh_torus_swap_port_presel_gen #(
                .V(V),
                .V(V),
                .ESCAP_VC_MASK(ESCAP_VC_MASK),
                .ESCAP_VC_MASK(ESCAP_VC_MASK),
                .VC_NUM(i)
                .VC_NUM(i)
            )
            )
            the_swap_port_presel
            the_swap_port_presel
            (
            (
                .avc_unavailable(avc_unavailable[i]),
                .avc_unavailable(avc_unavailable[i]),
                .y_evc_forbiden(y_evc_forbiden[i]),
                .y_evc_forbiden(y_evc_forbiden[i]),
                .x_evc_forbiden(x_evc_forbiden[i]),
                .x_evc_forbiden(x_evc_forbiden[i]),
                .non_assigned_ovc_request(non_assigned_ovc_request_all[i]),
                .non_assigned_ovc_request(non_assigned_ovc_request_all[i]),
                .sel(sel[i]),
                .sel(sel[i]),
                .clk(clk),
                .clk(clk),
                .reset(reset),
                .reset(reset),
                .swap_port_presel(swap_port_presel[i])
                .swap_port_presel(swap_port_presel[i])
            );
            );
        end else begin : partial_adpt
        end else begin : partial_adpt
            assign candidate_ovc_y_all[((i+1)*V)-1 : i*V] =   candidate_ovc_all [((i+1)*V)-1 : i*V];
            assign candidate_ovc_y_all[((i+1)*V)-1 : i*V] =   candidate_ovc_all [((i+1)*V)-1 : i*V];
            assign candidate_ovc_x_all[((i+1)*V)-1 : i*V] =   candidate_ovc_all [((i+1)*V)-1 : i*V];
            assign candidate_ovc_x_all[((i+1)*V)-1 : i*V] =   candidate_ovc_all [((i+1)*V)-1 : i*V];
            assign swap_port_presel[i]=1'b0;
            assign swap_port_presel[i]=1'b0;
            assign avc_unavailable[i]=1'b0;
            assign avc_unavailable[i]=1'b0;
        end// ROUTE_TYPE
        end// ROUTE_TYPE
    end//for
    end//for
endgenerate
endgenerate
endmodule
endmodule
module mesh_tori_dspt_clear_gen #(
module mesh_tori_dspt_clear_gen #(
    parameter SSA_EN="YES",
    parameter SSA_EN="YES",
    parameter DSTPw =4,
    parameter DSTPw =4,
    parameter SW_LOC=0
    parameter SW_LOC=0
)(
)(
    destport_clear,
    destport_clear,
    ivc_num_getting_ovc_grant,
    ivc_num_getting_ovc_grant,
    sel,
    sel,
    ssa_ivc_num_getting_ovc_grant
    ssa_ivc_num_getting_ovc_grant
);
);
    output [DSTPw-1 : 0] destport_clear;
    output [DSTPw-1 : 0] destport_clear;
    input ivc_num_getting_ovc_grant;
    input ivc_num_getting_ovc_grant;
    input sel;
    input sel;
    input ssa_ivc_num_getting_ovc_grant;
    input ssa_ivc_num_getting_ovc_grant;
 localparam
 localparam
    LOCAL   =   3'd0,
    LOCAL   =   3'd0,
    EAST    =   3'd1,
    EAST    =   3'd1,
    WEST    =   3'd3;
    WEST    =   3'd3;
generate
generate
    /* verilator lint_off WIDTH */
    /* verilator lint_off WIDTH */
    if ( SSA_EN=="YES" ) begin :predict_if
    if ( SSA_EN=="YES" ) begin :predict_if
    /* verilator lint_on WIDTH */
    /* verilator lint_on WIDTH */
        if (SW_LOC == LOCAL ) begin :local_if
        if (SW_LOC == LOCAL ) begin :local_if
            assign destport_clear= (ivc_num_getting_ovc_grant)?{2'b00,sel,~sel} :{DSTPw{1'b0}};
            assign destport_clear= (ivc_num_getting_ovc_grant)?{2'b00,sel,~sel} :{DSTPw{1'b0}};
        end else if (SW_LOC == EAST || SW_LOC == WEST ) begin :xdir_if
        end else if (SW_LOC == EAST || SW_LOC == WEST ) begin :xdir_if
            assign destport_clear = (ivc_num_getting_ovc_grant)? {2'b00,sel,~sel} :
            assign destport_clear = (ivc_num_getting_ovc_grant)? {2'b00,sel,~sel} :
                                                                   (ssa_ivc_num_getting_ovc_grant)? 4'b0001: //clear b
                                                                   (ssa_ivc_num_getting_ovc_grant)? 4'b0001: //clear b
                                                                   4'b0000;
                                                                   4'b0000;
        end else begin : ydir_if
        end else begin : ydir_if
             assign destport_clear = (ivc_num_getting_ovc_grant)? {2'b00,sel,~sel} :
             assign destport_clear = (ivc_num_getting_ovc_grant)? {2'b00,sel,~sel} :
                                                                    (ssa_ivc_num_getting_ovc_grant)? 4'b0010: //clear a
                                                                    (ssa_ivc_num_getting_ovc_grant)? 4'b0010: //clear a
                                                                    4'b0000;
                                                                    4'b0000;
        end
        end
        end else begin :nopredict_if
        end else begin :nopredict_if
              assign destport_clear = (ivc_num_getting_ovc_grant )? {2'b00,sel,~sel} :{DSTPw{1'b0}};
              assign destport_clear = (ivc_num_getting_ovc_grant )? {2'b00,sel,~sel} :{DSTPw{1'b0}};
        end//   nopredict_if
        end//   nopredict_if
endgenerate
endgenerate
endmodule
endmodule
module   mesh_torus_mask_non_assignable_destport #(
module   mesh_torus_mask_non_assignable_destport #(
    parameter TOPOLOGY="MESH",
    parameter TOPOLOGY="MESH",
    parameter ROUTE_NAME="XY",
    parameter ROUTE_NAME="XY",
    parameter SW_LOC=0,
    parameter SW_LOC=0,
    parameter P=5,
    parameter P=5,
    parameter SELF_LOOP_EN="NO"
    parameter SELF_LOOP_EN="NO"
)
)
(
(
   odd_column,// use only for odd even routing
   odd_column,// use only for odd even routing
   dest_port_in,
   dest_port_in,
   dest_port_out
   dest_port_out
);
);
    localparam P_1 = (SELF_LOOP_EN=="NO") ? P-1 : P;
    localparam P_1 = (SELF_LOOP_EN=="NO") ? P-1 : P;
    input  [P_1-1 : 0 ] dest_port_in;
    input  [P_1-1 : 0 ] dest_port_in;
    output [P_1-1 : 0 ] dest_port_out;
    output [P_1-1 : 0 ] dest_port_out;
    input odd_column;
    input odd_column;
    wire  [P-2 : 0] dest_port_in_tmp,dest_port_out_tmp;
    wire  [P-2 : 0] dest_port_in_tmp,dest_port_out_tmp;
    generate
    generate
    if(SELF_LOOP_EN == "NO") begin :nslp
    if(SELF_LOOP_EN == "NO") begin :nslp
        assign dest_port_in_tmp = dest_port_in;
        assign dest_port_in_tmp = dest_port_in;
        assign dest_port_out = dest_port_out_tmp;
        assign dest_port_out = dest_port_out_tmp;
    end else begin :slp
    end else begin :slp
        remove_sw_loc_one_hot #(
        remove_sw_loc_one_hot #(
            .P(P),
            .P(P),
            .SW_LOC(SW_LOC)
            .SW_LOC(SW_LOC)
        )
        )
        remove_sw_loc
        remove_sw_loc
        (
        (
                .destport_in(dest_port_in),
                .destport_in(dest_port_in),
                .destport_out(dest_port_in_tmp)
                .destport_out(dest_port_in_tmp)
        );
        );
        //currently loop-back only can happen in local ports.
        //currently loop-back only can happen in local ports.
        //Current supported routing algorithms does not results in loop-back in other ports
        //Current supported routing algorithms does not results in loop-back in other ports
        wire sw_loc_val = (SW_LOC>0 && SW_LOC<5) ? 1'b0 : dest_port_in [SW_LOC];
        wire sw_loc_val = (SW_LOC>0 && SW_LOC<5) ? 1'b0 : dest_port_in [SW_LOC];
        add_sw_loc_one_hot_val #(
        add_sw_loc_one_hot_val #(
            .P(P),
            .P(P),
            .SW_LOC(SW_LOC)
            .SW_LOC(SW_LOC)
        )add_sw_loc
        )add_sw_loc
        (
        (
            .sw_loc_val(sw_loc_val),
            .sw_loc_val(sw_loc_val),
            .destport_in (dest_port_out_tmp),
            .destport_in (dest_port_out_tmp),
            .destport_out(dest_port_out)
            .destport_out(dest_port_out)
        );
        );
    end
    end
    endgenerate
    endgenerate
    mesh_torus_mask_non_assignable_destport_no_self_loop # (
    mesh_torus_mask_non_assignable_destport_no_self_loop # (
        .TOPOLOGY(TOPOLOGY),
        .TOPOLOGY(TOPOLOGY),
        .ROUTE_NAME(ROUTE_NAME),
        .ROUTE_NAME(ROUTE_NAME),
        .SW_LOC(SW_LOC),
        .SW_LOC(SW_LOC),
        .P(P)
        .P(P)
    )
    )
    mask_no_self_loop
    mask_no_self_loop
    (
    (
        .dest_port_in(dest_port_in_tmp),
        .dest_port_in(dest_port_in_tmp),
        .dest_port_out(dest_port_out_tmp),
        .dest_port_out(dest_port_out_tmp),
        .odd_column(odd_column)
        .odd_column(odd_column)
    );
    );
endmodule
endmodule
module   mesh_torus_mask_non_assignable_destport_no_self_loop #(
module   mesh_torus_mask_non_assignable_destport_no_self_loop #(
    parameter TOPOLOGY="MESH",
    parameter TOPOLOGY="MESH",
    parameter ROUTE_NAME="XY",
    parameter ROUTE_NAME="XY",
    parameter SW_LOC=0,
    parameter SW_LOC=0,
    parameter P=5
    parameter P=5
)
)
(
(
   odd_column,// use only for odd even routing
   odd_column,// use only for odd even routing
   dest_port_in,
   dest_port_in,
   dest_port_out
   dest_port_out
);
);
localparam
localparam
    EAST    =       1,
    EAST    =       1,
    NORTH   =       2,
    NORTH   =       2,
    WEST    =       3,
    WEST    =       3,
    SOUTH   =       4;
    SOUTH   =       4;
//port number in north port
//port number in north port
localparam
localparam
    N_LOCAL   =       0,
    N_LOCAL   =       0,
    N_EAST    =       1,
    N_EAST    =       1,
    N_WEST    =       2,
    N_WEST    =       2,
    N_SOUTH   =       3;
    N_SOUTH   =       3;
 // port number in south port
 // port number in south port
 localparam
 localparam
    S_LOCAL   =       0,
    S_LOCAL   =       0,
    S_EAST    =       1,
    S_EAST    =       1,
    S_NORTH   =       2,
    S_NORTH   =       2,
    S_WEST    =       3;
    S_WEST    =       3;
 // port number in east port
 // port number in east port
 localparam
 localparam
    E_LOCAL   =       0,
    E_LOCAL   =       0,
    E_NORTH   =       1,
    E_NORTH   =       1,
    E_WEST    =       2,
    E_WEST    =       2,
    E_SOUTH   =       3;
    E_SOUTH   =       3;
   // port number in east port
   // port number in east port
 localparam
 localparam
    W_LOCAL   =       0,
    W_LOCAL   =       0,
    W_EAST    =       1,
    W_EAST    =       1,
    W_NORTH   =       2,
    W_NORTH   =       2,
    W_SOUTH   =       3;
    W_SOUTH   =       3;
    localparam P_1 = P-1;
    localparam P_1 = P-1;
    input [P_1-1  : 0 ] dest_port_in;
    input [P_1-1  : 0 ] dest_port_in;
    output [P_1-1 : 0 ] dest_port_out;
    output [P_1-1 : 0 ] dest_port_out;
    input odd_column;
    input odd_column;
    generate
    generate
    if(P>5)begin :p5
    if(P>5)begin :p5
            assign dest_port_out[P_1-1:4] = dest_port_in[P_1-1:4]; //other local ports
            assign dest_port_out[P_1-1:4] = dest_port_in[P_1-1:4]; //other local ports
            end
            end
    /* verilator lint_off WIDTH */
    /* verilator lint_off WIDTH */
    if (TOPOLOGY == "RING" || TOPOLOGY == "LINE") begin : oneD // A port can send packets to all other ports in these topologies
    if (TOPOLOGY == "RING" || TOPOLOGY == "LINE") begin : oneD // A port can send packets to all other ports in these topologies
    /* verilator lint_on WIDTH */
    /* verilator lint_on WIDTH */
        assign  dest_port_out = dest_port_in;
        assign  dest_port_out = dest_port_in;
    end else begin : towD
    end else begin : towD
    /*XY*/
    /*XY*/
        /* verilator lint_off WIDTH */
        /* verilator lint_off WIDTH */
        if ( ROUTE_NAME == "XY" || ROUTE_NAME  == "TRANC_XY") begin :xy
        if ( ROUTE_NAME == "XY" || ROUTE_NAME  == "TRANC_XY") begin :xy
        /* verilator lint_on WIDTH */
        /* verilator lint_on WIDTH */
            if (SW_LOC == NORTH  ) begin : nort_p // The port located in y axsis does not send packets to x dimension
            if (SW_LOC == NORTH  ) begin : nort_p // The port located in y axsis does not send packets to x dimension
                assign dest_port_out[N_LOCAL]= dest_port_in[N_LOCAL];
                assign dest_port_out[N_LOCAL]= dest_port_in[N_LOCAL];
                assign dest_port_out[N_EAST]= 1'b0; // mask east port
                assign dest_port_out[N_EAST]= 1'b0; // mask east port
                assign dest_port_out[N_WEST]= 1'b0; // mask west port
                assign dest_port_out[N_WEST]= 1'b0; // mask west port
                assign dest_port_out[N_SOUTH]= dest_port_in[N_SOUTH];
                assign dest_port_out[N_SOUTH]= dest_port_in[N_SOUTH];
            end else if ( SW_LOC == SOUTH) begin : south_p
            end else if ( SW_LOC == SOUTH) begin : south_p
                assign dest_port_out[S_LOCAL]= dest_port_in[S_LOCAL];
                assign dest_port_out[S_LOCAL]= dest_port_in[S_LOCAL];
                assign dest_port_out[S_EAST]= 1'b0; // mask east port
                assign dest_port_out[S_EAST]= 1'b0; // mask east port
                assign dest_port_out[S_NORTH]= dest_port_in[S_NORTH];
                assign dest_port_out[S_NORTH]= dest_port_in[S_NORTH];
                assign dest_port_out[S_WEST]= 1'b0; // mask west port
                assign dest_port_out[S_WEST]= 1'b0; // mask west port
            end else begin : non_vertical
            end else begin : non_vertical
                 assign  dest_port_out[3:0] = dest_port_in[3:0];
                 assign  dest_port_out[3:0] = dest_port_in[3:0];
            end
            end
    /*WEST-FIRST*/
    /*WEST-FIRST*/
        /* verilator lint_off WIDTH */
        /* verilator lint_off WIDTH */
        end else  if ( ROUTE_NAME == "WEST_FIRST" || ROUTE_NAME  == "TRANC_WEST_FIRST") begin :west_first
        end else  if ( ROUTE_NAME == "WEST_FIRST" || ROUTE_NAME  == "TRANC_WEST_FIRST") begin :west_first
        /* verilator lint_on WIDTH */
        /* verilator lint_on WIDTH */
         // SW &  NW are forbidden
         // SW &  NW are forbidden
            if (SW_LOC == NORTH  ) begin : nort_p // north port does not send packets to the west port.
            if (SW_LOC == NORTH  ) begin : nort_p // north port does not send packets to the west port.
                assign dest_port_out[N_LOCAL]= dest_port_in[N_LOCAL];
                assign dest_port_out[N_LOCAL]= dest_port_in[N_LOCAL];
                assign dest_port_out[N_EAST]= dest_port_in[N_EAST];
                assign dest_port_out[N_EAST]= dest_port_in[N_EAST];
                assign dest_port_out[N_WEST]= 1'b0; // mask west port
                assign dest_port_out[N_WEST]= 1'b0; // mask west port
                assign dest_port_out[N_SOUTH]= dest_port_in[N_SOUTH];
                assign dest_port_out[N_SOUTH]= dest_port_in[N_SOUTH];
            end else if ( SW_LOC == SOUTH) begin : south_p // south port does not sends packet to west
            end else if ( SW_LOC == SOUTH) begin : south_p // south port does not sends packet to west
                assign dest_port_out[S_LOCAL]= dest_port_in[S_LOCAL];
                assign dest_port_out[S_LOCAL]= dest_port_in[S_LOCAL];
                assign dest_port_out[S_EAST]= dest_port_in[S_EAST];
                assign dest_port_out[S_EAST]= dest_port_in[S_EAST];
                assign dest_port_out[S_NORTH]= dest_port_in[S_NORTH];
                assign dest_port_out[S_NORTH]= dest_port_in[S_NORTH];
                assign dest_port_out[S_WEST]= 1'b0; // mask west port
                assign dest_port_out[S_WEST]= 1'b0; // mask west port
            end else begin : non_vertical
            end else begin : non_vertical
                 assign  dest_port_out[3:0] = dest_port_in[3:0];
                 assign  dest_port_out[3:0] = dest_port_in[3:0];
            end
            end
    /*NORTH_LAST*/
    /*NORTH_LAST*/
        /* verilator lint_off WIDTH */
        /* verilator lint_off WIDTH */
        end else  if ( ROUTE_NAME == "NORTH_LAST" || ROUTE_NAME  == "TRANC_NORTH_LAST") begin :north_last
        end else  if ( ROUTE_NAME == "NORTH_LAST" || ROUTE_NAME  == "TRANC_NORTH_LAST") begin :north_last
        /* verilator lint_on WIDTH */
        /* verilator lint_on WIDTH */
            //NE & NW are forbidden
            //NE & NW are forbidden
            if (SW_LOC == SOUTH  ) begin : south_p // north port does not send packets to the east nor to the west port.
            if (SW_LOC == SOUTH  ) begin : south_p // north port does not send packets to the east nor to the west port.
                assign dest_port_out[S_LOCAL]= dest_port_in[S_LOCAL];
                assign dest_port_out[S_LOCAL]= dest_port_in[S_LOCAL];
                assign dest_port_out[S_EAST]= 1'b0; // mask east port
                assign dest_port_out[S_EAST]= 1'b0; // mask east port
                assign dest_port_out[S_WEST]= 1'b0; // mask west port
                assign dest_port_out[S_WEST]= 1'b0; // mask west port
                assign dest_port_out[S_NORTH]= dest_port_in[S_NORTH];
                assign dest_port_out[S_NORTH]= dest_port_in[S_NORTH];
            end else begin : other_p
            end else begin : other_p
                 assign  dest_port_out[3:0] = dest_port_in[3:0];
                 assign  dest_port_out[3:0] = dest_port_in[3:0];
            end
            end
    /*NEGETIVE_FIRST*/
    /*NEGETIVE_FIRST*/
        /* verilator lint_off WIDTH */
        /* verilator lint_off WIDTH */
        end else  if ( ROUTE_NAME == "NEGETIVE_FIRST" || ROUTE_NAME  == "TRANC_NEGETIVE_FIRST") begin :negetive_first
        end else  if ( ROUTE_NAME == "NEGETIVE_FIRST" || ROUTE_NAME  == "TRANC_NEGETIVE_FIRST") begin :negetive_first
        /* verilator lint_on WIDTH */
        /* verilator lint_on WIDTH */
          //ES & NW is forbiden
          //ES & NW is forbiden
            if (SW_LOC == SOUTH  ) begin : south_p // south port does not send packets to the west port. NW is forbiden
            if (SW_LOC == SOUTH  ) begin : south_p // south port does not send packets to the west port. NW is forbiden
                assign dest_port_out[S_LOCAL]= dest_port_in[S_LOCAL];
                assign dest_port_out[S_LOCAL]= dest_port_in[S_LOCAL];
                assign dest_port_out[S_EAST]= dest_port_in[S_EAST];
                assign dest_port_out[S_EAST]= dest_port_in[S_EAST];
                assign dest_port_out[S_WEST]= 1'b0; // mask west port
                assign dest_port_out[S_WEST]= 1'b0; // mask west port
                assign dest_port_out[S_NORTH]= dest_port_in[S_NORTH];
                assign dest_port_out[S_NORTH]= dest_port_in[S_NORTH];
            end else if ( SW_LOC == WEST) begin : west_p // west port does not sends packet to south. ES is forbiden
            end else if ( SW_LOC == WEST) begin : west_p // west port does not sends packet to south. ES is forbiden
                assign dest_port_out[W_LOCAL]= dest_port_in[W_LOCAL];
                assign dest_port_out[W_LOCAL]= dest_port_in[W_LOCAL];
                assign dest_port_out[W_NORTH]= dest_port_in[W_NORTH];
                assign dest_port_out[W_NORTH]= dest_port_in[W_NORTH];
                assign dest_port_out[W_EAST] = dest_port_in[W_EAST];
                assign dest_port_out[W_EAST] = dest_port_in[W_EAST];
                assign dest_port_out[W_SOUTH]= 1'b0; //mask south port
                assign dest_port_out[W_SOUTH]= 1'b0; //mask south port
            end else begin : other_p
            end else begin : other_p
                 assign  dest_port_out[3:0] = dest_port_in[3:0];
                 assign  dest_port_out[3:0] = dest_port_in[3:0];
            end
            end
    /*ODD_EVEN*/
    /*ODD_EVEN*/
        /* verilator lint_off WIDTH */
        /* verilator lint_off WIDTH */
        end else  if ( ROUTE_NAME == "ODD_EVEN" ) begin : odd_even
        end else  if ( ROUTE_NAME == "ODD_EVEN" ) begin : odd_even
        /* verilator lint_on WIDTH */
        /* verilator lint_on WIDTH */
        //Odd column : NW and SW turns are not allowed
        //Odd column : NW and SW turns are not allowed
        //Even column: EN and ES turns are not allowed
        //Even column: EN and ES turns are not allowed
           if (SW_LOC == NORTH  ) begin : nort_p // north port does not send packets to the west port in odd columns. SW is forbiden
           if (SW_LOC == NORTH  ) begin : nort_p // north port does not send packets to the west port in odd columns. SW is forbiden
                assign dest_port_out[N_LOCAL]= dest_port_in[N_LOCAL];
                assign dest_port_out[N_LOCAL]= dest_port_in[N_LOCAL];
                assign dest_port_out[N_EAST]= dest_port_in[N_EAST];
                assign dest_port_out[N_EAST]= dest_port_in[N_EAST];
                assign dest_port_out[N_WEST]= (odd_column)? 1'b0: dest_port_in[N_WEST];  // mask west port in odd columns
                assign dest_port_out[N_WEST]= (odd_column)? 1'b0: dest_port_in[N_WEST];  // mask west port in odd columns
                assign dest_port_out[N_SOUTH]= dest_port_in[N_SOUTH];
                assign dest_port_out[N_SOUTH]= dest_port_in[N_SOUTH];
             end else if (SW_LOC == SOUTH) begin : south_p // south port does not sends packet to west in odd columns. NW is forbiden
             end else if (SW_LOC == SOUTH) begin : south_p // south port does not sends packet to west in odd columns. NW is forbiden
                assign dest_port_out[S_LOCAL]= dest_port_in[S_LOCAL];
                assign dest_port_out[S_LOCAL]= dest_port_in[S_LOCAL];
                assign dest_port_out[S_EAST]= dest_port_in[S_EAST];
                assign dest_port_out[S_EAST]= dest_port_in[S_EAST];
                assign dest_port_out[S_NORTH]= dest_port_in[S_NORTH];
                assign dest_port_out[S_NORTH]= dest_port_in[S_NORTH];
                assign dest_port_out[S_WEST]= (odd_column)? 1'b0: dest_port_in[S_WEST];  // mask west port   in odd columns
                assign dest_port_out[S_WEST]= (odd_column)? 1'b0: dest_port_in[S_WEST];  // mask west port   in odd columns
           end else if (SW_LOC == WEST) begin : west_p // WEST port does not sends packet to north and south ports in even columns
           end else if (SW_LOC == WEST) begin : west_p // WEST port does not sends packet to north and south ports in even columns
            //ES & EN forbiden
            //ES & EN forbiden
                assign dest_port_out[W_LOCAL]= dest_port_in[W_LOCAL];
                assign dest_port_out[W_LOCAL]= dest_port_in[W_LOCAL];
                assign dest_port_out[W_NORTH]= (odd_column)?   dest_port_in[W_NORTH] : 1'b0; //mask north in even columns
                assign dest_port_out[W_NORTH]= (odd_column)?   dest_port_in[W_NORTH] : 1'b0; //mask north in even columns
                assign dest_port_out[W_EAST] = dest_port_in[W_EAST];
                assign dest_port_out[W_EAST] = dest_port_in[W_EAST];
                assign dest_port_out[W_SOUTH]= (odd_column)? dest_port_in[W_SOUTH] : 1'b0; //mask south in even columns
                assign dest_port_out[W_SOUTH]= (odd_column)? dest_port_in[W_SOUTH] : 1'b0; //mask south in even columns
            end else begin: other_p
            end else begin: other_p
                assign  dest_port_out[3:0] = dest_port_in[3:0];
                assign  dest_port_out[3:0] = dest_port_in[3:0];
            end
            end
    end else begin : f_adptv
    end else begin : f_adptv
                assign  dest_port_out[3:0] = dest_port_in[3:0];
                assign  dest_port_out[3:0] = dest_port_in[3:0];
        end
        end
    end
    end
    endgenerate
    endgenerate
endmodule
endmodule
/**********************
/**********************
    swap_port_presel_gen
    swap_port_presel_gen
**********************/
**********************/
module   mesh_torus_swap_port_presel_gen #(
module   mesh_torus_swap_port_presel_gen #(
    parameter V = 4,
    parameter V = 4,
    parameter [V-1  :   0] ESCAP_VC_MASK = 4'b1000,   // mask scape vc, valid only for full adaptive
    parameter [V-1  :   0] ESCAP_VC_MASK = 4'b1000,   // mask scape vc, valid only for full adaptive
    parameter VC_NUM=0
    parameter VC_NUM=0
)(
)(
    avc_unavailable,
    avc_unavailable,
    swap_port_presel,
    swap_port_presel,
    y_evc_forbiden,
    y_evc_forbiden,
    x_evc_forbiden,
    x_evc_forbiden,
    non_assigned_ovc_request,
    non_assigned_ovc_request,
    sel,
    sel,
    clk,
    clk,
    reset
    reset
);
);
    localparam LOCAL_VC_NUM= VC_NUM % V;
    localparam LOCAL_VC_NUM= VC_NUM % V;
    input    avc_unavailable;
    input    avc_unavailable;
    input    y_evc_forbiden,x_evc_forbiden;
    input    y_evc_forbiden,x_evc_forbiden;
    input    non_assigned_ovc_request,sel;
    input    non_assigned_ovc_request,sel;
    input    clk,reset;
    input    clk,reset;
    output   swap_port_presel;
    output   swap_port_presel;
    wire     swap_reg;
    wire     swap_reg;
    wire swap_port_presel_next;
    wire swap_port_presel_next;
    wire  evc_forbiden;
    wire  evc_forbiden;
    /************************
    /************************
        destination-port_in
        destination-port_in
            x:  1 EAST, 0 WEST
            x:  1 EAST, 0 WEST
            y:  1 NORTH, 0 SOUTH
            y:  1 NORTH, 0 SOUTH
            ab: 00 : LOCAL, 10: xdir, 01: ydir, 11 x&y dir
            ab: 00 : LOCAL, 10: xdir, 01: ydir, 11 x&y dir
        sel:
        sel:
             0: xdir
             0: xdir
             1: ydir
             1: ydir
        port_pre_sel
        port_pre_sel
             0: xdir
             0: xdir
             1: ydir
             1: ydir
************************/
************************/
    //For an EVC sender, if the use of EVC in destination port is restricted while the destination port has no available AVC,
    //For an EVC sender, if the use of EVC in destination port is restricted while the destination port has no available AVC,
    //the port pre selection must swap
    //the port pre selection must swap
   // generate
   // generate
    // check if it is an evc sender
    // check if it is an evc sender
   // if(ESCAP_VC_MASK[LOCAL_VC_NUM]== 1'b0)begin
   // if(ESCAP_VC_MASK[LOCAL_VC_NUM]== 1'b0)begin
    //its not EVC
    //its not EVC
    //   assign swap_port_presel=1'b0;
    //   assign swap_port_presel=1'b0;
   // end else begin // the sender is an EVC
   // end else begin // the sender is an EVC
       assign  evc_forbiden = (sel)? y_evc_forbiden : x_evc_forbiden;
       assign  evc_forbiden = (sel)? y_evc_forbiden : x_evc_forbiden;
       assign  swap_port_presel_next= non_assigned_ovc_request & evc_forbiden & avc_unavailable;
       assign  swap_port_presel_next= non_assigned_ovc_request & evc_forbiden & avc_unavailable;
       assign swap_port_presel = swap_reg;
       assign swap_port_presel = swap_reg;
       pronoc_register #(.W(1)) reg2 (.in(swap_port_presel_next ), .out(swap_reg), .reset(reset), .clk(clk));
       pronoc_register #(.W(1)) reg2 (.in(swap_port_presel_next ), .out(swap_reg), .reset(reset), .clk(clk));
 endmodule
 endmodule
/************************
/************************
    adaptive_avb_ovc_mux
    adaptive_avb_ovc_mux
************************/
************************/
module  mesh_torus_adaptive_avb_ovc_mux #(
module  mesh_torus_adaptive_avb_ovc_mux #(
   parameter V= 4
   parameter V= 4
)(
)(
    ovc_avalable,
    ovc_avalable,
    sel,
    sel,
    candidate_ovc_x,
    candidate_ovc_x,
    candidate_ovc_y,
    candidate_ovc_y,
    non_assigned_ovc_request,
    non_assigned_ovc_request,
    xydir,
    xydir,
    masked_ovc_request
    masked_ovc_request
);
);
    localparam  P       =   5;
    localparam  P       =   5;
    localparam  P_1     =   P-1,
    localparam  P_1     =   P-1,
                VP_1    =   V  *  P_1;
                VP_1    =   V  *  P_1;
    input   [VP_1-1    :    0] ovc_avalable;
    input   [VP_1-1    :    0] ovc_avalable;
    input                      sel;
    input                      sel;
    input   [V-1       :    0] candidate_ovc_x;
    input   [V-1       :    0] candidate_ovc_x;
    input   [V-1       :    0] candidate_ovc_y;
    input   [V-1       :    0] candidate_ovc_y;
    input                      non_assigned_ovc_request;
    input                      non_assigned_ovc_request;
    input   [1         :    0] xydir;
    input   [1         :    0] xydir;
    output  [V-1        :   0] masked_ovc_request;
    output  [V-1        :   0] masked_ovc_request;
    wire    x,y;
    wire    x,y;
    wire    [V-1        :   0] ovc_avb_x_plus,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_y_minus;
    wire    [V-1        :   0] ovc_avb_x_plus,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_y_minus;
    wire    [V-1        :   0] mux_out_x,mux_out_y;
    wire    [V-1        :   0] mux_out_x,mux_out_y;
    wire    [V-1        :   0] ovc_request_x,ovc_request_y,masked_ovc_request_x,masked_ovc_request_y;
    wire    [V-1        :   0] ovc_request_x,ovc_request_y,masked_ovc_request_x,masked_ovc_request_y;
    assign {x,y}= xydir;
    assign {x,y}= xydir;
    assign {ovc_avb_x_plus,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_y_minus}=ovc_avalable;
    assign {ovc_avb_x_plus,ovc_avb_x_minus,ovc_avb_y_plus,ovc_avb_y_minus}=ovc_avalable;
    //first level mux
    //first level mux
    //assign mux_out_x = (x)?  ovc_avb_x_plus :  ovc_avb_x_minus;
    //assign mux_out_x = (x)?  ovc_avb_x_plus :  ovc_avb_x_minus;
    //assign mux_out_y = (y)?  ovc_avb_y_plus :  ovc_avb_y_minus;
    //assign mux_out_y = (y)?  ovc_avb_y_plus :  ovc_avb_y_minus;
    assign mux_out_x = (ovc_avb_x_plus &{V{x}}) |  (ovc_avb_x_minus &{V{~x}});
    assign mux_out_x = (ovc_avb_x_plus &{V{x}}) |  (ovc_avb_x_minus &{V{~x}});
    assign mux_out_y = (ovc_avb_y_plus &{V{y}}) |  (ovc_avb_y_minus &{V{~y}});
    assign mux_out_y = (ovc_avb_y_plus &{V{y}}) |  (ovc_avb_y_minus &{V{~y}});
    //assign ovc_request_x = (non_assigned_ovc_request)? candidate_ovc_x : {V{1'b0}};
    //assign ovc_request_x = (non_assigned_ovc_request)? candidate_ovc_x : {V{1'b0}};
    //assign ovc_request_y = (non_assigned_ovc_request)? candidate_ovc_y : {V{1'b0}};
    //assign ovc_request_y = (non_assigned_ovc_request)? candidate_ovc_y : {V{1'b0}};
    assign ovc_request_x =  candidate_ovc_x & {V{non_assigned_ovc_request}};
    assign ovc_request_x =  candidate_ovc_x & {V{non_assigned_ovc_request}};
    assign ovc_request_y =  candidate_ovc_y & {V{non_assigned_ovc_request}};
    assign ovc_request_y =  candidate_ovc_y & {V{non_assigned_ovc_request}};
    //mask unavailble ovc
    //mask unavailble ovc
    assign masked_ovc_request_x = mux_out_x & ovc_request_x;
    assign masked_ovc_request_x = mux_out_x & ovc_request_x;
    assign masked_ovc_request_y = mux_out_y & ovc_request_y;
    assign masked_ovc_request_y = mux_out_y & ovc_request_y;
    //second mux
    //second mux
   // assign masked_ovc_request = (sel)?  masked_ovc_request_y: masked_ovc_request_x;
   // assign masked_ovc_request = (sel)?  masked_ovc_request_y: masked_ovc_request_x;
     assign masked_ovc_request =  (masked_ovc_request_y & {V{sel}})| (masked_ovc_request_x & {V{~sel}});
     assign masked_ovc_request =  (masked_ovc_request_y & {V{sel}})| (masked_ovc_request_x & {V{~sel}});
endmodule
endmodule
/*****************************************************
/*****************************************************
                port_selector
                port_selector
*****************************************************/
*****************************************************/
module mesh_torus_port_selector #(
module mesh_torus_port_selector #(
    parameter SW_LOC    = 0,
    parameter SW_LOC    = 0,
    parameter PPSw=4
    parameter PPSw=4
)
)
(
(
    port_pre_sel,
    port_pre_sel,
    dest_port_in,
    dest_port_in,
    swap_port_presel,
    swap_port_presel,
    sel,
    sel,
    y_evc_forbiden,
    y_evc_forbiden,
    x_evc_forbiden
    x_evc_forbiden
);
);
/************************
/************************
        destination-port_in
        destination-port_in
            x:  1 EAST, 0 WEST
            x:  1 EAST, 0 WEST
            y:  1 NORTH, 0 SOUTH
            y:  1 NORTH, 0 SOUTH
            ab: 00 : LOCAL, 10: xdir, 01: ydir, 11 x&y dir
            ab: 00 : LOCAL, 10: xdir, 01: ydir, 11 x&y dir
        sel:
        sel:
             0: xdir
             0: xdir
             1: ydir
             1: ydir
        port_pre_sel
        port_pre_sel
             0: xdir
             0: xdir
             1: ydir
             1: ydir
************************/
************************/
    //input           reset,clk;
    //input           reset,clk;
    input   [PPSw-1:0]   port_pre_sel;
    input   [PPSw-1:0]   port_pre_sel;
   // input           port_pre_sel_ld;
   // input           port_pre_sel_ld;
    output          sel;
    output          sel;
    input   [3:0]   dest_port_in;
    input   [3:0]   dest_port_in;
    input           swap_port_presel;
    input           swap_port_presel;
   // output          route_subfunc_violated;
   // output          route_subfunc_violated;
    output          y_evc_forbiden, x_evc_forbiden;
    output          y_evc_forbiden, x_evc_forbiden;
    wire  x,y,a,b;
    wire  x,y,a,b;
    wire [PPSw-1:0] port_pre_sel_final;
    wire [PPSw-1:0] port_pre_sel_final;
    //reg  [3:0] port_pre_sel_delayed , port_pre_sel_latched;
    //reg  [3:0] port_pre_sel_delayed , port_pre_sel_latched;
  //  wire o1,o2;
  //  wire o1,o2;
    localparam LOCAL    =       0,
    localparam LOCAL    =       0,
               EAST     =       1,
               EAST     =       1,
               NORTH    =       2,
               NORTH    =       2,
               WEST     =       3,
               WEST     =       3,
               SOUTH    =       4;
               SOUTH    =       4;
    localparam LOCAL_SEL = (SW_LOC == NORTH || SW_LOC == SOUTH )? 1'b1 : 1'b0;
    localparam LOCAL_SEL = (SW_LOC == NORTH || SW_LOC == SOUTH )? 1'b1 : 1'b0;
    assign port_pre_sel_final= (swap_port_presel)? ~port_pre_sel: port_pre_sel;
    assign port_pre_sel_final= (swap_port_presel)? ~port_pre_sel: port_pre_sel;
    assign {x,y,a,b} = dest_port_in;
    assign {x,y,a,b} = dest_port_in;
     wire sel_in,sel_pre, overwrite;
     wire sel_in,sel_pre, overwrite;
     wire [1:0] xy;
     wire [1:0] xy;
     assign xy={x,y};
     assign xy={x,y};
     assign sel_pre= port_pre_sel_final[xy];
     assign sel_pre= port_pre_sel_final[xy];
     assign overwrite= a&b;
     assign overwrite= a&b;
     generate
     generate
        if(LOCAL_SEL)begin :local_p
        if(LOCAL_SEL)begin :local_p
             assign sel_in= b | ~a;
             assign sel_in= b | ~a;
        end else begin :nonlocal_p
        end else begin :nonlocal_p
             assign sel_in= b ;
             assign sel_in= b ;
        end
        end
     endgenerate
     endgenerate
    assign sel= (overwrite)? sel_pre : sel_in;
    assign sel= (overwrite)? sel_pre : sel_in;
// check if EVC is allowed to be used
// check if EVC is allowed to be used
        // Using of all EVCs located in y dimension are restricted when the packet can be sent into both x&y direction
        // Using of all EVCs located in y dimension are restricted when the packet can be sent into both x&y direction
        assign y_evc_forbiden = a&b;
        assign y_evc_forbiden = a&b;
        //there is no restriction in using EVCs located in x dimension
        //there is no restriction in using EVCs located in x dimension
        assign x_evc_forbiden = 1'b0;
        assign x_evc_forbiden = 1'b0;
        //assign route_subfunc_violated = a&b;
        //assign route_subfunc_violated = a&b;
    /* verilator lint_off WIDTH */
    /* verilator lint_off WIDTH */
 endmodule
 endmodule
/*******************
/*******************
    mesh_torus_adaptive_lk_dest_encoder
    mesh_torus_adaptive_lk_dest_encoder
********************/
********************/
module  mesh_torus_adaptive_lk_dest_encoder #(
module  mesh_torus_adaptive_lk_dest_encoder #(
    parameter V=4,
    parameter V=4,
    parameter P=5,
    parameter P=5,
    parameter DSTPw=P-1,
    parameter DSTPw=P-1,
    parameter Fw=37,
    parameter Fw=37,
    parameter DST_P_MSB=11,
    parameter DST_P_MSB=11,
    parameter DST_P_LSB=8
    parameter DST_P_LSB=8
)(
)(
    sel,
    sel,
    flit_in,
    flit_in,
    dest_coded_out,
    dest_coded_out,
    vc_num_delayed,
    vc_num_delayed,
    lk_dest
    lk_dest
);
);
    input [V-1 : 0]  sel;
    input [V-1 : 0]  sel;
    output [DSTPw-1 : 0]dest_coded_out;
    output [DSTPw-1 : 0]dest_coded_out;
    input [V-1 : 0]  vc_num_delayed;
    input [V-1 : 0]  vc_num_delayed;
    input [DSTPw-1 : 0]  lk_dest;
    input [DSTPw-1 : 0]  lk_dest;
    input [Fw-1 : 0]  flit_in;
    input [Fw-1 : 0]  flit_in;
    wire [1 : 0]  ab,xy;
    wire [1 : 0]  ab,xy;
    wire sel_muxed;
    wire sel_muxed;
    onehot_mux_1D #(
    onehot_mux_1D #(
        .W(1),
        .W(1),
        .N(V)
        .N(V)
    )
    )
    sel_mux
    sel_mux
    (
    (
        .in(sel),
        .in(sel),
        .out(sel_muxed),
        .out(sel_muxed),
        .sel(vc_num_delayed)
        .sel(vc_num_delayed)
    );
    );
    //lkdestport = {lkdestport_x[1:0],lkdestport_y[1:0]};
    //lkdestport = {lkdestport_x[1:0],lkdestport_y[1:0]};
    // sel: 0: xdir     1: ydir
    // sel: 0: xdir     1: ydir
    assign ab = (sel_muxed)? lk_dest[1:0] : lk_dest[3:2];
    assign ab = (sel_muxed)? lk_dest[1:0] : lk_dest[3:2];
    //if ab==00 change x and y direction
    //if ab==00 change x and y direction
    assign xy = (ab>0)? flit_in[DST_P_MSB  : DST_P_LSB+2] : ~flit_in[DST_P_MSB  : DST_P_LSB+2] ;
    assign xy = (ab>0)? flit_in[DST_P_MSB  : DST_P_LSB+2] : ~flit_in[DST_P_MSB  : DST_P_LSB+2] ;
    assign dest_coded_out={xy,ab};
    assign dest_coded_out={xy,ab};
endmodule
endmodule
module  mesh_torus_dtrmn_dest_encoder #(
module  mesh_torus_dtrmn_dest_encoder #(
    parameter P=5,
    parameter P=5,
    parameter DSTPw=P-1,
    parameter DSTPw=P-1,
    parameter Fw=37,
    parameter Fw=37,
    parameter DST_P_MSB=11,
    parameter DST_P_MSB=11,
    parameter DST_P_LSB=8
    parameter DST_P_LSB=8
)(
)(
    flit_in,
    flit_in,
    dest_coded_out,
    dest_coded_out,
    lk_dest
    lk_dest
);
);
    output [DSTPw-1 : 0]dest_coded_out;
    output [DSTPw-1 : 0]dest_coded_out;
    input [DSTPw-1 : 0]  lk_dest;
    input [DSTPw-1 : 0]  lk_dest;
    input [Fw-1 : 0]  flit_in;
    input [Fw-1 : 0]  flit_in;
    wire [1 : 0]  ab,xy;
    wire [1 : 0]  ab,xy;
    //lkdestport = {lkdestport_x[1:0],lkdestport_y[1:0]};
    //lkdestport = {lkdestport_x[1:0],lkdestport_y[1:0]};
    // sel: 0: xdir     1: ydir
    // sel: 0: xdir     1: ydir
    assign ab =  lk_dest[1:0];
    assign ab =  lk_dest[1:0];
    //if ab==00 change x and y direction
    //if ab==00 change x and y direction
    assign xy = (ab>0)? flit_in[DST_P_MSB  : DST_P_LSB+2] : ~flit_in[DST_P_MSB  : DST_P_LSB+2] ;
    assign xy = (ab>0)? flit_in[DST_P_MSB  : DST_P_LSB+2] : ~flit_in[DST_P_MSB  : DST_P_LSB+2] ;
    assign dest_coded_out={xy,ab};
    assign dest_coded_out={xy,ab};
endmodule
endmodule
/********************
/********************
    distance_gen
    distance_gen
********************/
********************/
module mesh_torus_distance_gen #(
module mesh_torus_distance_gen #(
    parameter T1= 4,    // number of node in x axis
    parameter T1= 4,    // number of node in x axis
    parameter T2= 4,    // number of node in y axis
    parameter T2= 4,    // number of node in y axis
    parameter T3= 4,
    parameter T3= 4,
    parameter EAw=4,
    parameter EAw=4,
    parameter DISTw=4,
    parameter DISTw=4,
    parameter TOPOLOGY  = "MESH"
    parameter TOPOLOGY  = "MESH"
)(
)(
    src_e_addr,
    src_e_addr,
    dest_e_addr,
    dest_e_addr,
    distance
    distance
);
);
    function integer log2;
    function integer log2;
      input integer number; begin
      input integer number; begin
         log2=(number <=1) ? 1: 0;
         log2=(number <=1) ? 1: 0;
         while(2**log2
         while(2**log2
            log2=log2+1;
            log2=log2+1;
         end
         end
      end
      end
    endfunction // log2
    endfunction // log2
    localparam
    localparam
        Xw  =   log2(T1),   // number of node in x axis
        Xw  =   log2(T1),   // number of node in x axis
        Yw  =   log2(T2);    // number of node in y axis
        Yw  =   log2(T2);    // number of node in y axis
    localparam [Xw : 0] NX  = T1;
    localparam [Xw : 0] NX  = T1;
    localparam [Yw : 0] NY  = T2;
    localparam [Yw : 0] NY  = T2;
   input [EAw-1 : 0] src_e_addr;
   input [EAw-1 : 0] src_e_addr;
   input [EAw-1 : 0] dest_e_addr;
   input [EAw-1 : 0] dest_e_addr;
   output[DISTw-1:   0]distance;
   output[DISTw-1:   0]distance;
    wire [Xw-1 :   0]src_x,dest_x;
    wire [Xw-1 :   0]src_x,dest_x;
    wire [Yw-1 :   0]src_y,dest_y;
    wire [Yw-1 :   0]src_y,dest_y;
    mesh_tori_endp_addr_decode #(
    mesh_tori_endp_addr_decode #(
        .TOPOLOGY(TOPOLOGY),
        .TOPOLOGY(TOPOLOGY),
        .T1(T1),
        .T1(T1),
        .T2(T2),
        .T2(T2),
        .T3(T3),
        .T3(T3),
        .EAw(EAw)
        .EAw(EAw)
    )
    )
    src_addr_decode
    src_addr_decode
    (
    (
        .e_addr(src_e_addr),
        .e_addr(src_e_addr),
        .ex(src_x),
        .ex(src_x),
        .ey(src_y),
        .ey(src_y),
        .el(),
        .el(),
        .valid()
        .valid()
    );
    );
     mesh_tori_endp_addr_decode #(
     mesh_tori_endp_addr_decode #(
        .TOPOLOGY(TOPOLOGY),
        .TOPOLOGY(TOPOLOGY),
        .T1(T1),
        .T1(T1),
        .T2(T2),
        .T2(T2),
        .T3(T3),
        .T3(T3),
        .EAw(EAw)
        .EAw(EAw)
    )
    )
    dest_addr_decode
    dest_addr_decode
    (
    (
        .e_addr(dest_e_addr),
        .e_addr(dest_e_addr),
        .ex(dest_x),
        .ex(dest_x),
        .ey(dest_y),
        .ey(dest_y),
        .el(),
        .el(),
        .valid()
        .valid()
    );
    );
    reg [Xw-1  :   0] x_offset;
    reg [Xw-1  :   0] x_offset;
    reg [Yw-1  :   0] y_offset;
    reg [Yw-1  :   0] y_offset;
    generate
    generate
    /* verilator lint_off WIDTH */
    /* verilator lint_off WIDTH */
    if( TOPOLOGY == "MESH" || TOPOLOGY == "LINE") begin : oneD
    if( TOPOLOGY == "MESH" || TOPOLOGY == "LINE") begin : oneD
    /* verilator lint_on WIDTH */
    /* verilator lint_on WIDTH */
        always @(*) begin
        always @(*) begin
            x_offset     = (src_x> dest_x)? src_x - dest_x : dest_x - src_x;
            x_offset     = (src_x> dest_x)? src_x - dest_x : dest_x - src_x;
            y_offset     = (src_y> dest_y)? src_y - dest_y : dest_y - src_y;
            y_offset     = (src_y> dest_y)? src_y - dest_y : dest_y - src_y;
         end
         end
    end else begin : twoD //torus ring
    end else begin : twoD //torus ring
        wire tranc_x_plus,tranc_x_min,tranc_y_plus,tranc_y_min,same_x,same_y;
        wire tranc_x_plus,tranc_x_min,tranc_y_plus,tranc_y_min,same_x,same_y;
        /* verilator lint_off WIDTH */
        /* verilator lint_off WIDTH */
        always @ (*) begin
        always @ (*) begin
            x_offset= {Xw{1'b0}};
            x_offset= {Xw{1'b0}};
            y_offset= {Yw{1'b0}};
            y_offset= {Yw{1'b0}};
            //x_offset
            //x_offset
            if(same_x) x_offset= {Xw{1'b0}};
            if(same_x) x_offset= {Xw{1'b0}};
            else if(tranc_x_plus) begin
            else if(tranc_x_plus) begin
                if(dest_x   > src_x)    x_offset= dest_x-src_x;
                if(dest_x   > src_x)    x_offset= dest_x-src_x;
                else                    x_offset= (NX-src_x)+dest_x;
                else                    x_offset= (NX-src_x)+dest_x;
            end
            end
            else if(tranc_x_min)  begin
            else if(tranc_x_min)  begin
                if(dest_x   <  src_x)    x_offset= src_x-dest_x;
                if(dest_x   <  src_x)    x_offset= src_x-dest_x;
                else                     x_offset= src_x+(NX-dest_x);
                else                     x_offset= src_x+(NX-dest_x);
            end
            end
             //y_offset
             //y_offset
            if(same_y) y_offset= {Yw{1'b0}};
            if(same_y) y_offset= {Yw{1'b0}};
            else if(tranc_y_plus) begin
            else if(tranc_y_plus) begin
                if(dest_y   > src_y)    y_offset= dest_y-src_y;
                if(dest_y   > src_y)    y_offset= dest_y-src_y;
                else                    y_offset= (NY-src_y)+dest_y;
                else                    y_offset= (NY-src_y)+dest_y;
            end
            end
            else if(tranc_y_min)  begin
            else if(tranc_y_min)  begin
                if(dest_y   <  src_y)    y_offset= src_y-dest_y;
                if(dest_y   <  src_y)    y_offset= src_y-dest_y;
                else                     y_offset= src_y+(NY-dest_y);
                else                     y_offset= src_y+(NY-dest_y);
            end
            end
        end
        end
        /* verilator lint_on WIDTH */
        /* verilator lint_on WIDTH */
        tranc_dir #(
        tranc_dir #(
            .NX(NX),
            .NX(NX),
            .NY(NY)
            .NY(NY)
        )
        )
        tranc_dir
        tranc_dir
        (
        (
            .tranc_x_plus(tranc_x_plus),
            .tranc_x_plus(tranc_x_plus),
            .tranc_x_min(tranc_x_min),
            .tranc_x_min(tranc_x_min),
            .tranc_y_plus(tranc_y_plus),
            .tranc_y_plus(tranc_y_plus),
            .tranc_y_min(tranc_y_min),
            .tranc_y_min(tranc_y_min),
            .same_x(same_x),
            .same_x(same_x),
            .same_y(same_y),
            .same_y(same_y),
            .current_x(src_x),
            .current_x(src_x),
            .current_y(src_y),
            .current_y(src_y),
            .dest_x(dest_x),
            .dest_x(dest_x),
            .dest_y(dest_y)
            .dest_y(dest_y)
        );
        );
    end
    end
    endgenerate
    endgenerate
    /* verilator lint_off WIDTH */
    /* verilator lint_off WIDTH */
    assign distance     =   x_offset+y_offset+1'b1;
    assign distance     =   x_offset+y_offset+1'b1;
    /* verilator lint_on WIDTH */
    /* verilator lint_on WIDTH */
endmodule
endmodule
module mesh_torus_ssa_check_destport #(
module mesh_torus_ssa_check_destport #(
    parameter ROUTE_TYPE="DETERMINISTIC",
    parameter ROUTE_TYPE="DETERMINISTIC",
    parameter SW_LOC = 0,
    parameter SW_LOC = 0,
    parameter P=5,
    parameter P=5,
    parameter DEBUG_EN = 0,
    parameter DEBUG_EN = 0,
    parameter DSTPw = P-1,
    parameter DSTPw = P-1,
    parameter SS_PORT=0
    parameter SS_PORT=0
)(
)(
    destport_encoded, //exsited packet dest port
    destport_encoded, //exsited packet dest port
    destport_in_encoded, // incomming packet dest port
    destport_in_encoded, // incomming packet dest port
    ss_port_hdr_flit,
    ss_port_hdr_flit,
    ss_port_nonhdr_flit
    ss_port_nonhdr_flit
//synthesis translate_off
//synthesis translate_off
//synopsys  translate_off
//synopsys  translate_off
    ,clk,
    ,clk,
    ivc_num_getting_sw_grant,
    ivc_num_getting_sw_grant,
    hdr_flg
    hdr_flg
//synopsys  translate_on
//synopsys  translate_on
//synthesis translate_on
//synthesis translate_on
);
);
    input [DSTPw-1 : 0] destport_encoded, destport_in_encoded;
    input [DSTPw-1 : 0] destport_encoded, destport_in_encoded;
    output ss_port_hdr_flit, ss_port_nonhdr_flit;
    output ss_port_hdr_flit, ss_port_nonhdr_flit;
//synthesis translate_off
//synthesis translate_off
//synopsys  translate_off
//synopsys  translate_off
    input clk,   ivc_num_getting_sw_grant,hdr_flg;
    input clk,   ivc_num_getting_sw_grant,hdr_flg;
//synopsys  translate_on
//synopsys  translate_on
//synthesis translate_on
//synthesis translate_on
//MESH, TORUS Topology p=5
//MESH, TORUS Topology p=5
    localparam   LOCAL   =   0,
    localparam   LOCAL   =   0,
                 EAST    =   1,
                 EAST    =   1,
                 WEST    =   3;
                 WEST    =   3;
/************************
/************************
        destination port is coded
        destination port is coded
        destination-port_in
        destination-port_in
            x:  1 EAST, 0 WEST
            x:  1 EAST, 0 WEST
            y:  1 NORTH, 0 SOUTH
            y:  1 NORTH, 0 SOUTH
            ab: 00 : LOCAL, 10: xdir, 01: ydir, 11 x&y dir
            ab: 00 : LOCAL, 10: xdir, 01: ydir, 11 x&y dir
        sel:
        sel:
             0: xdir
             0: xdir
             1: ydir
             1: ydir
        port_pre_sel
        port_pre_sel
             0: xdir
             0: xdir
             1: ydir
             1: ydir
************************/
************************/
wire  a,b,aa,bb;
wire  a,b,aa,bb;
assign {a,b} = destport_in_encoded[1:0];
assign {a,b} = destport_in_encoded[1:0];
assign {aa,bb} = destport_encoded[1:0];
assign {aa,bb} = destport_encoded[1:0];
generate
generate
    if( SS_PORT == LOCAL) begin :local_p
    if( SS_PORT == LOCAL) begin :local_p
         assign ss_port_hdr_flit = 1'b0;
         assign ss_port_hdr_flit = 1'b0;
         assign ss_port_nonhdr_flit =   1'b0;
         assign ss_port_nonhdr_flit =   1'b0;
    end else if ((SS_PORT == EAST) || SS_PORT == WEST )begin :xdir
    end else if ((SS_PORT == EAST) || SS_PORT == WEST )begin :xdir
         assign ss_port_hdr_flit = a;
         assign ss_port_hdr_flit = a;
         assign ss_port_nonhdr_flit =   aa;
         assign ss_port_nonhdr_flit =   aa;
    end else begin :ydir
    end else begin :ydir
        assign ss_port_hdr_flit = b;
        assign ss_port_hdr_flit = b;
        assign ss_port_nonhdr_flit =   bb;
        assign ss_port_nonhdr_flit =   bb;
    end
    end
//synthesis translate_off
//synthesis translate_off
//synopsys  translate_off
//synopsys  translate_off
if(DEBUG_EN) begin :dbg
if(DEBUG_EN) begin :dbg
    always @(posedge clk) begin
    always @(posedge clk) begin
       //if(!reset)begin
       //if(!reset)begin
            if(ivc_num_getting_sw_grant & aa & bb & ~hdr_flg) begin
            if(ivc_num_getting_sw_grant & aa & bb & ~hdr_flg) begin
                $display("%t: SSA ERROR: There are two output ports that a non-header flit can be sent to. %m",$time);
                $display("%t: SSA ERROR: There are two output ports that a non-header flit can be sent to. %m",$time);
                $finish;
                $finish;
            end
            end
       //end
       //end
    end
    end
end //dbg
end //dbg
//synopsys  translate_on
//synopsys  translate_on
//synthesis translate_on
//synthesis translate_on
endgenerate
endgenerate
endmodule
endmodule
module line_ring_ssa_check_destport #(
module line_ring_ssa_check_destport #(
    parameter ROUTE_TYPE="DETERMINISTIC",
    parameter ROUTE_TYPE="DETERMINISTIC",
    parameter SW_LOC = 0,
    parameter SW_LOC = 0,
    parameter P=3,
    parameter P=3,
    parameter DEBUG_EN = 0,
    parameter DEBUG_EN = 0,
    parameter DSTPw = P-1,
    parameter DSTPw = P-1,
    parameter SS_PORT=0
    parameter SS_PORT=0
)(
)(
    destport_encoded, //exsited packet dest port
    destport_encoded, //exsited packet dest port
    destport_in_encoded, // incomming packet dest port
    destport_in_encoded, // incomming packet dest port
    ss_port_hdr_flit,
    ss_port_hdr_flit,
    ss_port_nonhdr_flit
    ss_port_nonhdr_flit
);
);
    input [DSTPw-1 : 0] destport_encoded, destport_in_encoded;
    input [DSTPw-1 : 0] destport_encoded, destport_in_encoded;
    output ss_port_hdr_flit, ss_port_nonhdr_flit;
    output ss_port_hdr_flit, ss_port_nonhdr_flit;
wire [P-1   :   0] dest_port_num,assigned_dest_port_num;
wire [P-1   :   0] dest_port_num,assigned_dest_port_num;
  line_ring_decode_dstport cnv1(
  line_ring_decode_dstport cnv1(
        .dstport_one_hot(dest_port_num),
        .dstport_one_hot(dest_port_num),
        .dstport_encoded(destport_in_encoded)
        .dstport_encoded(destport_in_encoded)
  );
  );
   line_ring_decode_dstport cnv2(
   line_ring_decode_dstport cnv2(
        .dstport_one_hot(assigned_dest_port_num),
        .dstport_one_hot(assigned_dest_port_num),
        .dstport_encoded(destport_encoded)
        .dstport_encoded(destport_encoded)
   );
   );
     assign ss_port_hdr_flit = dest_port_num [SS_PORT];
     assign ss_port_hdr_flit = dest_port_num [SS_PORT];
    assign ss_port_nonhdr_flit =  assigned_dest_port_num[SS_PORT];
    assign ss_port_nonhdr_flit =  assigned_dest_port_num[SS_PORT];
endmodule
endmodule
/*
/*
module mesh_torus_add_ss_port #(
module mesh_torus_add_ss_port #(
    parameter SW_LOC=1,
    parameter SW_LOC=1,
    parameter P=5,
    parameter P=5,
    parameter SELF_LOOP_EN="NO"
    parameter SELF_LOOP_EN="NO"
)(
)(
    destport_in,
    destport_in,
    destport_out
    destport_out
);
);
     localparam
     localparam
        P_1     = (SELF_LOOP_EN == "NO") ? P-1 : P,
        P_1     = (SELF_LOOP_EN == "NO") ? P-1 : P,
        LOCAL   =   0,
        LOCAL   =   0,
        EAST    =   1,
        EAST    =   1,
        NORTH   =   2,
        NORTH   =   2,
        WEST    =   3,
        WEST    =   3,
        SOUTH   =   4;
        SOUTH   =   4;
     localparam  NO_SELF_LOOP  = (SELF_LOOP_EN == "NO") ? 1 : 0;
     localparam  NO_SELF_LOOP  = (SELF_LOOP_EN == "NO") ? 1 : 0;
     localparam  SS_PORT_P5 = (SW_LOC== EAST   )? WEST- NO_SELF_LOOP : // the sender port must be removed from destination port code
     localparam  SS_PORT_P5 = (SW_LOC== EAST   )? WEST- NO_SELF_LOOP : // the sender port must be removed from destination port code
                              (SW_LOC== NORTH  )? SOUTH- NO_SELF_LOOP: // the sender port must be removed from destination port code
                              (SW_LOC== NORTH  )? SOUTH- NO_SELF_LOOP: // the sender port must be removed from destination port code
                              (SW_LOC== WEST   )? EAST  :
                              (SW_LOC== WEST   )? EAST  :
                                                  NORTH ;
                                                  NORTH ;
     localparam  SS_PORT_P3 =  (SELF_LOOP_EN == "NO") ? 1 :
     localparam  SS_PORT_P3 =  (SELF_LOOP_EN == "NO") ? 1 :
     localparam  SS_PORT      =   (P==5) ? SS_PORT_P5: SS_PORT_P3;
     localparam  SS_PORT      =   (P==5) ? SS_PORT_P5: SS_PORT_P3;
    input       [P_1-1  :   0] destport_in;
    input       [P_1-1  :   0] destport_in;
    output reg  [P_1-1  :   0] destport_out;
    output reg  [P_1-1  :   0] destport_out;
    always @(*)begin
    always @(*)begin
        destport_out=destport_in;
        destport_out=destport_in;
        if( SW_LOC != LOCAL ) begin
        if( SW_LOC != LOCAL ) begin
            if(destport_in=={P_1{1'b0}}) destport_out[SS_PORT]= 1'b1;
            if(destport_in=={P_1{1'b0}}) destport_out[SS_PORT]= 1'b1;
        end
        end
    end
    end
endmodule
endmodule
*/
*/
/**************
/**************
 *
 *
 * ************/
 * ************/
  module mesh_tori_router_addr_decode #(
  module mesh_tori_router_addr_decode #(
    parameter TOPOLOGY = "MESH",
    parameter TOPOLOGY = "MESH",
    parameter T1=4,
    parameter T1=4,
    parameter T2=4,
    parameter T2=4,
    parameter T3=4,
    parameter T3=4,
    parameter RAw=6
    parameter RAw=6
)(
)(
    r_addr,
    r_addr,
    rx,
    rx,
    ry,
    ry,
    valid
    valid
);
);
    function integer log2;
    function integer log2;
      input integer number; begin
      input integer number; begin
         log2=(number <=1) ? 1: 0;
         log2=(number <=1) ? 1: 0;
         while(2**log2
         while(2**log2
            log2=log2+1;
            log2=log2+1;
         end
         end
      end
      end
    endfunction // log2
    endfunction // log2
    localparam
    localparam
        NX = T1,
        NX = T1,
        NY = T2,
        NY = T2,
        RXw = log2(NX),    // number of node in x axis
        RXw = log2(NX),    // number of node in x axis
        RYw = log2(NY);    // number of node in y axis
        RYw = (TOPOLOGY=="RING" || TOPOLOGY == "LINE") ? 1 : log2(NY);    // number of node in y axis
 
 
    /* verilator lint_off WIDTH */
    /* verilator lint_off WIDTH */
    localparam [RXw-1 : 0]    MAXX = (NX-1);
    localparam [RXw-1 : 0]    MAXX = (NX-1);
    localparam [RYw-1 : 0]    MAXY = (NY-1);
    localparam [RYw-1 : 0]    MAXY = (NY-1);
    /* verilator lint_on WIDTH */
    /* verilator lint_on WIDTH */
    input  [RAw-1 : 0] r_addr;
    input  [RAw-1 : 0] r_addr;
    output [RXw-1 : 0] rx;
    output [RXw-1 : 0] rx;
    output [RYw-1 : 0] ry;
    output [RYw-1 : 0] ry;
    output valid;
    output valid;
    generate
    generate
    if ((TOPOLOGY == "RING") || (TOPOLOGY == "LINE")) begin :oneD
    if ((TOPOLOGY == "RING") || (TOPOLOGY == "LINE")) begin :oneD
         assign rx = r_addr;
         assign rx = r_addr;
         assign ry = 1'b0;
         assign ry = 1'b0;
    end else begin : twoD
    end else begin : twoD
        assign {ry,rx} = r_addr;
        assign {ry,rx} = r_addr;
    end
    end
    endgenerate
    endgenerate
    /* verilator lint_off CMPCONST */
    /* verilator lint_off CMPCONST */
    assign valid = (rx<= MAXX ) & (ry <= MAXY);
    assign valid = (rx<= MAXX ) & (ry <= MAXY);
    /* verilator lint_on CMPCONST */
    /* verilator lint_on CMPCONST */
endmodule
endmodule
module mesh_tori_endp_addr_decode #(
module mesh_tori_endp_addr_decode #(
    parameter TOPOLOGY = "MESH",
    parameter TOPOLOGY = "MESH",
    parameter T1=4,
    parameter T1=4,
    parameter T2=4,
    parameter T2=4,
    parameter T3=4,
    parameter T3=4,
    parameter EAw=9
    parameter EAw=9
)(
)(
    e_addr,
    e_addr,
    ex,
    ex,
    ey,
    ey,
    el,
    el,
    valid
    valid
);
);
    function integer log2;
    function integer log2;
      input integer number; begin
      input integer number; begin
         log2=(number <=1) ? 1: 0;
         log2=(number <=1) ? 1: 0;
         while(2**log2
         while(2**log2
            log2=log2+1;
            log2=log2+1;
         end
         end
      end
      end
    endfunction // log2
    endfunction // log2
    localparam
    localparam
        NX = T1,
        NX = T1,
        NY = T2,
        NY = T2,
        NL = T3,
        NL = T3,
        EXw = log2(NX),    // number of node in x axis
        EXw = log2(NX),    // number of node in x axis
        EYw = log2(NY),
        EYw = (TOPOLOGY=="RING" || TOPOLOGY == "LINE")? 1 : log2(NY),
        ELw = log2(NL);    // number of node in y axis
        ELw = log2(NL);    // number of node in y axis
    /* verilator lint_off WIDTH */
    /* verilator lint_off WIDTH */
    localparam [EXw-1 : 0]    MAXX = (NX-1);
    localparam [EXw-1 : 0]    MAXX = (NX-1);
    localparam [EYw-1 : 0]    MAXY = (NY-1);
    localparam [EYw-1 : 0]    MAXY = (NY-1);
    localparam [ELw-1 : 0]    MAXL = (NL-1);
    localparam [ELw-1 : 0]    MAXL = (NL-1);
    /* verilator lint_on WIDTH */
    /* verilator lint_on WIDTH */
    input  [EAw-1 : 0] e_addr;
    input  [EAw-1 : 0] e_addr;
    output [EXw-1 : 0] ex;
    output [EXw-1 : 0] ex;
    output [EYw-1 : 0] ey;
    output [EYw-1 : 0] ey;
    output [ELw-1 : 0] el;
    output [ELw-1 : 0] el;
    output valid;
    output valid;
    generate
    generate
    if ((TOPOLOGY == "RING") || (TOPOLOGY == "LINE")) begin :oneD
    if ((TOPOLOGY == "RING") || (TOPOLOGY == "LINE")) begin :oneD
        if(NL==1)begin:one_local
        if(NL==1)begin:one_local
             assign ex = e_addr;
             assign ex = e_addr;
             assign ey = 1'b0;
             assign ey = 1'b0;
             assign el = 1'b0;
             assign el = 1'b0;
             /* verilator lint_off CMPCONST */
             /* verilator lint_off CMPCONST */
             assign valid = ex<= MAXX;
             assign valid = ex<= MAXX;
             /* verilator lint_on CMPCONST */
             /* verilator lint_on CMPCONST */
        end else begin: multi_local
        end else begin: multi_local
             assign {el,ex} = e_addr;
             assign {el,ex} = e_addr;
             assign ey = 1'b0;
             assign ey = 1'b0;
             /* verilator lint_off CMPCONST */
             /* verilator lint_off CMPCONST */
             assign valid = ((ex<= MAXX) & (el<=MAXL));
             assign valid = ((ex<= MAXX) & (el<=MAXL));
             /* verilator lint_on CMPCONST */
             /* verilator lint_on CMPCONST */
        end
        end
    end else begin : twoD
    end else begin : twoD
        if(NL==1)begin:one_local
        if(NL==1)begin:one_local
            assign {ey,ex} = e_addr;
            assign {ey,ex} = e_addr;
            assign el = 1'b0;
            assign el = 1'b0;
            /* verilator lint_off CMPCONST */
            /* verilator lint_off CMPCONST */
            assign valid = (ex<= MAXX) & (ey <= MAXY);
            assign valid = (ex<= MAXX) & (ey <= MAXY);
            /* verilator lint_on CMPCONST */
            /* verilator lint_on CMPCONST */
        end else begin :multi_l
        end else begin :multi_l
            assign {el,ey,ex} = e_addr;
            assign {el,ey,ex} = e_addr;
            /* verilator lint_off CMPCONST */
            /* verilator lint_off CMPCONST */
            assign valid = ( (ex<= MAXX) & (ey <= MAXY) & (el<=MAXL) );
            assign valid = ( (ex<= MAXX) & (ey <= MAXY) & (el<=MAXL) );
            /* verilator lint_on CMPCONST */
            /* verilator lint_on CMPCONST */
        end
        end
    end
    end
    endgenerate
    endgenerate
endmodule
endmodule
/**************
/**************
    mesh_tori_addr_encoder
    mesh_tori_addr_encoder
    most probably it is only needed for simulation purposes
    most probably it is only needed for simulation purposes
***************/
***************/
module  mesh_tori_addr_encoder #(
module  mesh_tori_addr_encoder #(
    parameter   NX=2,
    parameter   NX=2,
    parameter   NY=2,
    parameter   NY=2,
    parameter   NL=2,
    parameter   NL=2,
    parameter   NE=16,
    parameter   NE=16,
    parameter   EAw=4,
    parameter   EAw=4,
    parameter   TOPOLOGY="MESH"
    parameter   TOPOLOGY="MESH"
)(
)(
    id,
    id,
    code
    code
);
);
    function integer log2;
    function integer log2;
      input integer number; begin
      input integer number; begin
         log2=(number <=1) ? 1: 0;
         log2=(number <=1) ? 1: 0;
         while(2**log2
         while(2**log2
            log2=log2+1;
            log2=log2+1;
         end
         end
      end
      end
    endfunction // log2
    endfunction // log2
    function integer addrencode;
    function integer addrencode;
        input integer in,nx,nxw,nl,nyw;
        input integer in,nx,nxw,nl,nyw;
        integer  y, x, l;begin
        integer  y, x, l;begin
            addrencode=0;
            addrencode=0;
            y = ((in/nl) / nx );
            y = ((in/nl) / nx );
            x = ((in/nl) % nx );
            x = ((in/nl) % nx );
            l = (in % nl);
            l = (in % nl);
            addrencode =(nl==1)?   (y<
            addrencode =(nl==1)?   (y<
        end
        end
    endfunction // addrencode
    endfunction // addrencode
    localparam
    localparam
        NXw= log2(NX),
        NXw= log2(NX),
        NYw= log2(NY),
        NYw= (TOPOLOGY=="RING" || TOPOLOGY=="LINE")? 0 : log2(NY),
        NEw = log2(NE);
        NEw = log2(NE);
     input [NEw-1 :0] id;
     input [NEw-1 :0] id;
     output [EAw-1 : 0] code;
     output [EAw-1 : 0] code;
    wire [EAw-1 : 0 ] codes [NE-1 : 0];
    wire [EAw-1 : 0 ] codes [NE-1 : 0];
    genvar i;
    genvar i;
    generate
    generate
    for(i=0; i< NE; i=i+1) begin : endpoints
    for(i=0; i< NE; i=i+1) begin : endpoints
        //Endpoint decoded address
        //Endpoint decoded address
       /* verilator lint_off WIDTH */
       /* verilator lint_off WIDTH */
        localparam [EAw-1 : 0] ENDP= addrencode(i,NX,NXw,NL,NYw);
        localparam [EAw-1 : 0] ENDP= addrencode(i,NX,NXw,NL,NYw);
       /* verilator lint_on WIDTH */
       /* verilator lint_on WIDTH */
        assign codes[i] = ENDP;
        assign codes[i] = ENDP;
    end
    end
    endgenerate
    endgenerate
    assign code = codes[id];
    assign code = codes[id];
endmodule
endmodule
module  mesh_tori_addr_coder #(
module  mesh_tori_addr_coder #(
 
    parameter   TOPOLOGY = "MESH",
    parameter   NX=2,
    parameter   NX=2,
    parameter   NY=2,
    parameter   NY=2,
    parameter   NL=2,
    parameter   NL=2,
    parameter   NE=16,
    parameter   NE=16,
    parameter   EAw=4
    parameter   EAw=4
)(
)(
    id,
    id,
    code
    code
);
);
    function integer log2;
    function integer log2;
      input integer number; begin
      input integer number; begin
         log2=(number <=1) ? 1: 0;
         log2=(number <=1) ? 1: 0;
         while(2**log2
         while(2**log2
            log2=log2+1;
            log2=log2+1;
         end
         end
      end
      end
    endfunction // log2
    endfunction // log2
    function integer addrencode;
    function integer addrencode;
        input integer in,nx,nxw,nl,nyw;
        input integer in,nx,nxw,nl,nyw;
        integer  y, x, l;begin
        integer  y, x, l;begin
            addrencode=0;
            addrencode=0;
            y = ((in/nl) / nx );
            y = ((in/nl) / nx );
            x = ((in/nl) % nx );
            x = ((in/nl) % nx );
            l = (in % nl);
            l = (in % nl);
            addrencode =(nl==1)?   (y<
            addrencode =(nl==1)?   (y<
        end
        end
    endfunction // addrencode
    endfunction // addrencode
    localparam
    localparam
        NXw= log2(NX),
        NXw= log2(NX),
        NYw= log2(NY),
        NYw= (TOPOLOGY=="RING" || TOPOLOGY=="LINE")? 0 : log2(NY),
        NEw = log2(NE);
        NEw = log2(NE);
     output [NEw-1 :0] id;
     output [NEw-1 :0] id;
     input [EAw-1 : 0] code;
     input [EAw-1 : 0] code;
    wire   [NEw-1 : 0]  codes   [(2**EAw)-1 : 0 ];
    wire   [NEw-1 : 0]  codes   [(2**EAw)-1 : 0 ];
    genvar i;
    genvar i;
    generate
    generate
    for(i=0; i< NE; i=i+1) begin : endpoints
    for(i=0; i< NE; i=i+1) begin : endpoints
        //Endpoint decoded address
        //Endpoint decoded address
       /* verilator lint_off WIDTH */
       /* verilator lint_off WIDTH */
        localparam [EAw-1 : 0] ENDP= addrencode(i,NX,NXw,NL,NYw);
        localparam [EAw-1 : 0] ENDP= addrencode(i,NX,NXw,NL,NYw);
       /* verilator lint_on WIDTH */
       /* verilator lint_on WIDTH */
        assign codes[ENDP] = i;
        assign codes[ENDP] = i;
    end
    end
    endgenerate
    endgenerate
    assign id = codes[code];
    assign id = codes[code];
endmodule
endmodule
module mesh_torus_destp_generator #(
module mesh_torus_destp_generator #(
    parameter TOPOLOGY = "MESH",
    parameter TOPOLOGY = "MESH",
    parameter ROUTE_NAME = "XY",
    parameter ROUTE_NAME = "XY",
    parameter ROUTE_TYPE = "DETERMINISTIC",
    parameter ROUTE_TYPE = "DETERMINISTIC",
    parameter P=5,
    parameter P=5,
    parameter DSTPw=4,
    parameter DSTPw=4,
    parameter NL=1,
    parameter NL=1,
    parameter PLw=1,
    parameter PLw=1,
    parameter PPSw=4,
    parameter PPSw=4,
    parameter SW_LOC=0,
    parameter SW_LOC=0,
    parameter SELF_LOOP_EN="NO"
    parameter SELF_LOOP_EN="NO"
)(
)(
    dest_port_out,
    dest_port_out,
    dest_port_coded,
    dest_port_coded,
    endp_localp_num,
    endp_localp_num,
    swap_port_presel,
    swap_port_presel,
    port_pre_sel,
    port_pre_sel,
    odd_column
    odd_column
);
);
    localparam P_1 =  ( SELF_LOOP_EN=="NO")?  P-1 : P;
    localparam P_1 =  ( SELF_LOOP_EN=="NO")?  P-1 : P;
    input  [DSTPw-1 : 0] dest_port_coded;
    input  [DSTPw-1 : 0] dest_port_coded;
    input  [PLw-1 : 0] endp_localp_num;
    input  [PLw-1 : 0] endp_localp_num;
    output [P_1-1 : 0] dest_port_out;
    output [P_1-1 : 0] dest_port_out;
    input           swap_port_presel;
    input           swap_port_presel;
    input  [PPSw-1 : 0] port_pre_sel;
    input  [PPSw-1 : 0] port_pre_sel;
    input odd_column;
    input odd_column;
    wire [P_1-1 : 0] dest_port_in;
    wire [P_1-1 : 0] dest_port_in;
        generate
        generate
        /* verilator lint_off WIDTH */
        /* verilator lint_off WIDTH */
        if (TOPOLOGY == "RING" || TOPOLOGY == "LINE" ) begin : one_D
        if (TOPOLOGY == "RING" || TOPOLOGY == "LINE" ) begin : one_D
        /* verilator lint_on WIDTH */
        /* verilator lint_on WIDTH */
            line_ring_destp_decoder #(
            line_ring_destp_decoder #(
                .ROUTE_TYPE(ROUTE_TYPE),
                .ROUTE_TYPE(ROUTE_TYPE),
                .P(P),
                .P(P),
                .DSTPw(DSTPw),
                .DSTPw(DSTPw),
                .NL(NL),
                .NL(NL),
                .ELw(PLw),
                .ELw(PLw),
                .PPSw(PPSw),
                .PPSw(PPSw),
                .SW_LOC(SW_LOC),
                .SW_LOC(SW_LOC),
                .SELF_LOOP_EN(SELF_LOOP_EN)
                .SELF_LOOP_EN(SELF_LOOP_EN)
            )
            )
            decoder
            decoder
            (
            (
                .dest_port_coded(dest_port_coded),
                .dest_port_coded(dest_port_coded),
                .dest_port_out(dest_port_in),
                .dest_port_out(dest_port_in),
                .endp_localp_num(endp_localp_num)
                .endp_localp_num(endp_localp_num)
            );
            );
       end else begin :two_D
       end else begin :two_D
            mesh_torus_destp_decoder #(
            mesh_torus_destp_decoder #(
                .ROUTE_TYPE(ROUTE_TYPE),
                .ROUTE_TYPE(ROUTE_TYPE),
                .P(P),
                .P(P),
                .DSTPw(DSTPw),
                .DSTPw(DSTPw),
                .NL(NL),
                .NL(NL),
                .ELw(PLw),
                .ELw(PLw),
                .PPSw(PPSw),
                .PPSw(PPSw),
                .SW_LOC(SW_LOC),
                .SW_LOC(SW_LOC),
                .SELF_LOOP_EN(SELF_LOOP_EN)
                .SELF_LOOP_EN(SELF_LOOP_EN)
            )
            )
            decoder
            decoder
            (
            (
                .dest_port_coded(dest_port_coded),
                .dest_port_coded(dest_port_coded),
                .dest_port_out(dest_port_in),
                .dest_port_out(dest_port_in),
                .endp_localp_num(endp_localp_num),
                .endp_localp_num(endp_localp_num),
                .swap_port_presel(swap_port_presel),
                .swap_port_presel(swap_port_presel),
                .port_pre_sel(port_pre_sel)
                .port_pre_sel(port_pre_sel)
            );
            );
      end
      end
 endgenerate
 endgenerate
      mesh_torus_mask_non_assignable_destport #(
      mesh_torus_mask_non_assignable_destport #(
                .TOPOLOGY(TOPOLOGY),
                .TOPOLOGY(TOPOLOGY),
                .ROUTE_NAME(ROUTE_NAME),
                .ROUTE_NAME(ROUTE_NAME),
                .SW_LOC(SW_LOC),
                .SW_LOC(SW_LOC),
                .P(P),
                .P(P),
                .SELF_LOOP_EN(SELF_LOOP_EN)
                .SELF_LOOP_EN(SELF_LOOP_EN)
            )
            )
            mask_destport
            mask_destport
            (
            (
                .dest_port_in(dest_port_in),
                .dest_port_in(dest_port_in),
                .dest_port_out(dest_port_out),
                .dest_port_out(dest_port_out),
                .odd_column(odd_column)
                .odd_column(odd_column)
            );
            );
endmodule
endmodule
module mesh_torus_destp_decoder #(
module mesh_torus_destp_decoder #(
    parameter ROUTE_TYPE="DETERMINISTIC",
    parameter ROUTE_TYPE="DETERMINISTIC",
    parameter P=6,
    parameter P=6,
    parameter DSTPw=4,
    parameter DSTPw=4,
    parameter NL=2,
    parameter NL=2,
    parameter ELw=1,
    parameter ELw=1,
    parameter PPSw=4,
    parameter PPSw=4,
    parameter SW_LOC=0,
    parameter SW_LOC=0,
    parameter SELF_LOOP_EN="NO"
    parameter SELF_LOOP_EN="NO"
)(
)(
    dest_port_coded,
    dest_port_coded,
    endp_localp_num,
    endp_localp_num,
    dest_port_out,
    dest_port_out,
    swap_port_presel,
    swap_port_presel,
    port_pre_sel
    port_pre_sel
 );
 );
    localparam P_1 = ( SELF_LOOP_EN=="NO")?  P-1 : P;
    localparam P_1 = ( SELF_LOOP_EN=="NO")?  P-1 : P;
    input  [DSTPw-1 : 0] dest_port_coded;
    input  [DSTPw-1 : 0] dest_port_coded;
    input  [ELw-1 : 0] endp_localp_num;
    input  [ELw-1 : 0] endp_localp_num;
    output [P_1-1 : 0] dest_port_out;
    output [P_1-1 : 0] dest_port_out;
    input           swap_port_presel;
    input           swap_port_presel;
    input  [PPSw-1 : 0] port_pre_sel;
    input  [PPSw-1 : 0] port_pre_sel;
    wire [NL-1 : 0] endp_localp_onehot;
    wire [NL-1 : 0] endp_localp_onehot;
    reg [4:0] portout;
    reg [4:0] portout;
    generate
    generate
    if( ROUTE_TYPE == "DETERMINISTIC") begin :dtrmn
    if( ROUTE_TYPE == "DETERMINISTIC") begin :dtrmn
        wire x,y,a,b;
        wire x,y,a,b;
        assign {x,y,a,b} = dest_port_coded;
        assign {x,y,a,b} = dest_port_coded;
        always @(*)begin
        always @(*)begin
            case({a,b})
            case({a,b})
                2'b10 : portout = {1'b0,~x,1'b0,x,1'b0};
                2'b10 : portout = {1'b0,~x,1'b0,x,1'b0};
                2'b01 : portout = {~y,1'b0,y,1'b0,1'b0};
                2'b01 : portout = {~y,1'b0,y,1'b0,1'b0};
                2'b00 : portout =  5'b00001;
                2'b00 : portout =  5'b00001;
                2'b11 : portout = {~y,1'b0,y,1'b0,1'b0}; //invalid condition in determinstic routing
                2'b11 : portout = {~y,1'b0,y,1'b0,1'b0}; //invalid condition in determinstic routing
            endcase
            endcase
        end //always
        end //always
    end else begin : adpv
    end else begin : adpv
        wire x,y,a,b;
        wire x,y,a,b;
        assign {x,y,a,b} = dest_port_coded;
        assign {x,y,a,b} = dest_port_coded;
        wire [PPSw-1:0] port_pre_sel_final;
        wire [PPSw-1:0] port_pre_sel_final;
        assign port_pre_sel_final= (swap_port_presel)? ~port_pre_sel: port_pre_sel;
        assign port_pre_sel_final= (swap_port_presel)? ~port_pre_sel: port_pre_sel;
        always @(*)begin
        always @(*)begin
            case({a,b})
            case({a,b})
                2'b10 : portout = {1'b0,~x,1'b0,x,1'b0};
                2'b10 : portout = {1'b0,~x,1'b0,x,1'b0};
                2'b01 : portout = {~y,1'b0,y,1'b0,1'b0};
                2'b01 : portout = {~y,1'b0,y,1'b0,1'b0};
                2'b11 : portout = (port_pre_sel_final[{x,y}])?  {~y,1'b0,y,1'b0,1'b0} : {1'b0,~x,1'b0,x,1'b0};
                2'b11 : portout = (port_pre_sel_final[{x,y}])?  {~y,1'b0,y,1'b0,1'b0} : {1'b0,~x,1'b0,x,1'b0};
                2'b00 : portout =  5'b00001;
                2'b00 : portout =  5'b00001;
            endcase
            endcase
        end //always
        end //always
     end
     end
     if(NL==1) begin :slp
     if(NL==1) begin :slp
        if(SELF_LOOP_EN == "NO") begin :nslp
        if(SELF_LOOP_EN == "NO") begin :nslp
            remove_sw_loc_one_hot #(
            remove_sw_loc_one_hot #(
                .P(5),
                .P(5),
                .SW_LOC(SW_LOC)
                .SW_LOC(SW_LOC)
            )
            )
            conv
            conv
            (
            (
                .destport_in(portout),
                .destport_in(portout),
                .destport_out(dest_port_out)
                .destport_out(dest_port_out)
            );
            );
         end else begin : slp
         end else begin : slp
            assign dest_port_out = portout;
            assign dest_port_out = portout;
         end
         end
     end else begin :mlp
     end else begin :mlp
            wire [P-1 : 0] destport_onehot;
            wire [P-1 : 0] destport_onehot;
            bin_to_one_hot #(
            bin_to_one_hot #(
                .BIN_WIDTH(ELw),
                .BIN_WIDTH(ELw),
                .ONE_HOT_WIDTH(NL)
                .ONE_HOT_WIDTH(NL)
            )
            )
            conv
            conv
            (
            (
                .bin_code(endp_localp_num),
                .bin_code(endp_localp_num),
                .one_hot_code(endp_localp_onehot)
                .one_hot_code(endp_localp_onehot)
            );
            );
           assign destport_onehot =(portout[0])?  { endp_localp_onehot[NL-1 : 1] ,{(P-NL){1'b0}},endp_localp_onehot[0]}: /*select local destination*/
           assign destport_onehot =(portout[0])?  { endp_localp_onehot[NL-1 : 1] ,{(P-NL){1'b0}},endp_localp_onehot[0]}: /*select local destination*/
                                                              { {(NL-1){1'b0}} ,portout};
                                                              { {(NL-1){1'b0}} ,portout};
           if(SELF_LOOP_EN == "NO") begin :nslp
           if(SELF_LOOP_EN == "NO") begin :nslp
                remove_sw_loc_one_hot #(
                remove_sw_loc_one_hot #(
                    .P(P),
                    .P(P),
                    .SW_LOC(SW_LOC)
                    .SW_LOC(SW_LOC)
                )
                )
                remove_sw_loc
                remove_sw_loc
                (
                (
                    .destport_in(destport_onehot),
                    .destport_in(destport_onehot),
                    .destport_out(dest_port_out)
                    .destport_out(dest_port_out)
                );
                );
            end else begin: slp
            end else begin: slp
                assign dest_port_out = destport_onehot;
                assign dest_port_out = destport_onehot;
            end
            end
    end
    end
    endgenerate
    endgenerate
endmodule
endmodule
/**************************
/**************************
 * line_ring_destp_decoder
 * line_ring_destp_decoder
 * ************************/
 * ************************/
module line_ring_destp_decoder #(
module line_ring_destp_decoder #(
    parameter ROUTE_TYPE="DETERMINISTIC",
    parameter ROUTE_TYPE="DETERMINISTIC",
    parameter P=4,
    parameter P=4,
    parameter DSTPw=2,
    parameter DSTPw=2,
    parameter NL=2,
    parameter NL=2,
    parameter ELw=1,
    parameter ELw=1,
    parameter PPSw=4,
    parameter PPSw=4,
    parameter SW_LOC=0,
    parameter SW_LOC=0,
    parameter SELF_LOOP_EN= "NO"
    parameter SELF_LOOP_EN= "NO"
)(
)(
    dest_port_coded,
    dest_port_coded,
    endp_localp_num,
    endp_localp_num,
    dest_port_out
    dest_port_out
 );
 );
    localparam P_1 = (SELF_LOOP_EN == "NO")?  P-1 : P;
    localparam P_1 = (SELF_LOOP_EN == "NO")?  P-1 : P;
    input  [DSTPw-1 : 0] dest_port_coded;
    input  [DSTPw-1 : 0] dest_port_coded;
    input  [ELw-1 : 0] endp_localp_num;
    input  [ELw-1 : 0] endp_localp_num;
    output [P_1-1 : 0] dest_port_out;
    output [P_1-1 : 0] dest_port_out;
    wire [NL-1 : 0] endp_localp_onehot;
    wire [NL-1 : 0] endp_localp_onehot;
    wire [2:0] portout;
    wire [2:0] portout;
      line_ring_decode_dstport decoder(
      line_ring_decode_dstport decoder(
        .dstport_one_hot(portout),
        .dstport_one_hot(portout),
        .dstport_encoded(dest_port_coded)
        .dstport_encoded(dest_port_coded)
      );
      );
     generate
     generate
     if(NL==1) begin :slp
     if(NL==1) begin :slp
        if(SELF_LOOP_EN == "NO") begin :nslp
        if(SELF_LOOP_EN == "NO") begin :nslp
            remove_sw_loc_one_hot #(
            remove_sw_loc_one_hot #(
                .P(3),
                .P(3),
                .SW_LOC(SW_LOC)
                .SW_LOC(SW_LOC)
            )
            )
            conv
            conv
            (
            (
                .destport_in(portout),
                .destport_in(portout),
                .destport_out(dest_port_out)
                .destport_out(dest_port_out)
            );
            );
         end else begin : slp
         end else begin : slp
            assign dest_port_out = portout;
            assign dest_port_out = portout;
         end
         end
     end else begin :mlp
     end else begin :mlp
            wire [P-1 : 0] destport_onehot;
            wire [P-1 : 0] destport_onehot;
            bin_to_one_hot #(
            bin_to_one_hot #(
                .BIN_WIDTH(ELw),
                .BIN_WIDTH(ELw),
                .ONE_HOT_WIDTH(NL)
                .ONE_HOT_WIDTH(NL)
            )
            )
            conv
            conv
            (
            (
                .bin_code(endp_localp_num),
                .bin_code(endp_localp_num),
                .one_hot_code(endp_localp_onehot)
                .one_hot_code(endp_localp_onehot)
            );
            );
           assign destport_onehot =(portout[0])?  { endp_localp_onehot[NL-1 : 1] ,{(P-NL){1'b0}},endp_localp_onehot[0]}: /*select local destination*/
           assign destport_onehot =(portout[0])?  { endp_localp_onehot[NL-1 : 1] ,{(P-NL){1'b0}},endp_localp_onehot[0]}: /*select local destination*/
                                                  { {(NL-1){1'b0}} ,portout};
                                                  { {(NL-1){1'b0}} ,portout};
            if(SELF_LOOP_EN == "NO") begin :nslp
            if(SELF_LOOP_EN == "NO") begin :nslp
                remove_sw_loc_one_hot #(
                remove_sw_loc_one_hot #(
                    .P(P),
                    .P(P),
                    .SW_LOC(SW_LOC)
                    .SW_LOC(SW_LOC)
                )
                )
                remove_sw_loc
                remove_sw_loc
                (
                (
                    .destport_in(destport_onehot),
                    .destport_in(destport_onehot),
                    .destport_out(dest_port_out)
                    .destport_out(dest_port_out)
                );
                );
            end else begin :slp
            end else begin :slp
                assign dest_port_out = destport_onehot;
                assign dest_port_out = destport_onehot;
            end
            end
    end
    end
    endgenerate
    endgenerate
endmodule
endmodule
/*****************
/*****************
*   mesh_torus_dynamic_portsel_control
*   mesh_torus_dynamic_portsel_control
*****************/
*****************/
module  mesh_torus_dynamic_portsel_control #(
module  mesh_torus_dynamic_portsel_control #(
    parameter  P = 5,
    parameter  P = 5,
    parameter ROUTE_TYPE =  "FULL_ADAPTIVE",    // "FULL_ADAPTIVE", "PAR_ADAPTIVE"
    parameter ROUTE_TYPE =  "FULL_ADAPTIVE",    // "FULL_ADAPTIVE", "PAR_ADAPTIVE"
    parameter V = 4,
    parameter V = 4,
    parameter DSTPw=4,
    parameter DSTPw=4,
    parameter SSA_EN ="NO",
    parameter SSA_EN ="NO",
    parameter PPSw=4,
    parameter PPSw=4,
    parameter [V-1  :   0] ESCAP_VC_MASK = 4'b1000   // mask scape vc, valid only for full adaptive
    parameter [V-1  :   0] ESCAP_VC_MASK = 4'b1000   // mask scape vc, valid only for full adaptive
)(
)(
    dest_port_coded_all,
    dest_port_coded_all,
    ivc_request_all,
    ivc_request_all,
    ovc_is_assigned_all,
    ovc_is_assigned_all,
    port_pre_sel,
    port_pre_sel,
    swap_port_presel,
    swap_port_presel,
    destport_clear_all,
    destport_clear_all,
    ivc_num_getting_ovc_grant,
    ivc_num_getting_ovc_grant,
    ssa_ivc_num_getting_ovc_grant_all,
    ssa_ivc_num_getting_ovc_grant_all,
    masked_ovc_request_all,
    masked_ovc_request_all,
    sel,
    sel,
    reset,
    reset,
    clk
    clk
);
);
    localparam
    localparam
        PV = V * P,
        PV = V * P,
        PVV= PV * V,
        PVV= PV * V,
        PVDSTPw = PV * DSTPw;
        PVDSTPw = PV * DSTPw;
     localparam LOCAL   =   0,
     localparam LOCAL   =   0,
                EAST    =   1,
                EAST    =   1,
                NORTH   =   2,
                NORTH   =   2,
                WEST    =   3,
                WEST    =   3,
                SOUTH   =   4;
                SOUTH   =   4;
    input   [PVDSTPw-1  :   0]  dest_port_coded_all;
    input   [PVDSTPw-1  :   0]  dest_port_coded_all;
    input   [PV-1       :   0]  ivc_request_all;
    input   [PV-1       :   0]  ivc_request_all;
    input   [PV-1       :   0]  ovc_is_assigned_all;
    input   [PV-1       :   0]  ovc_is_assigned_all;
    input   [PVV-1      :   0]  masked_ovc_request_all;
    input   [PVV-1      :   0]  masked_ovc_request_all;
    input   [PPSw-1      :   0]  port_pre_sel;
    input   [PPSw-1      :   0]  port_pre_sel;
    output  [PV-1       :   0]  swap_port_presel;
    output  [PV-1       :   0]  swap_port_presel;
    output  [PV-1       :   0]  sel;
    output  [PV-1       :   0]  sel;
    output  [PVDSTPw-1 : 0] destport_clear_all;
    output  [PVDSTPw-1 : 0] destport_clear_all;
    input   [PV-1 : 0] ivc_num_getting_ovc_grant;
    input   [PV-1 : 0] ivc_num_getting_ovc_grant;
    input   [PV-1 : 0] ssa_ivc_num_getting_ovc_grant_all;
    input   [PV-1 : 0] ssa_ivc_num_getting_ovc_grant_all;
    input                       reset,clk;
    input                       reset,clk;
    wire    [PV-1       :   0]  non_assigned_ovc_request_all;
    wire    [PV-1       :   0]  non_assigned_ovc_request_all;
    wire    [PV-1       :   0]  y_evc_forbiden,x_evc_forbiden;
    wire    [PV-1       :   0]  y_evc_forbiden,x_evc_forbiden;
    wire    [PPSw-1      :   0]  port_pre_sel_perport            [P-1    :   0];
    wire    [PPSw-1      :   0]  port_pre_sel_perport            [P-1    :   0];
    assign non_assigned_ovc_request_all =   ivc_request_all & ~ovc_is_assigned_all;
    assign non_assigned_ovc_request_all =   ivc_request_all & ~ovc_is_assigned_all;
    assign port_pre_sel_perport[LOCAL]   = port_pre_sel;
    assign port_pre_sel_perport[LOCAL]   = port_pre_sel;
    assign port_pre_sel_perport[EAST]    = {2'b00,port_pre_sel[1:0]};
    assign port_pre_sel_perport[EAST]    = {2'b00,port_pre_sel[1:0]};
    assign port_pre_sel_perport[NORTH]   = {1'b0,port_pre_sel[2],1'b0,port_pre_sel[0]};
    assign port_pre_sel_perport[NORTH]   = {1'b0,port_pre_sel[2],1'b0,port_pre_sel[0]};
    assign port_pre_sel_perport[WEST]    = {port_pre_sel[3:2],2'b0};
    assign port_pre_sel_perport[WEST]    = {port_pre_sel[3:2],2'b0};
    assign port_pre_sel_perport[SOUTH]   = {port_pre_sel[3],1'b0,port_pre_sel[1],1'b0};
    assign port_pre_sel_perport[SOUTH]   = {port_pre_sel[3],1'b0,port_pre_sel[1],1'b0};
    wire    [PV-1   :   0]  avc_unavailable;
    wire    [PV-1   :   0]  avc_unavailable;
    genvar i;
    genvar i;
    generate
    generate
    for(i=0;i< PV;i=i+1) begin :all_vc_loop
    for(i=0;i< PV;i=i+1) begin :all_vc_loop
        localparam SW_LOC = ((i/V)<5)? i/V : LOCAL;
        localparam SW_LOC = ((i/V)<5)? i/V : LOCAL;
        mesh_torus_port_selector #(
        mesh_torus_port_selector #(
           .SW_LOC     (SW_LOC),
           .SW_LOC     (SW_LOC),
           .PPSw(PPSw)
           .PPSw(PPSw)
        )
        )
        the_portsel
        the_portsel
        (
        (
           .port_pre_sel       (port_pre_sel_perport[SW_LOC]),
           .port_pre_sel       (port_pre_sel_perport[SW_LOC]),
           .swap_port_presel   (swap_port_presel[i]),
           .swap_port_presel   (swap_port_presel[i]),
           .sel                (sel[i]),
           .sel                (sel[i]),
           .dest_port_in       (dest_port_coded_all[((i+1)*DSTPw)-1 : i*DSTPw]),
           .dest_port_in       (dest_port_coded_all[((i+1)*DSTPw)-1 : i*DSTPw]),
           .y_evc_forbiden     (y_evc_forbiden[i]),
           .y_evc_forbiden     (y_evc_forbiden[i]),
           .x_evc_forbiden     (x_evc_forbiden[i])
           .x_evc_forbiden     (x_evc_forbiden[i])
          );
          );
        mesh_tori_dspt_clear_gen #(
        mesh_tori_dspt_clear_gen #(
            .SSA_EN(SSA_EN),
            .SSA_EN(SSA_EN),
            .DSTPw(DSTPw),
            .DSTPw(DSTPw),
            .SW_LOC(SW_LOC)
            .SW_LOC(SW_LOC)
        )
        )
        dspt_clear_gen
        dspt_clear_gen
        (
        (
            .destport_clear(destport_clear_all[((i+1)*DSTPw)-1 : i*DSTPw]),
            .destport_clear(destport_clear_all[((i+1)*DSTPw)-1 : i*DSTPw]),
            .ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant[i]),
            .ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant[i]),
            .sel(sel[i]),
            .sel(sel[i]),
            .ssa_ivc_num_getting_ovc_grant(ssa_ivc_num_getting_ovc_grant_all[i])
            .ssa_ivc_num_getting_ovc_grant(ssa_ivc_num_getting_ovc_grant_all[i])
        );
        );
        /* 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 */
        assign avc_unavailable[i] = (masked_ovc_request_all [((i+1)*V)-1 : i*V] & ~ESCAP_VC_MASK) == {V{1'b0}};
        assign avc_unavailable[i] = (masked_ovc_request_all [((i+1)*V)-1 : i*V] & ~ESCAP_VC_MASK) == {V{1'b0}};
            mesh_torus_swap_port_presel_gen #(
            mesh_torus_swap_port_presel_gen #(
                .V(V),
                .V(V),
                .ESCAP_VC_MASK(ESCAP_VC_MASK),
                .ESCAP_VC_MASK(ESCAP_VC_MASK),
                .VC_NUM(i)
                .VC_NUM(i)
            )
            )
            the_swap_port_presel
            the_swap_port_presel
            (
            (
                .avc_unavailable(avc_unavailable[i]),
                .avc_unavailable(avc_unavailable[i]),
                .y_evc_forbiden(y_evc_forbiden[i]),
                .y_evc_forbiden(y_evc_forbiden[i]),
                .x_evc_forbiden(x_evc_forbiden[i]),
                .x_evc_forbiden(x_evc_forbiden[i]),
                .non_assigned_ovc_request(non_assigned_ovc_request_all[i]),
                .non_assigned_ovc_request(non_assigned_ovc_request_all[i]),
                .sel(sel[i]),
                .sel(sel[i]),
                .clk(clk),
                .clk(clk),
                .reset(reset),
                .reset(reset),
                .swap_port_presel(swap_port_presel[i])
                .swap_port_presel(swap_port_presel[i])
            );
            );
        end else begin : partial_adpt
        end else begin : partial_adpt
            assign swap_port_presel[i]=1'b0;
            assign swap_port_presel[i]=1'b0;
            assign avc_unavailable[i]=1'b0;
            assign avc_unavailable[i]=1'b0;
        end// ROUTE_TYPE
        end// ROUTE_TYPE
    end//for
    end//for
endgenerate
endgenerate
endmodule
endmodule
 
 

powered by: WebSVN 2.1.0

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