data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v
1: b'%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:3: Cannot find include file: noc_parameter.vh\n    `include "noc_parameter.vh" \n             ^~~~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog,data/full_repos/permissive/463204869/noc_parameter.vh\n             data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog,data/full_repos/permissive/463204869/noc_parameter.vh.v\n             data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog,data/full_repos/permissive/463204869/noc_parameter.vh.sv\n             noc_parameter.vh\n             noc_parameter.vh.v\n             noc_parameter.vh.sv\n             obj_dir/noc_parameter.vh\n             obj_dir/noc_parameter.vh.v\n             obj_dir/noc_parameter.vh.sv\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:4: Cannot find include file: tcu_parameter.vh\n    ,`include "tcu_parameter.vh" \n              ^~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:49: Cannot find include file: tcu_functions.v\n    `include "tcu_functions.v" \n             ^~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:4: syntax error, unexpected \',\', expecting \'[\'\n    , \n    ^\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:6: syntax error, unexpected parameter, expecting IDENTIFIER\n    parameter [31:0] TIMEOUT_RECV_CYCLES = 0\n    ^~~~~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:7: syntax error, unexpected \')\', expecting \';\'\n)(\n^\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:9: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire                          reset_n_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:13: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire                    [2:0] mar_mem_en_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:14: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire  [TCU_MEM_BSEL_SIZE-1:0] mar_mem_wben_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:15: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire  [TCU_MEM_ADDR_SIZE-1:0] mar_mem_addr_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:16: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire  [TCU_MEM_DATA_SIZE-1:0] mar_mem_wdata_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:17: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire                          mar_mem_wdata_infifo_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:18: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output reg                           mar_mem_wabort_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:19: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n    input  wire                          mar_mem_stall_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:23: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output reg                           noc_fifo_pop_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:24: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n    input  wire                          noc_wrreq_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:25: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire                          noc_burst_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:26: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire      [NOC_BSEL_SIZE-1:0] noc_bsel_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:27: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire    [NOC_CHIPID_SIZE-1:0] noc_chipid_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:28: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire     [NOC_MODID_SIZE-1:0] noc_modid_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:29: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire      [NOC_ADDR_SIZE-1:0] noc_addr_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:30: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire      [NOC_MODE_SIZE-1:0] noc_mode_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:31: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire      [NOC_DATA_SIZE-1:0] noc_data0_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:32: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire                          noc_stall_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:33: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire                          noc_wrreq_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:34: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire    [NOC_CHIPID_SIZE-1:0] noc_chipid_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:35: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire     [NOC_MODID_SIZE-1:0] noc_modid_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:36: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire      [NOC_ADDR_SIZE-1:0] noc_addr_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:37: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire                   [31:0] noc_data_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:41: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire                          mar_start_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:42: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire                          mar_abort_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:43: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire                          mar_active_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:44: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output reg                           mar_done_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:45: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output wire     [TCU_ERROR_SIZE-1:0] mar_error_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:46: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire                    [3:0] mar_shift_o\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:47: syntax error, unexpected \')\', expecting \',\' or \';\'\n);\n^\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_ctrl_mem_access_recv.v:110: syntax error, unexpected always\n    always @(posedge clk_i) begin\n    ^~~~~~\n%Error: Exiting due to 37 error(s)\n'
module tcu_ctrl_mem_access_recv #(
    `include "noc_parameter.vh"
    ,`include "tcu_parameter.vh"
    ,parameter TCU_ENABLE_DRAM           = 0,
    parameter [31:0] TIMEOUT_RECV_CYCLES = 0
)(
    input  wire                          clk_i,
    input  wire                          reset_n_i,



    output wire                    [2:0] mar_mem_en_o,
    output wire  [TCU_MEM_BSEL_SIZE-1:0] mar_mem_wben_o,
    output wire  [TCU_MEM_ADDR_SIZE-1:0] mar_mem_addr_o,
    output wire  [TCU_MEM_DATA_SIZE-1:0] mar_mem_wdata_o,
    input  wire                          mar_mem_wdata_infifo_i,
    output reg                           mar_mem_wabort_o,
    input  wire                          mar_mem_stall_i,



    output reg                           noc_fifo_pop_o,
    input  wire                          noc_wrreq_i,
    input  wire                          noc_burst_i,
    input  wire      [NOC_BSEL_SIZE-1:0] noc_bsel_i,
    input  wire    [NOC_CHIPID_SIZE-1:0] noc_chipid_i,
    input  wire     [NOC_MODID_SIZE-1:0] noc_modid_i,
    input  wire      [NOC_ADDR_SIZE-1:0] noc_addr_i,
    input  wire      [NOC_MODE_SIZE-1:0] noc_mode_i,
    input  wire      [NOC_DATA_SIZE-1:0] noc_data0_i,
    input  wire                          noc_stall_i,
    output wire                          noc_wrreq_o,
    output wire    [NOC_CHIPID_SIZE-1:0] noc_chipid_o,
    output wire     [NOC_MODID_SIZE-1:0] noc_modid_o,
    output wire      [NOC_ADDR_SIZE-1:0] noc_addr_o,
    output wire                   [31:0] noc_data_o,



    input  wire                          mar_start_i,
    input  wire                          mar_abort_i,
    output wire                          mar_active_o,
    output reg                           mar_done_o,
    output wire     [TCU_ERROR_SIZE-1:0] mar_error_o,
    output wire                    [3:0] mar_shift_o
);

    `include "tcu_functions.v"


    localparam CTRL_MAR_STATES_SIZE        = 4;
    localparam S_CTRL_MAR_IDLE             = 4'h0;
    localparam S_CTRL_MAR_PACKET_CHECK     = 4'h1;
    localparam S_CTRL_MAR_PREPARE_MEM      = 4'h2;
    localparam S_CTRL_MAR_MEM_WRITE1       = 4'h3;
    localparam S_CTRL_MAR_MEM_WRITE1_SPLIT = 4'h4;
    localparam S_CTRL_MAR_MEM_WRITE2       = 4'h5;
    localparam S_CTRL_MAR_MEM_WRITE3       = 4'h6;
    localparam S_CTRL_MAR_MEM_WRITE4       = 4'h7;
    localparam S_CTRL_MAR_WAIT_DRAM        = 4'h8;
    localparam S_CTRL_MAR_ERROR            = 4'h9;
    localparam S_CTRL_MAR_FINISH           = 4'hF;

    reg [CTRL_MAR_STATES_SIZE-1:0] ctrl_mar_state, next_ctrl_mar_state;



    reg [31:0] r_laddr, rin_laddr;
    reg [15:0] r_size, rin_size;
    reg  [3:0] r_start_shift, rin_start_shift;
    reg  [4:0] r_end_shift, rin_end_shift;
    reg  [3:0] r_shift, rin_shift;


    reg                       r_mode_write_posted, rin_mode_write_posted;
    reg [NOC_CHIPID_SIZE-1:0] r_ack_chipid, rin_ack_chipid;
    reg  [NOC_MODID_SIZE-1:0] r_ack_modid, rin_ack_modid;
    reg   [NOC_ADDR_SIZE-1:0] r_ack_addr, rin_ack_addr;
    reg                [31:0] r_ack_size, rin_ack_size;

    reg                   [2:0] r_mem_en, rin_mem_en;
    reg [TCU_MEM_BSEL_SIZE-1:0] r_mem_wben, rin_mem_wben;
    reg [TCU_MEM_ADDR_SIZE-1:0] r_mem_addr;

    reg [TCU_MEM_BSEL_SIZE-1:0] r_wben, rin_wben;
    reg                         r2_wben_msb, rin2_wben_msb;

    reg [12:0] r_burst_length, rin_burst_length;


    reg [TCU_ERROR_SIZE-1:0] r_mar_error, rin_mar_error;


    reg [31:0] r_mar_timeout, rin_mar_timeout;


    wire  [3:0] start_shift  = ~noc_bsel_i[3:0];
    wire  [4:0] end_shift    = noc_bsel_i[7:4] + 5'd1;
    wire [12:0] burst_length = noc_data0_i[12:0];

    wire  [3:0] bsel_count_ones = count_ones8(noc_bsel_i);
    wire  [4:0] wben_count_ones = count_ones8(r_wben[7:0]) + count_ones8(r_wben[15:8]);

    wire  [2:0] bsel_firstone = get_firstone8(noc_bsel_i);




    always @(posedge clk_i) begin
        if (reset_n_i == 1'b0) begin
            ctrl_mar_state <= S_CTRL_MAR_IDLE;
            
            r_laddr <= 32'h0;
            r_size <= 16'h0;
            r_start_shift <= 4'h0;
            r_end_shift <= 5'h0;
            r_shift <= 4'h0;

            r_mode_write_posted <= 1'b0;
            r_ack_chipid <= {NOC_CHIPID_SIZE{1'b0}};
            r_ack_modid <= {NOC_MODID_SIZE{1'b0}};
            r_ack_addr <= {NOC_ADDR_SIZE{1'b0}};
            r_ack_size <= 32'h0;

            r_mem_en <= 3'h0;
            r_mem_wben <= {TCU_MEM_BSEL_SIZE{1'b0}};
            r_mem_addr <= {TCU_MEM_ADDR_SIZE{1'b0}};

            r_wben <= {TCU_MEM_BSEL_SIZE{1'b0}};
            r2_wben_msb <= 1'b0;

            r_burst_length <= 13'h0;

            r_mar_error <= TCU_ERROR_NONE;

            r_mar_timeout <= 32'h0;
        end
        else begin
            ctrl_mar_state <= next_ctrl_mar_state;
            
            r_laddr <= rin_laddr;
            r_size <= rin_size;
            r_start_shift <= rin_start_shift;
            r_end_shift <= rin_end_shift;
            r_shift <= rin_shift;

            r_mode_write_posted <= rin_mode_write_posted;
            r_ack_chipid <= rin_ack_chipid;
            r_ack_modid <= rin_ack_modid;
            r_ack_addr <= rin_ack_addr;
            r_ack_size <= rin_ack_size;

            r_mem_en <= rin_mem_en;
            r_mem_wben <= rin_mem_wben;
            r_mem_addr <= r_laddr;

            r_wben <= rin_wben;
            r2_wben_msb <= rin2_wben_msb;

            r_burst_length <= rin_burst_length;

            r_mar_error <= rin_mar_error;

            r_mar_timeout <= rin_mar_timeout;
        end
    end






    always @* begin
        next_ctrl_mar_state = ctrl_mar_state;

        rin_laddr = r_laddr;
        rin_size = r_size;
        rin_start_shift = r_start_shift;
        rin_end_shift = r_end_shift;

        rin_mode_write_posted = r_mode_write_posted;
        rin_ack_chipid = r_ack_chipid;
        rin_ack_modid = r_ack_modid;
        rin_ack_addr = r_ack_addr;
        rin_ack_size = r_ack_size;

        rin_wben = r_wben;
        rin2_wben_msb = r2_wben_msb;

        rin_burst_length = r_burst_length;

        noc_fifo_pop_o = 1'b0;

        rin_mar_error = r_mar_error;
        mar_done_o = 1'b0;

        rin_mar_timeout = 32'h0;

        mar_mem_wabort_o = 1'b0;


        case (ctrl_mar_state)



            S_CTRL_MAR_IDLE: begin
                if (mar_start_i) begin

                    rin_mode_write_posted = (noc_mode_i == MODE_WRITE_POSTED);
                    rin_ack_chipid = noc_chipid_i;
                    rin_ack_modid = noc_modid_i;
                    rin_ack_addr = noc_addr_i;
                    if (noc_burst_i) begin
                        rin_size = {burst_length, 4'h0} - start_shift - (5'd16 - end_shift);
                        rin_ack_size = {burst_length, 4'h0} - start_shift - (5'd16 - end_shift);
                    end else begin
                        rin_size = bsel_count_ones;
                        rin_ack_size = bsel_count_ones;
                    end


                    if (mar_abort_i) begin
                        rin_mar_error = TCU_ERROR_ABORT;
                        next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                    end
                    else begin
                        rin_laddr = noc_addr_i;

                        rin_mar_error = TCU_ERROR_NONE;
                        next_ctrl_mar_state = S_CTRL_MAR_PACKET_CHECK;
                    end
                end
            end

            


            S_CTRL_MAR_PACKET_CHECK: begin

                if (mar_abort_i) begin
                    rin_mar_error = TCU_ERROR_ABORT;
                    next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                end
                else if (noc_wrreq_i &&
                        ((noc_mode_i == MODE_WRITE_POSTED) || (noc_mode_i == MODE_READ_RSP) ||
                        (noc_mode_i == MODE_WRITE_POSTED_2) || (noc_mode_i == MODE_READ_RSP_2))) begin


                    if (TCU_ENABLE_DRAM && noc_burst_i && (burst_length > 'd1)) begin
                        next_ctrl_mar_state = S_CTRL_MAR_PREPARE_MEM;
                    end


                    else begin
                        next_ctrl_mar_state = S_CTRL_MAR_MEM_WRITE1;
                    end
                end


                else if (TIMEOUT_RECV_CYCLES != 32'h0) begin
                    rin_mar_timeout = r_mar_timeout + 32'd1;
                    if (r_mar_timeout > TIMEOUT_RECV_CYCLES) begin
                        rin_mar_error = TCU_ERROR_TIMEOUT_NOC;
                        next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                    end
                end
            end


            S_CTRL_MAR_PREPARE_MEM: begin
                if (!mar_mem_stall_i) begin
                    next_ctrl_mar_state = S_CTRL_MAR_MEM_WRITE1;
                end


                else if (TIMEOUT_RECV_CYCLES != 32'h0) begin
                    rin_mar_timeout = r_mar_timeout + 32'd1;
                    if (r_mar_timeout > TIMEOUT_RECV_CYCLES) begin
                        rin_mar_error = TCU_ERROR_TIMEOUT_MEM;
                        next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                    end
                end
            end




            S_CTRL_MAR_MEM_WRITE1: begin
                if (noc_wrreq_i) begin
                    if (!mar_mem_stall_i) begin

                        if (noc_burst_i) begin
                            noc_fifo_pop_o = 1'b1;

                            rin_start_shift = start_shift;
                            rin_end_shift = end_shift;

                            rin_wben = ({TCU_MEM_BSEL_SIZE{1'b1}} >> start_shift) << r_laddr[3:0];
                            rin2_wben_msb = r_wben[TCU_MEM_BSEL_SIZE-1];

                            rin_burst_length = burst_length;


                            if (burst_length == 'd1) begin
                                next_ctrl_mar_state = S_CTRL_MAR_MEM_WRITE3;
                            end else begin
                                next_ctrl_mar_state = S_CTRL_MAR_MEM_WRITE2;
                            end
                        end


                        else begin


                            if ((5'd16 - r_laddr[3:0]) < bsel_count_ones) begin
                                rin_laddr = {(r_laddr[31:4]+'d1), 4'h0};
                                rin_size = r_size - (5'd16 - r_laddr[3:0]);
                                next_ctrl_mar_state = S_CTRL_MAR_MEM_WRITE1_SPLIT;
                            end
                            else begin
                                noc_fifo_pop_o = 1'b1;
                                rin_size = 'd0;
                                next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                            end
                        end
                    end


                    else if (TIMEOUT_RECV_CYCLES != 32'h0) begin
                        rin_mar_timeout = r_mar_timeout + 32'd1;
                        if (r_mar_timeout > TIMEOUT_RECV_CYCLES) begin
                            rin_mar_error = TCU_ERROR_TIMEOUT_MEM;
                            next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                        end
                    end
                end
            end


            S_CTRL_MAR_MEM_WRITE1_SPLIT: begin
                if (!mar_mem_stall_i) begin
                    noc_fifo_pop_o = 1'b1;
                    rin_size = 'd0;
                    next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                end
            end


            S_CTRL_MAR_MEM_WRITE2: begin
                if (noc_wrreq_i && !mar_mem_stall_i) begin
                    noc_fifo_pop_o = 1'b1;


                    if (mar_abort_i) begin
                        mar_mem_wabort_o = 1'b1;
                        rin_mar_error = TCU_ERROR_ABORT;
                        next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                    end


                    else if (noc_bsel_i == {NOC_BSEL_SIZE{1'b0}}) begin
                        mar_mem_wabort_o = 1'b1;
                        rin_mar_error = TCU_ERROR_ABORT;
                        next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                    end
                    else begin
                        rin_laddr = r_laddr + (5'd16 - r_start_shift);


                        if (r_start_shift > r_laddr[3:0]) begin
                            rin_size = r_size - (5'd16 - r_start_shift);
                            rin_wben = ~r_wben & ({TCU_MEM_BSEL_SIZE{1'b1}} << r_laddr[3:0]);
                            rin2_wben_msb = r_wben[TCU_MEM_BSEL_SIZE-1];
                        end
                        else begin
                            rin_size = r_size - (5'd16 - r_laddr[3:0]);
                            rin_wben = {TCU_MEM_BSEL_SIZE{1'b1}};
                            rin2_wben_msb = r_wben[TCU_MEM_BSEL_SIZE-1];
                        end


                        if (noc_burst_i) begin
                            next_ctrl_mar_state = S_CTRL_MAR_MEM_WRITE3;
                        end
                        else if (TCU_ENABLE_DRAM) begin
                            next_ctrl_mar_state = S_CTRL_MAR_WAIT_DRAM;
                        end
                        else begin
                            next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                        end
                    end
                end


                else if (TIMEOUT_RECV_CYCLES != 32'h0) begin
                    rin_mar_timeout = r_mar_timeout + 32'd1;
                    if (r_mar_timeout > TIMEOUT_RECV_CYCLES) begin
                        mar_mem_wabort_o = 1'b1;
                        rin_mar_error = noc_wrreq_i ? TCU_ERROR_TIMEOUT_MEM : TCU_ERROR_TIMEOUT_NOC;
                        next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                    end
                end
            end


            S_CTRL_MAR_MEM_WRITE3: begin
                if (noc_wrreq_i && !mar_mem_stall_i) begin
                    noc_fifo_pop_o = 1'b1;


                    if (mar_abort_i) begin
                        mar_mem_wabort_o = 1'b1;
                        rin_mar_error = TCU_ERROR_ABORT;
                        next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                    end


                    else if (noc_bsel_i == {NOC_BSEL_SIZE{1'b0}}) begin
                        mar_mem_wabort_o = 1'b1;
                        rin_mar_error = TCU_ERROR_ABORT;
                        next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                    end
                    else begin

                        if (noc_burst_i) begin
                            rin_wben = {TCU_MEM_BSEL_SIZE{1'b1}};
                            rin2_wben_msb = r_wben[TCU_MEM_BSEL_SIZE-1];
                            rin_laddr = r_laddr + 'd16;
                            rin_size = r_size - wben_count_ones;


                            if (r_size > 'd16) begin
                                noc_fifo_pop_o = 1'b1;
                                next_ctrl_mar_state = S_CTRL_MAR_MEM_WRITE3;
                            end
                            else begin
                                rin_mar_error = TCU_ERROR_CRITICAL;
                                next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                            end
                        end


                        else begin


                            if (r_size > 'd16) begin
                                rin_wben = ({TCU_MEM_BSEL_SIZE{1'b1}} >> (5'd16 - r_size[3:0]));
                                rin2_wben_msb = r_wben[TCU_MEM_BSEL_SIZE-1];

                                rin_size = r_size - 'd16;
                                rin_laddr = r_laddr + 'd16;
                                next_ctrl_mar_state = S_CTRL_MAR_MEM_WRITE4;
                            end


                            else if (((r_size + r_laddr[3:0]) > 'd16) && ((r_end_shift + r_laddr[3:0]) > 'd16)) begin
                                rin_wben = {TCU_MEM_BSEL_SIZE{1'b1}} >> (6'd32 - r_size - r_laddr[3:0]);
                                rin2_wben_msb = r_wben[TCU_MEM_BSEL_SIZE-1];
                                rin_laddr = r_laddr + 'd16;
                                rin_size = r_size - (5'd16 - r_laddr[3:0]);
                                next_ctrl_mar_state = S_CTRL_MAR_MEM_WRITE4;
                            end


                            else begin
                                rin_size = 'd0;

                                if (TCU_ENABLE_DRAM) begin
                                    next_ctrl_mar_state = S_CTRL_MAR_WAIT_DRAM;
                                end else begin
                                    next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                                end
                            end
                        end
                    end
                end


                else if (TIMEOUT_RECV_CYCLES != 32'h0) begin
                    rin_mar_timeout = r_mar_timeout + 32'd1;
                    if (r_mar_timeout > TIMEOUT_RECV_CYCLES) begin
                        rin_mar_timeout = 32'h0;
                        mar_mem_wabort_o = 1'b1;
                        rin_mar_error = noc_wrreq_i ? TCU_ERROR_TIMEOUT_MEM : TCU_ERROR_TIMEOUT_NOC;
                        next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                    end
                end
            end


            S_CTRL_MAR_MEM_WRITE4: begin
                if (!mar_mem_stall_i) begin
                    rin_size = 'd0;
                    if (TCU_ENABLE_DRAM) begin
                        next_ctrl_mar_state = S_CTRL_MAR_WAIT_DRAM;
                    end else begin
                        next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                    end
                end


                else if (TIMEOUT_RECV_CYCLES != 32'h0) begin
                    rin_mar_timeout = r_mar_timeout + 32'd1;
                    if (r_mar_timeout > TIMEOUT_RECV_CYCLES) begin
                        mar_mem_wabort_o = 1'b1;
                        rin_mar_error = TCU_ERROR_TIMEOUT_MEM;
                        next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                    end
                end
            end


            S_CTRL_MAR_WAIT_DRAM: begin
                if (!mar_mem_wdata_infifo_i) begin
                    next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                end


                else if (TIMEOUT_RECV_CYCLES != 32'h0) begin
                    rin_mar_timeout = r_mar_timeout + 32'd1;
                    if (r_mar_timeout > TIMEOUT_RECV_CYCLES) begin
                        mar_mem_wabort_o = 1'b1;
                        rin_mar_error = TCU_ERROR_TIMEOUT_MEM;
                        next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                    end
                end
            end



            S_CTRL_MAR_ERROR: begin
                if (!noc_stall_i && !mar_mem_stall_i) begin
                    mar_done_o = 1'b1;
                    next_ctrl_mar_state = S_CTRL_MAR_IDLE;
                end
            end


            S_CTRL_MAR_FINISH: begin

                if (!noc_stall_i && !mar_mem_stall_i) begin
                    mar_done_o = 1'b1;
                    next_ctrl_mar_state = S_CTRL_MAR_IDLE;
                end


                else if (mar_mem_stall_i && (TIMEOUT_RECV_CYCLES != 32'h0)) begin
                    rin_mar_timeout = r_mar_timeout + 32'd1;
                    if (r_mar_timeout > TIMEOUT_RECV_CYCLES) begin
                        mar_mem_wabort_o = 1'b1;
                        rin_mar_error = TCU_ERROR_TIMEOUT_MEM;
                        next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                    end
                end
            end

            default: next_ctrl_mar_state = S_CTRL_MAR_IDLE;

        endcase
    end






    always @* begin



        rin_mem_en = 3'b000;
        rin_mem_wben = {TCU_MEM_BSEL_SIZE{1'b0}};

        rin_shift = 4'h0;

        if (!mar_mem_stall_i) begin

            if (ctrl_mar_state == S_CTRL_MAR_PREPARE_MEM) begin
                rin_mem_en = 3'b100;
                rin_mem_wben = {TCU_MEM_BSEL_SIZE{1'b1}};
            end


            else if (noc_wrreq_i && (ctrl_mar_state == S_CTRL_MAR_MEM_WRITE1) && !noc_burst_i) begin
                rin_mem_en = 3'b001;
                rin_shift = bsel_firstone;
                rin_mem_wben = ({{(TCU_MEM_BSEL_SIZE/2){1'b0}}, noc_bsel_i} >> bsel_firstone) << r_laddr[3:0];
            end


            else if (ctrl_mar_state == S_CTRL_MAR_MEM_WRITE1_SPLIT) begin
                rin_mem_en = 3'b001;
                rin_shift = bsel_firstone + bsel_count_ones - r_size[3:0];
                rin_mem_wben = ({{(TCU_MEM_BSEL_SIZE/2){1'b0}}, noc_bsel_i} >> bsel_firstone) >> (bsel_count_ones - r_size[3:0]);
            end


            else if (noc_wrreq_i && (ctrl_mar_state == S_CTRL_MAR_MEM_WRITE2) && !mar_mem_wabort_o) begin
                rin_shift = r_start_shift;
                rin_mem_en = 3'b001;
                rin_mem_wben = r_wben;
            end


            else if (noc_wrreq_i && (ctrl_mar_state == S_CTRL_MAR_MEM_WRITE3) && !mar_mem_wabort_o) begin
                


                if (r_burst_length == 'd1) begin
                    rin_shift = r_start_shift;
                    rin_mem_en = 3'b001;
                end
                else begin
                    rin_shift = 4'h0;
                    if (r_laddr[3:0] == 4'h0) begin
                        rin_mem_en = 3'b001;
                    end else begin
                        rin_mem_en = 3'b010;
                    end
                end

                if (noc_burst_i) begin
                    rin_mem_wben = r_wben;
                end
                else begin

                    if ((r_size > 'd16) || ((r_end_shift + r_laddr[3:0]) > 'd16)) begin
                        rin_mem_wben = r_wben;
                    end
                    else if (r_size == 'd16) begin
                        rin_mem_wben = {TCU_MEM_BSEL_SIZE{1'b1}};
                    end
                    else begin


                        if ((r_burst_length != 'd1) && r2_wben_msb) begin
                            rin_mem_wben = {TCU_MEM_BSEL_SIZE{1'b1}} >> (5'd16 - r_size[3:0]);
                        end else begin
                            rin_mem_wben = ({TCU_MEM_BSEL_SIZE{1'b1}} >> (5'd16 - r_size[3:0])) << r_laddr[3:0];
                        end
                    end
                end
            end


            else if (ctrl_mar_state == S_CTRL_MAR_MEM_WRITE4) begin

                if (r_burst_length == 'd1) begin
                    rin_shift = r_start_shift;
                end
                rin_mem_en = 3'b010;
                rin_mem_wben = r_wben;
            end
        end
    end


    assign mar_mem_en_o = r_mem_en;
    assign mar_mem_wben_o = r_mem_wben;
    assign mar_mem_addr_o = r_mem_addr;
    assign mar_mem_wdata_o = r_size;

    assign mar_error_o = r_mar_error;
    assign mar_active_o = (ctrl_mar_state != S_CTRL_MAR_IDLE);
    assign mar_shift_o = r_shift;


    assign noc_wrreq_o = mar_done_o && r_mode_write_posted;
    assign noc_chipid_o = r_ack_chipid;
    assign noc_modid_o = r_ack_modid;
    assign noc_addr_o = r_ack_addr;
    assign noc_data_o = r_ack_size;

endmodule
module tcu_ctrl_mem_access_recv #(
    `include "noc_parameter.vh"
    ,`include "tcu_parameter.vh"
    ,parameter TCU_ENABLE_DRAM           = 0,
    parameter [31:0] TIMEOUT_RECV_CYCLES = 0
)(
    input  wire                          clk_i,
    input  wire                          reset_n_i,



    output wire                    [2:0] mar_mem_en_o,
    output wire  [TCU_MEM_BSEL_SIZE-1:0] mar_mem_wben_o,
    output wire  [TCU_MEM_ADDR_SIZE-1:0] mar_mem_addr_o,
    output wire  [TCU_MEM_DATA_SIZE-1:0] mar_mem_wdata_o,
    input  wire                          mar_mem_wdata_infifo_i,
    output reg                           mar_mem_wabort_o,
    input  wire                          mar_mem_stall_i,



    output reg                           noc_fifo_pop_o,
    input  wire                          noc_wrreq_i,
    input  wire                          noc_burst_i,
    input  wire      [NOC_BSEL_SIZE-1:0] noc_bsel_i,
    input  wire    [NOC_CHIPID_SIZE-1:0] noc_chipid_i,
    input  wire     [NOC_MODID_SIZE-1:0] noc_modid_i,
    input  wire      [NOC_ADDR_SIZE-1:0] noc_addr_i,
    input  wire      [NOC_MODE_SIZE-1:0] noc_mode_i,
    input  wire      [NOC_DATA_SIZE-1:0] noc_data0_i,
    input  wire                          noc_stall_i,
    output wire                          noc_wrreq_o,
    output wire    [NOC_CHIPID_SIZE-1:0] noc_chipid_o,
    output wire     [NOC_MODID_SIZE-1:0] noc_modid_o,
    output wire      [NOC_ADDR_SIZE-1:0] noc_addr_o,
    output wire                   [31:0] noc_data_o,



    input  wire                          mar_start_i,
    input  wire                          mar_abort_i,
    output wire                          mar_active_o,
    output reg                           mar_done_o,
    output wire     [TCU_ERROR_SIZE-1:0] mar_error_o,
    output wire                    [3:0] mar_shift_o
);


    `include "tcu_functions.v"


    localparam CTRL_MAR_STATES_SIZE        = 4;
    localparam S_CTRL_MAR_IDLE             = 4'h0;
    localparam S_CTRL_MAR_PACKET_CHECK     = 4'h1;
    localparam S_CTRL_MAR_PREPARE_MEM      = 4'h2;
    localparam S_CTRL_MAR_MEM_WRITE1       = 4'h3;
    localparam S_CTRL_MAR_MEM_WRITE1_SPLIT = 4'h4;
    localparam S_CTRL_MAR_MEM_WRITE2       = 4'h5;
    localparam S_CTRL_MAR_MEM_WRITE3       = 4'h6;
    localparam S_CTRL_MAR_MEM_WRITE4       = 4'h7;
    localparam S_CTRL_MAR_WAIT_DRAM        = 4'h8;
    localparam S_CTRL_MAR_ERROR            = 4'h9;
    localparam S_CTRL_MAR_FINISH           = 4'hF;

    reg [CTRL_MAR_STATES_SIZE-1:0] ctrl_mar_state, next_ctrl_mar_state;



    reg [31:0] r_laddr, rin_laddr;
    reg [15:0] r_size, rin_size;
    reg  [3:0] r_start_shift, rin_start_shift;
    reg  [4:0] r_end_shift, rin_end_shift;
    reg  [3:0] r_shift, rin_shift;


    reg                       r_mode_write_posted, rin_mode_write_posted;
    reg [NOC_CHIPID_SIZE-1:0] r_ack_chipid, rin_ack_chipid;
    reg  [NOC_MODID_SIZE-1:0] r_ack_modid, rin_ack_modid;
    reg   [NOC_ADDR_SIZE-1:0] r_ack_addr, rin_ack_addr;
    reg                [31:0] r_ack_size, rin_ack_size;

    reg                   [2:0] r_mem_en, rin_mem_en;
    reg [TCU_MEM_BSEL_SIZE-1:0] r_mem_wben, rin_mem_wben;
    reg [TCU_MEM_ADDR_SIZE-1:0] r_mem_addr;

    reg [TCU_MEM_BSEL_SIZE-1:0] r_wben, rin_wben;
    reg                         r2_wben_msb, rin2_wben_msb;

    reg [12:0] r_burst_length, rin_burst_length;


    reg [TCU_ERROR_SIZE-1:0] r_mar_error, rin_mar_error;


    reg [31:0] r_mar_timeout, rin_mar_timeout;


    wire  [3:0] start_shift  = ~noc_bsel_i[3:0];
    wire  [4:0] end_shift    = noc_bsel_i[7:4] + 5'd1;
    wire [12:0] burst_length = noc_data0_i[12:0];

    wire  [3:0] bsel_count_ones = count_ones8(noc_bsel_i);
    wire  [4:0] wben_count_ones = count_ones8(r_wben[7:0]) + count_ones8(r_wben[15:8]);

    wire  [2:0] bsel_firstone = get_firstone8(noc_bsel_i);




    always @(posedge clk_i) begin
        if (reset_n_i == 1'b0) begin
            ctrl_mar_state <= S_CTRL_MAR_IDLE;
            
            r_laddr <= 32'h0;
            r_size <= 16'h0;
            r_start_shift <= 4'h0;
            r_end_shift <= 5'h0;
            r_shift <= 4'h0;

            r_mode_write_posted <= 1'b0;
            r_ack_chipid <= {NOC_CHIPID_SIZE{1'b0}};
            r_ack_modid <= {NOC_MODID_SIZE{1'b0}};
            r_ack_addr <= {NOC_ADDR_SIZE{1'b0}};
            r_ack_size <= 32'h0;

            r_mem_en <= 3'h0;
            r_mem_wben <= {TCU_MEM_BSEL_SIZE{1'b0}};
            r_mem_addr <= {TCU_MEM_ADDR_SIZE{1'b0}};

            r_wben <= {TCU_MEM_BSEL_SIZE{1'b0}};
            r2_wben_msb <= 1'b0;

            r_burst_length <= 13'h0;

            r_mar_error <= TCU_ERROR_NONE;

            r_mar_timeout <= 32'h0;
        end
        else begin
            ctrl_mar_state <= next_ctrl_mar_state;
            
            r_laddr <= rin_laddr;
            r_size <= rin_size;
            r_start_shift <= rin_start_shift;
            r_end_shift <= rin_end_shift;
            r_shift <= rin_shift;

            r_mode_write_posted <= rin_mode_write_posted;
            r_ack_chipid <= rin_ack_chipid;
            r_ack_modid <= rin_ack_modid;
            r_ack_addr <= rin_ack_addr;
            r_ack_size <= rin_ack_size;

            r_mem_en <= rin_mem_en;
            r_mem_wben <= rin_mem_wben;
            r_mem_addr <= r_laddr;

            r_wben <= rin_wben;
            r2_wben_msb <= rin2_wben_msb;

            r_burst_length <= rin_burst_length;

            r_mar_error <= rin_mar_error;

            r_mar_timeout <= rin_mar_timeout;
        end
    end






    always @* begin
        next_ctrl_mar_state = ctrl_mar_state;

        rin_laddr = r_laddr;
        rin_size = r_size;
        rin_start_shift = r_start_shift;
        rin_end_shift = r_end_shift;

        rin_mode_write_posted = r_mode_write_posted;
        rin_ack_chipid = r_ack_chipid;
        rin_ack_modid = r_ack_modid;
        rin_ack_addr = r_ack_addr;
        rin_ack_size = r_ack_size;

        rin_wben = r_wben;
        rin2_wben_msb = r2_wben_msb;

        rin_burst_length = r_burst_length;

        noc_fifo_pop_o = 1'b0;

        rin_mar_error = r_mar_error;
        mar_done_o = 1'b0;

        rin_mar_timeout = 32'h0;

        mar_mem_wabort_o = 1'b0;


        case (ctrl_mar_state)



            S_CTRL_MAR_IDLE: begin
                if (mar_start_i) begin

                    rin_mode_write_posted = (noc_mode_i == MODE_WRITE_POSTED);
                    rin_ack_chipid = noc_chipid_i;
                    rin_ack_modid = noc_modid_i;
                    rin_ack_addr = noc_addr_i;
                    if (noc_burst_i) begin
                        rin_size = {burst_length, 4'h0} - start_shift - (5'd16 - end_shift);
                        rin_ack_size = {burst_length, 4'h0} - start_shift - (5'd16 - end_shift);
                    end else begin
                        rin_size = bsel_count_ones;
                        rin_ack_size = bsel_count_ones;
                    end


                    if (mar_abort_i) begin
                        rin_mar_error = TCU_ERROR_ABORT;
                        next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                    end
                    else begin
                        rin_laddr = noc_addr_i;

                        rin_mar_error = TCU_ERROR_NONE;
                        next_ctrl_mar_state = S_CTRL_MAR_PACKET_CHECK;
                    end
                end
            end

            


            S_CTRL_MAR_PACKET_CHECK: begin

                if (mar_abort_i) begin
                    rin_mar_error = TCU_ERROR_ABORT;
                    next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                end
                else if (noc_wrreq_i &&
                        ((noc_mode_i == MODE_WRITE_POSTED) || (noc_mode_i == MODE_READ_RSP) ||
                        (noc_mode_i == MODE_WRITE_POSTED_2) || (noc_mode_i == MODE_READ_RSP_2))) begin


                    if (TCU_ENABLE_DRAM && noc_burst_i && (burst_length > 'd1)) begin
                        next_ctrl_mar_state = S_CTRL_MAR_PREPARE_MEM;
                    end


                    else begin
                        next_ctrl_mar_state = S_CTRL_MAR_MEM_WRITE1;
                    end
                end


                else if (TIMEOUT_RECV_CYCLES != 32'h0) begin
                    rin_mar_timeout = r_mar_timeout + 32'd1;
                    if (r_mar_timeout > TIMEOUT_RECV_CYCLES) begin
                        rin_mar_error = TCU_ERROR_TIMEOUT_NOC;
                        next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                    end
                end
            end


            S_CTRL_MAR_PREPARE_MEM: begin
                if (!mar_mem_stall_i) begin
                    next_ctrl_mar_state = S_CTRL_MAR_MEM_WRITE1;
                end


                else if (TIMEOUT_RECV_CYCLES != 32'h0) begin
                    rin_mar_timeout = r_mar_timeout + 32'd1;
                    if (r_mar_timeout > TIMEOUT_RECV_CYCLES) begin
                        rin_mar_error = TCU_ERROR_TIMEOUT_MEM;
                        next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                    end
                end
            end




            S_CTRL_MAR_MEM_WRITE1: begin
                if (noc_wrreq_i) begin
                    if (!mar_mem_stall_i) begin

                        if (noc_burst_i) begin
                            noc_fifo_pop_o = 1'b1;

                            rin_start_shift = start_shift;
                            rin_end_shift = end_shift;

                            rin_wben = ({TCU_MEM_BSEL_SIZE{1'b1}} >> start_shift) << r_laddr[3:0];
                            rin2_wben_msb = r_wben[TCU_MEM_BSEL_SIZE-1];

                            rin_burst_length = burst_length;


                            if (burst_length == 'd1) begin
                                next_ctrl_mar_state = S_CTRL_MAR_MEM_WRITE3;
                            end else begin
                                next_ctrl_mar_state = S_CTRL_MAR_MEM_WRITE2;
                            end
                        end


                        else begin


                            if ((5'd16 - r_laddr[3:0]) < bsel_count_ones) begin
                                rin_laddr = {(r_laddr[31:4]+'d1), 4'h0};
                                rin_size = r_size - (5'd16 - r_laddr[3:0]);
                                next_ctrl_mar_state = S_CTRL_MAR_MEM_WRITE1_SPLIT;
                            end
                            else begin
                                noc_fifo_pop_o = 1'b1;
                                rin_size = 'd0;
                                next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                            end
                        end
                    end


                    else if (TIMEOUT_RECV_CYCLES != 32'h0) begin
                        rin_mar_timeout = r_mar_timeout + 32'd1;
                        if (r_mar_timeout > TIMEOUT_RECV_CYCLES) begin
                            rin_mar_error = TCU_ERROR_TIMEOUT_MEM;
                            next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                        end
                    end
                end
            end


            S_CTRL_MAR_MEM_WRITE1_SPLIT: begin
                if (!mar_mem_stall_i) begin
                    noc_fifo_pop_o = 1'b1;
                    rin_size = 'd0;
                    next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                end
            end


            S_CTRL_MAR_MEM_WRITE2: begin
                if (noc_wrreq_i && !mar_mem_stall_i) begin
                    noc_fifo_pop_o = 1'b1;


                    if (mar_abort_i) begin
                        mar_mem_wabort_o = 1'b1;
                        rin_mar_error = TCU_ERROR_ABORT;
                        next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                    end


                    else if (noc_bsel_i == {NOC_BSEL_SIZE{1'b0}}) begin
                        mar_mem_wabort_o = 1'b1;
                        rin_mar_error = TCU_ERROR_ABORT;
                        next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                    end
                    else begin
                        rin_laddr = r_laddr + (5'd16 - r_start_shift);


                        if (r_start_shift > r_laddr[3:0]) begin
                            rin_size = r_size - (5'd16 - r_start_shift);
                            rin_wben = ~r_wben & ({TCU_MEM_BSEL_SIZE{1'b1}} << r_laddr[3:0]);
                            rin2_wben_msb = r_wben[TCU_MEM_BSEL_SIZE-1];
                        end
                        else begin
                            rin_size = r_size - (5'd16 - r_laddr[3:0]);
                            rin_wben = {TCU_MEM_BSEL_SIZE{1'b1}};
                            rin2_wben_msb = r_wben[TCU_MEM_BSEL_SIZE-1];
                        end


                        if (noc_burst_i) begin
                            next_ctrl_mar_state = S_CTRL_MAR_MEM_WRITE3;
                        end
                        else if (TCU_ENABLE_DRAM) begin
                            next_ctrl_mar_state = S_CTRL_MAR_WAIT_DRAM;
                        end
                        else begin
                            next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                        end
                    end
                end


                else if (TIMEOUT_RECV_CYCLES != 32'h0) begin
                    rin_mar_timeout = r_mar_timeout + 32'd1;
                    if (r_mar_timeout > TIMEOUT_RECV_CYCLES) begin
                        mar_mem_wabort_o = 1'b1;
                        rin_mar_error = noc_wrreq_i ? TCU_ERROR_TIMEOUT_MEM : TCU_ERROR_TIMEOUT_NOC;
                        next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                    end
                end
            end


            S_CTRL_MAR_MEM_WRITE3: begin
                if (noc_wrreq_i && !mar_mem_stall_i) begin
                    noc_fifo_pop_o = 1'b1;


                    if (mar_abort_i) begin
                        mar_mem_wabort_o = 1'b1;
                        rin_mar_error = TCU_ERROR_ABORT;
                        next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                    end


                    else if (noc_bsel_i == {NOC_BSEL_SIZE{1'b0}}) begin
                        mar_mem_wabort_o = 1'b1;
                        rin_mar_error = TCU_ERROR_ABORT;
                        next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                    end
                    else begin

                        if (noc_burst_i) begin
                            rin_wben = {TCU_MEM_BSEL_SIZE{1'b1}};
                            rin2_wben_msb = r_wben[TCU_MEM_BSEL_SIZE-1];
                            rin_laddr = r_laddr + 'd16;
                            rin_size = r_size - wben_count_ones;


                            if (r_size > 'd16) begin
                                noc_fifo_pop_o = 1'b1;
                                next_ctrl_mar_state = S_CTRL_MAR_MEM_WRITE3;
                            end
                            else begin
                                rin_mar_error = TCU_ERROR_CRITICAL;
                                next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                            end
                        end


                        else begin


                            if (r_size > 'd16) begin
                                rin_wben = ({TCU_MEM_BSEL_SIZE{1'b1}} >> (5'd16 - r_size[3:0]));
                                rin2_wben_msb = r_wben[TCU_MEM_BSEL_SIZE-1];

                                rin_size = r_size - 'd16;
                                rin_laddr = r_laddr + 'd16;
                                next_ctrl_mar_state = S_CTRL_MAR_MEM_WRITE4;
                            end


                            else if (((r_size + r_laddr[3:0]) > 'd16) && ((r_end_shift + r_laddr[3:0]) > 'd16)) begin
                                rin_wben = {TCU_MEM_BSEL_SIZE{1'b1}} >> (6'd32 - r_size - r_laddr[3:0]);
                                rin2_wben_msb = r_wben[TCU_MEM_BSEL_SIZE-1];
                                rin_laddr = r_laddr + 'd16;
                                rin_size = r_size - (5'd16 - r_laddr[3:0]);
                                next_ctrl_mar_state = S_CTRL_MAR_MEM_WRITE4;
                            end


                            else begin
                                rin_size = 'd0;

                                if (TCU_ENABLE_DRAM) begin
                                    next_ctrl_mar_state = S_CTRL_MAR_WAIT_DRAM;
                                end else begin
                                    next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                                end
                            end
                        end
                    end
                end


                else if (TIMEOUT_RECV_CYCLES != 32'h0) begin
                    rin_mar_timeout = r_mar_timeout + 32'd1;
                    if (r_mar_timeout > TIMEOUT_RECV_CYCLES) begin
                        rin_mar_timeout = 32'h0;
                        mar_mem_wabort_o = 1'b1;
                        rin_mar_error = noc_wrreq_i ? TCU_ERROR_TIMEOUT_MEM : TCU_ERROR_TIMEOUT_NOC;
                        next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                    end
                end
            end


            S_CTRL_MAR_MEM_WRITE4: begin
                if (!mar_mem_stall_i) begin
                    rin_size = 'd0;
                    if (TCU_ENABLE_DRAM) begin
                        next_ctrl_mar_state = S_CTRL_MAR_WAIT_DRAM;
                    end else begin
                        next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                    end
                end


                else if (TIMEOUT_RECV_CYCLES != 32'h0) begin
                    rin_mar_timeout = r_mar_timeout + 32'd1;
                    if (r_mar_timeout > TIMEOUT_RECV_CYCLES) begin
                        mar_mem_wabort_o = 1'b1;
                        rin_mar_error = TCU_ERROR_TIMEOUT_MEM;
                        next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                    end
                end
            end


            S_CTRL_MAR_WAIT_DRAM: begin
                if (!mar_mem_wdata_infifo_i) begin
                    next_ctrl_mar_state = S_CTRL_MAR_FINISH;
                end


                else if (TIMEOUT_RECV_CYCLES != 32'h0) begin
                    rin_mar_timeout = r_mar_timeout + 32'd1;
                    if (r_mar_timeout > TIMEOUT_RECV_CYCLES) begin
                        mar_mem_wabort_o = 1'b1;
                        rin_mar_error = TCU_ERROR_TIMEOUT_MEM;
                        next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                    end
                end
            end



            S_CTRL_MAR_ERROR: begin
                if (!noc_stall_i && !mar_mem_stall_i) begin
                    mar_done_o = 1'b1;
                    next_ctrl_mar_state = S_CTRL_MAR_IDLE;
                end
            end


            S_CTRL_MAR_FINISH: begin

                if (!noc_stall_i && !mar_mem_stall_i) begin
                    mar_done_o = 1'b1;
                    next_ctrl_mar_state = S_CTRL_MAR_IDLE;
                end


                else if (mar_mem_stall_i && (TIMEOUT_RECV_CYCLES != 32'h0)) begin
                    rin_mar_timeout = r_mar_timeout + 32'd1;
                    if (r_mar_timeout > TIMEOUT_RECV_CYCLES) begin
                        mar_mem_wabort_o = 1'b1;
                        rin_mar_error = TCU_ERROR_TIMEOUT_MEM;
                        next_ctrl_mar_state = S_CTRL_MAR_ERROR;
                    end
                end
            end

            default: next_ctrl_mar_state = S_CTRL_MAR_IDLE;

        endcase
    end






    always @* begin



        rin_mem_en = 3'b000;
        rin_mem_wben = {TCU_MEM_BSEL_SIZE{1'b0}};

        rin_shift = 4'h0;

        if (!mar_mem_stall_i) begin

            if (ctrl_mar_state == S_CTRL_MAR_PREPARE_MEM) begin
                rin_mem_en = 3'b100;
                rin_mem_wben = {TCU_MEM_BSEL_SIZE{1'b1}};
            end


            else if (noc_wrreq_i && (ctrl_mar_state == S_CTRL_MAR_MEM_WRITE1) && !noc_burst_i) begin
                rin_mem_en = 3'b001;
                rin_shift = bsel_firstone;
                rin_mem_wben = ({{(TCU_MEM_BSEL_SIZE/2){1'b0}}, noc_bsel_i} >> bsel_firstone) << r_laddr[3:0];
            end


            else if (ctrl_mar_state == S_CTRL_MAR_MEM_WRITE1_SPLIT) begin
                rin_mem_en = 3'b001;
                rin_shift = bsel_firstone + bsel_count_ones - r_size[3:0];
                rin_mem_wben = ({{(TCU_MEM_BSEL_SIZE/2){1'b0}}, noc_bsel_i} >> bsel_firstone) >> (bsel_count_ones - r_size[3:0]);
            end


            else if (noc_wrreq_i && (ctrl_mar_state == S_CTRL_MAR_MEM_WRITE2) && !mar_mem_wabort_o) begin
                rin_shift = r_start_shift;
                rin_mem_en = 3'b001;
                rin_mem_wben = r_wben;
            end


            else if (noc_wrreq_i && (ctrl_mar_state == S_CTRL_MAR_MEM_WRITE3) && !mar_mem_wabort_o) begin
                


                if (r_burst_length == 'd1) begin
                    rin_shift = r_start_shift;
                    rin_mem_en = 3'b001;
                end
                else begin
                    rin_shift = 4'h0;
                    if (r_laddr[3:0] == 4'h0) begin
                        rin_mem_en = 3'b001;
                    end else begin
                        rin_mem_en = 3'b010;
                    end
                end

                if (noc_burst_i) begin
                    rin_mem_wben = r_wben;
                end
                else begin

                    if ((r_size > 'd16) || ((r_end_shift + r_laddr[3:0]) > 'd16)) begin
                        rin_mem_wben = r_wben;
                    end
                    else if (r_size == 'd16) begin
                        rin_mem_wben = {TCU_MEM_BSEL_SIZE{1'b1}};
                    end
                    else begin


                        if ((r_burst_length != 'd1) && r2_wben_msb) begin
                            rin_mem_wben = {TCU_MEM_BSEL_SIZE{1'b1}} >> (5'd16 - r_size[3:0]);
                        end else begin
                            rin_mem_wben = ({TCU_MEM_BSEL_SIZE{1'b1}} >> (5'd16 - r_size[3:0])) << r_laddr[3:0];
                        end
                    end
                end
            end


            else if (ctrl_mar_state == S_CTRL_MAR_MEM_WRITE4) begin

                if (r_burst_length == 'd1) begin
                    rin_shift = r_start_shift;
                end
                rin_mem_en = 3'b010;
                rin_mem_wben = r_wben;
            end
        end
    end


    assign mar_mem_en_o = r_mem_en;
    assign mar_mem_wben_o = r_mem_wben;
    assign mar_mem_addr_o = r_mem_addr;
    assign mar_mem_wdata_o = r_size;

    assign mar_error_o = r_mar_error;
    assign mar_active_o = (ctrl_mar_state != S_CTRL_MAR_IDLE);
    assign mar_shift_o = r_shift;


    assign noc_wrreq_o = mar_done_o && r_mode_write_posted;
    assign noc_chipid_o = r_ack_chipid;
    assign noc_modid_o = r_ack_modid;
    assign noc_addr_o = r_ack_addr;
    assign noc_data_o = r_ack_size;

endmodule