data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/core/axis_pyld_ctxt_to_chdr.v
 line:145: before: "("
1: b'%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/core/axis_pyld_ctxt_to_chdr.v:84: 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/axis_pyld_ctxt_to_chdr.v:85: Cannot find include file: rfnoc_axis_ctrl_utils.vh\n  `include "rfnoc_axis_ctrl_utils.vh" \n           ^~~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: Exiting due to 2 error(s)\n'
module axis_pyld_ctxt_to_chdr #(
  parameter CHDR_W              = 256,
  parameter ITEM_W              = 32,
  parameter NIPC                = 2,
  parameter SYNC_CLKS           = 0,
  parameter CONTEXT_FIFO_SIZE   = 1,
  parameter PAYLOAD_FIFO_SIZE   = 1,
  parameter MTU                 = 10,
  parameter CONTEXT_PREFETCH_EN = 1
)(

  input  wire                     axis_chdr_clk,
  input  wire                     axis_chdr_rst,
  input  wire                     axis_data_clk,
  input  wire                     axis_data_rst,

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

  input  wire [(ITEM_W*NIPC)-1:0] s_axis_payload_tdata,
  input  wire [NIPC-1:0]          s_axis_payload_tkeep,
  input  wire                     s_axis_payload_tlast,
  input  wire                     s_axis_payload_tvalid,
  output wire                     s_axis_payload_tready,

  input  wire [CHDR_W-1:0]        s_axis_context_tdata,
  input  wire [3:0]               s_axis_context_tuser,
  input  wire                     s_axis_context_tlast,
  input  wire                     s_axis_context_tvalid,
  output wire                     s_axis_context_tready,

  output reg  [31:0]              framer_errors,

  input  wire                     flush_en,
  input  wire [31:0]              flush_timeout,
  output wire                     flush_active,
  output wire                     flush_done
);




  `include "rfnoc_chdr_utils.vh"
  `include "rfnoc_axis_ctrl_utils.vh"




  reg [2:0] ctxt_pkt_cnt = 3'd0, pyld_pkt_cnt = 3'd0;

  wire pass_pyld = ((ctxt_pkt_cnt - pyld_pkt_cnt) > 3'd0);


  wire pass_ctxt = ((ctxt_pkt_cnt - pyld_pkt_cnt) < (CONTEXT_PREFETCH_EN == 1 ? 3'd2 : 3'd1));

  always @(posedge axis_data_clk) begin
    if (axis_data_rst) begin
      ctxt_pkt_cnt <= 3'd0;
      pyld_pkt_cnt <= 3'd0;
    end else begin
      if (s_axis_context_tvalid && s_axis_context_tready && s_axis_context_tlast)
        ctxt_pkt_cnt <= ctxt_pkt_cnt + 3'd1;
      if (s_axis_payload_tvalid && s_axis_payload_tready && s_axis_payload_tlast)
        pyld_pkt_cnt <= pyld_pkt_cnt + 3'd1;
    end
  end

  wire tmp_ctxt_tvalid, tmp_ctxt_tready;
  wire tmp_pyld_tvalid, tmp_pyld_tready;

  assign tmp_ctxt_tvalid       = s_axis_context_tvalid && pass_ctxt;
  assign tmp_pyld_tvalid       = s_axis_payload_tvalid && pass_pyld;
  assign s_axis_context_tready = tmp_ctxt_tready       && pass_ctxt;
  assign s_axis_payload_tready = tmp_pyld_tready       && pass_pyld;




  wire [CHDR_W-1:0] in_pyld_tdata;
  wire              in_pyld_tlast;
  wire              in_pyld_tvalid;
  wire              in_pyld_tready;

  axis_width_conv #(
    .WORD_W(ITEM_W), .IN_WORDS(NIPC), .OUT_WORDS(CHDR_W/ITEM_W),
    .SYNC_CLKS(1), .PIPELINE("IN")
  ) payload_width_conv_i (
    .s_axis_aclk(axis_data_clk), .s_axis_rst(axis_data_rst),
    .s_axis_tdata(s_axis_payload_tdata),
    .s_axis_tkeep(s_axis_payload_tkeep),
    .s_axis_tlast(s_axis_payload_tlast),
    .s_axis_tvalid(tmp_pyld_tvalid),
    .s_axis_tready(tmp_pyld_tready),
    .m_axis_aclk(axis_data_clk), .m_axis_rst(axis_data_rst),
    .m_axis_tdata(in_pyld_tdata),
    .m_axis_tkeep(),
    .m_axis_tlast(in_pyld_tlast),
    .m_axis_tvalid(in_pyld_tvalid),
    .m_axis_tready(in_pyld_tready)
  );




  wire [CHDR_W-1:0] out_ctxt_tdata , out_pyld_tdata ;
  wire [3:0]        out_ctxt_tuser;
  wire              out_ctxt_tlast , out_pyld_tlast ;
  wire              out_ctxt_tvalid, out_pyld_tvalid;
  reg               out_ctxt_tready, out_pyld_tready;

  generate if (SYNC_CLKS) begin
    axi_fifo #(.WIDTH(CHDR_W+4+1), .SIZE(CONTEXT_FIFO_SIZE)) ctxt_fifo_i (
      .clk(axis_chdr_clk), .reset(axis_chdr_rst), .clear(1'b0),
      .i_tdata({s_axis_context_tlast, s_axis_context_tuser, s_axis_context_tdata}),
      .i_tvalid(tmp_ctxt_tvalid), .i_tready(tmp_ctxt_tready),
      .o_tdata({out_ctxt_tlast, out_ctxt_tuser, out_ctxt_tdata}),
      .o_tvalid(out_ctxt_tvalid), .o_tready(out_ctxt_tready),
      .space(), .occupied()
    );
    axi_fifo #(.WIDTH(CHDR_W+1), .SIZE(PAYLOAD_FIFO_SIZE)) pyld_fifo_i (
      .clk(axis_chdr_clk), .reset(axis_chdr_rst), .clear(1'b0),
      .i_tdata({in_pyld_tlast, in_pyld_tdata}),
      .i_tvalid(in_pyld_tvalid), .i_tready(in_pyld_tready),
      .o_tdata({out_pyld_tlast, out_pyld_tdata}),
      .o_tvalid(out_pyld_tvalid), .o_tready(out_pyld_tready),
      .space(), .occupied()
    );
  end else begin
    axi_fifo_2clk #(.WIDTH(CHDR_W+4+1), .SIZE(CONTEXT_FIFO_SIZE)) ctxt_fifo_i (
      .reset(axis_data_rst),
      .i_aclk(axis_data_clk),
      .i_tdata({s_axis_context_tlast, s_axis_context_tuser, s_axis_context_tdata}),
      .i_tvalid(tmp_ctxt_tvalid), .i_tready(tmp_ctxt_tready),
      .o_aclk(axis_chdr_clk),
      .o_tdata({out_ctxt_tlast, out_ctxt_tuser, out_ctxt_tdata}),
      .o_tvalid(out_ctxt_tvalid), .o_tready(out_ctxt_tready)
    );
    axi_fifo_2clk #(.WIDTH(CHDR_W+1), .SIZE(PAYLOAD_FIFO_SIZE)) pyld_fifo_i (
      .reset(axis_data_rst),
      .i_aclk(axis_data_clk),
      .i_tdata({in_pyld_tlast, in_pyld_tdata}),
      .i_tvalid(in_pyld_tvalid), .i_tready(in_pyld_tready),
      .o_aclk(axis_chdr_clk),
      .o_tdata({out_pyld_tlast, out_pyld_tdata}),
      .o_tvalid(out_pyld_tvalid), .o_tready(out_pyld_tready)
    );
  end endgenerate




  wire [CHDR_W-1:0] chdr_pg_tdata;
  reg               chdr_pg_tlast, chdr_pg_tvalid;
  wire              chdr_pg_terror, chdr_pg_tready;

  localparam [2:0] ST_HDR       = 3'd0;
  localparam [2:0] ST_TS        = 3'd1;
  localparam [2:0] ST_MDATA     = 3'd2;
  localparam [2:0] ST_BODY      = 3'd3;
  localparam [2:0] ST_DROP_CTXT = 3'd4;
  localparam [2:0] ST_DROP_PYLD = 3'd5;
  localparam [2:0] ST_TERMINATE = 3'd6;

  reg [2:0] state = ST_HDR;
  reg [4:0] mdata_pending = 5'd0;


  wire [2:0] out_pkt_type = chdr_get_pkt_type(out_ctxt_tdata[63:0]);
  wire [4:0] out_num_mdata = chdr_get_num_mdata(out_ctxt_tdata[63:0]);

  always @(posedge axis_chdr_clk) begin
    if (axis_chdr_rst) begin
      state <= ST_HDR;
      framer_errors <= 32'd0;
    end else begin
      case (state)



        ST_HDR: begin
          if (out_ctxt_tvalid && out_ctxt_tready) begin
            mdata_pending <= out_num_mdata;
            if (CHDR_W > 64) begin



              if (out_num_mdata != CHDR_NO_MDATA) begin
                if (!out_ctxt_tlast)
                  if (out_ctxt_tuser == CONTEXT_FIELD_HDR_TS)
                    state <= ST_MDATA;
                  else
                    state <= ST_DROP_CTXT;
                else
                  state <= ST_DROP_PYLD;
              end else begin
                if (out_ctxt_tlast)
                  if (out_ctxt_tuser == CONTEXT_FIELD_HDR_TS)
                    state <= ST_BODY;
                  else
                    state <= ST_DROP_PYLD;
                else
                  state <= ST_DROP_CTXT;
              end
            end else begin



              if (out_pkt_type == CHDR_PKT_TYPE_DATA_TS) begin
                if (!out_ctxt_tlast)
                  if (out_ctxt_tuser == CONTEXT_FIELD_HDR)
                    state <= ST_TS;
                  else
                    state <= ST_DROP_CTXT;
                else
                  state <= ST_DROP_PYLD;
              end else begin
                if (out_num_mdata != CHDR_NO_MDATA) begin
                  if (!out_ctxt_tlast)
                    if (out_ctxt_tuser == CONTEXT_FIELD_HDR)
                      state <= ST_MDATA;
                    else
                      state <= ST_DROP_CTXT;
                  else
                    state <= ST_DROP_PYLD;
                end else begin
                  if (out_ctxt_tlast)
                    if (out_ctxt_tuser == CONTEXT_FIELD_HDR)
                      state <= ST_BODY;
                    else
                      state <= ST_DROP_PYLD;
                  else
                    state <= ST_DROP_CTXT;
                end
              end
            end
          end
        end



        ST_TS: begin
          if (out_ctxt_tvalid && out_ctxt_tready) begin
            if (mdata_pending != CHDR_NO_MDATA) begin
              if (!out_ctxt_tlast)
                if (out_ctxt_tuser == CONTEXT_FIELD_TS)
                  state <= ST_MDATA;
                else
                  state <= ST_DROP_CTXT;
              else
                state <= ST_DROP_PYLD;
            end else begin
              if (out_ctxt_tlast)
                if (out_ctxt_tuser == CONTEXT_FIELD_TS)
                  state <= ST_BODY;
                else
                  state <= ST_DROP_PYLD;
              else
                state <= ST_DROP_CTXT;
            end
          end
        end



        ST_MDATA: begin
          if (out_ctxt_tvalid && out_ctxt_tready) begin
            if (mdata_pending != 5'd1) begin
              mdata_pending <= mdata_pending - 'd1;
              if (!out_ctxt_tlast)
                if (out_ctxt_tuser == CONTEXT_FIELD_MDATA)
                  state <= ST_MDATA;
                else
                  state <= ST_DROP_CTXT;
              else
                state <= ST_DROP_PYLD;
            end else begin
              if (out_ctxt_tlast)
                if (out_ctxt_tuser == CONTEXT_FIELD_MDATA)
                  state <= ST_BODY;
                else
                  state <= ST_DROP_PYLD;
              else
                state <= ST_DROP_CTXT;
            end
          end
        end



        ST_BODY: begin
          if (out_pyld_tvalid && out_pyld_tready) begin
            state <= out_pyld_tlast ? ST_HDR : ST_BODY;
          end
        end



        ST_DROP_CTXT: begin
          if (out_ctxt_tvalid && out_ctxt_tready) begin
            state <= out_ctxt_tlast ? ST_DROP_PYLD : ST_DROP_CTXT;
          end
        end



        ST_DROP_PYLD: begin
          if (out_pyld_tvalid && out_pyld_tready) begin
            state <= out_pyld_tlast ? ST_TERMINATE : ST_DROP_PYLD;
          end
        end



        ST_TERMINATE: begin
          if (chdr_pg_tready) begin
            state <= ST_HDR;
            framer_errors <= framer_errors + 32'd1;
          end
        end

        default: begin

          state <= ST_HDR;
        end
      endcase
    end
  end


  always @(*) begin
    case (state)
      ST_HDR: begin

        chdr_pg_tvalid  = out_ctxt_tvalid;
        chdr_pg_tlast   = 1'b0;
        out_ctxt_tready = chdr_pg_tready;
        out_pyld_tready = 1'b0;
      end
      ST_TS: begin

        chdr_pg_tvalid  = out_ctxt_tvalid;
        chdr_pg_tlast   = 1'b0;
        out_ctxt_tready = chdr_pg_tready;
        out_pyld_tready = 1'b0;
      end
      ST_MDATA: begin

        chdr_pg_tvalid  = out_ctxt_tvalid;
        chdr_pg_tlast   = 1'b0;
        out_ctxt_tready = chdr_pg_tready;
        out_pyld_tready = 1'b0;
      end
      ST_BODY: begin

        chdr_pg_tvalid  = out_pyld_tvalid;
        chdr_pg_tlast   = out_pyld_tlast;
        out_ctxt_tready = 1'b0;
        out_pyld_tready = chdr_pg_tready;
      end
      ST_DROP_CTXT: begin

        chdr_pg_tvalid  = 1'b0;
        chdr_pg_tlast   = 1'b0;
        out_ctxt_tready = 1'b1;
        out_pyld_tready = 1'b0;
      end
      ST_DROP_PYLD: begin

        chdr_pg_tvalid  = 1'b0;
        chdr_pg_tlast   = 1'b0;
        out_ctxt_tready = 1'b0;
        out_pyld_tready = 1'b1;
      end
      ST_TERMINATE: begin


        chdr_pg_tvalid  = 1'b1;
        chdr_pg_tlast   = 1'b1;
        out_ctxt_tready = 1'b0;
        out_pyld_tready = 1'b0;
      end
      default: begin
        chdr_pg_tvalid  = 1'b0;
        chdr_pg_tlast   = 1'b0;
        out_ctxt_tready = 1'b0;
        out_pyld_tready = 1'b0;
      end
    endcase
  end

  assign chdr_pg_tdata  = (state == ST_BODY) ? out_pyld_tdata : out_ctxt_tdata;
  assign chdr_pg_terror = (state == ST_TERMINATE);





  wire [CHDR_W-1:0] chdr_flush_tdata;
  wire              chdr_flush_tlast, chdr_flush_tvalid;
  wire              chdr_flush_terror, chdr_flush_tready;

  axis_packet_flush #(
    .WIDTH(CHDR_W+1), .FLUSH_PARTIAL_PKTS(0), .TIMEOUT_W(32), .PIPELINE("IN")
  ) chdr_flusher_i (
    .clk(axis_chdr_clk), .reset(axis_chdr_rst),
    .enable(flush_en), .timeout(flush_timeout),
    .flushing(flush_active), .done(flush_done),
    .s_axis_tdata({chdr_pg_terror, chdr_pg_tdata}), .s_axis_tlast(chdr_pg_tlast),
    .s_axis_tvalid(chdr_pg_tvalid), .s_axis_tready(chdr_pg_tready),
    .m_axis_tdata({chdr_flush_terror, chdr_flush_tdata}), .m_axis_tlast(chdr_flush_tlast),
    .m_axis_tvalid(chdr_flush_tvalid), .m_axis_tready(chdr_flush_tready)
  );

  axi_packet_gate #( .WIDTH(CHDR_W), .SIZE(MTU), .USE_AS_BUFF(0) ) out_gate_i (
    .clk(axis_chdr_clk), .reset(axis_chdr_rst), .clear(flush_active),
    .i_tdata(chdr_flush_tdata), .i_tlast(chdr_flush_tlast), .i_terror(chdr_flush_terror),
    .i_tvalid(chdr_flush_tvalid), .i_tready(chdr_flush_tready),
    .o_tdata(m_axis_chdr_tdata), .o_tlast(m_axis_chdr_tlast),
    .o_tvalid(m_axis_chdr_tvalid), .o_tready(m_axis_chdr_tready)
  );

endmodule
module axis_pyld_ctxt_to_chdr #(
  parameter CHDR_W              = 256,
  parameter ITEM_W              = 32,
  parameter NIPC                = 2,
  parameter SYNC_CLKS           = 0,
  parameter CONTEXT_FIFO_SIZE   = 1,
  parameter PAYLOAD_FIFO_SIZE   = 1,
  parameter MTU                 = 10,
  parameter CONTEXT_PREFETCH_EN = 1
)(

  input  wire                     axis_chdr_clk,
  input  wire                     axis_chdr_rst,
  input  wire                     axis_data_clk,
  input  wire                     axis_data_rst,

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

  input  wire [(ITEM_W*NIPC)-1:0] s_axis_payload_tdata,
  input  wire [NIPC-1:0]          s_axis_payload_tkeep,
  input  wire                     s_axis_payload_tlast,
  input  wire                     s_axis_payload_tvalid,
  output wire                     s_axis_payload_tready,

  input  wire [CHDR_W-1:0]        s_axis_context_tdata,
  input  wire [3:0]               s_axis_context_tuser,
  input  wire                     s_axis_context_tlast,
  input  wire                     s_axis_context_tvalid,
  output wire                     s_axis_context_tready,

  output reg  [31:0]              framer_errors,

  input  wire                     flush_en,
  input  wire [31:0]              flush_timeout,
  output wire                     flush_active,
  output wire                     flush_done
);





  `include "rfnoc_chdr_utils.vh"
  `include "rfnoc_axis_ctrl_utils.vh"




  reg [2:0] ctxt_pkt_cnt = 3'd0, pyld_pkt_cnt = 3'd0;

  wire pass_pyld = ((ctxt_pkt_cnt - pyld_pkt_cnt) > 3'd0);


  wire pass_ctxt = ((ctxt_pkt_cnt - pyld_pkt_cnt) < (CONTEXT_PREFETCH_EN == 1 ? 3'd2 : 3'd1));

  always @(posedge axis_data_clk) begin
    if (axis_data_rst) begin
      ctxt_pkt_cnt <= 3'd0;
      pyld_pkt_cnt <= 3'd0;
    end else begin
      if (s_axis_context_tvalid && s_axis_context_tready && s_axis_context_tlast)
        ctxt_pkt_cnt <= ctxt_pkt_cnt + 3'd1;
      if (s_axis_payload_tvalid && s_axis_payload_tready && s_axis_payload_tlast)
        pyld_pkt_cnt <= pyld_pkt_cnt + 3'd1;
    end
  end

  wire tmp_ctxt_tvalid, tmp_ctxt_tready;
  wire tmp_pyld_tvalid, tmp_pyld_tready;

  assign tmp_ctxt_tvalid       = s_axis_context_tvalid && pass_ctxt;
  assign tmp_pyld_tvalid       = s_axis_payload_tvalid && pass_pyld;
  assign s_axis_context_tready = tmp_ctxt_tready       && pass_ctxt;
  assign s_axis_payload_tready = tmp_pyld_tready       && pass_pyld;




  wire [CHDR_W-1:0] in_pyld_tdata;
  wire              in_pyld_tlast;
  wire              in_pyld_tvalid;
  wire              in_pyld_tready;

  axis_width_conv #(
    .WORD_W(ITEM_W), .IN_WORDS(NIPC), .OUT_WORDS(CHDR_W/ITEM_W),
    .SYNC_CLKS(1), .PIPELINE("IN")
  ) payload_width_conv_i (
    .s_axis_aclk(axis_data_clk), .s_axis_rst(axis_data_rst),
    .s_axis_tdata(s_axis_payload_tdata),
    .s_axis_tkeep(s_axis_payload_tkeep),
    .s_axis_tlast(s_axis_payload_tlast),
    .s_axis_tvalid(tmp_pyld_tvalid),
    .s_axis_tready(tmp_pyld_tready),
    .m_axis_aclk(axis_data_clk), .m_axis_rst(axis_data_rst),
    .m_axis_tdata(in_pyld_tdata),
    .m_axis_tkeep(),
    .m_axis_tlast(in_pyld_tlast),
    .m_axis_tvalid(in_pyld_tvalid),
    .m_axis_tready(in_pyld_tready)
  );




  wire [CHDR_W-1:0] out_ctxt_tdata , out_pyld_tdata ;
  wire [3:0]        out_ctxt_tuser;
  wire              out_ctxt_tlast , out_pyld_tlast ;
  wire              out_ctxt_tvalid, out_pyld_tvalid;
  reg               out_ctxt_tready, out_pyld_tready;

  generate if (SYNC_CLKS) begin
    axi_fifo #(.WIDTH(CHDR_W+4+1), .SIZE(CONTEXT_FIFO_SIZE)) ctxt_fifo_i (
      .clk(axis_chdr_clk), .reset(axis_chdr_rst), .clear(1'b0),
      .i_tdata({s_axis_context_tlast, s_axis_context_tuser, s_axis_context_tdata}),
      .i_tvalid(tmp_ctxt_tvalid), .i_tready(tmp_ctxt_tready),
      .o_tdata({out_ctxt_tlast, out_ctxt_tuser, out_ctxt_tdata}),
      .o_tvalid(out_ctxt_tvalid), .o_tready(out_ctxt_tready),
      .space(), .occupied()
    );
    axi_fifo #(.WIDTH(CHDR_W+1), .SIZE(PAYLOAD_FIFO_SIZE)) pyld_fifo_i (
      .clk(axis_chdr_clk), .reset(axis_chdr_rst), .clear(1'b0),
      .i_tdata({in_pyld_tlast, in_pyld_tdata}),
      .i_tvalid(in_pyld_tvalid), .i_tready(in_pyld_tready),
      .o_tdata({out_pyld_tlast, out_pyld_tdata}),
      .o_tvalid(out_pyld_tvalid), .o_tready(out_pyld_tready),
      .space(), .occupied()
    );
  end else begin
    axi_fifo_2clk #(.WIDTH(CHDR_W+4+1), .SIZE(CONTEXT_FIFO_SIZE)) ctxt_fifo_i (
      .reset(axis_data_rst),
      .i_aclk(axis_data_clk),
      .i_tdata({s_axis_context_tlast, s_axis_context_tuser, s_axis_context_tdata}),
      .i_tvalid(tmp_ctxt_tvalid), .i_tready(tmp_ctxt_tready),
      .o_aclk(axis_chdr_clk),
      .o_tdata({out_ctxt_tlast, out_ctxt_tuser, out_ctxt_tdata}),
      .o_tvalid(out_ctxt_tvalid), .o_tready(out_ctxt_tready)
    );
    axi_fifo_2clk #(.WIDTH(CHDR_W+1), .SIZE(PAYLOAD_FIFO_SIZE)) pyld_fifo_i (
      .reset(axis_data_rst),
      .i_aclk(axis_data_clk),
      .i_tdata({in_pyld_tlast, in_pyld_tdata}),
      .i_tvalid(in_pyld_tvalid), .i_tready(in_pyld_tready),
      .o_aclk(axis_chdr_clk),
      .o_tdata({out_pyld_tlast, out_pyld_tdata}),
      .o_tvalid(out_pyld_tvalid), .o_tready(out_pyld_tready)
    );
  end endgenerate




  wire [CHDR_W-1:0] chdr_pg_tdata;
  reg               chdr_pg_tlast, chdr_pg_tvalid;
  wire              chdr_pg_terror, chdr_pg_tready;

  localparam [2:0] ST_HDR       = 3'd0;
  localparam [2:0] ST_TS        = 3'd1;
  localparam [2:0] ST_MDATA     = 3'd2;
  localparam [2:0] ST_BODY      = 3'd3;
  localparam [2:0] ST_DROP_CTXT = 3'd4;
  localparam [2:0] ST_DROP_PYLD = 3'd5;
  localparam [2:0] ST_TERMINATE = 3'd6;

  reg [2:0] state = ST_HDR;
  reg [4:0] mdata_pending = 5'd0;


  wire [2:0] out_pkt_type = chdr_get_pkt_type(out_ctxt_tdata[63:0]);
  wire [4:0] out_num_mdata = chdr_get_num_mdata(out_ctxt_tdata[63:0]);

  always @(posedge axis_chdr_clk) begin
    if (axis_chdr_rst) begin
      state <= ST_HDR;
      framer_errors <= 32'd0;
    end else begin
      case (state)



        ST_HDR: begin
          if (out_ctxt_tvalid && out_ctxt_tready) begin
            mdata_pending <= out_num_mdata;
            if (CHDR_W > 64) begin



              if (out_num_mdata != CHDR_NO_MDATA) begin
                if (!out_ctxt_tlast)
                  if (out_ctxt_tuser == CONTEXT_FIELD_HDR_TS)
                    state <= ST_MDATA;
                  else
                    state <= ST_DROP_CTXT;
                else
                  state <= ST_DROP_PYLD;
              end else begin
                if (out_ctxt_tlast)
                  if (out_ctxt_tuser == CONTEXT_FIELD_HDR_TS)
                    state <= ST_BODY;
                  else
                    state <= ST_DROP_PYLD;
                else
                  state <= ST_DROP_CTXT;
              end
            end else begin



              if (out_pkt_type == CHDR_PKT_TYPE_DATA_TS) begin
                if (!out_ctxt_tlast)
                  if (out_ctxt_tuser == CONTEXT_FIELD_HDR)
                    state <= ST_TS;
                  else
                    state <= ST_DROP_CTXT;
                else
                  state <= ST_DROP_PYLD;
              end else begin
                if (out_num_mdata != CHDR_NO_MDATA) begin
                  if (!out_ctxt_tlast)
                    if (out_ctxt_tuser == CONTEXT_FIELD_HDR)
                      state <= ST_MDATA;
                    else
                      state <= ST_DROP_CTXT;
                  else
                    state <= ST_DROP_PYLD;
                end else begin
                  if (out_ctxt_tlast)
                    if (out_ctxt_tuser == CONTEXT_FIELD_HDR)
                      state <= ST_BODY;
                    else
                      state <= ST_DROP_PYLD;
                  else
                    state <= ST_DROP_CTXT;
                end
              end
            end
          end
        end



        ST_TS: begin
          if (out_ctxt_tvalid && out_ctxt_tready) begin
            if (mdata_pending != CHDR_NO_MDATA) begin
              if (!out_ctxt_tlast)
                if (out_ctxt_tuser == CONTEXT_FIELD_TS)
                  state <= ST_MDATA;
                else
                  state <= ST_DROP_CTXT;
              else
                state <= ST_DROP_PYLD;
            end else begin
              if (out_ctxt_tlast)
                if (out_ctxt_tuser == CONTEXT_FIELD_TS)
                  state <= ST_BODY;
                else
                  state <= ST_DROP_PYLD;
              else
                state <= ST_DROP_CTXT;
            end
          end
        end



        ST_MDATA: begin
          if (out_ctxt_tvalid && out_ctxt_tready) begin
            if (mdata_pending != 5'd1) begin
              mdata_pending <= mdata_pending - 'd1;
              if (!out_ctxt_tlast)
                if (out_ctxt_tuser == CONTEXT_FIELD_MDATA)
                  state <= ST_MDATA;
                else
                  state <= ST_DROP_CTXT;
              else
                state <= ST_DROP_PYLD;
            end else begin
              if (out_ctxt_tlast)
                if (out_ctxt_tuser == CONTEXT_FIELD_MDATA)
                  state <= ST_BODY;
                else
                  state <= ST_DROP_PYLD;
              else
                state <= ST_DROP_CTXT;
            end
          end
        end



        ST_BODY: begin
          if (out_pyld_tvalid && out_pyld_tready) begin
            state <= out_pyld_tlast ? ST_HDR : ST_BODY;
          end
        end



        ST_DROP_CTXT: begin
          if (out_ctxt_tvalid && out_ctxt_tready) begin
            state <= out_ctxt_tlast ? ST_DROP_PYLD : ST_DROP_CTXT;
          end
        end



        ST_DROP_PYLD: begin
          if (out_pyld_tvalid && out_pyld_tready) begin
            state <= out_pyld_tlast ? ST_TERMINATE : ST_DROP_PYLD;
          end
        end



        ST_TERMINATE: begin
          if (chdr_pg_tready) begin
            state <= ST_HDR;
            framer_errors <= framer_errors + 32'd1;
          end
        end

        default: begin

          state <= ST_HDR;
        end
      endcase
    end
  end


  always @(*) begin
    case (state)
      ST_HDR: begin

        chdr_pg_tvalid  = out_ctxt_tvalid;
        chdr_pg_tlast   = 1'b0;
        out_ctxt_tready = chdr_pg_tready;
        out_pyld_tready = 1'b0;
      end
      ST_TS: begin

        chdr_pg_tvalid  = out_ctxt_tvalid;
        chdr_pg_tlast   = 1'b0;
        out_ctxt_tready = chdr_pg_tready;
        out_pyld_tready = 1'b0;
      end
      ST_MDATA: begin

        chdr_pg_tvalid  = out_ctxt_tvalid;
        chdr_pg_tlast   = 1'b0;
        out_ctxt_tready = chdr_pg_tready;
        out_pyld_tready = 1'b0;
      end
      ST_BODY: begin

        chdr_pg_tvalid  = out_pyld_tvalid;
        chdr_pg_tlast   = out_pyld_tlast;
        out_ctxt_tready = 1'b0;
        out_pyld_tready = chdr_pg_tready;
      end
      ST_DROP_CTXT: begin

        chdr_pg_tvalid  = 1'b0;
        chdr_pg_tlast   = 1'b0;
        out_ctxt_tready = 1'b1;
        out_pyld_tready = 1'b0;
      end
      ST_DROP_PYLD: begin

        chdr_pg_tvalid  = 1'b0;
        chdr_pg_tlast   = 1'b0;
        out_ctxt_tready = 1'b0;
        out_pyld_tready = 1'b1;
      end
      ST_TERMINATE: begin


        chdr_pg_tvalid  = 1'b1;
        chdr_pg_tlast   = 1'b1;
        out_ctxt_tready = 1'b0;
        out_pyld_tready = 1'b0;
      end
      default: begin
        chdr_pg_tvalid  = 1'b0;
        chdr_pg_tlast   = 1'b0;
        out_ctxt_tready = 1'b0;
        out_pyld_tready = 1'b0;
      end
    endcase
  end

  assign chdr_pg_tdata  = (state == ST_BODY) ? out_pyld_tdata : out_ctxt_tdata;
  assign chdr_pg_terror = (state == ST_TERMINATE);





  wire [CHDR_W-1:0] chdr_flush_tdata;
  wire              chdr_flush_tlast, chdr_flush_tvalid;
  wire              chdr_flush_terror, chdr_flush_tready;

  axis_packet_flush #(
    .WIDTH(CHDR_W+1), .FLUSH_PARTIAL_PKTS(0), .TIMEOUT_W(32), .PIPELINE("IN")
  ) chdr_flusher_i (
    .clk(axis_chdr_clk), .reset(axis_chdr_rst),
    .enable(flush_en), .timeout(flush_timeout),
    .flushing(flush_active), .done(flush_done),
    .s_axis_tdata({chdr_pg_terror, chdr_pg_tdata}), .s_axis_tlast(chdr_pg_tlast),
    .s_axis_tvalid(chdr_pg_tvalid), .s_axis_tready(chdr_pg_tready),
    .m_axis_tdata({chdr_flush_terror, chdr_flush_tdata}), .m_axis_tlast(chdr_flush_tlast),
    .m_axis_tvalid(chdr_flush_tvalid), .m_axis_tready(chdr_flush_tready)
  );

  axi_packet_gate #( .WIDTH(CHDR_W), .SIZE(MTU), .USE_AS_BUFF(0) ) out_gate_i (
    .clk(axis_chdr_clk), .reset(axis_chdr_rst), .clear(flush_active),
    .i_tdata(chdr_flush_tdata), .i_tlast(chdr_flush_tlast), .i_terror(chdr_flush_terror),
    .i_tvalid(chdr_flush_tvalid), .i_tready(chdr_flush_tready),
    .o_tdata(m_axis_chdr_tdata), .o_tlast(m_axis_chdr_tlast),
    .o_tvalid(m_axis_chdr_tvalid), .o_tready(m_axis_chdr_tready)
  );

endmodule