data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/core/chdr_mgmt_pkt_handler.v
 line:47 column:4: Illegal character '\x00'
1: b'%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/core/chdr_mgmt_pkt_handler.v:82: Cannot find include file: rfnoc_chdr_utils.vh\n  `include "rfnoc_chdr_utils.vh" \n           ^~~~~~~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/core,data/full_repos/permissive/214858095/rfnoc_chdr_utils.vh\n             data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/core,data/full_repos/permissive/214858095/rfnoc_chdr_utils.vh.v\n             data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/core,data/full_repos/permissive/214858095/rfnoc_chdr_utils.vh.sv\n             rfnoc_chdr_utils.vh\n             rfnoc_chdr_utils.vh.v\n             rfnoc_chdr_utils.vh.sv\n             obj_dir/rfnoc_chdr_utils.vh\n             obj_dir/rfnoc_chdr_utils.vh.v\n             obj_dir/rfnoc_chdr_utils.vh.sv\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/core/chdr_mgmt_pkt_handler.v:83: Cannot find include file: rfnoc_chdr_internal_utils.vh\n  `include "rfnoc_chdr_internal_utils.vh" \n           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: Exiting due to 2 error(s)\n'
module chdr_mgmt_pkt_handler #(
  parameter [15:0] PROTOVER       = {8'd1, 8'd0},
  parameter        CHDR_W         = 256,
  parameter        USER_W         = 1,
  parameter [0:0]  MGMT_ONLY      = 0,
  parameter        RESP_FIFO_SIZE = 5
)(

  input  wire              clk,
  input  wire              rst,

  input  wire [47:0]       node_info,

  input  wire [CHDR_W-1:0] s_axis_chdr_tdata,
  input  wire              s_axis_chdr_tlast,
  input  wire              s_axis_chdr_tvalid,
  output wire              s_axis_chdr_tready,
  input  wire [USER_W-1:0] s_axis_chdr_tuser,

  output wire [CHDR_W-1:0] m_axis_chdr_tdata,
  output wire [1:0]        m_axis_chdr_tid,
  output wire [9:0]        m_axis_chdr_tdest,
  output wire              m_axis_chdr_tlast,
  output wire              m_axis_chdr_tvalid,
  input  wire              m_axis_chdr_tready,

  output reg               ctrlport_req_wr,
  output reg               ctrlport_req_rd,
  output reg  [15:0]       ctrlport_req_addr,
  output reg  [31:0]       ctrlport_req_data,
  input  wire              ctrlport_resp_ack,
  input  wire [31:0]       ctrlport_resp_data,

  output wire [USER_W-1:0] op_data,
  output wire              op_stb,
  output wire [15:0]       op_dst_epid,
  output wire [15:0]       op_src_epid
);




  `include "rfnoc_chdr_utils.vh"
  `include "rfnoc_chdr_internal_utils.vh"






  localparam CHDR_W_BYTES = CHDR_W / 8;
  localparam LOG2_CHDR_W_BYTES = $clog2(CHDR_W_BYTES);

  wire [CHDR_W-1:0] s_mgmt_tdata, m_mgmt_tdata;
  wire [USER_W-1:0] s_mgmt_tuser;
  wire [9:0]        m_mgmt_tdest;
  wire [1:0]        m_mgmt_tid;
  wire              s_mgmt_tlast, s_mgmt_tvalid, s_mgmt_tready;
  wire              m_mgmt_tlast, m_mgmt_tvalid, m_mgmt_tready;

  generate if (!MGMT_ONLY) begin : gen_not_mgmt_only



    wire [CHDR_W-1:0] bypass_tdata;
    wire [9:0]        bypass_tdest;
    wire [1:0]        bypass_tid;
    wire              bypass_tlast, bypass_tvalid, bypass_tready;
    wire [CHDR_W-1:0] s_header;




    wire consume_mgmt_pkt = (chdr_get_pkt_type(s_header[63:0]) == CHDR_PKT_TYPE_MGMT) &&
                            (chdr_get_dst_epid(s_header[63:0]) == NULL_EPID);

    axi_demux #(
      .WIDTH(CHDR_W), .SIZE(2), .PRE_FIFO_SIZE(1), .POST_FIFO_SIZE(0)
    ) mgmt_demux_i (
      .clk(clk), .reset(rst), .clear(1'b0),
      .header(s_header), .dest(consume_mgmt_pkt ? 1'b1 : 1'b0),
      .i_tdata(s_axis_chdr_tdata), .i_tlast(s_axis_chdr_tlast),
      .i_tvalid(s_axis_chdr_tvalid), .i_tready(s_axis_chdr_tready),
      .o_tdata({s_mgmt_tdata, bypass_tdata}), .o_tlast({s_mgmt_tlast, bypass_tlast}),
      .o_tvalid({s_mgmt_tvalid, bypass_tvalid}), .o_tready({s_mgmt_tready, bypass_tready})
    );



    assign s_mgmt_tuser               = s_axis_chdr_tuser;

    assign {bypass_tid, bypass_tdest} = {CHDR_MGMT_ROUTE_EPID, 10'h0};

    axi_mux #(
      .WIDTH(CHDR_W+10+2), .SIZE(2), .PRE_FIFO_SIZE(0), .POST_FIFO_SIZE(1)
    ) mgmt_mux_i (
      .clk(clk), .reset(rst), .clear(1'b0),
      .i_tdata({m_mgmt_tid, m_mgmt_tdest, m_mgmt_tdata, bypass_tid, bypass_tdest, bypass_tdata}),
      .i_tlast({m_mgmt_tlast, bypass_tlast}),
      .i_tvalid({m_mgmt_tvalid, bypass_tvalid}), .i_tready({m_mgmt_tready, bypass_tready}),
      .o_tdata({m_axis_chdr_tid, m_axis_chdr_tdest, m_axis_chdr_tdata}),
      .o_tlast(m_axis_chdr_tlast),
      .o_tvalid(m_axis_chdr_tvalid), .o_tready(m_axis_chdr_tready)
    );
  end else begin : gen_mgmt_only


    assign s_mgmt_tdata       = s_axis_chdr_tdata;
    assign s_mgmt_tlast       = s_axis_chdr_tlast;
    assign s_mgmt_tvalid      = s_axis_chdr_tvalid;
    assign s_mgmt_tuser       = s_axis_chdr_tuser;
    assign s_axis_chdr_tready = s_mgmt_tready;

    assign m_axis_chdr_tdata  = m_mgmt_tdata;
    assign m_axis_chdr_tdest  = m_mgmt_tdest;
    assign m_axis_chdr_tid    = m_mgmt_tid;
    assign m_axis_chdr_tlast  = m_mgmt_tlast;
    assign m_axis_chdr_tvalid = m_mgmt_tvalid;
    assign m_mgmt_tready      = m_axis_chdr_tready;
  end endgenerate





  wire [63:0]       i64_tdata;
  wire [USER_W-1:0] i64_tuser;
  wire              i64_tlast, i64_tvalid;
  reg               i64_tready;
  reg [63:0]        o64_tdata;
  reg [9:0]         o64_tdest;
  reg [1:0]         o64_tid;
  reg               o64_tlast, o64_tvalid;
  wire              o64_tready;

  axi_fifo #(.WIDTH(USER_W+65), .SIZE(1)) in_flop_i (
    .clk(clk), .reset(rst), .clear(1'b0),
    .i_tdata({s_mgmt_tuser, s_mgmt_tlast, s_mgmt_tdata[63:0]}),
    .i_tvalid(s_mgmt_tvalid), .i_tready(s_mgmt_tready),
    .o_tdata({i64_tuser, i64_tlast, i64_tdata}),
    .o_tvalid(i64_tvalid), .o_tready(i64_tready),
    .space(), .occupied()
  );

  axi_fifo #(.WIDTH(64+10+2+1), .SIZE(1)) out_flop_i (
    .clk(clk), .reset(rst), .clear(1'b0),
    .i_tdata({o64_tlast, o64_tdest, o64_tid, o64_tdata}),
    .i_tvalid(o64_tvalid), .i_tready(o64_tready),
    .o_tdata({m_mgmt_tlast, m_mgmt_tdest, m_mgmt_tid, m_mgmt_tdata[63:0]}),
    .o_tvalid(m_mgmt_tvalid), .o_tready(m_mgmt_tready),
    .space(), .occupied()
  );

  generate
    if (CHDR_W > 64) begin : gen_upper_mgmt_tdata
      assign m_mgmt_tdata[CHDR_W-1:64] = 'h0;
    end
  endgenerate




  localparam [3:0] ST_CHDR_IN_HDR     = 4'd0;
  localparam [3:0] ST_CHDR_IN_MDATA   = 4'd1;
  localparam [3:0] ST_MGMT_IN_HDR     = 4'd2;
  localparam [3:0] ST_MGMT_OP_EXEC    = 4'd3;
  localparam [3:0] ST_MGMT_OP_WAIT    = 4'd4;
  localparam [3:0] ST_MGMT_OP_DONE    = 4'd5;
  localparam [3:0] ST_CHDR_OUT_HDR    = 4'd6;
  localparam [3:0] ST_MGMT_OUT_HDR    = 4'd7;
  localparam [3:0] ST_PASS_PAYLOAD    = 4'd8;
  localparam [3:0] ST_MOD_LAST_HOP    = 4'd9;
  localparam [3:0] ST_POP_RESPONSE    = 4'd10;
  localparam [3:0] ST_APPEND_LAST_HOP = 4'd11;
  localparam [3:0] ST_FAILSAFE_DROP   = 4'd12;


  reg [3:0]  pkt_state = ST_CHDR_IN_HDR;
  reg [4:0]  num_mdata;
  reg [63:0] cached_chdr_hdr, cached_mgmt_hdr;
  reg [15:0] stripped_len;
  reg [9:0]  hops_remaining;
  reg [7:0]  resp_op_code;
  reg [47:0] resp_op_payload;
  reg [USER_W-1:0] cached_tuser;


  wire [7:0]  op_code = chdr_mgmt_get_op_code(i64_tdata);
  wire [47:0] op_payload = chdr_mgmt_get_op_payload(i64_tdata);


  wire [55:0] resp_i_tdata, resp_o_tdata;
  wire        resp_i_tvalid, resp_o_tvalid;
  wire [7:0]  num_resp_pending;



  always @(posedge clk) begin
    if (rst) begin


      pkt_state <= ST_CHDR_IN_HDR;
    end else begin
      case (pkt_state)






        ST_CHDR_IN_HDR: begin
          if (i64_tvalid && i64_tready) begin
            cached_chdr_hdr <= i64_tdata;
            cached_tuser <= i64_tuser;
            stripped_len <= chdr_get_length(i64_tdata);
            num_mdata <= chdr_get_num_mdata(i64_tdata) - 5'd1;
            if (!i64_tlast) begin
              if (chdr_get_pkt_type(i64_tdata) != CHDR_PKT_TYPE_MGMT)
                pkt_state <= ST_FAILSAFE_DROP;
              else if (chdr_get_num_mdata(i64_tdata) != CHDR_NO_MDATA)
                pkt_state <= ST_CHDR_IN_MDATA;
              else
                pkt_state <= ST_MGMT_IN_HDR;
            end else begin
              pkt_state <= ST_CHDR_IN_HDR;
            end
          end
        end




        ST_CHDR_IN_MDATA: begin
          if (i64_tvalid && i64_tready) begin
            num_mdata <= num_mdata - 5'd1;
            if (!i64_tlast)
              pkt_state <= (num_mdata == CHDR_NO_MDATA) ? ST_MGMT_IN_HDR : ST_CHDR_IN_MDATA;
            else
              pkt_state <= ST_CHDR_IN_HDR;
          end
        end






        ST_MGMT_IN_HDR: begin
          if (i64_tvalid && i64_tready) begin
            cached_mgmt_hdr <= i64_tdata;
            hops_remaining <= chdr_mgmt_get_num_hops(i64_tdata);
            pkt_state <= (!i64_tlast) ? ST_MGMT_OP_EXEC : ST_CHDR_IN_HDR;
          end
        end





        ST_MGMT_OP_EXEC: begin
          if (i64_tvalid) begin


            o64_tid   <= CHDR_MGMT_ROUTE_EPID;
            o64_tdest <= 10'd0;
            case (op_code)

              CHDR_MGMT_OP_NOP: begin

                pkt_state <= ST_MGMT_OP_DONE;
              end

              CHDR_MGMT_OP_ADVERTISE: begin

                pkt_state <= ST_MGMT_OP_DONE;
              end

              CHDR_MGMT_OP_SEL_DEST: begin
                o64_tid   <= CHDR_MGMT_ROUTE_TDEST;
                o64_tdest <= chdr_mgmt_sel_dest_get_tdest(op_payload);
                pkt_state <= ST_MGMT_OP_DONE;
              end

              CHDR_MGMT_OP_RETURN: begin
                o64_tid   <= CHDR_MGMT_RETURN_TO_SRC;
                pkt_state <= ST_MGMT_OP_DONE;
              end


              CHDR_MGMT_OP_INFO_REQ: begin
                pkt_state <= ST_MGMT_OP_DONE;
              end


              CHDR_MGMT_OP_INFO_RESP: begin
                pkt_state <= ST_MGMT_OP_DONE;
              end

              CHDR_MGMT_OP_CFG_WR_REQ: begin

                pkt_state <= ST_MGMT_OP_WAIT;
              end

              CHDR_MGMT_OP_CFG_RD_REQ: begin

                pkt_state <= ST_MGMT_OP_WAIT;
              end


              CHDR_MGMT_OP_CFG_RD_RESP: begin
                pkt_state <= ST_MGMT_OP_DONE;
              end
              default: begin

                pkt_state <= ST_CHDR_IN_HDR;
              end
            endcase
          end
        end




        ST_MGMT_OP_WAIT: begin
          if (i64_tvalid) begin
            if (op_code == CHDR_MGMT_OP_CFG_WR_REQ ||
                op_code == CHDR_MGMT_OP_CFG_RD_REQ) begin

              if (ctrlport_resp_ack) begin
                pkt_state <= ST_MGMT_OP_DONE;
              end
            end else begin

              pkt_state <= ST_MGMT_OP_DONE;
            end
          end
        end





        ST_MGMT_OP_DONE: begin
          if (i64_tvalid && i64_tready) begin
            if (!i64_tlast) begin

              stripped_len <= stripped_len - CHDR_W_BYTES;


              if (chdr_mgmt_get_ops_pending(i64_tdata) == 8'd0) begin
                hops_remaining <= hops_remaining - 10'd1;
                pkt_state <= ST_CHDR_OUT_HDR;
              end else begin
                pkt_state <= ST_MGMT_OP_EXEC;
              end
            end else begin


              pkt_state <= ST_CHDR_IN_HDR;
            end
          end
        end




        ST_CHDR_OUT_HDR: begin
          if (o64_tvalid && o64_tready)
            pkt_state <= ST_MGMT_OUT_HDR;
        end




        ST_MGMT_OUT_HDR: begin
          if (o64_tvalid && o64_tready)
            if (resp_o_tvalid && (hops_remaining == 10'd1))
              pkt_state <= ST_MOD_LAST_HOP;
            else
              pkt_state <= ST_PASS_PAYLOAD;
        end




        ST_PASS_PAYLOAD: begin
          if (o64_tvalid && o64_tready) begin
            if (!i64_tlast) begin




              if (chdr_mgmt_get_ops_pending(i64_tdata) == 8'd0) begin
                hops_remaining <= hops_remaining - 10'd1;
                if (resp_o_tvalid && (hops_remaining == 10'd1))
                  pkt_state <= ST_MOD_LAST_HOP;
                else
                  pkt_state <= ST_PASS_PAYLOAD;
              end else begin
                pkt_state <= ST_PASS_PAYLOAD;
              end
            end else begin
              pkt_state <= ST_CHDR_IN_HDR;
            end
          end
        end








        ST_MOD_LAST_HOP: begin
          if (o64_tvalid && o64_tready) begin

            if (chdr_mgmt_get_ops_pending(i64_tdata) == 8'd0) begin
              if (resp_o_tvalid)
                pkt_state <= ST_POP_RESPONSE;
              else
                pkt_state <= i64_tlast ? ST_CHDR_IN_HDR : ST_FAILSAFE_DROP;
            end
          end
        end




        ST_POP_RESPONSE: begin
          if (resp_o_tvalid) begin
            resp_op_code <= resp_o_tdata[7:0];
            resp_op_payload <= resp_o_tdata[55:8];
            pkt_state <= ST_APPEND_LAST_HOP;
          end
        end





        ST_APPEND_LAST_HOP: begin
          if (o64_tvalid && o64_tready)
            pkt_state <= resp_o_tvalid ? ST_POP_RESPONSE : ST_CHDR_IN_HDR;
        end




        ST_FAILSAFE_DROP: begin
          if (i64_tvalid && i64_tready)
            pkt_state <= i64_tlast ? ST_CHDR_IN_HDR : ST_FAILSAFE_DROP;
        end

        default: begin

          pkt_state <= ST_CHDR_IN_HDR;
        end
      endcase
    end
  end


  always @(*) begin
    case (pkt_state)
      ST_CHDR_IN_HDR:
        i64_tready = 1'b1;
      ST_CHDR_IN_MDATA:
        i64_tready = 1'b1;
      ST_MGMT_IN_HDR:
        i64_tready = 1'b1;
      ST_MGMT_OP_DONE:
        i64_tready = 1'b1;
      ST_PASS_PAYLOAD:
        i64_tready = o64_tready;
      ST_MOD_LAST_HOP:
        i64_tready = o64_tready;
      ST_FAILSAFE_DROP:
        i64_tready = 1'b1;
      default:
        i64_tready = 1'b0;
    endcase
  end


  wire [15:0] o64_dst_epid = (o64_tid == CHDR_MGMT_RETURN_TO_SRC) ?
    chdr_mgmt_get_src_epid(cached_mgmt_hdr) : chdr_get_dst_epid(cached_chdr_hdr);
  wire [15:0] o64_src_epid = (o64_tid == CHDR_MGMT_RETURN_TO_SRC) ?
    chdr_get_dst_epid(cached_chdr_hdr) : chdr_mgmt_get_src_epid(cached_mgmt_hdr);


  always @(*) begin
    case (pkt_state)
      ST_CHDR_OUT_HDR: begin


        o64_tdata  = chdr_set_length(
          chdr_set_dst_epid(cached_chdr_hdr, o64_dst_epid),
          (stripped_len + (num_resp_pending << LOG2_CHDR_W_BYTES)));
        o64_tvalid = 1'b1;
        o64_tlast  = 1'b0;
      end
      ST_MGMT_OUT_HDR: begin


        o64_tdata  = chdr_mgmt_build_hdr(PROTOVER, chdr_w_to_enum(CHDR_W),
          chdr_mgmt_get_num_hops(cached_mgmt_hdr) - 10'd1, o64_src_epid);
        o64_tvalid = 1'b1;
        o64_tlast  = 1'b0;
      end
      ST_PASS_PAYLOAD: begin

        o64_tdata  = i64_tdata;
        o64_tvalid = i64_tvalid;
        o64_tlast  = i64_tlast;
      end
      ST_MOD_LAST_HOP: begin

        o64_tdata  = chdr_mgmt_build_op(chdr_mgmt_get_op_payload(i64_tdata),
          chdr_mgmt_get_op_code(i64_tdata),
          chdr_mgmt_get_ops_pending(i64_tdata) + num_resp_pending);
        o64_tvalid = i64_tvalid;
        o64_tlast  = i64_tlast && !resp_o_tvalid;
      end
      ST_APPEND_LAST_HOP: begin

        o64_tdata  = chdr_mgmt_build_op(resp_op_payload, resp_op_code, num_resp_pending);
        o64_tvalid = 1'b1;
        o64_tlast  = !resp_o_tvalid;
      end
      default: begin

        o64_tdata  = 64'h0;
        o64_tvalid = 1'b0;
        o64_tlast  = 1'b0;
      end
    endcase
  end



  assign op_stb      = i64_tvalid && (pkt_state == ST_MGMT_OP_DONE) &&
                       (op_code == CHDR_MGMT_OP_ADVERTISE);
  assign op_dst_epid = chdr_get_dst_epid(cached_chdr_hdr);
  assign op_src_epid = chdr_mgmt_get_src_epid(cached_mgmt_hdr);
  assign op_data     = cached_tuser;






  always @(posedge clk) begin
    if (rst) begin
      ctrlport_req_wr   <= 1'b0;
      ctrlport_req_rd   <= 1'b0;
    end else begin
      ctrlport_req_wr   <= i64_tvalid && (pkt_state == ST_MGMT_OP_EXEC) &&
                          (op_code == CHDR_MGMT_OP_CFG_WR_REQ);
      ctrlport_req_rd   <= i64_tvalid && (pkt_state == ST_MGMT_OP_EXEC) &&
                          (op_code == CHDR_MGMT_OP_CFG_RD_REQ);
      ctrlport_req_addr <= chdr_mgmt_cfg_reg_get_addr(op_payload);
      ctrlport_req_data <= chdr_mgmt_cfg_reg_get_data(op_payload);
    end
  end





  assign resp_i_tvalid = i64_tvalid && (
    ((pkt_state == ST_MGMT_OP_WAIT) && (op_code == CHDR_MGMT_OP_CFG_RD_REQ) && ctrlport_resp_ack) ||
    ((pkt_state == ST_MGMT_OP_DONE) && (op_code == CHDR_MGMT_OP_INFO_REQ)));
  assign resp_i_tdata = (op_code == CHDR_MGMT_OP_CFG_RD_REQ) ?
    {ctrlport_resp_data, ctrlport_req_addr, CHDR_MGMT_OP_CFG_RD_RESP} :
    {node_info, CHDR_MGMT_OP_INFO_RESP};


  wire [15:0] resp_fifo_occ;
  axi_fifo #(.WIDTH(56), .SIZE(RESP_FIFO_SIZE)) resp_fifo_i (
    .clk(clk), .reset(rst), .clear(pkt_state == ST_CHDR_IN_HDR),
    .i_tdata(resp_i_tdata), .i_tvalid(resp_i_tvalid),
    .i_tready(),
    .o_tdata(resp_o_tdata), .o_tvalid(resp_o_tvalid),
    .o_tready(resp_o_tvalid && (pkt_state == ST_POP_RESPONSE)),
    .space(), .occupied(resp_fifo_occ)
  );
  assign num_resp_pending = resp_fifo_occ[7:0];

endmodule
module chdr_mgmt_pkt_handler #(
  parameter [15:0] PROTOVER       = {8'd1, 8'd0},
  parameter        CHDR_W         = 256,
  parameter        USER_W         = 1,
  parameter [0:0]  MGMT_ONLY      = 0,
  parameter        RESP_FIFO_SIZE = 5
)(

  input  wire              clk,
  input  wire              rst,

  input  wire [47:0]       node_info,

  input  wire [CHDR_W-1:0] s_axis_chdr_tdata,
  input  wire              s_axis_chdr_tlast,
  input  wire              s_axis_chdr_tvalid,
  output wire              s_axis_chdr_tready,
  input  wire [USER_W-1:0] s_axis_chdr_tuser,

  output wire [CHDR_W-1:0] m_axis_chdr_tdata,
  output wire [1:0]        m_axis_chdr_tid,
  output wire [9:0]        m_axis_chdr_tdest,
  output wire              m_axis_chdr_tlast,
  output wire              m_axis_chdr_tvalid,
  input  wire              m_axis_chdr_tready,

  output reg               ctrlport_req_wr,
  output reg               ctrlport_req_rd,
  output reg  [15:0]       ctrlport_req_addr,
  output reg  [31:0]       ctrlport_req_data,
  input  wire              ctrlport_resp_ack,
  input  wire [31:0]       ctrlport_resp_data,

  output wire [USER_W-1:0] op_data,
  output wire              op_stb,
  output wire [15:0]       op_dst_epid,
  output wire [15:0]       op_src_epid
);





  `include "rfnoc_chdr_utils.vh"
  `include "rfnoc_chdr_internal_utils.vh"






  localparam CHDR_W_BYTES = CHDR_W / 8;
  localparam LOG2_CHDR_W_BYTES = $clog2(CHDR_W_BYTES);

  wire [CHDR_W-1:0] s_mgmt_tdata, m_mgmt_tdata;
  wire [USER_W-1:0] s_mgmt_tuser;
  wire [9:0]        m_mgmt_tdest;
  wire [1:0]        m_mgmt_tid;
  wire              s_mgmt_tlast, s_mgmt_tvalid, s_mgmt_tready;
  wire              m_mgmt_tlast, m_mgmt_tvalid, m_mgmt_tready;

  generate if (!MGMT_ONLY) begin : gen_not_mgmt_only



    wire [CHDR_W-1:0] bypass_tdata;
    wire [9:0]        bypass_tdest;
    wire [1:0]        bypass_tid;
    wire              bypass_tlast, bypass_tvalid, bypass_tready;
    wire [CHDR_W-1:0] s_header;




    wire consume_mgmt_pkt = (chdr_get_pkt_type(s_header[63:0]) == CHDR_PKT_TYPE_MGMT) &&
                            (chdr_get_dst_epid(s_header[63:0]) == NULL_EPID);

    axi_demux #(
      .WIDTH(CHDR_W), .SIZE(2), .PRE_FIFO_SIZE(1), .POST_FIFO_SIZE(0)
    ) mgmt_demux_i (
      .clk(clk), .reset(rst), .clear(1'b0),
      .header(s_header), .dest(consume_mgmt_pkt ? 1'b1 : 1'b0),
      .i_tdata(s_axis_chdr_tdata), .i_tlast(s_axis_chdr_tlast),
      .i_tvalid(s_axis_chdr_tvalid), .i_tready(s_axis_chdr_tready),
      .o_tdata({s_mgmt_tdata, bypass_tdata}), .o_tlast({s_mgmt_tlast, bypass_tlast}),
      .o_tvalid({s_mgmt_tvalid, bypass_tvalid}), .o_tready({s_mgmt_tready, bypass_tready})
    );



    assign s_mgmt_tuser               = s_axis_chdr_tuser;

    assign {bypass_tid, bypass_tdest} = {CHDR_MGMT_ROUTE_EPID, 10'h0};

    axi_mux #(
      .WIDTH(CHDR_W+10+2), .SIZE(2), .PRE_FIFO_SIZE(0), .POST_FIFO_SIZE(1)
    ) mgmt_mux_i (
      .clk(clk), .reset(rst), .clear(1'b0),
      .i_tdata({m_mgmt_tid, m_mgmt_tdest, m_mgmt_tdata, bypass_tid, bypass_tdest, bypass_tdata}),
      .i_tlast({m_mgmt_tlast, bypass_tlast}),
      .i_tvalid({m_mgmt_tvalid, bypass_tvalid}), .i_tready({m_mgmt_tready, bypass_tready}),
      .o_tdata({m_axis_chdr_tid, m_axis_chdr_tdest, m_axis_chdr_tdata}),
      .o_tlast(m_axis_chdr_tlast),
      .o_tvalid(m_axis_chdr_tvalid), .o_tready(m_axis_chdr_tready)
    );
  end else begin : gen_mgmt_only


    assign s_mgmt_tdata       = s_axis_chdr_tdata;
    assign s_mgmt_tlast       = s_axis_chdr_tlast;
    assign s_mgmt_tvalid      = s_axis_chdr_tvalid;
    assign s_mgmt_tuser       = s_axis_chdr_tuser;
    assign s_axis_chdr_tready = s_mgmt_tready;

    assign m_axis_chdr_tdata  = m_mgmt_tdata;
    assign m_axis_chdr_tdest  = m_mgmt_tdest;
    assign m_axis_chdr_tid    = m_mgmt_tid;
    assign m_axis_chdr_tlast  = m_mgmt_tlast;
    assign m_axis_chdr_tvalid = m_mgmt_tvalid;
    assign m_mgmt_tready      = m_axis_chdr_tready;
  end endgenerate





  wire [63:0]       i64_tdata;
  wire [USER_W-1:0] i64_tuser;
  wire              i64_tlast, i64_tvalid;
  reg               i64_tready;
  reg [63:0]        o64_tdata;
  reg [9:0]         o64_tdest;
  reg [1:0]         o64_tid;
  reg               o64_tlast, o64_tvalid;
  wire              o64_tready;

  axi_fifo #(.WIDTH(USER_W+65), .SIZE(1)) in_flop_i (
    .clk(clk), .reset(rst), .clear(1'b0),
    .i_tdata({s_mgmt_tuser, s_mgmt_tlast, s_mgmt_tdata[63:0]}),
    .i_tvalid(s_mgmt_tvalid), .i_tready(s_mgmt_tready),
    .o_tdata({i64_tuser, i64_tlast, i64_tdata}),
    .o_tvalid(i64_tvalid), .o_tready(i64_tready),
    .space(), .occupied()
  );

  axi_fifo #(.WIDTH(64+10+2+1), .SIZE(1)) out_flop_i (
    .clk(clk), .reset(rst), .clear(1'b0),
    .i_tdata({o64_tlast, o64_tdest, o64_tid, o64_tdata}),
    .i_tvalid(o64_tvalid), .i_tready(o64_tready),
    .o_tdata({m_mgmt_tlast, m_mgmt_tdest, m_mgmt_tid, m_mgmt_tdata[63:0]}),
    .o_tvalid(m_mgmt_tvalid), .o_tready(m_mgmt_tready),
    .space(), .occupied()
  );

  generate
    if (CHDR_W > 64) begin : gen_upper_mgmt_tdata
      assign m_mgmt_tdata[CHDR_W-1:64] = 'h0;
    end
  endgenerate




  localparam [3:0] ST_CHDR_IN_HDR     = 4'd0;
  localparam [3:0] ST_CHDR_IN_MDATA   = 4'd1;
  localparam [3:0] ST_MGMT_IN_HDR     = 4'd2;
  localparam [3:0] ST_MGMT_OP_EXEC    = 4'd3;
  localparam [3:0] ST_MGMT_OP_WAIT    = 4'd4;
  localparam [3:0] ST_MGMT_OP_DONE    = 4'd5;
  localparam [3:0] ST_CHDR_OUT_HDR    = 4'd6;
  localparam [3:0] ST_MGMT_OUT_HDR    = 4'd7;
  localparam [3:0] ST_PASS_PAYLOAD    = 4'd8;
  localparam [3:0] ST_MOD_LAST_HOP    = 4'd9;
  localparam [3:0] ST_POP_RESPONSE    = 4'd10;
  localparam [3:0] ST_APPEND_LAST_HOP = 4'd11;
  localparam [3:0] ST_FAILSAFE_DROP   = 4'd12;


  reg [3:0]  pkt_state = ST_CHDR_IN_HDR;
  reg [4:0]  num_mdata;
  reg [63:0] cached_chdr_hdr, cached_mgmt_hdr;
  reg [15:0] stripped_len;
  reg [9:0]  hops_remaining;
  reg [7:0]  resp_op_code;
  reg [47:0] resp_op_payload;
  reg [USER_W-1:0] cached_tuser;


  wire [7:0]  op_code = chdr_mgmt_get_op_code(i64_tdata);
  wire [47:0] op_payload = chdr_mgmt_get_op_payload(i64_tdata);


  wire [55:0] resp_i_tdata, resp_o_tdata;
  wire        resp_i_tvalid, resp_o_tvalid;
  wire [7:0]  num_resp_pending;



  always @(posedge clk) begin
    if (rst) begin


      pkt_state <= ST_CHDR_IN_HDR;
    end else begin
      case (pkt_state)






        ST_CHDR_IN_HDR: begin
          if (i64_tvalid && i64_tready) begin
            cached_chdr_hdr <= i64_tdata;
            cached_tuser <= i64_tuser;
            stripped_len <= chdr_get_length(i64_tdata);
            num_mdata <= chdr_get_num_mdata(i64_tdata) - 5'd1;
            if (!i64_tlast) begin
              if (chdr_get_pkt_type(i64_tdata) != CHDR_PKT_TYPE_MGMT)
                pkt_state <= ST_FAILSAFE_DROP;
              else if (chdr_get_num_mdata(i64_tdata) != CHDR_NO_MDATA)
                pkt_state <= ST_CHDR_IN_MDATA;
              else
                pkt_state <= ST_MGMT_IN_HDR;
            end else begin
              pkt_state <= ST_CHDR_IN_HDR;
            end
          end
        end




        ST_CHDR_IN_MDATA: begin
          if (i64_tvalid && i64_tready) begin
            num_mdata <= num_mdata - 5'd1;
            if (!i64_tlast)
              pkt_state <= (num_mdata == CHDR_NO_MDATA) ? ST_MGMT_IN_HDR : ST_CHDR_IN_MDATA;
            else
              pkt_state <= ST_CHDR_IN_HDR;
          end
        end






        ST_MGMT_IN_HDR: begin
          if (i64_tvalid && i64_tready) begin
            cached_mgmt_hdr <= i64_tdata;
            hops_remaining <= chdr_mgmt_get_num_hops(i64_tdata);
            pkt_state <= (!i64_tlast) ? ST_MGMT_OP_EXEC : ST_CHDR_IN_HDR;
          end
        end





        ST_MGMT_OP_EXEC: begin
          if (i64_tvalid) begin


            o64_tid   <= CHDR_MGMT_ROUTE_EPID;
            o64_tdest <= 10'd0;
            case (op_code)

              CHDR_MGMT_OP_NOP: begin

                pkt_state <= ST_MGMT_OP_DONE;
              end

              CHDR_MGMT_OP_ADVERTISE: begin

                pkt_state <= ST_MGMT_OP_DONE;
              end

              CHDR_MGMT_OP_SEL_DEST: begin
                o64_tid   <= CHDR_MGMT_ROUTE_TDEST;
                o64_tdest <= chdr_mgmt_sel_dest_get_tdest(op_payload);
                pkt_state <= ST_MGMT_OP_DONE;
              end

              CHDR_MGMT_OP_RETURN: begin
                o64_tid   <= CHDR_MGMT_RETURN_TO_SRC;
                pkt_state <= ST_MGMT_OP_DONE;
              end


              CHDR_MGMT_OP_INFO_REQ: begin
                pkt_state <= ST_MGMT_OP_DONE;
              end


              CHDR_MGMT_OP_INFO_RESP: begin
                pkt_state <= ST_MGMT_OP_DONE;
              end

              CHDR_MGMT_OP_CFG_WR_REQ: begin

                pkt_state <= ST_MGMT_OP_WAIT;
              end

              CHDR_MGMT_OP_CFG_RD_REQ: begin

                pkt_state <= ST_MGMT_OP_WAIT;
              end


              CHDR_MGMT_OP_CFG_RD_RESP: begin
                pkt_state <= ST_MGMT_OP_DONE;
              end
              default: begin

                pkt_state <= ST_CHDR_IN_HDR;
              end
            endcase
          end
        end




        ST_MGMT_OP_WAIT: begin
          if (i64_tvalid) begin
            if (op_code == CHDR_MGMT_OP_CFG_WR_REQ ||
                op_code == CHDR_MGMT_OP_CFG_RD_REQ) begin

              if (ctrlport_resp_ack) begin
                pkt_state <= ST_MGMT_OP_DONE;
              end
            end else begin

              pkt_state <= ST_MGMT_OP_DONE;
            end
          end
        end





        ST_MGMT_OP_DONE: begin
          if (i64_tvalid && i64_tready) begin
            if (!i64_tlast) begin

              stripped_len <= stripped_len - CHDR_W_BYTES;


              if (chdr_mgmt_get_ops_pending(i64_tdata) == 8'd0) begin
                hops_remaining <= hops_remaining - 10'd1;
                pkt_state <= ST_CHDR_OUT_HDR;
              end else begin
                pkt_state <= ST_MGMT_OP_EXEC;
              end
            end else begin


              pkt_state <= ST_CHDR_IN_HDR;
            end
          end
        end




        ST_CHDR_OUT_HDR: begin
          if (o64_tvalid && o64_tready)
            pkt_state <= ST_MGMT_OUT_HDR;
        end




        ST_MGMT_OUT_HDR: begin
          if (o64_tvalid && o64_tready)
            if (resp_o_tvalid && (hops_remaining == 10'd1))
              pkt_state <= ST_MOD_LAST_HOP;
            else
              pkt_state <= ST_PASS_PAYLOAD;
        end




        ST_PASS_PAYLOAD: begin
          if (o64_tvalid && o64_tready) begin
            if (!i64_tlast) begin




              if (chdr_mgmt_get_ops_pending(i64_tdata) == 8'd0) begin
                hops_remaining <= hops_remaining - 10'd1;
                if (resp_o_tvalid && (hops_remaining == 10'd1))
                  pkt_state <= ST_MOD_LAST_HOP;
                else
                  pkt_state <= ST_PASS_PAYLOAD;
              end else begin
                pkt_state <= ST_PASS_PAYLOAD;
              end
            end else begin
              pkt_state <= ST_CHDR_IN_HDR;
            end
          end
        end








        ST_MOD_LAST_HOP: begin
          if (o64_tvalid && o64_tready) begin

            if (chdr_mgmt_get_ops_pending(i64_tdata) == 8'd0) begin
              if (resp_o_tvalid)
                pkt_state <= ST_POP_RESPONSE;
              else
                pkt_state <= i64_tlast ? ST_CHDR_IN_HDR : ST_FAILSAFE_DROP;
            end
          end
        end




        ST_POP_RESPONSE: begin
          if (resp_o_tvalid) begin
            resp_op_code <= resp_o_tdata[7:0];
            resp_op_payload <= resp_o_tdata[55:8];
            pkt_state <= ST_APPEND_LAST_HOP;
          end
        end





        ST_APPEND_LAST_HOP: begin
          if (o64_tvalid && o64_tready)
            pkt_state <= resp_o_tvalid ? ST_POP_RESPONSE : ST_CHDR_IN_HDR;
        end




        ST_FAILSAFE_DROP: begin
          if (i64_tvalid && i64_tready)
            pkt_state <= i64_tlast ? ST_CHDR_IN_HDR : ST_FAILSAFE_DROP;
        end

        default: begin

          pkt_state <= ST_CHDR_IN_HDR;
        end
      endcase
    end
  end


  always @(*) begin
    case (pkt_state)
      ST_CHDR_IN_HDR:
        i64_tready = 1'b1;
      ST_CHDR_IN_MDATA:
        i64_tready = 1'b1;
      ST_MGMT_IN_HDR:
        i64_tready = 1'b1;
      ST_MGMT_OP_DONE:
        i64_tready = 1'b1;
      ST_PASS_PAYLOAD:
        i64_tready = o64_tready;
      ST_MOD_LAST_HOP:
        i64_tready = o64_tready;
      ST_FAILSAFE_DROP:
        i64_tready = 1'b1;
      default:
        i64_tready = 1'b0;
    endcase
  end


  wire [15:0] o64_dst_epid = (o64_tid == CHDR_MGMT_RETURN_TO_SRC) ?
    chdr_mgmt_get_src_epid(cached_mgmt_hdr) : chdr_get_dst_epid(cached_chdr_hdr);
  wire [15:0] o64_src_epid = (o64_tid == CHDR_MGMT_RETURN_TO_SRC) ?
    chdr_get_dst_epid(cached_chdr_hdr) : chdr_mgmt_get_src_epid(cached_mgmt_hdr);


  always @(*) begin
    case (pkt_state)
      ST_CHDR_OUT_HDR: begin


        o64_tdata  = chdr_set_length(
          chdr_set_dst_epid(cached_chdr_hdr, o64_dst_epid),
          (stripped_len + (num_resp_pending << LOG2_CHDR_W_BYTES)));
        o64_tvalid = 1'b1;
        o64_tlast  = 1'b0;
      end
      ST_MGMT_OUT_HDR: begin


        o64_tdata  = chdr_mgmt_build_hdr(PROTOVER, chdr_w_to_enum(CHDR_W),
          chdr_mgmt_get_num_hops(cached_mgmt_hdr) - 10'd1, o64_src_epid);
        o64_tvalid = 1'b1;
        o64_tlast  = 1'b0;
      end
      ST_PASS_PAYLOAD: begin

        o64_tdata  = i64_tdata;
        o64_tvalid = i64_tvalid;
        o64_tlast  = i64_tlast;
      end
      ST_MOD_LAST_HOP: begin

        o64_tdata  = chdr_mgmt_build_op(chdr_mgmt_get_op_payload(i64_tdata),
          chdr_mgmt_get_op_code(i64_tdata),
          chdr_mgmt_get_ops_pending(i64_tdata) + num_resp_pending);
        o64_tvalid = i64_tvalid;
        o64_tlast  = i64_tlast && !resp_o_tvalid;
      end
      ST_APPEND_LAST_HOP: begin

        o64_tdata  = chdr_mgmt_build_op(resp_op_payload, resp_op_code, num_resp_pending);
        o64_tvalid = 1'b1;
        o64_tlast  = !resp_o_tvalid;
      end
      default: begin

        o64_tdata  = 64'h0;
        o64_tvalid = 1'b0;
        o64_tlast  = 1'b0;
      end
    endcase
  end



  assign op_stb      = i64_tvalid && (pkt_state == ST_MGMT_OP_DONE) &&
                       (op_code == CHDR_MGMT_OP_ADVERTISE);
  assign op_dst_epid = chdr_get_dst_epid(cached_chdr_hdr);
  assign op_src_epid = chdr_mgmt_get_src_epid(cached_mgmt_hdr);
  assign op_data     = cached_tuser;






  always @(posedge clk) begin
    if (rst) begin
      ctrlport_req_wr   <= 1'b0;
      ctrlport_req_rd   <= 1'b0;
    end else begin
      ctrlport_req_wr   <= i64_tvalid && (pkt_state == ST_MGMT_OP_EXEC) &&
                          (op_code == CHDR_MGMT_OP_CFG_WR_REQ);
      ctrlport_req_rd   <= i64_tvalid && (pkt_state == ST_MGMT_OP_EXEC) &&
                          (op_code == CHDR_MGMT_OP_CFG_RD_REQ);
      ctrlport_req_addr <= chdr_mgmt_cfg_reg_get_addr(op_payload);
      ctrlport_req_data <= chdr_mgmt_cfg_reg_get_data(op_payload);
    end
  end





  assign resp_i_tvalid = i64_tvalid && (
    ((pkt_state == ST_MGMT_OP_WAIT) && (op_code == CHDR_MGMT_OP_CFG_RD_REQ) && ctrlport_resp_ack) ||
    ((pkt_state == ST_MGMT_OP_DONE) && (op_code == CHDR_MGMT_OP_INFO_REQ)));
  assign resp_i_tdata = (op_code == CHDR_MGMT_OP_CFG_RD_REQ) ?
    {ctrlport_resp_data, ctrlport_req_addr, CHDR_MGMT_OP_CFG_RD_RESP} :
    {node_info, CHDR_MGMT_OP_INFO_RESP};


  wire [15:0] resp_fifo_occ;
  axi_fifo #(.WIDTH(56), .SIZE(RESP_FIFO_SIZE)) resp_fifo_i (
    .clk(clk), .reset(rst), .clear(pkt_state == ST_CHDR_IN_HDR),
    .i_tdata(resp_i_tdata), .i_tvalid(resp_i_tvalid),
    .i_tready(),
    .o_tdata(resp_o_tdata), .o_tvalid(resp_o_tvalid),
    .o_tready(resp_o_tvalid && (pkt_state == ST_POP_RESPONSE)),
    .space(), .occupied(resp_fifo_occ)
  );
  assign num_resp_pending = resp_fifo_occ[7:0];

endmodule