data/full_repos/permissive/164569208/rtl/dma_ram_demux_rd.v
 line:101: before: ","
1: b'%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/dma_ram_demux_rd.v:151: Operator ASSIGNW expects 1 bits on the Assign RHS, but Assign RHS\'s COND generates 32 or 3 bits.\n                                                                               : ... In instance dma_ram_demux_rd\n    wire [CL_PORTS-1:0] select_cmd = PORTS > 1 ? (seg_ctrl_rd_cmd_sel >> (M_RAM_SEL_WIDTH - CL_PORTS)) : 0;\n                                   ^\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/dma_ram_demux_rd.v:154: Operator ASSIGN expects 2 bits on the Assign RHS, but Assign RHS\'s VARREF \'seg_ctrl_rd_cmd_sel\' generates 3 bits.\n                                                                               : ... In instance dma_ram_demux_rd\n        seg_ram_rd_cmd_sel_int   = seg_ctrl_rd_cmd_sel;\n                                 ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/dma_ram_demux_rd.v:156: Operator SHIFTL expects 2 bits on the LHS, but LHS\'s LOGAND generates 1 bits.\n                                                                               : ... In instance dma_ram_demux_rd\n        seg_ram_rd_cmd_valid_int = (seg_ctrl_rd_cmd_valid && seg_ctrl_rd_cmd_ready) << select_cmd;\n                                                                                    ^~\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/dma_ram_demux_rd.v:189: Logical Operator LOGOR expects 1 bit on the LHS, but LHS\'s AND generates 2 bits.\n                                                                               : ... In instance dma_ram_demux_rd\n    assign seg_ram_rd_cmd_ready_int_early = (seg_ram_rd_cmd_ready & seg_ram_rd_cmd_valid) || (!temp_seg_ram_rd_cmd_valid_reg && !seg_ram_rd_cmd_valid_reg);\n                                                                                          ^~\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/dma_ram_demux_rd.v:189: Logical Operator LOGNOT expects 1 bit on the LHS, but LHS\'s VARREF \'temp_seg_ram_rd_cmd_valid_reg\' generates 2 bits.\n                                                                               : ... In instance dma_ram_demux_rd\n    assign seg_ram_rd_cmd_ready_int_early = (seg_ram_rd_cmd_ready & seg_ram_rd_cmd_valid) || (!temp_seg_ram_rd_cmd_valid_reg && !seg_ram_rd_cmd_valid_reg);\n                                                                                              ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/dma_ram_demux_rd.v:189: Logical Operator LOGNOT expects 1 bit on the LHS, but LHS\'s VARREF \'seg_ram_rd_cmd_valid_reg\' generates 2 bits.\n                                                                               : ... In instance dma_ram_demux_rd\n    assign seg_ram_rd_cmd_ready_int_early = (seg_ram_rd_cmd_ready & seg_ram_rd_cmd_valid) || (!temp_seg_ram_rd_cmd_valid_reg && !seg_ram_rd_cmd_valid_reg);\n                                                                                                                                ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/dma_ram_demux_rd.v:202: Logical Operator LOGOR expects 1 bit on the LHS, but LHS\'s AND generates 2 bits.\n                                                                               : ... In instance dma_ram_demux_rd\n            if ((seg_ram_rd_cmd_ready & seg_ram_rd_cmd_valid_reg) || !seg_ram_rd_cmd_valid_reg) begin\n                                                                  ^~\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/dma_ram_demux_rd.v:202: Logical Operator LOGNOT expects 1 bit on the LHS, but LHS\'s VARREF \'seg_ram_rd_cmd_valid_reg\' generates 2 bits.\n                                                                               : ... In instance dma_ram_demux_rd\n            if ((seg_ram_rd_cmd_ready & seg_ram_rd_cmd_valid_reg) || !seg_ram_rd_cmd_valid_reg) begin\n                                                                     ^\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/dma_ram_demux_rd.v:211: Logical Operator IF expects 1 bit on the If, but If\'s AND generates 2 bits.\n                                                                               : ... In instance dma_ram_demux_rd\n        end else if (seg_ram_rd_cmd_ready & seg_ram_rd_cmd_valid_reg) begin\n                 ^~\n%Warning-WIDTH: data/full_repos/permissive/164569208/rtl/dma_ram_demux_rd.v:271: Operator SHIFTL expects 2 bits on the LHS, but LHS\'s LOGAND generates 1 bits.\n                                                                               : ... In instance dma_ram_demux_rd\n    assign seg_ram_rd_resp_ready = (seg_ctrl_rd_resp_ready_int && !fifo_empty) << select_resp;\n                                                                               ^~\n%Error: Exiting due to 10 warning(s)\n'
module dma_ram_demux_rd #
(

    parameter PORTS = 2,

    parameter SEG_COUNT = 2,

    parameter SEG_DATA_WIDTH = 64,

    parameter SEG_ADDR_WIDTH = 8,

    parameter S_RAM_SEL_WIDTH = 2,


    parameter M_RAM_SEL_WIDTH = S_RAM_SEL_WIDTH+$clog2(PORTS)
)
(
    input  wire                                       clk,
    input  wire                                       rst,


    input  wire [SEG_COUNT*M_RAM_SEL_WIDTH-1:0]       ctrl_rd_cmd_sel,
    input  wire [SEG_COUNT*SEG_ADDR_WIDTH-1:0]        ctrl_rd_cmd_addr,
    input  wire [SEG_COUNT-1:0]                       ctrl_rd_cmd_valid,
    output wire [SEG_COUNT-1:0]                       ctrl_rd_cmd_ready,
    output wire [SEG_COUNT*SEG_DATA_WIDTH-1:0]        ctrl_rd_resp_data,
    output wire [SEG_COUNT-1:0]                       ctrl_rd_resp_valid,
    input  wire [SEG_COUNT-1:0]                       ctrl_rd_resp_ready,


    output wire [PORTS*SEG_COUNT*S_RAM_SEL_WIDTH-1:0] ram_rd_cmd_sel,
    output wire [PORTS*SEG_COUNT*SEG_ADDR_WIDTH-1:0]  ram_rd_cmd_addr,
    output wire [PORTS*SEG_COUNT-1:0]                 ram_rd_cmd_valid,
    input  wire [PORTS*SEG_COUNT-1:0]                 ram_rd_cmd_ready,
    input  wire [PORTS*SEG_COUNT*SEG_DATA_WIDTH-1:0]  ram_rd_resp_data,
    input  wire [PORTS*SEG_COUNT-1:0]                 ram_rd_resp_valid,
    output wire [PORTS*SEG_COUNT-1:0]                 ram_rd_resp_ready
);

parameter CL_PORTS = $clog2(PORTS);

parameter S_RAM_SEL_WIDTH_INT = S_RAM_SEL_WIDTH > 0 ? S_RAM_SEL_WIDTH : 1;

parameter FIFO_ADDR_WIDTH = 5;
parameter OUTPUT_FIFO_ADDR_WIDTH = 5;


initial begin
    if (M_RAM_SEL_WIDTH < S_RAM_SEL_WIDTH+$clog2(PORTS)) begin
        $error("Error: M_RAM_SEL_WIDTH must be at least $clog2(PORTS) larger than S_RAM_SEL_WIDTH (instance %m)");
        $finish;
    end
end

generate

genvar n, p;

for (n = 0; n < SEG_COUNT; n = n + 1) begin


    reg [FIFO_ADDR_WIDTH+1-1:0] fifo_wr_ptr_reg = 0;
    reg [FIFO_ADDR_WIDTH+1-1:0] fifo_rd_ptr_reg = 0;
    (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
    reg [CL_PORTS-1:0] fifo_sel[(2**FIFO_ADDR_WIDTH)-1:0];

    wire fifo_empty = fifo_wr_ptr_reg == fifo_rd_ptr_reg;
    wire fifo_full = fifo_wr_ptr_reg == (fifo_rd_ptr_reg ^ (1 << FIFO_ADDR_WIDTH));

    integer i;

    initial begin
        for (i = 0; i < 2**FIFO_ADDR_WIDTH; i = i + 1) begin
            fifo_sel[i] = 0;
        end
    end



    wire [M_RAM_SEL_WIDTH-1:0] seg_ctrl_rd_cmd_sel   = ctrl_rd_cmd_sel[M_RAM_SEL_WIDTH*n +: M_RAM_SEL_WIDTH];
    wire [SEG_ADDR_WIDTH-1:0]  seg_ctrl_rd_cmd_addr  = ctrl_rd_cmd_addr[SEG_ADDR_WIDTH*n +: SEG_ADDR_WIDTH];
    wire                       seg_ctrl_rd_cmd_valid = ctrl_rd_cmd_valid[n];
    wire                       seg_ctrl_rd_cmd_ready;

    assign ctrl_rd_cmd_ready[n] = seg_ctrl_rd_cmd_ready;

    wire [PORTS*S_RAM_SEL_WIDTH-1:0] seg_ram_rd_cmd_sel;
    wire [PORTS*SEG_ADDR_WIDTH-1:0]  seg_ram_rd_cmd_addr;
    wire [PORTS-1:0]                 seg_ram_rd_cmd_valid;
    wire [PORTS-1:0]                 seg_ram_rd_cmd_ready;

    for (p = 0; p < PORTS; p = p + 1) begin
        if (S_RAM_SEL_WIDTH > 0) begin
            assign ram_rd_cmd_sel[(p*SEG_COUNT+n)*S_RAM_SEL_WIDTH +: S_RAM_SEL_WIDTH_INT] = seg_ram_rd_cmd_sel[p*S_RAM_SEL_WIDTH +: S_RAM_SEL_WIDTH_INT];
        end
        assign ram_rd_cmd_addr[(p*SEG_COUNT+n)*SEG_ADDR_WIDTH +: SEG_ADDR_WIDTH] = seg_ram_rd_cmd_addr[p*SEG_ADDR_WIDTH +: SEG_ADDR_WIDTH];
        assign ram_rd_cmd_valid[p*SEG_COUNT+n] = seg_ram_rd_cmd_valid[p];
        assign seg_ram_rd_cmd_ready[p] = ram_rd_cmd_ready[p*SEG_COUNT+n];
    end

    if (S_RAM_SEL_WIDTH == 0) begin
        assign ram_rd_cmd_sel = 0;
    end


    reg  [S_RAM_SEL_WIDTH-1:0] seg_ram_rd_cmd_sel_int;
    reg  [SEG_ADDR_WIDTH-1:0]  seg_ram_rd_cmd_addr_int;
    reg  [PORTS-1:0]           seg_ram_rd_cmd_valid_int;
    reg                        seg_ram_rd_cmd_ready_int_reg = 1'b0;
    wire                       seg_ram_rd_cmd_ready_int_early;

    assign seg_ctrl_rd_cmd_ready = seg_ram_rd_cmd_ready_int_reg && !fifo_full;

    wire [CL_PORTS-1:0] select_cmd = PORTS > 1 ? (seg_ctrl_rd_cmd_sel >> (M_RAM_SEL_WIDTH - CL_PORTS)) : 0;

    always @* begin
        seg_ram_rd_cmd_sel_int   = seg_ctrl_rd_cmd_sel;
        seg_ram_rd_cmd_addr_int  = seg_ctrl_rd_cmd_addr;
        seg_ram_rd_cmd_valid_int = (seg_ctrl_rd_cmd_valid && seg_ctrl_rd_cmd_ready) << select_cmd;
    end

    always @(posedge clk) begin
        if (seg_ctrl_rd_cmd_valid && seg_ctrl_rd_cmd_ready) begin
            fifo_sel[fifo_wr_ptr_reg[FIFO_ADDR_WIDTH-1:0]] <= select_cmd;
            fifo_wr_ptr_reg <= fifo_wr_ptr_reg + 1;
        end

        if (rst) begin
            fifo_wr_ptr_reg <= 0;
        end
    end


    reg [S_RAM_SEL_WIDTH-1:0] seg_ram_rd_cmd_sel_reg   = {S_RAM_SEL_WIDTH_INT{1'b0}};
    reg [SEG_ADDR_WIDTH-1:0]  seg_ram_rd_cmd_addr_reg  = {SEG_ADDR_WIDTH{1'b0}};
    reg [PORTS-1:0]           seg_ram_rd_cmd_valid_reg = {PORTS{1'b0}}, seg_ram_rd_cmd_valid_next;

    reg [S_RAM_SEL_WIDTH-1:0] temp_seg_ram_rd_cmd_sel_reg   = {S_RAM_SEL_WIDTH_INT{1'b0}};
    reg [SEG_ADDR_WIDTH-1:0]  temp_seg_ram_rd_cmd_addr_reg  = {SEG_ADDR_WIDTH{1'b0}};
    reg [PORTS-1:0]           temp_seg_ram_rd_cmd_valid_reg = {PORTS{1'b0}}, temp_seg_ram_rd_cmd_valid_next;


    reg store_axis_resp_int_to_output;
    reg store_axis_resp_int_to_temp;
    reg store_axis_resp_temp_to_output;

    assign seg_ram_rd_cmd_sel = {PORTS{seg_ram_rd_cmd_sel_reg}};
    assign seg_ram_rd_cmd_addr = {PORTS{seg_ram_rd_cmd_addr_reg}};
    assign seg_ram_rd_cmd_valid = seg_ram_rd_cmd_valid_reg;


    assign seg_ram_rd_cmd_ready_int_early = (seg_ram_rd_cmd_ready & seg_ram_rd_cmd_valid) || (!temp_seg_ram_rd_cmd_valid_reg && !seg_ram_rd_cmd_valid_reg);

    always @* begin

        seg_ram_rd_cmd_valid_next = seg_ram_rd_cmd_valid_reg;
        temp_seg_ram_rd_cmd_valid_next = temp_seg_ram_rd_cmd_valid_reg;

        store_axis_resp_int_to_output = 1'b0;
        store_axis_resp_int_to_temp = 1'b0;
        store_axis_resp_temp_to_output = 1'b0;

        if (seg_ram_rd_cmd_ready_int_reg) begin

            if ((seg_ram_rd_cmd_ready & seg_ram_rd_cmd_valid_reg) || !seg_ram_rd_cmd_valid_reg) begin

                seg_ram_rd_cmd_valid_next = seg_ram_rd_cmd_valid_int;
                store_axis_resp_int_to_output = 1'b1;
            end else begin

                temp_seg_ram_rd_cmd_valid_next = seg_ram_rd_cmd_valid_int;
                store_axis_resp_int_to_temp = 1'b1;
            end
        end else if (seg_ram_rd_cmd_ready & seg_ram_rd_cmd_valid_reg) begin

            seg_ram_rd_cmd_valid_next = temp_seg_ram_rd_cmd_valid_reg;
            temp_seg_ram_rd_cmd_valid_next = {PORTS{1'b0}};
            store_axis_resp_temp_to_output = 1'b1;
        end
    end

    always @(posedge clk) begin
        seg_ram_rd_cmd_valid_reg <= seg_ram_rd_cmd_valid_next;
        seg_ram_rd_cmd_ready_int_reg <= seg_ram_rd_cmd_ready_int_early;
        temp_seg_ram_rd_cmd_valid_reg <= temp_seg_ram_rd_cmd_valid_next;


        if (store_axis_resp_int_to_output) begin
            seg_ram_rd_cmd_sel_reg <= seg_ram_rd_cmd_sel_int;
            seg_ram_rd_cmd_addr_reg <= seg_ram_rd_cmd_addr_int;
        end else if (store_axis_resp_temp_to_output) begin
            seg_ram_rd_cmd_sel_reg <= temp_seg_ram_rd_cmd_sel_reg;
            seg_ram_rd_cmd_addr_reg <= temp_seg_ram_rd_cmd_addr_reg;
        end

        if (store_axis_resp_int_to_temp) begin
            temp_seg_ram_rd_cmd_sel_reg <= seg_ram_rd_cmd_sel_int;
            temp_seg_ram_rd_cmd_addr_reg <= seg_ram_rd_cmd_addr_int;
        end

        if (rst) begin
            seg_ram_rd_cmd_valid_reg <= {PORTS{1'b0}};
            seg_ram_rd_cmd_ready_int_reg <= 1'b0;
            temp_seg_ram_rd_cmd_valid_reg <= {PORTS{1'b0}};
        end
    end



    wire [PORTS*SEG_DATA_WIDTH-1:0] seg_ram_rd_resp_data;
    wire [PORTS-1:0]                seg_ram_rd_resp_valid;
    wire [PORTS-1:0]                seg_ram_rd_resp_ready;

    for (p = 0; p < PORTS; p = p + 1) begin
        assign seg_ram_rd_resp_data[p*SEG_DATA_WIDTH +: SEG_DATA_WIDTH] = ram_rd_resp_data[(p*SEG_COUNT+n)*SEG_DATA_WIDTH +: SEG_DATA_WIDTH];
        assign seg_ram_rd_resp_valid[p] = ram_rd_resp_valid[p*SEG_COUNT+n];
        assign ram_rd_resp_ready[p*SEG_COUNT+n] = seg_ram_rd_resp_ready[p];
    end

    wire [SEG_DATA_WIDTH-1:0] seg_ctrl_rd_resp_data;
    wire                      seg_ctrl_rd_resp_valid;
    wire                      seg_ctrl_rd_resp_ready = ctrl_rd_resp_ready[n];

    assign ctrl_rd_resp_data[n*SEG_DATA_WIDTH +: SEG_DATA_WIDTH] = seg_ctrl_rd_resp_data;
    assign ctrl_rd_resp_valid[n] = seg_ctrl_rd_resp_valid;


    reg  [SEG_DATA_WIDTH-1:0] seg_ctrl_rd_resp_data_int;
    reg                       seg_ctrl_rd_resp_valid_int;
    wire                      seg_ctrl_rd_resp_ready_int;

    wire [CL_PORTS-1:0] select_resp = fifo_sel[fifo_rd_ptr_reg[FIFO_ADDR_WIDTH-1:0]];

    assign seg_ram_rd_resp_ready = (seg_ctrl_rd_resp_ready_int && !fifo_empty) << select_resp;


    wire [SEG_DATA_WIDTH-1:0] current_resp_data  = seg_ram_rd_resp_data[select_resp*SEG_DATA_WIDTH +: SEG_DATA_WIDTH];
    wire                      current_resp_valid = seg_ram_rd_resp_valid[select_resp];
    wire                      current_resp_ready = seg_ram_rd_resp_ready[select_resp];

    always @* begin

        seg_ctrl_rd_resp_data_int  = current_resp_data;
        seg_ctrl_rd_resp_valid_int = current_resp_valid && seg_ctrl_rd_resp_ready_int && !fifo_empty;
    end

    always @(posedge clk) begin
        if (current_resp_valid && seg_ctrl_rd_resp_ready_int && !fifo_empty) begin
            fifo_rd_ptr_reg <= fifo_rd_ptr_reg + 1;
        end

        if (rst) begin
            fifo_rd_ptr_reg <= 0;
        end
    end


    reg [SEG_DATA_WIDTH-1:0] seg_ctrl_rd_resp_data_reg  = {SEG_DATA_WIDTH{1'b0}};
    reg                      seg_ctrl_rd_resp_valid_reg = 1'b0;

    reg [OUTPUT_FIFO_ADDR_WIDTH+1-1:0] out_fifo_wr_ptr_reg = 0;
    reg [OUTPUT_FIFO_ADDR_WIDTH+1-1:0] out_fifo_rd_ptr_reg = 0;
    reg out_fifo_half_full_reg = 1'b0;

    wire out_fifo_full = out_fifo_wr_ptr_reg == (out_fifo_rd_ptr_reg ^ {1'b1, {OUTPUT_FIFO_ADDR_WIDTH{1'b0}}});
    wire out_fifo_empty = out_fifo_wr_ptr_reg == out_fifo_rd_ptr_reg;

    (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
    reg [SEG_DATA_WIDTH-1:0] out_fifo_rd_resp_data[2**OUTPUT_FIFO_ADDR_WIDTH-1:0];

    assign seg_ctrl_rd_resp_ready_int = !out_fifo_half_full_reg;

    assign seg_ctrl_rd_resp_data = seg_ctrl_rd_resp_data_reg;
    assign seg_ctrl_rd_resp_valid = seg_ctrl_rd_resp_valid_reg;

    always @(posedge clk) begin
        seg_ctrl_rd_resp_valid_reg <= seg_ctrl_rd_resp_valid_reg && !seg_ctrl_rd_resp_ready;

        out_fifo_half_full_reg <= $unsigned(out_fifo_wr_ptr_reg - out_fifo_rd_ptr_reg) >= 2**(OUTPUT_FIFO_ADDR_WIDTH-1);

        if (!out_fifo_full && seg_ctrl_rd_resp_valid_int) begin
            out_fifo_rd_resp_data[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= seg_ctrl_rd_resp_data_int;
            out_fifo_wr_ptr_reg <= out_fifo_wr_ptr_reg + 1;
        end

        if (!out_fifo_empty && (!seg_ctrl_rd_resp_valid_reg || seg_ctrl_rd_resp_ready)) begin
            seg_ctrl_rd_resp_data_reg <= out_fifo_rd_resp_data[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]];
            seg_ctrl_rd_resp_valid_reg <= 1'b1;
            out_fifo_rd_ptr_reg <= out_fifo_rd_ptr_reg + 1;
        end

        if (rst) begin
            out_fifo_wr_ptr_reg <= 0;
            out_fifo_rd_ptr_reg <= 0;
            seg_ctrl_rd_resp_valid_reg <= 1'b0;
        end
    end

end

endgenerate

endmodule
module dma_ram_demux_rd #
(

    parameter PORTS = 2,

    parameter SEG_COUNT = 2,

    parameter SEG_DATA_WIDTH = 64,

    parameter SEG_ADDR_WIDTH = 8,

    parameter S_RAM_SEL_WIDTH = 2,


    parameter M_RAM_SEL_WIDTH = S_RAM_SEL_WIDTH+$clog2(PORTS)
)
(
    input  wire                                       clk,
    input  wire                                       rst,


    input  wire [SEG_COUNT*M_RAM_SEL_WIDTH-1:0]       ctrl_rd_cmd_sel,
    input  wire [SEG_COUNT*SEG_ADDR_WIDTH-1:0]        ctrl_rd_cmd_addr,
    input  wire [SEG_COUNT-1:0]                       ctrl_rd_cmd_valid,
    output wire [SEG_COUNT-1:0]                       ctrl_rd_cmd_ready,
    output wire [SEG_COUNT*SEG_DATA_WIDTH-1:0]        ctrl_rd_resp_data,
    output wire [SEG_COUNT-1:0]                       ctrl_rd_resp_valid,
    input  wire [SEG_COUNT-1:0]                       ctrl_rd_resp_ready,


    output wire [PORTS*SEG_COUNT*S_RAM_SEL_WIDTH-1:0] ram_rd_cmd_sel,
    output wire [PORTS*SEG_COUNT*SEG_ADDR_WIDTH-1:0]  ram_rd_cmd_addr,
    output wire [PORTS*SEG_COUNT-1:0]                 ram_rd_cmd_valid,
    input  wire [PORTS*SEG_COUNT-1:0]                 ram_rd_cmd_ready,
    input  wire [PORTS*SEG_COUNT*SEG_DATA_WIDTH-1:0]  ram_rd_resp_data,
    input  wire [PORTS*SEG_COUNT-1:0]                 ram_rd_resp_valid,
    output wire [PORTS*SEG_COUNT-1:0]                 ram_rd_resp_ready
);


parameter CL_PORTS = $clog2(PORTS);

parameter S_RAM_SEL_WIDTH_INT = S_RAM_SEL_WIDTH > 0 ? S_RAM_SEL_WIDTH : 1;

parameter FIFO_ADDR_WIDTH = 5;
parameter OUTPUT_FIFO_ADDR_WIDTH = 5;


initial begin
    if (M_RAM_SEL_WIDTH < S_RAM_SEL_WIDTH+$clog2(PORTS)) begin
        $error("Error: M_RAM_SEL_WIDTH must be at least $clog2(PORTS) larger than S_RAM_SEL_WIDTH (instance %m)");
        $finish;
    end
end

generate

genvar n, p;

for (n = 0; n < SEG_COUNT; n = n + 1) begin


    reg [FIFO_ADDR_WIDTH+1-1:0] fifo_wr_ptr_reg = 0;
    reg [FIFO_ADDR_WIDTH+1-1:0] fifo_rd_ptr_reg = 0;
    (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
    reg [CL_PORTS-1:0] fifo_sel[(2**FIFO_ADDR_WIDTH)-1:0];

    wire fifo_empty = fifo_wr_ptr_reg == fifo_rd_ptr_reg;
    wire fifo_full = fifo_wr_ptr_reg == (fifo_rd_ptr_reg ^ (1 << FIFO_ADDR_WIDTH));

    integer i;

    initial begin
        for (i = 0; i < 2**FIFO_ADDR_WIDTH; i = i + 1) begin
            fifo_sel[i] = 0;
        end
    end



    wire [M_RAM_SEL_WIDTH-1:0] seg_ctrl_rd_cmd_sel   = ctrl_rd_cmd_sel[M_RAM_SEL_WIDTH*n +: M_RAM_SEL_WIDTH];
    wire [SEG_ADDR_WIDTH-1:0]  seg_ctrl_rd_cmd_addr  = ctrl_rd_cmd_addr[SEG_ADDR_WIDTH*n +: SEG_ADDR_WIDTH];
    wire                       seg_ctrl_rd_cmd_valid = ctrl_rd_cmd_valid[n];
    wire                       seg_ctrl_rd_cmd_ready;

    assign ctrl_rd_cmd_ready[n] = seg_ctrl_rd_cmd_ready;

    wire [PORTS*S_RAM_SEL_WIDTH-1:0] seg_ram_rd_cmd_sel;
    wire [PORTS*SEG_ADDR_WIDTH-1:0]  seg_ram_rd_cmd_addr;
    wire [PORTS-1:0]                 seg_ram_rd_cmd_valid;
    wire [PORTS-1:0]                 seg_ram_rd_cmd_ready;

    for (p = 0; p < PORTS; p = p + 1) begin
        if (S_RAM_SEL_WIDTH > 0) begin
            assign ram_rd_cmd_sel[(p*SEG_COUNT+n)*S_RAM_SEL_WIDTH +: S_RAM_SEL_WIDTH_INT] = seg_ram_rd_cmd_sel[p*S_RAM_SEL_WIDTH +: S_RAM_SEL_WIDTH_INT];
        end
        assign ram_rd_cmd_addr[(p*SEG_COUNT+n)*SEG_ADDR_WIDTH +: SEG_ADDR_WIDTH] = seg_ram_rd_cmd_addr[p*SEG_ADDR_WIDTH +: SEG_ADDR_WIDTH];
        assign ram_rd_cmd_valid[p*SEG_COUNT+n] = seg_ram_rd_cmd_valid[p];
        assign seg_ram_rd_cmd_ready[p] = ram_rd_cmd_ready[p*SEG_COUNT+n];
    end

    if (S_RAM_SEL_WIDTH == 0) begin
        assign ram_rd_cmd_sel = 0;
    end


    reg  [S_RAM_SEL_WIDTH-1:0] seg_ram_rd_cmd_sel_int;
    reg  [SEG_ADDR_WIDTH-1:0]  seg_ram_rd_cmd_addr_int;
    reg  [PORTS-1:0]           seg_ram_rd_cmd_valid_int;
    reg                        seg_ram_rd_cmd_ready_int_reg = 1'b0;
    wire                       seg_ram_rd_cmd_ready_int_early;

    assign seg_ctrl_rd_cmd_ready = seg_ram_rd_cmd_ready_int_reg && !fifo_full;

    wire [CL_PORTS-1:0] select_cmd = PORTS > 1 ? (seg_ctrl_rd_cmd_sel >> (M_RAM_SEL_WIDTH - CL_PORTS)) : 0;

    always @* begin
        seg_ram_rd_cmd_sel_int   = seg_ctrl_rd_cmd_sel;
        seg_ram_rd_cmd_addr_int  = seg_ctrl_rd_cmd_addr;
        seg_ram_rd_cmd_valid_int = (seg_ctrl_rd_cmd_valid && seg_ctrl_rd_cmd_ready) << select_cmd;
    end

    always @(posedge clk) begin
        if (seg_ctrl_rd_cmd_valid && seg_ctrl_rd_cmd_ready) begin
            fifo_sel[fifo_wr_ptr_reg[FIFO_ADDR_WIDTH-1:0]] <= select_cmd;
            fifo_wr_ptr_reg <= fifo_wr_ptr_reg + 1;
        end

        if (rst) begin
            fifo_wr_ptr_reg <= 0;
        end
    end


    reg [S_RAM_SEL_WIDTH-1:0] seg_ram_rd_cmd_sel_reg   = {S_RAM_SEL_WIDTH_INT{1'b0}};
    reg [SEG_ADDR_WIDTH-1:0]  seg_ram_rd_cmd_addr_reg  = {SEG_ADDR_WIDTH{1'b0}};
    reg [PORTS-1:0]           seg_ram_rd_cmd_valid_reg = {PORTS{1'b0}}, seg_ram_rd_cmd_valid_next;

    reg [S_RAM_SEL_WIDTH-1:0] temp_seg_ram_rd_cmd_sel_reg   = {S_RAM_SEL_WIDTH_INT{1'b0}};
    reg [SEG_ADDR_WIDTH-1:0]  temp_seg_ram_rd_cmd_addr_reg  = {SEG_ADDR_WIDTH{1'b0}};
    reg [PORTS-1:0]           temp_seg_ram_rd_cmd_valid_reg = {PORTS{1'b0}}, temp_seg_ram_rd_cmd_valid_next;


    reg store_axis_resp_int_to_output;
    reg store_axis_resp_int_to_temp;
    reg store_axis_resp_temp_to_output;

    assign seg_ram_rd_cmd_sel = {PORTS{seg_ram_rd_cmd_sel_reg}};
    assign seg_ram_rd_cmd_addr = {PORTS{seg_ram_rd_cmd_addr_reg}};
    assign seg_ram_rd_cmd_valid = seg_ram_rd_cmd_valid_reg;


    assign seg_ram_rd_cmd_ready_int_early = (seg_ram_rd_cmd_ready & seg_ram_rd_cmd_valid) || (!temp_seg_ram_rd_cmd_valid_reg && !seg_ram_rd_cmd_valid_reg);

    always @* begin

        seg_ram_rd_cmd_valid_next = seg_ram_rd_cmd_valid_reg;
        temp_seg_ram_rd_cmd_valid_next = temp_seg_ram_rd_cmd_valid_reg;

        store_axis_resp_int_to_output = 1'b0;
        store_axis_resp_int_to_temp = 1'b0;
        store_axis_resp_temp_to_output = 1'b0;

        if (seg_ram_rd_cmd_ready_int_reg) begin

            if ((seg_ram_rd_cmd_ready & seg_ram_rd_cmd_valid_reg) || !seg_ram_rd_cmd_valid_reg) begin

                seg_ram_rd_cmd_valid_next = seg_ram_rd_cmd_valid_int;
                store_axis_resp_int_to_output = 1'b1;
            end else begin

                temp_seg_ram_rd_cmd_valid_next = seg_ram_rd_cmd_valid_int;
                store_axis_resp_int_to_temp = 1'b1;
            end
        end else if (seg_ram_rd_cmd_ready & seg_ram_rd_cmd_valid_reg) begin

            seg_ram_rd_cmd_valid_next = temp_seg_ram_rd_cmd_valid_reg;
            temp_seg_ram_rd_cmd_valid_next = {PORTS{1'b0}};
            store_axis_resp_temp_to_output = 1'b1;
        end
    end

    always @(posedge clk) begin
        seg_ram_rd_cmd_valid_reg <= seg_ram_rd_cmd_valid_next;
        seg_ram_rd_cmd_ready_int_reg <= seg_ram_rd_cmd_ready_int_early;
        temp_seg_ram_rd_cmd_valid_reg <= temp_seg_ram_rd_cmd_valid_next;


        if (store_axis_resp_int_to_output) begin
            seg_ram_rd_cmd_sel_reg <= seg_ram_rd_cmd_sel_int;
            seg_ram_rd_cmd_addr_reg <= seg_ram_rd_cmd_addr_int;
        end else if (store_axis_resp_temp_to_output) begin
            seg_ram_rd_cmd_sel_reg <= temp_seg_ram_rd_cmd_sel_reg;
            seg_ram_rd_cmd_addr_reg <= temp_seg_ram_rd_cmd_addr_reg;
        end

        if (store_axis_resp_int_to_temp) begin
            temp_seg_ram_rd_cmd_sel_reg <= seg_ram_rd_cmd_sel_int;
            temp_seg_ram_rd_cmd_addr_reg <= seg_ram_rd_cmd_addr_int;
        end

        if (rst) begin
            seg_ram_rd_cmd_valid_reg <= {PORTS{1'b0}};
            seg_ram_rd_cmd_ready_int_reg <= 1'b0;
            temp_seg_ram_rd_cmd_valid_reg <= {PORTS{1'b0}};
        end
    end



    wire [PORTS*SEG_DATA_WIDTH-1:0] seg_ram_rd_resp_data;
    wire [PORTS-1:0]                seg_ram_rd_resp_valid;
    wire [PORTS-1:0]                seg_ram_rd_resp_ready;

    for (p = 0; p < PORTS; p = p + 1) begin
        assign seg_ram_rd_resp_data[p*SEG_DATA_WIDTH +: SEG_DATA_WIDTH] = ram_rd_resp_data[(p*SEG_COUNT+n)*SEG_DATA_WIDTH +: SEG_DATA_WIDTH];
        assign seg_ram_rd_resp_valid[p] = ram_rd_resp_valid[p*SEG_COUNT+n];
        assign ram_rd_resp_ready[p*SEG_COUNT+n] = seg_ram_rd_resp_ready[p];
    end

    wire [SEG_DATA_WIDTH-1:0] seg_ctrl_rd_resp_data;
    wire                      seg_ctrl_rd_resp_valid;
    wire                      seg_ctrl_rd_resp_ready = ctrl_rd_resp_ready[n];

    assign ctrl_rd_resp_data[n*SEG_DATA_WIDTH +: SEG_DATA_WIDTH] = seg_ctrl_rd_resp_data;
    assign ctrl_rd_resp_valid[n] = seg_ctrl_rd_resp_valid;


    reg  [SEG_DATA_WIDTH-1:0] seg_ctrl_rd_resp_data_int;
    reg                       seg_ctrl_rd_resp_valid_int;
    wire                      seg_ctrl_rd_resp_ready_int;

    wire [CL_PORTS-1:0] select_resp = fifo_sel[fifo_rd_ptr_reg[FIFO_ADDR_WIDTH-1:0]];

    assign seg_ram_rd_resp_ready = (seg_ctrl_rd_resp_ready_int && !fifo_empty) << select_resp;


    wire [SEG_DATA_WIDTH-1:0] current_resp_data  = seg_ram_rd_resp_data[select_resp*SEG_DATA_WIDTH +: SEG_DATA_WIDTH];
    wire                      current_resp_valid = seg_ram_rd_resp_valid[select_resp];
    wire                      current_resp_ready = seg_ram_rd_resp_ready[select_resp];

    always @* begin

        seg_ctrl_rd_resp_data_int  = current_resp_data;
        seg_ctrl_rd_resp_valid_int = current_resp_valid && seg_ctrl_rd_resp_ready_int && !fifo_empty;
    end

    always @(posedge clk) begin
        if (current_resp_valid && seg_ctrl_rd_resp_ready_int && !fifo_empty) begin
            fifo_rd_ptr_reg <= fifo_rd_ptr_reg + 1;
        end

        if (rst) begin
            fifo_rd_ptr_reg <= 0;
        end
    end


    reg [SEG_DATA_WIDTH-1:0] seg_ctrl_rd_resp_data_reg  = {SEG_DATA_WIDTH{1'b0}};
    reg                      seg_ctrl_rd_resp_valid_reg = 1'b0;

    reg [OUTPUT_FIFO_ADDR_WIDTH+1-1:0] out_fifo_wr_ptr_reg = 0;
    reg [OUTPUT_FIFO_ADDR_WIDTH+1-1:0] out_fifo_rd_ptr_reg = 0;
    reg out_fifo_half_full_reg = 1'b0;

    wire out_fifo_full = out_fifo_wr_ptr_reg == (out_fifo_rd_ptr_reg ^ {1'b1, {OUTPUT_FIFO_ADDR_WIDTH{1'b0}}});
    wire out_fifo_empty = out_fifo_wr_ptr_reg == out_fifo_rd_ptr_reg;

    (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
    reg [SEG_DATA_WIDTH-1:0] out_fifo_rd_resp_data[2**OUTPUT_FIFO_ADDR_WIDTH-1:0];

    assign seg_ctrl_rd_resp_ready_int = !out_fifo_half_full_reg;

    assign seg_ctrl_rd_resp_data = seg_ctrl_rd_resp_data_reg;
    assign seg_ctrl_rd_resp_valid = seg_ctrl_rd_resp_valid_reg;

    always @(posedge clk) begin
        seg_ctrl_rd_resp_valid_reg <= seg_ctrl_rd_resp_valid_reg && !seg_ctrl_rd_resp_ready;

        out_fifo_half_full_reg <= $unsigned(out_fifo_wr_ptr_reg - out_fifo_rd_ptr_reg) >= 2**(OUTPUT_FIFO_ADDR_WIDTH-1);

        if (!out_fifo_full && seg_ctrl_rd_resp_valid_int) begin
            out_fifo_rd_resp_data[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= seg_ctrl_rd_resp_data_int;
            out_fifo_wr_ptr_reg <= out_fifo_wr_ptr_reg + 1;
        end

        if (!out_fifo_empty && (!seg_ctrl_rd_resp_valid_reg || seg_ctrl_rd_resp_ready)) begin
            seg_ctrl_rd_resp_data_reg <= out_fifo_rd_resp_data[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]];
            seg_ctrl_rd_resp_valid_reg <= 1'b1;
            out_fifo_rd_ptr_reg <= out_fifo_rd_ptr_reg + 1;
        end

        if (rst) begin
            out_fifo_wr_ptr_reg <= 0;
            out_fifo_rd_ptr_reg <= 0;
            seg_ctrl_rd_resp_valid_reg <= 1'b0;
        end
    end

end

endgenerate

endmodule