data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/chdr_crossbar_nxn.v
 line:139: before: "("
1: b'%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/chdr_crossbar_nxn.v:78: Cannot find include file: ../core/rfnoc_chdr_utils.vh\n  `include "../core/rfnoc_chdr_utils.vh" \n           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar,data/full_repos/permissive/214858095/../core/rfnoc_chdr_utils.vh\n             data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar,data/full_repos/permissive/214858095/../core/rfnoc_chdr_utils.vh.v\n             data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar,data/full_repos/permissive/214858095/../core/rfnoc_chdr_utils.vh.sv\n             ../core/rfnoc_chdr_utils.vh\n             ../core/rfnoc_chdr_utils.vh.v\n             ../core/rfnoc_chdr_utils.vh.sv\n             obj_dir/../core/rfnoc_chdr_utils.vh\n             obj_dir/../core/rfnoc_chdr_utils.vh.v\n             obj_dir/../core/rfnoc_chdr_utils.vh.sv\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/chdr_crossbar_nxn.v:79: Cannot find include file: ../core/rfnoc_chdr_internal_utils.vh\n  `include "../core/rfnoc_chdr_internal_utils.vh" \n           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: Exiting due to 2 error(s)\n'
module chdr_crossbar_nxn #(
  parameter [15:0] PROTOVER       = {8'd1, 8'd0},
  parameter        CHDR_W         = 64,
  parameter [7:0]  NPORTS         = 8,
  parameter [7:0]  DEFAULT_PORT   = 0,
  parameter        MTU            = 10,
  parameter        ROUTE_TBL_SIZE = 6,
  parameter        MUX_ALLOC      = "ROUND-ROBIN",
  parameter        OPTIMIZE       = "AREA",
  parameter [7:0]  NPORTS_MGMT    = NPORTS,
  parameter [0:0]  EXT_RTCFG_PORT = 0
) (
  input  wire                       clk,
  input  wire                       reset,

  input  wire [15:0]                device_id,

  input  wire [(CHDR_W*NPORTS)-1:0] s_axis_tdata,
  input  wire [NPORTS-1:0]          s_axis_tlast,
  input  wire [NPORTS-1:0]          s_axis_tvalid,
  output wire [NPORTS-1:0]          s_axis_tready,

  output wire [(CHDR_W*NPORTS)-1:0] m_axis_tdata,
  output wire [NPORTS-1:0]          m_axis_tlast,
  output wire [NPORTS-1:0]          m_axis_tvalid,
  input  wire [NPORTS-1:0]          m_axis_tready,

  input  wire                       ext_rtcfg_stb,
  input  wire [15:0]                ext_rtcfg_addr,
  input  wire [31:0]                ext_rtcfg_data,
  output wire                       ext_rtcfg_ack
);



  `include "../core/rfnoc_chdr_utils.vh"
  `include "../core/rfnoc_chdr_internal_utils.vh"

  localparam        NPORTS_W = $clog2(NPORTS);
  localparam        EPID_W   = 16;
  localparam [17:0] EXT_INFO = {1'b0, EXT_RTCFG_PORT, NPORTS_MGMT, NPORTS};

  localparam [0:0] PKT_ST_HEAD = 1'b0;
  localparam [0:0] PKT_ST_BODY = 1'b1;



  function [NPORTS_W-1:0] compute_mux_alloc;
    input [NPORTS-1:0] pkt_waiting;
    input [NPORTS_W-1:0] last_alloc;
    reg signed [NPORTS_W:0] i;
  begin
    compute_mux_alloc = last_alloc;
    for (i = NPORTS-1; i >= 0; i=i-1) begin
      if (MUX_ALLOC == "PRIO") begin

        if (pkt_waiting[i])
          compute_mux_alloc = i;
      end else begin

        if (pkt_waiting[(last_alloc + i + 1) % NPORTS])
          compute_mux_alloc = (last_alloc + i + 1) % NPORTS;
      end
    end
  end
  endfunction

  wire [NPORTS-1:0]            rtcfg_req_wr;
  wire [(16*NPORTS)-1:0]       rtcfg_req_addr;
  wire [(32*NPORTS)-1:0]       rtcfg_req_data;
  wire [NPORTS-1:0]            rtcfg_resp_ack;
  wire [(EPID_W*NPORTS)-1:0]   find_tdata;
  wire [NPORTS-1:0]            find_tvalid;
  wire [NPORTS-1:0]            find_tready;
  wire [(NPORTS_W*NPORTS)-1:0] result_tdata;
  wire [NPORTS-1:0]            result_tkeep;
  wire [NPORTS-1:0]            result_tvalid;
  wire [NPORTS-1:0]            result_tready;





  chdr_xb_routing_table #(
    .SIZE(ROUTE_TBL_SIZE), .NPORTS(NPORTS),
    .EXT_INS_PORT_EN(EXT_RTCFG_PORT)
  ) routing_tbl_i (
    .clk               (clk           ),
    .reset             (reset         ),
    .port_req_wr       (rtcfg_req_wr  ),
    .port_req_addr     (rtcfg_req_addr),
    .port_req_data     (rtcfg_req_data),
    .port_resp_ack     (rtcfg_resp_ack),
    .ext_req_wr        (ext_rtcfg_stb ),
    .ext_req_addr      (ext_rtcfg_addr),
    .ext_req_data      (ext_rtcfg_data),
    .ext_resp_ack      (ext_rtcfg_ack ),
    .axis_find_tdata   (find_tdata    ),
    .axis_find_tvalid  (find_tvalid   ),
    .axis_find_tready  (find_tready   ),
    .axis_result_tdata (result_tdata  ),
    .axis_result_tkeep (result_tkeep  ),
    .axis_result_tvalid(result_tvalid ),
    .axis_result_tready(result_tready )
  );

  wire [CHDR_W-1:0]          i_tdata   [0:NPORTS-1];
  wire [9:0]                 i_tdest   [0:NPORTS-1];
  wire [1:0]                 i_tid     [0:NPORTS-1];
  wire                       i_tlast   [0:NPORTS-1];
  wire                       i_tvalid  [0:NPORTS-1];
  wire                       i_tready  [0:NPORTS-1];
  wire [CHDR_W-1:0]          buf_tdata [0:NPORTS-1];
  wire [NPORTS_W-1:0]        buf_tdest [0:NPORTS-1], buf_tdest_tmp[0:NPORTS-1];
  wire                       buf_tkeep [0:NPORTS-1];
  wire                       buf_tlast [0:NPORTS-1];
  wire                       buf_tvalid[0:NPORTS-1];
  wire                       buf_tready[0:NPORTS-1];
  wire [CHDR_W-1:0]          swi_tdata [0:NPORTS-1];
  wire [NPORTS_W-1:0]        swi_tdest [0:NPORTS-1];
  wire                       swi_tlast [0:NPORTS-1];
  wire                       swi_tvalid[0:NPORTS-1];
  wire                       swi_tready[0:NPORTS-1];
  wire [(CHDR_W*NPORTS)-1:0] swo_tdata [0:NPORTS-1], muxi_tdata [0:NPORTS-1];
  wire [NPORTS-1:0]          swo_tlast [0:NPORTS-1], muxi_tlast [0:NPORTS-1];
  wire [NPORTS-1:0]          swo_tvalid[0:NPORTS-1], muxi_tvalid[0:NPORTS-1];
  wire [NPORTS-1:0]          swo_tready[0:NPORTS-1], muxi_tready[0:NPORTS-1];

  genvar n, i, j;
  generate
    for (n = 0; n < NPORTS; n = n + 1) begin: i_ports





      if (n < NPORTS_MGMT) begin
        chdr_mgmt_pkt_handler #(
          .PROTOVER(PROTOVER), .CHDR_W(CHDR_W), .MGMT_ONLY(0)
        ) mgmt_ep_i (
          .clk                (clk                                                              ),
          .rst                (reset                                                            ),
          .node_info          (chdr_mgmt_build_node_info(EXT_INFO, n, NODE_TYPE_XBAR, device_id)),
          .s_axis_chdr_tdata  (s_axis_tdata [(n*CHDR_W)+:CHDR_W]                                ),
          .s_axis_chdr_tlast  (s_axis_tlast [n]                                                 ),
          .s_axis_chdr_tvalid (s_axis_tvalid[n]                                                 ),
          .s_axis_chdr_tready (s_axis_tready[n]                                                 ),
          .s_axis_chdr_tuser  (1'd0                                                             ),
          .m_axis_chdr_tdata  (i_tdata      [n]                                                 ),
          .m_axis_chdr_tdest  (i_tdest      [n]                                                 ), 
          .m_axis_chdr_tid    (i_tid        [n]                                                 ),
          .m_axis_chdr_tlast  (i_tlast      [n]                                                 ),
          .m_axis_chdr_tvalid (i_tvalid     [n]                                                 ),
          .m_axis_chdr_tready (i_tready     [n]                                                 ),
          .ctrlport_req_wr    (rtcfg_req_wr [n]                                                 ),
          .ctrlport_req_rd    (),
          .ctrlport_req_addr  (rtcfg_req_addr[(n*16)+:16]                                       ),
          .ctrlport_req_data  (rtcfg_req_data[(n*32)+:32]                                       ),
          .ctrlport_resp_ack  (rtcfg_resp_ack[n]                                                ),
          .ctrlport_resp_data (32'h0),
          .op_stb             (),
          .op_dst_epid        (),
          .op_src_epid        (),
          .op_data            ()
        );
      end else begin
        assign i_tdata      [n] = s_axis_tdata [(n*CHDR_W)+:CHDR_W];
        assign i_tid        [n] = CHDR_MGMT_ROUTE_EPID;
        assign i_tdest      [n] = 10'd0;
        assign i_tlast      [n] = s_axis_tlast [n];
        assign i_tvalid     [n] = s_axis_tvalid[n];
        assign s_axis_tready[n] = i_tready     [n];

        assign rtcfg_req_wr  [n]          =  1'b0;
        assign rtcfg_req_addr[(n*16)+:16] = 16'h0;
        assign rtcfg_req_data[(n*32)+:32] = 32'h0;
      end




      chdr_xb_ingress_buff #(
        .WIDTH(CHDR_W), .MTU(MTU), .DEST_W(NPORTS_W), .NODE_ID(n)
      ) buf_i (
        .clk                 (clk                                  ),
        .reset               (reset                                ),
        .s_axis_chdr_tdata   (i_tdata      [n]                     ),
        .s_axis_chdr_tdest   (i_tdest      [n][NPORTS_W-1:0]       ),
        .s_axis_chdr_tid     (i_tid        [n]                     ),
        .s_axis_chdr_tlast   (i_tlast      [n]                     ),
        .s_axis_chdr_tvalid  (i_tvalid     [n]                     ),
        .s_axis_chdr_tready  (i_tready     [n]                     ),
        .m_axis_chdr_tdata   (buf_tdata    [n]                     ),
        .m_axis_chdr_tdest   (buf_tdest_tmp[n]                     ),
        .m_axis_chdr_tkeep   (buf_tkeep    [n]                     ),
        .m_axis_chdr_tlast   (buf_tlast    [n]                     ),
        .m_axis_chdr_tvalid  (buf_tvalid   [n]                     ),
        .m_axis_chdr_tready  (buf_tready   [n]                     ),
        .m_axis_find_tdata   (find_tdata   [(n*EPID_W)+:EPID_W]    ),
        .m_axis_find_tvalid  (find_tvalid  [n]                     ),
        .m_axis_find_tready  (find_tready  [n]                     ),
        .s_axis_result_tdata (result_tdata [(n*NPORTS_W)+:NPORTS_W]),
        .s_axis_result_tkeep (result_tkeep [n]                     ),
        .s_axis_result_tvalid(result_tvalid[n]                     ),
        .s_axis_result_tready(result_tready[n]                     )
      );
      assign buf_tdest[n] = buf_tkeep[n] ? buf_tdest_tmp[n] : DEFAULT_PORT[NPORTS_W-1:0];


      axi_fifo #(
        .WIDTH(CHDR_W+1+NPORTS_W), .SIZE(1)
      ) pipe_i (
        .clk      (clk                                       ), 
        .reset    (reset                                     ), 
        .clear    (1'b0                                      ),
        .i_tdata  ({buf_tlast[n], buf_tdest[n], buf_tdata[n]}),
        .i_tvalid (buf_tvalid[n]                             ),
        .i_tready (buf_tready[n]                             ),
        .o_tdata  ({swi_tlast[n], swi_tdest[n], swi_tdata[n]}),
        .o_tvalid (swi_tvalid[n]                             ),
        .o_tready (swi_tready[n]                             ),
        .space    (),
        .occupied ()
      );


      axis_switch #(
        .DATA_W(CHDR_W), .DEST_W(1), .IN_PORTS(1), .OUT_PORTS(NPORTS), .PIPELINE(1)
      ) demux_i (
        .clk           (clk                  ),
        .reset         (reset                ),
        .s_axis_tdata  (swi_tdata [n]        ),
        .s_axis_tdest  ({1'b0, swi_tdest [n]}), 
        .s_axis_tlast  (swi_tlast [n]        ),
        .s_axis_tvalid (swi_tvalid[n]        ),
        .s_axis_tready (swi_tready[n]        ),
        .s_axis_alloc  (1'b0                 ),
        .m_axis_tdata  (swo_tdata [n]        ),
        .m_axis_tdest  (),
        .m_axis_tlast  (swo_tlast [n]        ),
        .m_axis_tvalid (swo_tvalid[n]        ),
        .m_axis_tready (swo_tready[n]        )
      );
    end

    for (i = 0; i < NPORTS; i = i + 1) begin
      for (j = 0; j < NPORTS; j = j + 1) begin
        assign muxi_tdata [i][j*CHDR_W+:CHDR_W] = swo_tdata  [j][i*CHDR_W+:CHDR_W];
        assign muxi_tlast [i][j]                = swo_tlast  [j][i];
        assign muxi_tvalid[i][j]                = swo_tvalid [j][i];
        assign swo_tready [i][j]                = muxi_tready[j][i];
      end
    end

    for (n = 0; n < NPORTS; n = n + 1) begin: o_ports
      if (OPTIMIZE == "PERFORMANCE") begin





        wire mux_ready = |muxi_tready[n];
        wire mux_valid = |muxi_tvalid[n];
        wire mux_last  = |(muxi_tvalid[n] & muxi_tlast[n]);
  

        reg [0:0] pkt_state = PKT_ST_HEAD;
        always @(posedge clk) begin
          if (reset) begin
            pkt_state <= PKT_ST_HEAD;
          end else if (mux_valid & mux_ready) begin
            pkt_state <= mux_last ? PKT_ST_HEAD : PKT_ST_BODY;
          end
        end
  



        reg  [NPORTS_W-1:0] prev_sw_alloc = {NPORTS_W{1'b0}};
        reg  [NPORTS_W-1:0] pkt_sw_alloc  = {NPORTS_W{1'b0}};
        wire [NPORTS_W-1:0] muxi_sw_alloc = (mux_valid && pkt_state == PKT_ST_HEAD) ? 
          compute_mux_alloc(muxi_tvalid[n], prev_sw_alloc) : pkt_sw_alloc;
  
        always @(posedge clk) begin
          if (reset) begin
            prev_sw_alloc <= {NPORTS_W{1'b0}};
            pkt_sw_alloc <= {NPORTS_W{1'b0}};
          end else if (mux_valid & mux_ready) begin
            if (pkt_state == PKT_ST_HEAD)
              pkt_sw_alloc <= muxi_sw_alloc;
            if (mux_last)
              prev_sw_alloc <= muxi_sw_alloc;
          end
        end
  
        axis_switch #(
          .DATA_W(CHDR_W), .DEST_W(1), .IN_PORTS(NPORTS), .OUT_PORTS(1),
          .PIPELINE(0)
        ) mux_i (
          .clk           (clk                              ),
          .reset         (reset                            ),
          .s_axis_tdata  (muxi_tdata [n]                   ),
          .s_axis_tdest  ({NPORTS{1'b0}}),
          .s_axis_tlast  (muxi_tlast [n]                   ),
          .s_axis_tvalid (muxi_tvalid[n]                   ),
          .s_axis_tready (muxi_tready[n]                   ),
          .s_axis_alloc  (muxi_sw_alloc                    ),
          .m_axis_tdata  (m_axis_tdata [(n*CHDR_W)+:CHDR_W]),
          .m_axis_tdest  (),
          .m_axis_tlast  (m_axis_tlast [n]                 ),
          .m_axis_tvalid (m_axis_tvalid[n]                 ),
          .m_axis_tready (m_axis_tready[n]                 )
        );
      end else begin



        axi_mux #(
          .PRIO(MUX_ALLOC == "PRIO"), .WIDTH(CHDR_W), .SIZE(NPORTS),
          .PRE_FIFO_SIZE(OPTIMIZE == "TIMING" ? 1 : 0), .POST_FIFO_SIZE(1)
        ) mux_i (
          .clk      (clk                              ),
          .reset    (reset                            ),
          .clear    (1'b0                             ),
          .i_tdata  (muxi_tdata   [n]                 ),
          .i_tlast  (muxi_tlast   [n]                 ),
          .i_tvalid (muxi_tvalid  [n]                 ),
          .i_tready (muxi_tready  [n]                 ),
          .o_tdata  (m_axis_tdata [(n*CHDR_W)+:CHDR_W]),
          .o_tlast  (m_axis_tlast [n]                 ),
          .o_tvalid (m_axis_tvalid[n]                 ),
          .o_tready (m_axis_tready[n]                 )
        );
      end
    end
  endgenerate


endmodule
module chdr_crossbar_nxn #(
  parameter [15:0] PROTOVER       = {8'd1, 8'd0},
  parameter        CHDR_W         = 64,
  parameter [7:0]  NPORTS         = 8,
  parameter [7:0]  DEFAULT_PORT   = 0,
  parameter        MTU            = 10,
  parameter        ROUTE_TBL_SIZE = 6,
  parameter        MUX_ALLOC      = "ROUND-ROBIN",
  parameter        OPTIMIZE       = "AREA",
  parameter [7:0]  NPORTS_MGMT    = NPORTS,
  parameter [0:0]  EXT_RTCFG_PORT = 0
) (
  input  wire                       clk,
  input  wire                       reset,

  input  wire [15:0]                device_id,

  input  wire [(CHDR_W*NPORTS)-1:0] s_axis_tdata,
  input  wire [NPORTS-1:0]          s_axis_tlast,
  input  wire [NPORTS-1:0]          s_axis_tvalid,
  output wire [NPORTS-1:0]          s_axis_tready,

  output wire [(CHDR_W*NPORTS)-1:0] m_axis_tdata,
  output wire [NPORTS-1:0]          m_axis_tlast,
  output wire [NPORTS-1:0]          m_axis_tvalid,
  input  wire [NPORTS-1:0]          m_axis_tready,

  input  wire                       ext_rtcfg_stb,
  input  wire [15:0]                ext_rtcfg_addr,
  input  wire [31:0]                ext_rtcfg_data,
  output wire                       ext_rtcfg_ack
);




  `include "../core/rfnoc_chdr_utils.vh"
  `include "../core/rfnoc_chdr_internal_utils.vh"

  localparam        NPORTS_W = $clog2(NPORTS);
  localparam        EPID_W   = 16;
  localparam [17:0] EXT_INFO = {1'b0, EXT_RTCFG_PORT, NPORTS_MGMT, NPORTS};

  localparam [0:0] PKT_ST_HEAD = 1'b0;
  localparam [0:0] PKT_ST_BODY = 1'b1;



  function [NPORTS_W-1:0] compute_mux_alloc;
    input [NPORTS-1:0] pkt_waiting;
    input [NPORTS_W-1:0] last_alloc;
    reg signed [NPORTS_W:0] i;
  begin
    compute_mux_alloc = last_alloc;
    for (i = NPORTS-1; i >= 0; i=i-1) begin
      if (MUX_ALLOC == "PRIO") begin

        if (pkt_waiting[i])
          compute_mux_alloc = i;
      end else begin

        if (pkt_waiting[(last_alloc + i + 1) % NPORTS])
          compute_mux_alloc = (last_alloc + i + 1) % NPORTS;
      end
    end
  end
  endfunction

  wire [NPORTS-1:0]            rtcfg_req_wr;
  wire [(16*NPORTS)-1:0]       rtcfg_req_addr;
  wire [(32*NPORTS)-1:0]       rtcfg_req_data;
  wire [NPORTS-1:0]            rtcfg_resp_ack;
  wire [(EPID_W*NPORTS)-1:0]   find_tdata;
  wire [NPORTS-1:0]            find_tvalid;
  wire [NPORTS-1:0]            find_tready;
  wire [(NPORTS_W*NPORTS)-1:0] result_tdata;
  wire [NPORTS-1:0]            result_tkeep;
  wire [NPORTS-1:0]            result_tvalid;
  wire [NPORTS-1:0]            result_tready;





  chdr_xb_routing_table #(
    .SIZE(ROUTE_TBL_SIZE), .NPORTS(NPORTS),
    .EXT_INS_PORT_EN(EXT_RTCFG_PORT)
  ) routing_tbl_i (
    .clk               (clk           ),
    .reset             (reset         ),
    .port_req_wr       (rtcfg_req_wr  ),
    .port_req_addr     (rtcfg_req_addr),
    .port_req_data     (rtcfg_req_data),
    .port_resp_ack     (rtcfg_resp_ack),
    .ext_req_wr        (ext_rtcfg_stb ),
    .ext_req_addr      (ext_rtcfg_addr),
    .ext_req_data      (ext_rtcfg_data),
    .ext_resp_ack      (ext_rtcfg_ack ),
    .axis_find_tdata   (find_tdata    ),
    .axis_find_tvalid  (find_tvalid   ),
    .axis_find_tready  (find_tready   ),
    .axis_result_tdata (result_tdata  ),
    .axis_result_tkeep (result_tkeep  ),
    .axis_result_tvalid(result_tvalid ),
    .axis_result_tready(result_tready )
  );

  wire [CHDR_W-1:0]          i_tdata   [0:NPORTS-1];
  wire [9:0]                 i_tdest   [0:NPORTS-1];
  wire [1:0]                 i_tid     [0:NPORTS-1];
  wire                       i_tlast   [0:NPORTS-1];
  wire                       i_tvalid  [0:NPORTS-1];
  wire                       i_tready  [0:NPORTS-1];
  wire [CHDR_W-1:0]          buf_tdata [0:NPORTS-1];
  wire [NPORTS_W-1:0]        buf_tdest [0:NPORTS-1], buf_tdest_tmp[0:NPORTS-1];
  wire                       buf_tkeep [0:NPORTS-1];
  wire                       buf_tlast [0:NPORTS-1];
  wire                       buf_tvalid[0:NPORTS-1];
  wire                       buf_tready[0:NPORTS-1];
  wire [CHDR_W-1:0]          swi_tdata [0:NPORTS-1];
  wire [NPORTS_W-1:0]        swi_tdest [0:NPORTS-1];
  wire                       swi_tlast [0:NPORTS-1];
  wire                       swi_tvalid[0:NPORTS-1];
  wire                       swi_tready[0:NPORTS-1];
  wire [(CHDR_W*NPORTS)-1:0] swo_tdata [0:NPORTS-1], muxi_tdata [0:NPORTS-1];
  wire [NPORTS-1:0]          swo_tlast [0:NPORTS-1], muxi_tlast [0:NPORTS-1];
  wire [NPORTS-1:0]          swo_tvalid[0:NPORTS-1], muxi_tvalid[0:NPORTS-1];
  wire [NPORTS-1:0]          swo_tready[0:NPORTS-1], muxi_tready[0:NPORTS-1];

  genvar n, i, j;
  generate
    for (n = 0; n < NPORTS; n = n + 1) begin: i_ports





      if (n < NPORTS_MGMT) begin
        chdr_mgmt_pkt_handler #(
          .PROTOVER(PROTOVER), .CHDR_W(CHDR_W), .MGMT_ONLY(0)
        ) mgmt_ep_i (
          .clk                (clk                                                              ),
          .rst                (reset                                                            ),
          .node_info          (chdr_mgmt_build_node_info(EXT_INFO, n, NODE_TYPE_XBAR, device_id)),
          .s_axis_chdr_tdata  (s_axis_tdata [(n*CHDR_W)+:CHDR_W]                                ),
          .s_axis_chdr_tlast  (s_axis_tlast [n]                                                 ),
          .s_axis_chdr_tvalid (s_axis_tvalid[n]                                                 ),
          .s_axis_chdr_tready (s_axis_tready[n]                                                 ),
          .s_axis_chdr_tuser  (1'd0                                                             ),
          .m_axis_chdr_tdata  (i_tdata      [n]                                                 ),
          .m_axis_chdr_tdest  (i_tdest      [n]                                                 ), 
          .m_axis_chdr_tid    (i_tid        [n]                                                 ),
          .m_axis_chdr_tlast  (i_tlast      [n]                                                 ),
          .m_axis_chdr_tvalid (i_tvalid     [n]                                                 ),
          .m_axis_chdr_tready (i_tready     [n]                                                 ),
          .ctrlport_req_wr    (rtcfg_req_wr [n]                                                 ),
          .ctrlport_req_rd    (),
          .ctrlport_req_addr  (rtcfg_req_addr[(n*16)+:16]                                       ),
          .ctrlport_req_data  (rtcfg_req_data[(n*32)+:32]                                       ),
          .ctrlport_resp_ack  (rtcfg_resp_ack[n]                                                ),
          .ctrlport_resp_data (32'h0),
          .op_stb             (),
          .op_dst_epid        (),
          .op_src_epid        (),
          .op_data            ()
        );
      end else begin
        assign i_tdata      [n] = s_axis_tdata [(n*CHDR_W)+:CHDR_W];
        assign i_tid        [n] = CHDR_MGMT_ROUTE_EPID;
        assign i_tdest      [n] = 10'd0;
        assign i_tlast      [n] = s_axis_tlast [n];
        assign i_tvalid     [n] = s_axis_tvalid[n];
        assign s_axis_tready[n] = i_tready     [n];

        assign rtcfg_req_wr  [n]          =  1'b0;
        assign rtcfg_req_addr[(n*16)+:16] = 16'h0;
        assign rtcfg_req_data[(n*32)+:32] = 32'h0;
      end




      chdr_xb_ingress_buff #(
        .WIDTH(CHDR_W), .MTU(MTU), .DEST_W(NPORTS_W), .NODE_ID(n)
      ) buf_i (
        .clk                 (clk                                  ),
        .reset               (reset                                ),
        .s_axis_chdr_tdata   (i_tdata      [n]                     ),
        .s_axis_chdr_tdest   (i_tdest      [n][NPORTS_W-1:0]       ),
        .s_axis_chdr_tid     (i_tid        [n]                     ),
        .s_axis_chdr_tlast   (i_tlast      [n]                     ),
        .s_axis_chdr_tvalid  (i_tvalid     [n]                     ),
        .s_axis_chdr_tready  (i_tready     [n]                     ),
        .m_axis_chdr_tdata   (buf_tdata    [n]                     ),
        .m_axis_chdr_tdest   (buf_tdest_tmp[n]                     ),
        .m_axis_chdr_tkeep   (buf_tkeep    [n]                     ),
        .m_axis_chdr_tlast   (buf_tlast    [n]                     ),
        .m_axis_chdr_tvalid  (buf_tvalid   [n]                     ),
        .m_axis_chdr_tready  (buf_tready   [n]                     ),
        .m_axis_find_tdata   (find_tdata   [(n*EPID_W)+:EPID_W]    ),
        .m_axis_find_tvalid  (find_tvalid  [n]                     ),
        .m_axis_find_tready  (find_tready  [n]                     ),
        .s_axis_result_tdata (result_tdata [(n*NPORTS_W)+:NPORTS_W]),
        .s_axis_result_tkeep (result_tkeep [n]                     ),
        .s_axis_result_tvalid(result_tvalid[n]                     ),
        .s_axis_result_tready(result_tready[n]                     )
      );
      assign buf_tdest[n] = buf_tkeep[n] ? buf_tdest_tmp[n] : DEFAULT_PORT[NPORTS_W-1:0];


      axi_fifo #(
        .WIDTH(CHDR_W+1+NPORTS_W), .SIZE(1)
      ) pipe_i (
        .clk      (clk                                       ), 
        .reset    (reset                                     ), 
        .clear    (1'b0                                      ),
        .i_tdata  ({buf_tlast[n], buf_tdest[n], buf_tdata[n]}),
        .i_tvalid (buf_tvalid[n]                             ),
        .i_tready (buf_tready[n]                             ),
        .o_tdata  ({swi_tlast[n], swi_tdest[n], swi_tdata[n]}),
        .o_tvalid (swi_tvalid[n]                             ),
        .o_tready (swi_tready[n]                             ),
        .space    (),
        .occupied ()
      );


      axis_switch #(
        .DATA_W(CHDR_W), .DEST_W(1), .IN_PORTS(1), .OUT_PORTS(NPORTS), .PIPELINE(1)
      ) demux_i (
        .clk           (clk                  ),
        .reset         (reset                ),
        .s_axis_tdata  (swi_tdata [n]        ),
        .s_axis_tdest  ({1'b0, swi_tdest [n]}), 
        .s_axis_tlast  (swi_tlast [n]        ),
        .s_axis_tvalid (swi_tvalid[n]        ),
        .s_axis_tready (swi_tready[n]        ),
        .s_axis_alloc  (1'b0                 ),
        .m_axis_tdata  (swo_tdata [n]        ),
        .m_axis_tdest  (),
        .m_axis_tlast  (swo_tlast [n]        ),
        .m_axis_tvalid (swo_tvalid[n]        ),
        .m_axis_tready (swo_tready[n]        )
      );
    end

    for (i = 0; i < NPORTS; i = i + 1) begin
      for (j = 0; j < NPORTS; j = j + 1) begin
        assign muxi_tdata [i][j*CHDR_W+:CHDR_W] = swo_tdata  [j][i*CHDR_W+:CHDR_W];
        assign muxi_tlast [i][j]                = swo_tlast  [j][i];
        assign muxi_tvalid[i][j]                = swo_tvalid [j][i];
        assign swo_tready [i][j]                = muxi_tready[j][i];
      end
    end

    for (n = 0; n < NPORTS; n = n + 1) begin: o_ports
      if (OPTIMIZE == "PERFORMANCE") begin





        wire mux_ready = |muxi_tready[n];
        wire mux_valid = |muxi_tvalid[n];
        wire mux_last  = |(muxi_tvalid[n] & muxi_tlast[n]);
  

        reg [0:0] pkt_state = PKT_ST_HEAD;
        always @(posedge clk) begin
          if (reset) begin
            pkt_state <= PKT_ST_HEAD;
          end else if (mux_valid & mux_ready) begin
            pkt_state <= mux_last ? PKT_ST_HEAD : PKT_ST_BODY;
          end
        end
  



        reg  [NPORTS_W-1:0] prev_sw_alloc = {NPORTS_W{1'b0}};
        reg  [NPORTS_W-1:0] pkt_sw_alloc  = {NPORTS_W{1'b0}};
        wire [NPORTS_W-1:0] muxi_sw_alloc = (mux_valid && pkt_state == PKT_ST_HEAD) ? 
          compute_mux_alloc(muxi_tvalid[n], prev_sw_alloc) : pkt_sw_alloc;
  
        always @(posedge clk) begin
          if (reset) begin
            prev_sw_alloc <= {NPORTS_W{1'b0}};
            pkt_sw_alloc <= {NPORTS_W{1'b0}};
          end else if (mux_valid & mux_ready) begin
            if (pkt_state == PKT_ST_HEAD)
              pkt_sw_alloc <= muxi_sw_alloc;
            if (mux_last)
              prev_sw_alloc <= muxi_sw_alloc;
          end
        end
  
        axis_switch #(
          .DATA_W(CHDR_W), .DEST_W(1), .IN_PORTS(NPORTS), .OUT_PORTS(1),
          .PIPELINE(0)
        ) mux_i (
          .clk           (clk                              ),
          .reset         (reset                            ),
          .s_axis_tdata  (muxi_tdata [n]                   ),
          .s_axis_tdest  ({NPORTS{1'b0}}),
          .s_axis_tlast  (muxi_tlast [n]                   ),
          .s_axis_tvalid (muxi_tvalid[n]                   ),
          .s_axis_tready (muxi_tready[n]                   ),
          .s_axis_alloc  (muxi_sw_alloc                    ),
          .m_axis_tdata  (m_axis_tdata [(n*CHDR_W)+:CHDR_W]),
          .m_axis_tdest  (),
          .m_axis_tlast  (m_axis_tlast [n]                 ),
          .m_axis_tvalid (m_axis_tvalid[n]                 ),
          .m_axis_tready (m_axis_tready[n]                 )
        );
      end else begin



        axi_mux #(
          .PRIO(MUX_ALLOC == "PRIO"), .WIDTH(CHDR_W), .SIZE(NPORTS),
          .PRE_FIFO_SIZE(OPTIMIZE == "TIMING" ? 1 : 0), .POST_FIFO_SIZE(1)
        ) mux_i (
          .clk      (clk                              ),
          .reset    (reset                            ),
          .clear    (1'b0                             ),
          .i_tdata  (muxi_tdata   [n]                 ),
          .i_tlast  (muxi_tlast   [n]                 ),
          .i_tvalid (muxi_tvalid  [n]                 ),
          .i_tready (muxi_tready  [n]                 ),
          .o_tdata  (m_axis_tdata [(n*CHDR_W)+:CHDR_W]),
          .o_tlast  (m_axis_tlast [n]                 ),
          .o_tvalid (m_axis_tvalid[n]                 ),
          .o_tready (m_axis_tready[n]                 )
        );
      end
    end
  endgenerate


endmodule