data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v
 line:136: before: ","
1: b'%Warning-LITENDIAN: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:141: Little bit endian vector: MSB < LSB of bit range: -1:0\nreg [SEG_SEL_WIDTH-1:0] seg_offset_cyc;\n    ^\n                    ... Use "/* verilator lint_off LITENDIAN */" and lint_on around source to disable this message.\n%Warning-LITENDIAN: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:185: Little bit endian vector: MSB < LSB of bit range: -1:0\nwire [SEG_SEL_WIDTH-1:0] fifo_seg_offset;\n     ^\n%Error: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:191: Cannot find file containing module: \'pcie_tlp_fifo_raw\'\npcie_tlp_fifo_raw #(\n^~~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/164569208/rtl,data/full_repos/permissive/164569208/pcie_tlp_fifo_raw\n             data/full_repos/permissive/164569208/rtl,data/full_repos/permissive/164569208/pcie_tlp_fifo_raw.v\n             data/full_repos/permissive/164569208/rtl,data/full_repos/permissive/164569208/pcie_tlp_fifo_raw.sv\n             pcie_tlp_fifo_raw\n             pcie_tlp_fifo_raw.v\n             pcie_tlp_fifo_raw.sv\n             obj_dir/pcie_tlp_fifo_raw\n             obj_dir/pcie_tlp_fifo_raw.v\n             obj_dir/pcie_tlp_fifo_raw.sv\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:308: Bit extraction of var[0:0] requires 1 bit index, not 2 bits.\n                                                                            : ... In instance pcie_us_if_cc\n            if (fifo_tlp_valid[seg_offset_cyc]) begin\n                              ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:314: Bit extraction of var[0:0] requires 1 bit index, not 2 bits.\n                                                                            : ... In instance pcie_us_if_cc\n        valid = fifo_tlp_valid[seg_offset_cyc];\n                              ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:315: Bit extraction of var[0:0] requires 1 bit index, not 2 bits.\n                                                                            : ... In instance pcie_us_if_cc\n        sop = fifo_tlp_sop[seg_offset_cyc];\n                          ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:316: Bit extraction of var[0:0] requires 1 bit index, not 2 bits.\n                                                                            : ... In instance pcie_us_if_cc\n        eop = fifo_tlp_eop[seg_offset_cyc];\n                          ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:321: Operator ASSIGN expects 1 bits on the Assign RHS, but Assign RHS\'s VARREF \'seg_offset_cyc\' generates 2 bits.\n                                                                            : ... In instance pcie_us_if_cc\n        out_sel_seg[seg] = seg_offset_cyc;\n                         ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:330: Logical Operator LOGAND expects 1 bit on the RHS, but RHS\'s SHIFTR generates 8 bits.\n                                                                            : ... In instance pcie_us_if_cc\n        end else if (eop && fifo_tlp_strb[seg_offset_cyc*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH] >> (INT_TLP_SEG_STRB_WIDTH-(AXIS_PCIE_DATA_WIDTH == 64 ? 1 : 3))) begin\n                         ^~\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:394: Operator ASSIGN expects 13 bits on the Assign RHS, but Assign RHS\'s SEL generates 12 bits.\n                                                                            : ... In instance pcie_us_if_cc\n        seg_cc_hdr[28:16] = seg_tlp_hdr[75:64];  \n                          ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:397: Operator ASSIGN expects 11 bits on the Assign RHS, but Assign RHS\'s SEL generates 10 bits.\n                                                                            : ... In instance pcie_us_if_cc\n        seg_cc_hdr[42:32] = seg_tlp_hdr[105:96];  \n                          ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:411: Operator ASSIGN expects 256 bits on the Assign RHS, but Assign RHS\'s VARREF \'out_shift_tlp_data_next\' generates 96 bits.\n                                                                            : ... In instance pcie_us_if_cc\n            out_tlp_data[seg*INT_TLP_SEG_DATA_WIDTH +: INT_TLP_SEG_DATA_WIDTH] = out_shift_tlp_data_next;\n                                                                               ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:412: Operator ASSIGN expects 8 bits on the Assign RHS, but Assign RHS\'s VARREF \'out_shift_tlp_strb_next\' generates 3 bits.\n                                                                            : ... In instance pcie_us_if_cc\n            out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH] = out_shift_tlp_strb_next;\n                                                                               ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:419: Operator ASSIGN expects 256 bits on the Assign RHS, but Assign RHS\'s SEL generates 64 bits.\n                                                                            : ... In instance pcie_us_if_cc\n                out_tlp_data[seg*INT_TLP_SEG_DATA_WIDTH +: INT_TLP_SEG_DATA_WIDTH] = seg_cc_hdr[63:0];\n                                                                                   ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:420: Operator ASSIGN expects 8 bits on the Assign RHS, but Assign RHS\'s CONST \'2\'h3\' generates 2 bits.\n                                                                            : ... In instance pcie_us_if_cc\n                out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH] = 2\'b11;\n                                                                                   ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:431: Operator ADD expects 32 or 9 bits on the LHS, but LHS\'s ARRAYSEL generates 1 bits.\n                                                                            : ... In instance pcie_us_if_cc\n                out_shift_tlp_data_next = fifo_tlp_data[(out_sel_seg[seg]+1)*INT_TLP_SEG_DATA_WIDTH-32 +: 32];\n                                                                         ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:431: Operator ASSIGN expects 96 bits on the Assign RHS, but Assign RHS\'s SEL generates 32 bits.\n                                                                            : ... In instance pcie_us_if_cc\n                out_shift_tlp_data_next = fifo_tlp_data[(out_sel_seg[seg]+1)*INT_TLP_SEG_DATA_WIDTH-32 +: 32];\n                                        ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:432: Operator ADD expects 32 or 9 bits on the LHS, but LHS\'s ARRAYSEL generates 1 bits.\n                                                                            : ... In instance pcie_us_if_cc\n                out_shift_tlp_strb_next = fifo_tlp_strb[(out_sel_seg[seg]+1)*INT_TLP_SEG_STRB_WIDTH-1 +: 1];\n                                                                         ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:432: Operator ASSIGN expects 3 bits on the Assign RHS, but Assign RHS\'s SEL generates 1 bits.\n                                                                            : ... In instance pcie_us_if_cc\n                out_shift_tlp_strb_next = fifo_tlp_strb[(out_sel_seg[seg]+1)*INT_TLP_SEG_STRB_WIDTH-1 +: 1];\n                                        ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:435: Operator ASSIGN expects 256 bits on the Assign RHS, but Assign RHS\'s VARREF \'out_shift_tlp_data_next\' generates 96 bits.\n                                                                            : ... In instance pcie_us_if_cc\n            out_tlp_data[seg*INT_TLP_SEG_DATA_WIDTH +: INT_TLP_SEG_DATA_WIDTH] = out_shift_tlp_data_next;\n                                                                               ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:436: Operator ASSIGN expects 8 bits on the Assign RHS, but Assign RHS\'s VARREF \'out_shift_tlp_strb_next\' generates 3 bits.\n                                                                            : ... In instance pcie_us_if_cc\n            out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH] = out_shift_tlp_strb_next;\n                                                                               ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:452: Operator ADD expects 32 or 9 bits on the LHS, but LHS\'s ARRAYSEL generates 1 bits.\n                                                                            : ... In instance pcie_us_if_cc\n                out_shift_tlp_data_next = fifo_tlp_data[(out_sel_seg[seg]+1)*INT_TLP_SEG_DATA_WIDTH-96 +: 96];\n                                                                         ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:453: Operator ADD expects 32 or 9 bits on the LHS, but LHS\'s ARRAYSEL generates 1 bits.\n                                                                            : ... In instance pcie_us_if_cc\n                out_shift_tlp_strb_next = fifo_tlp_strb[(out_sel_seg[seg]+1)*INT_TLP_SEG_STRB_WIDTH-3 +: 3];\n                                                                         ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:462: Operator ASSIGN expects 3 bits on the Assign RHS, but Assign RHS\'s VARREF \'lane\' generates 32 bits.\n                                                                            : ... In instance pcie_us_if_cc\n                eop_index[seg*3 +: 3] = lane;\n                                      ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:482: Operator AND expects 2 bits on the LHS, but LHS\'s VARREF \'out_tlp_valid\' generates 1 bits.\n                                                                            : ... In instance pcie_us_if_cc\n            case (out_tlp_valid & out_tlp_sop)\n                                ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:482: Operator AND expects 2 bits on the RHS, but RHS\'s VARREF \'out_tlp_sop\' generates 1 bits.\n                                                                            : ... In instance pcie_us_if_cc\n            case (out_tlp_valid & out_tlp_sop)\n                                ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:512: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s SEL generates 3 bits.\n                                                                            : ... In instance pcie_us_if_cc\n                    m_axis_cc_tuser_next[11:8]  = eop_index[0*3 +: 3];  \n                                                ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:522: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s SEL generates 3 bits.\n                                                                            : ... In instance pcie_us_if_cc\n                    m_axis_cc_tuser_next[11:8]  = eop_index[0*3 +: 3];  \n                                                ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:504: Operator AND expects 2 bits on the LHS, but LHS\'s VARREF \'out_tlp_valid\' generates 1 bits.\n                                                                            : ... In instance pcie_us_if_cc\n            case (out_tlp_valid & out_tlp_eop)\n                                ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:504: Operator AND expects 2 bits on the RHS, but RHS\'s VARREF \'out_tlp_eop\' generates 1 bits.\n                                                                            : ... In instance pcie_us_if_cc\n            case (out_tlp_valid & out_tlp_eop)\n                                ^\n%Error: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:527: Extracting 64 bits from only 33 bit number\n                                                                    : ... In instance pcie_us_if_cc\n            m_axis_cc_tuser_next[80:17] = 64\'d0;  \n                                ^\n%Warning-SELRANGE: data/full_repos/permissive/164569208/rtl/pcie_us_if_cc.v:527: Selection index out of range: 80:17 outside 32:0\n                                                                               : ... In instance pcie_us_if_cc\n            m_axis_cc_tuser_next[80:17] = 64\'d0;  \n                                ^\n%Error: Exiting due to 2 error(s), 30 warning(s)\n'
module pcie_us_if_cc #
(

    parameter AXIS_PCIE_DATA_WIDTH = 256,

    parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32),

    parameter AXIS_PCIE_CC_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 33 : 81,

    parameter CC_STRADDLE = AXIS_PCIE_DATA_WIDTH >= 512,

    parameter TLP_DATA_WIDTH = AXIS_PCIE_DATA_WIDTH,

    parameter TLP_STRB_WIDTH = TLP_DATA_WIDTH/32,

    parameter TLP_HDR_WIDTH = 128,

    parameter TLP_SEG_COUNT = 1
)
(
    input  wire                                    clk,
    input  wire                                    rst,


    output wire [AXIS_PCIE_DATA_WIDTH-1:0]         m_axis_cc_tdata,
    output wire [AXIS_PCIE_KEEP_WIDTH-1:0]         m_axis_cc_tkeep,
    output wire                                    m_axis_cc_tvalid,
    input  wire                                    m_axis_cc_tready,
    output wire                                    m_axis_cc_tlast,
    output wire [AXIS_PCIE_CC_USER_WIDTH-1:0]      m_axis_cc_tuser,


    input  wire [TLP_DATA_WIDTH-1:0]               tx_cpl_tlp_data,
    input  wire [TLP_STRB_WIDTH-1:0]               tx_cpl_tlp_strb,
    input  wire [TLP_SEG_COUNT*TLP_HDR_WIDTH-1:0]  tx_cpl_tlp_hdr,
    input  wire [TLP_SEG_COUNT-1:0]                tx_cpl_tlp_valid,
    input  wire [TLP_SEG_COUNT-1:0]                tx_cpl_tlp_sop,
    input  wire [TLP_SEG_COUNT-1:0]                tx_cpl_tlp_eop,
    output wire                                    tx_cpl_tlp_ready
);

parameter TLP_DATA_WIDTH_BYTES = TLP_DATA_WIDTH/8;
parameter TLP_DATA_WIDTH_DWORDS = TLP_DATA_WIDTH/32;

parameter INT_TLP_SEG_COUNT = (CC_STRADDLE && AXIS_PCIE_DATA_WIDTH >= 512) ? 2 : 1;
parameter INT_TLP_SEG_DATA_WIDTH = TLP_DATA_WIDTH / INT_TLP_SEG_COUNT;
parameter INT_TLP_SEG_STRB_WIDTH = TLP_STRB_WIDTH / INT_TLP_SEG_COUNT;

parameter SEG_SEL_WIDTH = $clog2(INT_TLP_SEG_COUNT);


initial begin
    if (AXIS_PCIE_DATA_WIDTH != 64 && AXIS_PCIE_DATA_WIDTH != 128 && AXIS_PCIE_DATA_WIDTH != 256 && AXIS_PCIE_DATA_WIDTH != 512) begin
        $error("Error: PCIe interface width must be 64, 128, 256, or 512 (instance %m)");
        $finish;
    end

    if (AXIS_PCIE_KEEP_WIDTH * 32 != AXIS_PCIE_DATA_WIDTH) begin
        $error("Error: PCIe interface requires dword (32-bit) granularity (instance %m)");
        $finish;
    end

    if (AXIS_PCIE_DATA_WIDTH == 512) begin
        if (AXIS_PCIE_CC_USER_WIDTH != 81) begin
            $error("Error: PCIe CC tuser width must be 81 (instance %m)");
            $finish;
        end
    end else begin
        if (AXIS_PCIE_CC_USER_WIDTH != 33) begin
            $error("Error: PCIe CC tuser width must be 33 (instance %m)");
            $finish;
        end
    end

    if (TLP_DATA_WIDTH != AXIS_PCIE_DATA_WIDTH) begin
        $error("Error: Interface widths must match (instance %m)");
        $finish;
    end

    if (TLP_HDR_WIDTH != 128) begin
        $error("Error: TLP segment header width must be 128 (instance %m)");
        $finish;
    end
end

localparam [2:0]
    TLP_FMT_3DW = 3'b000,
    TLP_FMT_4DW = 3'b001,
    TLP_FMT_3DW_DATA = 3'b010,
    TLP_FMT_4DW_DATA = 3'b011,
    TLP_FMT_PREFIX = 3'b100;

localparam [2:0]
    CPL_STATUS_SC  = 3'b000,
    CPL_STATUS_UR  = 3'b001,
    CPL_STATUS_CRS = 3'b010,
    CPL_STATUS_CA  = 3'b100;

reg frame_reg = 1'b0, frame_next, frame_cyc;
reg tlp_hdr1_reg = 1'b0, tlp_hdr1_next, tlp_hdr1_cyc;
reg tlp_hdr2_reg = 1'b0, tlp_hdr2_next, tlp_hdr2_cyc;
reg tlp_split1_reg = 1'b0, tlp_split1_next, tlp_split1_cyc;
reg tlp_split2_reg = 1'b0, tlp_split2_next, tlp_split2_cyc;
reg [SEG_SEL_WIDTH-1:0] seg_offset_cyc;
reg [SEG_SEL_WIDTH+1-1:0] seg_count_cyc;
reg valid, sop, eop;
reg frame, abort;

reg [INT_TLP_SEG_COUNT-1:0] out_sel, out_sel_cyc;
reg [INT_TLP_SEG_COUNT-1:0] out_sop;
reg [INT_TLP_SEG_COUNT-1:0] out_eop;
reg [INT_TLP_SEG_COUNT-1:0] out_tlp_hdr1;
reg [INT_TLP_SEG_COUNT-1:0] out_tlp_hdr2;
reg [INT_TLP_SEG_COUNT-1:0] out_tlp_split1;
reg [INT_TLP_SEG_COUNT-1:0] out_tlp_split2;
reg [SEG_SEL_WIDTH+1-1:0] out_sel_seg[0:INT_TLP_SEG_COUNT-1];

reg [TLP_DATA_WIDTH-1:0] out_tlp_data;
reg [TLP_STRB_WIDTH-1:0] out_tlp_strb;
reg [INT_TLP_SEG_COUNT-1:0] out_tlp_valid;
reg [INT_TLP_SEG_COUNT-1:0] out_tlp_sop;
reg [INT_TLP_SEG_COUNT-1:0] out_tlp_eop;
reg [95:0] out_shift_tlp_data_reg = 0, out_shift_tlp_data_next;
reg [2:0] out_shift_tlp_strb_reg = 0, out_shift_tlp_strb_next;

reg [127:0] seg_tlp_hdr;
reg [95:0] seg_cc_hdr;
reg [INT_TLP_SEG_COUNT*3-1:0] eop_index;

reg [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata_reg = 0, m_axis_cc_tdata_next;
reg [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep_reg = 0, m_axis_cc_tkeep_next;
reg m_axis_cc_tvalid_reg = 1'b0, m_axis_cc_tvalid_next;
reg m_axis_cc_tlast_reg = 1'b0, m_axis_cc_tlast_next;
reg [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser_reg = 0, m_axis_cc_tuser_next;

assign m_axis_cc_tdata = m_axis_cc_tdata_reg;
assign m_axis_cc_tkeep = m_axis_cc_tkeep_reg;
assign m_axis_cc_tvalid = m_axis_cc_tvalid_reg;
assign m_axis_cc_tlast = m_axis_cc_tlast_reg;
assign m_axis_cc_tuser = m_axis_cc_tuser_reg;

wire [TLP_DATA_WIDTH-1:0] fifo_tlp_data;
wire [TLP_STRB_WIDTH-1:0] fifo_tlp_strb;
wire [INT_TLP_SEG_COUNT*TLP_HDR_WIDTH-1:0] fifo_tlp_hdr;
wire [INT_TLP_SEG_COUNT-1:0] fifo_tlp_valid;
wire [INT_TLP_SEG_COUNT-1:0] fifo_tlp_sop;
wire [INT_TLP_SEG_COUNT-1:0] fifo_tlp_eop;
wire [SEG_SEL_WIDTH-1:0] fifo_seg_offset;
wire [SEG_SEL_WIDTH+1-1:0] fifo_seg_count;
reg fifo_read_en;
reg [SEG_SEL_WIDTH+1-1:0] fifo_read_seg_count;


pcie_tlp_fifo_raw #(
    .DEPTH((1024/4)*2),
    .TLP_DATA_WIDTH(TLP_DATA_WIDTH),
    .TLP_STRB_WIDTH(TLP_STRB_WIDTH),
    .TLP_HDR_WIDTH(TLP_HDR_WIDTH),
    .SEQ_NUM_WIDTH(1),
    .IN_TLP_SEG_COUNT(TLP_SEG_COUNT),
    .OUT_TLP_SEG_COUNT(INT_TLP_SEG_COUNT),
    .CTRL_OUT_EN(0)
)
cpl_fifo_inst (
    .clk(clk),
    .rst(rst),


    .in_tlp_data(tx_cpl_tlp_data),
    .in_tlp_strb(tx_cpl_tlp_strb),
    .in_tlp_hdr(tx_cpl_tlp_hdr),
    .in_tlp_seq(0),
    .in_tlp_bar_id(0),
    .in_tlp_func_num(0),
    .in_tlp_error(0),
    .in_tlp_valid(tx_cpl_tlp_valid),
    .in_tlp_sop(tx_cpl_tlp_sop),
    .in_tlp_eop(tx_cpl_tlp_eop),
    .in_tlp_ready(tx_cpl_tlp_ready),


    .out_tlp_data(fifo_tlp_data),
    .out_tlp_strb(fifo_tlp_strb),
    .out_tlp_hdr(fifo_tlp_hdr),
    .out_tlp_seq(),
    .out_tlp_bar_id(),
    .out_tlp_func_num(),
    .out_tlp_error(),
    .out_tlp_valid(fifo_tlp_valid),
    .out_tlp_sop(fifo_tlp_sop),
    .out_tlp_eop(fifo_tlp_eop),
    .out_seg_offset(fifo_seg_offset),
    .out_seg_count(fifo_seg_count),
    .out_read_en(fifo_read_en),
    .out_read_seg_count(fifo_read_seg_count),

    .out_ctrl_tlp_strb(),
    .out_ctrl_tlp_hdr(),
    .out_ctrl_tlp_valid(),
    .out_ctrl_tlp_sop(),
    .out_ctrl_tlp_eop(),
    .out_ctrl_seg_offset(),
    .out_ctrl_seg_count(),
    .out_ctrl_read_en(0),
    .out_ctrl_read_seg_count(0),


    .half_full(),
    .watermark()
);

integer seg, cur_seg, lane;

always @* begin
    frame_next = frame_reg;
    tlp_hdr1_next = tlp_hdr1_reg;
    tlp_hdr2_next = tlp_hdr2_reg;
    tlp_split1_next = tlp_split1_reg;
    tlp_split2_next = tlp_split2_reg;

    m_axis_cc_tdata_next = m_axis_cc_tdata_reg;
    m_axis_cc_tkeep_next = m_axis_cc_tkeep_reg;
    m_axis_cc_tvalid_next = m_axis_cc_tvalid_reg && !m_axis_cc_tready;
    m_axis_cc_tlast_next = m_axis_cc_tlast_reg;
    m_axis_cc_tuser_next = m_axis_cc_tuser_reg;

    fifo_read_en = 0;

    frame_cyc = frame_reg;
    tlp_hdr1_cyc = tlp_hdr1_reg;
    tlp_hdr2_cyc = tlp_hdr2_reg;
    tlp_split1_cyc = tlp_split1_reg;
    tlp_split2_cyc = tlp_split2_reg;
    seg_offset_cyc = fifo_seg_offset;
    seg_count_cyc = 0;
    valid = 0;
    eop = 0;
    frame = frame_cyc;
    abort = 0;

    fifo_read_seg_count = 0;

    out_sel = 0;
    out_sel_cyc = 0;
    out_sop = 0;
    out_eop = 0;
    out_tlp_hdr1 = 0;
    out_tlp_hdr2 = 0;
    out_tlp_split1 = 0;
    out_tlp_split2 = 0;
    for (seg = 0; seg < INT_TLP_SEG_COUNT; seg = seg + 1) begin
        out_sel_seg[seg] = 0;
    end

    out_shift_tlp_data_next = out_shift_tlp_data_reg;
    out_shift_tlp_strb_next = out_shift_tlp_strb_reg;


    for (seg = 0; seg < INT_TLP_SEG_COUNT; seg = seg + 1) begin
        if (!frame_cyc && !abort) begin
            tlp_hdr1_cyc = 1'b1;
            tlp_hdr2_cyc = 1'b0;
            tlp_split1_cyc = 1'b0;
            tlp_split2_cyc = 1'b0;
            if (fifo_tlp_valid[seg_offset_cyc]) begin
                frame_cyc = 1'b1;
            end
        end


        valid = fifo_tlp_valid[seg_offset_cyc];
        sop = fifo_tlp_sop[seg_offset_cyc];
        eop = fifo_tlp_eop[seg_offset_cyc];
        frame = frame_cyc;

        out_sel_cyc[seg] = 1'b1;
        out_sop[seg] = tlp_hdr1_cyc;
        out_sel_seg[seg] = seg_offset_cyc;

        out_tlp_hdr1[seg] = tlp_hdr1_cyc;
        out_tlp_hdr2[seg] = tlp_hdr2_cyc;

        if (AXIS_PCIE_DATA_WIDTH == 64 && tlp_hdr1_cyc) begin

            tlp_hdr1_cyc = 1'b0;
            tlp_hdr2_cyc = 1'b1;
        end else if (eop && fifo_tlp_strb[seg_offset_cyc*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH] >> (INT_TLP_SEG_STRB_WIDTH-(AXIS_PCIE_DATA_WIDTH == 64 ? 1 : 3))) begin

            tlp_hdr1_cyc = 1'b0;
            tlp_hdr2_cyc = 1'b0;
            if (tlp_split1_cyc) begin
                frame_cyc = 0;
                out_eop[seg] = 1'b1;
                tlp_split1_cyc = 1'b0;
                tlp_split2_cyc = 1'b1;
                seg_offset_cyc = seg_offset_cyc + 1;
                seg_count_cyc = seg_count_cyc + 1;
            end else begin
                tlp_split1_cyc = 1'b1;
            end
        end else begin
            tlp_hdr1_cyc = 1'b0;
            tlp_hdr2_cyc = 1'b0;
            if (eop) begin

                frame_cyc = 0;
                out_eop[seg] = 1'b1;
            end
            seg_offset_cyc = seg_offset_cyc + 1;
            seg_count_cyc = seg_count_cyc + 1;
        end

        out_tlp_split1[seg] = tlp_split1_cyc;
        out_tlp_split2[seg] = tlp_split2_cyc;

        if (frame && !abort) begin
            if (valid) begin
                if (eop || seg == INT_TLP_SEG_COUNT-1) begin

                    fifo_read_seg_count = seg_count_cyc;
                    if (!m_axis_cc_tvalid || m_axis_cc_tready) begin
                        frame_next = frame_cyc;
                        tlp_hdr1_next = tlp_hdr1_cyc;
                        tlp_hdr2_next = tlp_hdr2_cyc;
                        tlp_split1_next = tlp_split1_cyc;
                        tlp_split2_next = tlp_split2_cyc;
                        out_sel = out_sel_cyc;
                        fifo_read_en = seg_count_cyc != 0;
                    end
                end
            end else begin

                abort = 1;
            end
        end
    end

    out_tlp_data = 0;
    out_tlp_strb = 0;
    out_tlp_valid = 0;
    out_tlp_sop = 0;
    out_tlp_eop = 0;

    for (seg = 0; seg < INT_TLP_SEG_COUNT; seg = seg + 1) begin

        seg_tlp_hdr = fifo_tlp_hdr[out_sel_seg[seg]*TLP_HDR_WIDTH +: TLP_HDR_WIDTH];
        seg_cc_hdr[6:0] = seg_tlp_hdr[38:32];
        seg_cc_hdr[7] = 1'b0;
        seg_cc_hdr[9:8] = seg_tlp_hdr[107:106];
        seg_cc_hdr[15:10] = 6'd0;
        seg_cc_hdr[28:16] = seg_tlp_hdr[75:64];
        seg_cc_hdr[29] = 1'b0;
        seg_cc_hdr[31:30] = 2'd0;
        seg_cc_hdr[42:32] = seg_tlp_hdr[105:96];
        seg_cc_hdr[45:43] = seg_tlp_hdr[79:77];
        seg_cc_hdr[46] = seg_tlp_hdr[110];
        seg_cc_hdr[47] = 1'b0;
        seg_cc_hdr[63:48] = seg_tlp_hdr[63:48];
        seg_cc_hdr[71:64] = seg_tlp_hdr[47:40];
        seg_cc_hdr[87:72] = seg_tlp_hdr[95:80];
        seg_cc_hdr[88] = 1'b0;
        seg_cc_hdr[91:89] = seg_tlp_hdr[118:116];
        seg_cc_hdr[94:92] = {seg_tlp_hdr[114], seg_tlp_hdr[109:108]};
        seg_cc_hdr[95] = 1'b0;


        if (AXIS_PCIE_DATA_WIDTH == 64) begin
            out_tlp_data[seg*INT_TLP_SEG_DATA_WIDTH +: INT_TLP_SEG_DATA_WIDTH] = out_shift_tlp_data_next;
            out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH] = out_shift_tlp_strb_next;
            out_tlp_data[seg*INT_TLP_SEG_DATA_WIDTH+32 +: INT_TLP_SEG_DATA_WIDTH-32] = fifo_tlp_data[out_sel_seg[seg]*INT_TLP_SEG_DATA_WIDTH +: INT_TLP_SEG_DATA_WIDTH-32];
            if (!out_tlp_split2[seg]) begin
                out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH+1 +: INT_TLP_SEG_STRB_WIDTH-1] = fifo_tlp_strb[out_sel_seg[seg]*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH-1];
            end

            if (out_tlp_hdr1[seg]) begin
                out_tlp_data[seg*INT_TLP_SEG_DATA_WIDTH +: INT_TLP_SEG_DATA_WIDTH] = seg_cc_hdr[63:0];
                out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH] = 2'b11;
            end else if (out_tlp_hdr2[seg]) begin
                out_tlp_data[seg*INT_TLP_SEG_DATA_WIDTH +: 32] = seg_cc_hdr[95:64];
                out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH +: 1] = 1'b1;
            end

            out_tlp_valid[seg] = out_sel[seg];
            out_tlp_sop[seg] = out_sop[seg];
            out_tlp_eop[seg] = out_eop[seg];

            if (out_sel[seg]) begin
                out_shift_tlp_data_next = fifo_tlp_data[(out_sel_seg[seg]+1)*INT_TLP_SEG_DATA_WIDTH-32 +: 32];
                out_shift_tlp_strb_next = fifo_tlp_strb[(out_sel_seg[seg]+1)*INT_TLP_SEG_STRB_WIDTH-1 +: 1];
            end
        end else begin
            out_tlp_data[seg*INT_TLP_SEG_DATA_WIDTH +: INT_TLP_SEG_DATA_WIDTH] = out_shift_tlp_data_next;
            out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH] = out_shift_tlp_strb_next;
            out_tlp_data[seg*INT_TLP_SEG_DATA_WIDTH+96 +: INT_TLP_SEG_DATA_WIDTH-96] = fifo_tlp_data[out_sel_seg[seg]*INT_TLP_SEG_DATA_WIDTH +: INT_TLP_SEG_DATA_WIDTH-96];
            if (!out_tlp_split2[seg]) begin
                out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH+3 +: INT_TLP_SEG_STRB_WIDTH-3] = fifo_tlp_strb[out_sel_seg[seg]*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH-3];
            end

            if (out_tlp_hdr1[seg]) begin
                out_tlp_data[seg*INT_TLP_SEG_DATA_WIDTH +: 96] = seg_cc_hdr;
                out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH +: 3] = 3'b111;
            end

            out_tlp_valid[seg] = out_sel[seg];
            out_tlp_sop[seg] = out_sop[seg];
            out_tlp_eop[seg] = out_eop[seg];

            if (out_sel[seg]) begin
                out_shift_tlp_data_next = fifo_tlp_data[(out_sel_seg[seg]+1)*INT_TLP_SEG_DATA_WIDTH-96 +: 96];
                out_shift_tlp_strb_next = fifo_tlp_strb[(out_sel_seg[seg]+1)*INT_TLP_SEG_STRB_WIDTH-3 +: 3];
            end
        end
    end

    eop_index = 0;
    for (seg = 0; seg < INT_TLP_SEG_COUNT; seg = seg + 1) begin
        for (lane = 0; lane < INT_TLP_SEG_STRB_WIDTH; lane = lane + 1) begin
            if (out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH+lane]) begin
                eop_index[seg*3 +: 3] = lane;
            end
        end
    end

    if (!m_axis_cc_tvalid || m_axis_cc_tready) begin

        m_axis_cc_tdata_next = out_tlp_data;
        m_axis_cc_tkeep_next = 0;
        m_axis_cc_tvalid_next = out_tlp_valid != 0;
        m_axis_cc_tlast_next = !(CC_STRADDLE && AXIS_PCIE_DATA_WIDTH == 512) && (out_tlp_valid & out_tlp_eop);
        m_axis_cc_tuser_next = 0;

        for (seg = 0; seg < INT_TLP_SEG_COUNT; seg = seg + 1) begin
            if (out_tlp_valid[seg]) begin
                m_axis_cc_tkeep_next[seg*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH] = out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH];
            end
        end

        if (AXIS_PCIE_DATA_WIDTH == 512) begin
            case (out_tlp_valid & out_tlp_sop)
                2'b00: begin
                    m_axis_cc_tuser_next[1:0] = 2'b00;
                    m_axis_cc_tuser_next[3:2] = 2'd0;
                    m_axis_cc_tuser_next[5:4] = 2'd0;
                end
                2'b01: begin
                    m_axis_cc_tuser_next[1:0] = 2'b01;
                    m_axis_cc_tuser_next[3:2] = 2'd0;
                    m_axis_cc_tuser_next[5:4] = 2'd0;
                end
                2'b10: begin
                    m_axis_cc_tuser_next[1:0] = 2'b01;
                    m_axis_cc_tuser_next[3:2] = 2'd2;
                    m_axis_cc_tuser_next[5:4] = 2'd0;
                end
                2'b11: begin
                    m_axis_cc_tuser_next[1:0] = 2'b11;
                    m_axis_cc_tuser_next[3:2] = 2'd0;
                    m_axis_cc_tuser_next[5:4] = 2'd2;
                end
            endcase
            case (out_tlp_valid & out_tlp_eop)
                2'b00: begin
                    m_axis_cc_tuser_next[7:6] = 2'b00;
                    m_axis_cc_tuser_next[11:8]  = 4'd0;
                    m_axis_cc_tuser_next[15:12] = 4'd0;
                end
                2'b01: begin
                    m_axis_cc_tuser_next[7:6] = 2'b01;
                    m_axis_cc_tuser_next[11:8]  = eop_index[0*3 +: 3];
                    m_axis_cc_tuser_next[15:12] = 4'd0;
                end
                2'b10: begin
                    m_axis_cc_tuser_next[7:6] = 2'b01;
                    m_axis_cc_tuser_next[11:8]  = 4'd8+eop_index[1*3 +: 3];
                    m_axis_cc_tuser_next[15:12] = 4'd0;
                end
                2'b11: begin
                    m_axis_cc_tuser_next[7:6] = 2'b11;
                    m_axis_cc_tuser_next[11:8]  = eop_index[0*3 +: 3];
                    m_axis_cc_tuser_next[15:12] = 4'd8+eop_index[1*3 +: 3];
                end
            endcase
            m_axis_cc_tuser_next[16] = 1'b0;
            m_axis_cc_tuser_next[80:17] = 64'd0;
        end else begin
            m_axis_cc_tuser_next[1] = 1'b0;
            m_axis_cc_tuser_next[32:1] = 32'd0;
        end
    end
end

integer i;

always @(posedge clk) begin
    frame_reg <= frame_next;
    tlp_hdr1_reg <= tlp_hdr1_next;
    tlp_hdr2_reg <= tlp_hdr2_next;
    tlp_split1_reg <= tlp_split1_next;
    tlp_split2_reg <= tlp_split2_next;

    out_shift_tlp_data_reg <= out_shift_tlp_data_next;
    out_shift_tlp_strb_reg <= out_shift_tlp_strb_next;

    m_axis_cc_tdata_reg <= m_axis_cc_tdata_next;
    m_axis_cc_tkeep_reg <= m_axis_cc_tkeep_next;
    m_axis_cc_tvalid_reg <= m_axis_cc_tvalid_next;
    m_axis_cc_tlast_reg <= m_axis_cc_tlast_next;
    m_axis_cc_tuser_reg <= m_axis_cc_tuser_next;

    if (rst) begin
        frame_reg <= 1'b0;

        m_axis_cc_tvalid_reg <= 0;
    end
end

endmodule
module pcie_us_if_cc #
(

    parameter AXIS_PCIE_DATA_WIDTH = 256,

    parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32),

    parameter AXIS_PCIE_CC_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 33 : 81,

    parameter CC_STRADDLE = AXIS_PCIE_DATA_WIDTH >= 512,

    parameter TLP_DATA_WIDTH = AXIS_PCIE_DATA_WIDTH,

    parameter TLP_STRB_WIDTH = TLP_DATA_WIDTH/32,

    parameter TLP_HDR_WIDTH = 128,

    parameter TLP_SEG_COUNT = 1
)
(
    input  wire                                    clk,
    input  wire                                    rst,


    output wire [AXIS_PCIE_DATA_WIDTH-1:0]         m_axis_cc_tdata,
    output wire [AXIS_PCIE_KEEP_WIDTH-1:0]         m_axis_cc_tkeep,
    output wire                                    m_axis_cc_tvalid,
    input  wire                                    m_axis_cc_tready,
    output wire                                    m_axis_cc_tlast,
    output wire [AXIS_PCIE_CC_USER_WIDTH-1:0]      m_axis_cc_tuser,


    input  wire [TLP_DATA_WIDTH-1:0]               tx_cpl_tlp_data,
    input  wire [TLP_STRB_WIDTH-1:0]               tx_cpl_tlp_strb,
    input  wire [TLP_SEG_COUNT*TLP_HDR_WIDTH-1:0]  tx_cpl_tlp_hdr,
    input  wire [TLP_SEG_COUNT-1:0]                tx_cpl_tlp_valid,
    input  wire [TLP_SEG_COUNT-1:0]                tx_cpl_tlp_sop,
    input  wire [TLP_SEG_COUNT-1:0]                tx_cpl_tlp_eop,
    output wire                                    tx_cpl_tlp_ready
);


parameter TLP_DATA_WIDTH_BYTES = TLP_DATA_WIDTH/8;
parameter TLP_DATA_WIDTH_DWORDS = TLP_DATA_WIDTH/32;

parameter INT_TLP_SEG_COUNT = (CC_STRADDLE && AXIS_PCIE_DATA_WIDTH >= 512) ? 2 : 1;
parameter INT_TLP_SEG_DATA_WIDTH = TLP_DATA_WIDTH / INT_TLP_SEG_COUNT;
parameter INT_TLP_SEG_STRB_WIDTH = TLP_STRB_WIDTH / INT_TLP_SEG_COUNT;

parameter SEG_SEL_WIDTH = $clog2(INT_TLP_SEG_COUNT);


initial begin
    if (AXIS_PCIE_DATA_WIDTH != 64 && AXIS_PCIE_DATA_WIDTH != 128 && AXIS_PCIE_DATA_WIDTH != 256 && AXIS_PCIE_DATA_WIDTH != 512) begin
        $error("Error: PCIe interface width must be 64, 128, 256, or 512 (instance %m)");
        $finish;
    end

    if (AXIS_PCIE_KEEP_WIDTH * 32 != AXIS_PCIE_DATA_WIDTH) begin
        $error("Error: PCIe interface requires dword (32-bit) granularity (instance %m)");
        $finish;
    end

    if (AXIS_PCIE_DATA_WIDTH == 512) begin
        if (AXIS_PCIE_CC_USER_WIDTH != 81) begin
            $error("Error: PCIe CC tuser width must be 81 (instance %m)");
            $finish;
        end
    end else begin
        if (AXIS_PCIE_CC_USER_WIDTH != 33) begin
            $error("Error: PCIe CC tuser width must be 33 (instance %m)");
            $finish;
        end
    end

    if (TLP_DATA_WIDTH != AXIS_PCIE_DATA_WIDTH) begin
        $error("Error: Interface widths must match (instance %m)");
        $finish;
    end

    if (TLP_HDR_WIDTH != 128) begin
        $error("Error: TLP segment header width must be 128 (instance %m)");
        $finish;
    end
end

localparam [2:0]
    TLP_FMT_3DW = 3'b000,
    TLP_FMT_4DW = 3'b001,
    TLP_FMT_3DW_DATA = 3'b010,
    TLP_FMT_4DW_DATA = 3'b011,
    TLP_FMT_PREFIX = 3'b100;

localparam [2:0]
    CPL_STATUS_SC  = 3'b000,
    CPL_STATUS_UR  = 3'b001,
    CPL_STATUS_CRS = 3'b010,
    CPL_STATUS_CA  = 3'b100;

reg frame_reg = 1'b0, frame_next, frame_cyc;
reg tlp_hdr1_reg = 1'b0, tlp_hdr1_next, tlp_hdr1_cyc;
reg tlp_hdr2_reg = 1'b0, tlp_hdr2_next, tlp_hdr2_cyc;
reg tlp_split1_reg = 1'b0, tlp_split1_next, tlp_split1_cyc;
reg tlp_split2_reg = 1'b0, tlp_split2_next, tlp_split2_cyc;
reg [SEG_SEL_WIDTH-1:0] seg_offset_cyc;
reg [SEG_SEL_WIDTH+1-1:0] seg_count_cyc;
reg valid, sop, eop;
reg frame, abort;

reg [INT_TLP_SEG_COUNT-1:0] out_sel, out_sel_cyc;
reg [INT_TLP_SEG_COUNT-1:0] out_sop;
reg [INT_TLP_SEG_COUNT-1:0] out_eop;
reg [INT_TLP_SEG_COUNT-1:0] out_tlp_hdr1;
reg [INT_TLP_SEG_COUNT-1:0] out_tlp_hdr2;
reg [INT_TLP_SEG_COUNT-1:0] out_tlp_split1;
reg [INT_TLP_SEG_COUNT-1:0] out_tlp_split2;
reg [SEG_SEL_WIDTH+1-1:0] out_sel_seg[0:INT_TLP_SEG_COUNT-1];

reg [TLP_DATA_WIDTH-1:0] out_tlp_data;
reg [TLP_STRB_WIDTH-1:0] out_tlp_strb;
reg [INT_TLP_SEG_COUNT-1:0] out_tlp_valid;
reg [INT_TLP_SEG_COUNT-1:0] out_tlp_sop;
reg [INT_TLP_SEG_COUNT-1:0] out_tlp_eop;
reg [95:0] out_shift_tlp_data_reg = 0, out_shift_tlp_data_next;
reg [2:0] out_shift_tlp_strb_reg = 0, out_shift_tlp_strb_next;

reg [127:0] seg_tlp_hdr;
reg [95:0] seg_cc_hdr;
reg [INT_TLP_SEG_COUNT*3-1:0] eop_index;

reg [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata_reg = 0, m_axis_cc_tdata_next;
reg [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep_reg = 0, m_axis_cc_tkeep_next;
reg m_axis_cc_tvalid_reg = 1'b0, m_axis_cc_tvalid_next;
reg m_axis_cc_tlast_reg = 1'b0, m_axis_cc_tlast_next;
reg [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser_reg = 0, m_axis_cc_tuser_next;

assign m_axis_cc_tdata = m_axis_cc_tdata_reg;
assign m_axis_cc_tkeep = m_axis_cc_tkeep_reg;
assign m_axis_cc_tvalid = m_axis_cc_tvalid_reg;
assign m_axis_cc_tlast = m_axis_cc_tlast_reg;
assign m_axis_cc_tuser = m_axis_cc_tuser_reg;

wire [TLP_DATA_WIDTH-1:0] fifo_tlp_data;
wire [TLP_STRB_WIDTH-1:0] fifo_tlp_strb;
wire [INT_TLP_SEG_COUNT*TLP_HDR_WIDTH-1:0] fifo_tlp_hdr;
wire [INT_TLP_SEG_COUNT-1:0] fifo_tlp_valid;
wire [INT_TLP_SEG_COUNT-1:0] fifo_tlp_sop;
wire [INT_TLP_SEG_COUNT-1:0] fifo_tlp_eop;
wire [SEG_SEL_WIDTH-1:0] fifo_seg_offset;
wire [SEG_SEL_WIDTH+1-1:0] fifo_seg_count;
reg fifo_read_en;
reg [SEG_SEL_WIDTH+1-1:0] fifo_read_seg_count;


pcie_tlp_fifo_raw #(
    .DEPTH((1024/4)*2),
    .TLP_DATA_WIDTH(TLP_DATA_WIDTH),
    .TLP_STRB_WIDTH(TLP_STRB_WIDTH),
    .TLP_HDR_WIDTH(TLP_HDR_WIDTH),
    .SEQ_NUM_WIDTH(1),
    .IN_TLP_SEG_COUNT(TLP_SEG_COUNT),
    .OUT_TLP_SEG_COUNT(INT_TLP_SEG_COUNT),
    .CTRL_OUT_EN(0)
)
cpl_fifo_inst (
    .clk(clk),
    .rst(rst),


    .in_tlp_data(tx_cpl_tlp_data),
    .in_tlp_strb(tx_cpl_tlp_strb),
    .in_tlp_hdr(tx_cpl_tlp_hdr),
    .in_tlp_seq(0),
    .in_tlp_bar_id(0),
    .in_tlp_func_num(0),
    .in_tlp_error(0),
    .in_tlp_valid(tx_cpl_tlp_valid),
    .in_tlp_sop(tx_cpl_tlp_sop),
    .in_tlp_eop(tx_cpl_tlp_eop),
    .in_tlp_ready(tx_cpl_tlp_ready),


    .out_tlp_data(fifo_tlp_data),
    .out_tlp_strb(fifo_tlp_strb),
    .out_tlp_hdr(fifo_tlp_hdr),
    .out_tlp_seq(),
    .out_tlp_bar_id(),
    .out_tlp_func_num(),
    .out_tlp_error(),
    .out_tlp_valid(fifo_tlp_valid),
    .out_tlp_sop(fifo_tlp_sop),
    .out_tlp_eop(fifo_tlp_eop),
    .out_seg_offset(fifo_seg_offset),
    .out_seg_count(fifo_seg_count),
    .out_read_en(fifo_read_en),
    .out_read_seg_count(fifo_read_seg_count),

    .out_ctrl_tlp_strb(),
    .out_ctrl_tlp_hdr(),
    .out_ctrl_tlp_valid(),
    .out_ctrl_tlp_sop(),
    .out_ctrl_tlp_eop(),
    .out_ctrl_seg_offset(),
    .out_ctrl_seg_count(),
    .out_ctrl_read_en(0),
    .out_ctrl_read_seg_count(0),


    .half_full(),
    .watermark()
);

integer seg, cur_seg, lane;

always @* begin
    frame_next = frame_reg;
    tlp_hdr1_next = tlp_hdr1_reg;
    tlp_hdr2_next = tlp_hdr2_reg;
    tlp_split1_next = tlp_split1_reg;
    tlp_split2_next = tlp_split2_reg;

    m_axis_cc_tdata_next = m_axis_cc_tdata_reg;
    m_axis_cc_tkeep_next = m_axis_cc_tkeep_reg;
    m_axis_cc_tvalid_next = m_axis_cc_tvalid_reg && !m_axis_cc_tready;
    m_axis_cc_tlast_next = m_axis_cc_tlast_reg;
    m_axis_cc_tuser_next = m_axis_cc_tuser_reg;

    fifo_read_en = 0;

    frame_cyc = frame_reg;
    tlp_hdr1_cyc = tlp_hdr1_reg;
    tlp_hdr2_cyc = tlp_hdr2_reg;
    tlp_split1_cyc = tlp_split1_reg;
    tlp_split2_cyc = tlp_split2_reg;
    seg_offset_cyc = fifo_seg_offset;
    seg_count_cyc = 0;
    valid = 0;
    eop = 0;
    frame = frame_cyc;
    abort = 0;

    fifo_read_seg_count = 0;

    out_sel = 0;
    out_sel_cyc = 0;
    out_sop = 0;
    out_eop = 0;
    out_tlp_hdr1 = 0;
    out_tlp_hdr2 = 0;
    out_tlp_split1 = 0;
    out_tlp_split2 = 0;
    for (seg = 0; seg < INT_TLP_SEG_COUNT; seg = seg + 1) begin
        out_sel_seg[seg] = 0;
    end

    out_shift_tlp_data_next = out_shift_tlp_data_reg;
    out_shift_tlp_strb_next = out_shift_tlp_strb_reg;


    for (seg = 0; seg < INT_TLP_SEG_COUNT; seg = seg + 1) begin
        if (!frame_cyc && !abort) begin
            tlp_hdr1_cyc = 1'b1;
            tlp_hdr2_cyc = 1'b0;
            tlp_split1_cyc = 1'b0;
            tlp_split2_cyc = 1'b0;
            if (fifo_tlp_valid[seg_offset_cyc]) begin
                frame_cyc = 1'b1;
            end
        end


        valid = fifo_tlp_valid[seg_offset_cyc];
        sop = fifo_tlp_sop[seg_offset_cyc];
        eop = fifo_tlp_eop[seg_offset_cyc];
        frame = frame_cyc;

        out_sel_cyc[seg] = 1'b1;
        out_sop[seg] = tlp_hdr1_cyc;
        out_sel_seg[seg] = seg_offset_cyc;

        out_tlp_hdr1[seg] = tlp_hdr1_cyc;
        out_tlp_hdr2[seg] = tlp_hdr2_cyc;

        if (AXIS_PCIE_DATA_WIDTH == 64 && tlp_hdr1_cyc) begin

            tlp_hdr1_cyc = 1'b0;
            tlp_hdr2_cyc = 1'b1;
        end else if (eop && fifo_tlp_strb[seg_offset_cyc*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH] >> (INT_TLP_SEG_STRB_WIDTH-(AXIS_PCIE_DATA_WIDTH == 64 ? 1 : 3))) begin

            tlp_hdr1_cyc = 1'b0;
            tlp_hdr2_cyc = 1'b0;
            if (tlp_split1_cyc) begin
                frame_cyc = 0;
                out_eop[seg] = 1'b1;
                tlp_split1_cyc = 1'b0;
                tlp_split2_cyc = 1'b1;
                seg_offset_cyc = seg_offset_cyc + 1;
                seg_count_cyc = seg_count_cyc + 1;
            end else begin
                tlp_split1_cyc = 1'b1;
            end
        end else begin
            tlp_hdr1_cyc = 1'b0;
            tlp_hdr2_cyc = 1'b0;
            if (eop) begin

                frame_cyc = 0;
                out_eop[seg] = 1'b1;
            end
            seg_offset_cyc = seg_offset_cyc + 1;
            seg_count_cyc = seg_count_cyc + 1;
        end

        out_tlp_split1[seg] = tlp_split1_cyc;
        out_tlp_split2[seg] = tlp_split2_cyc;

        if (frame && !abort) begin
            if (valid) begin
                if (eop || seg == INT_TLP_SEG_COUNT-1) begin

                    fifo_read_seg_count = seg_count_cyc;
                    if (!m_axis_cc_tvalid || m_axis_cc_tready) begin
                        frame_next = frame_cyc;
                        tlp_hdr1_next = tlp_hdr1_cyc;
                        tlp_hdr2_next = tlp_hdr2_cyc;
                        tlp_split1_next = tlp_split1_cyc;
                        tlp_split2_next = tlp_split2_cyc;
                        out_sel = out_sel_cyc;
                        fifo_read_en = seg_count_cyc != 0;
                    end
                end
            end else begin

                abort = 1;
            end
        end
    end

    out_tlp_data = 0;
    out_tlp_strb = 0;
    out_tlp_valid = 0;
    out_tlp_sop = 0;
    out_tlp_eop = 0;

    for (seg = 0; seg < INT_TLP_SEG_COUNT; seg = seg + 1) begin

        seg_tlp_hdr = fifo_tlp_hdr[out_sel_seg[seg]*TLP_HDR_WIDTH +: TLP_HDR_WIDTH];
        seg_cc_hdr[6:0] = seg_tlp_hdr[38:32];
        seg_cc_hdr[7] = 1'b0;
        seg_cc_hdr[9:8] = seg_tlp_hdr[107:106];
        seg_cc_hdr[15:10] = 6'd0;
        seg_cc_hdr[28:16] = seg_tlp_hdr[75:64];
        seg_cc_hdr[29] = 1'b0;
        seg_cc_hdr[31:30] = 2'd0;
        seg_cc_hdr[42:32] = seg_tlp_hdr[105:96];
        seg_cc_hdr[45:43] = seg_tlp_hdr[79:77];
        seg_cc_hdr[46] = seg_tlp_hdr[110];
        seg_cc_hdr[47] = 1'b0;
        seg_cc_hdr[63:48] = seg_tlp_hdr[63:48];
        seg_cc_hdr[71:64] = seg_tlp_hdr[47:40];
        seg_cc_hdr[87:72] = seg_tlp_hdr[95:80];
        seg_cc_hdr[88] = 1'b0;
        seg_cc_hdr[91:89] = seg_tlp_hdr[118:116];
        seg_cc_hdr[94:92] = {seg_tlp_hdr[114], seg_tlp_hdr[109:108]};
        seg_cc_hdr[95] = 1'b0;


        if (AXIS_PCIE_DATA_WIDTH == 64) begin
            out_tlp_data[seg*INT_TLP_SEG_DATA_WIDTH +: INT_TLP_SEG_DATA_WIDTH] = out_shift_tlp_data_next;
            out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH] = out_shift_tlp_strb_next;
            out_tlp_data[seg*INT_TLP_SEG_DATA_WIDTH+32 +: INT_TLP_SEG_DATA_WIDTH-32] = fifo_tlp_data[out_sel_seg[seg]*INT_TLP_SEG_DATA_WIDTH +: INT_TLP_SEG_DATA_WIDTH-32];
            if (!out_tlp_split2[seg]) begin
                out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH+1 +: INT_TLP_SEG_STRB_WIDTH-1] = fifo_tlp_strb[out_sel_seg[seg]*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH-1];
            end

            if (out_tlp_hdr1[seg]) begin
                out_tlp_data[seg*INT_TLP_SEG_DATA_WIDTH +: INT_TLP_SEG_DATA_WIDTH] = seg_cc_hdr[63:0];
                out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH] = 2'b11;
            end else if (out_tlp_hdr2[seg]) begin
                out_tlp_data[seg*INT_TLP_SEG_DATA_WIDTH +: 32] = seg_cc_hdr[95:64];
                out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH +: 1] = 1'b1;
            end

            out_tlp_valid[seg] = out_sel[seg];
            out_tlp_sop[seg] = out_sop[seg];
            out_tlp_eop[seg] = out_eop[seg];

            if (out_sel[seg]) begin
                out_shift_tlp_data_next = fifo_tlp_data[(out_sel_seg[seg]+1)*INT_TLP_SEG_DATA_WIDTH-32 +: 32];
                out_shift_tlp_strb_next = fifo_tlp_strb[(out_sel_seg[seg]+1)*INT_TLP_SEG_STRB_WIDTH-1 +: 1];
            end
        end else begin
            out_tlp_data[seg*INT_TLP_SEG_DATA_WIDTH +: INT_TLP_SEG_DATA_WIDTH] = out_shift_tlp_data_next;
            out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH] = out_shift_tlp_strb_next;
            out_tlp_data[seg*INT_TLP_SEG_DATA_WIDTH+96 +: INT_TLP_SEG_DATA_WIDTH-96] = fifo_tlp_data[out_sel_seg[seg]*INT_TLP_SEG_DATA_WIDTH +: INT_TLP_SEG_DATA_WIDTH-96];
            if (!out_tlp_split2[seg]) begin
                out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH+3 +: INT_TLP_SEG_STRB_WIDTH-3] = fifo_tlp_strb[out_sel_seg[seg]*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH-3];
            end

            if (out_tlp_hdr1[seg]) begin
                out_tlp_data[seg*INT_TLP_SEG_DATA_WIDTH +: 96] = seg_cc_hdr;
                out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH +: 3] = 3'b111;
            end

            out_tlp_valid[seg] = out_sel[seg];
            out_tlp_sop[seg] = out_sop[seg];
            out_tlp_eop[seg] = out_eop[seg];

            if (out_sel[seg]) begin
                out_shift_tlp_data_next = fifo_tlp_data[(out_sel_seg[seg]+1)*INT_TLP_SEG_DATA_WIDTH-96 +: 96];
                out_shift_tlp_strb_next = fifo_tlp_strb[(out_sel_seg[seg]+1)*INT_TLP_SEG_STRB_WIDTH-3 +: 3];
            end
        end
    end

    eop_index = 0;
    for (seg = 0; seg < INT_TLP_SEG_COUNT; seg = seg + 1) begin
        for (lane = 0; lane < INT_TLP_SEG_STRB_WIDTH; lane = lane + 1) begin
            if (out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH+lane]) begin
                eop_index[seg*3 +: 3] = lane;
            end
        end
    end

    if (!m_axis_cc_tvalid || m_axis_cc_tready) begin

        m_axis_cc_tdata_next = out_tlp_data;
        m_axis_cc_tkeep_next = 0;
        m_axis_cc_tvalid_next = out_tlp_valid != 0;
        m_axis_cc_tlast_next = !(CC_STRADDLE && AXIS_PCIE_DATA_WIDTH == 512) && (out_tlp_valid & out_tlp_eop);
        m_axis_cc_tuser_next = 0;

        for (seg = 0; seg < INT_TLP_SEG_COUNT; seg = seg + 1) begin
            if (out_tlp_valid[seg]) begin
                m_axis_cc_tkeep_next[seg*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH] = out_tlp_strb[seg*INT_TLP_SEG_STRB_WIDTH +: INT_TLP_SEG_STRB_WIDTH];
            end
        end

        if (AXIS_PCIE_DATA_WIDTH == 512) begin
            case (out_tlp_valid & out_tlp_sop)
                2'b00: begin
                    m_axis_cc_tuser_next[1:0] = 2'b00;
                    m_axis_cc_tuser_next[3:2] = 2'd0;
                    m_axis_cc_tuser_next[5:4] = 2'd0;
                end
                2'b01: begin
                    m_axis_cc_tuser_next[1:0] = 2'b01;
                    m_axis_cc_tuser_next[3:2] = 2'd0;
                    m_axis_cc_tuser_next[5:4] = 2'd0;
                end
                2'b10: begin
                    m_axis_cc_tuser_next[1:0] = 2'b01;
                    m_axis_cc_tuser_next[3:2] = 2'd2;
                    m_axis_cc_tuser_next[5:4] = 2'd0;
                end
                2'b11: begin
                    m_axis_cc_tuser_next[1:0] = 2'b11;
                    m_axis_cc_tuser_next[3:2] = 2'd0;
                    m_axis_cc_tuser_next[5:4] = 2'd2;
                end
            endcase
            case (out_tlp_valid & out_tlp_eop)
                2'b00: begin
                    m_axis_cc_tuser_next[7:6] = 2'b00;
                    m_axis_cc_tuser_next[11:8]  = 4'd0;
                    m_axis_cc_tuser_next[15:12] = 4'd0;
                end
                2'b01: begin
                    m_axis_cc_tuser_next[7:6] = 2'b01;
                    m_axis_cc_tuser_next[11:8]  = eop_index[0*3 +: 3];
                    m_axis_cc_tuser_next[15:12] = 4'd0;
                end
                2'b10: begin
                    m_axis_cc_tuser_next[7:6] = 2'b01;
                    m_axis_cc_tuser_next[11:8]  = 4'd8+eop_index[1*3 +: 3];
                    m_axis_cc_tuser_next[15:12] = 4'd0;
                end
                2'b11: begin
                    m_axis_cc_tuser_next[7:6] = 2'b11;
                    m_axis_cc_tuser_next[11:8]  = eop_index[0*3 +: 3];
                    m_axis_cc_tuser_next[15:12] = 4'd8+eop_index[1*3 +: 3];
                end
            endcase
            m_axis_cc_tuser_next[16] = 1'b0;
            m_axis_cc_tuser_next[80:17] = 64'd0;
        end else begin
            m_axis_cc_tuser_next[1] = 1'b0;
            m_axis_cc_tuser_next[32:1] = 32'd0;
        end
    end
end

integer i;

always @(posedge clk) begin
    frame_reg <= frame_next;
    tlp_hdr1_reg <= tlp_hdr1_next;
    tlp_hdr2_reg <= tlp_hdr2_next;
    tlp_split1_reg <= tlp_split1_next;
    tlp_split2_reg <= tlp_split2_next;

    out_shift_tlp_data_reg <= out_shift_tlp_data_next;
    out_shift_tlp_strb_reg <= out_shift_tlp_strb_next;

    m_axis_cc_tdata_reg <= m_axis_cc_tdata_next;
    m_axis_cc_tkeep_reg <= m_axis_cc_tkeep_next;
    m_axis_cc_tvalid_reg <= m_axis_cc_tvalid_next;
    m_axis_cc_tlast_reg <= m_axis_cc_tlast_next;
    m_axis_cc_tuser_reg <= m_axis_cc_tuser_next;

    if (rst) begin
        frame_reg <= 1'b0;

        m_axis_cc_tvalid_reg <= 0;
    end
end

endmodule