data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv
1: b"%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:271: syntax error, unexpected ::\n                if ((slv_aw_atop_i      ==  axi_pkg::ATOP_ATOMICSWAP) ||\n                                                   ^~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:276: syntax error, unexpected ::, expecting ',' or '}'\n                if (slv_aw_atop_i[5:3] == {axi_pkg::ATOP_ATOMICSTORE, axi_pkg::ATOP_LITTLE_END}) begin\n                                                  ^~\n                                                                                                                                         : ... Perhaps 'axi_pkg' is a package which needs to be predeclared? (IEEE 1800-2017 26.3)\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:289: syntax error, unexpected end\n        end\n        ^~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:338: syntax error, unexpected '=', expecting IDENTIFIER\n            mst_aw_valid_o = 1'b0;\n                           ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:342: syntax error, unexpected '=', expecting IDENTIFIER\n            mst_aw_valid_o = 1'b0;\n                           ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:346: syntax error, unexpected '=', expecting IDENTIFIER\n            mst_aw_valid_o = 1'b0;\n                           ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:350: syntax error, unexpected '=', expecting IDENTIFIER\n            mst_aw_valid_o  = slv_aw_valid_i;\n                            ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:356: syntax error, unexpected '=', expecting IDENTIFIER\n            w_cnt_inj_d = w_cnt_inj_q - 1;\n                        ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:378: syntax error, unexpected '=', expecting IDENTIFIER\n                        aw_state_d = WAIT_RESULT_AW;\n                                   ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:404: syntax error, unexpected '=', expecting IDENTIFIER\n                        aw_state_d = FEEDTHROUGH_AW;\n                                   ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:406: syntax error, unexpected '=', expecting IDENTIFIER\n                        aw_state_d = SEND_AW;\n                                   ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:411: syntax error, unexpected '=', expecting IDENTIFIER\n                            w_cnt_inj_d = w_cnt_q - 1;\n                                        ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:413: syntax error, unexpected '=', expecting IDENTIFIER\n                            w_cnt_inj_d = w_cnt_q;\n                                        ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:416: syntax error, unexpected end\n                end\n                ^~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:447: syntax error, unexpected '=', expecting IDENTIFIER\n            slv_w_ready_o = 1'b0;\n                          ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:450: syntax error, unexpected '=', expecting IDENTIFIER\n            mst_w_valid_o = slv_w_valid_i;\n                          ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:466: syntax error, unexpected '=', expecting IDENTIFIER\n                            mst_w_valid_o = 1'b0;\n                                          ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:471: syntax error, unexpected '=', expecting IDENTIFIER\n                                    w_data_d    = slv_w_data_i;\n                                                ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:478: syntax error, unexpected '=', expecting IDENTIFIER\n                                w_cnt_req_d = '0;\n                                            ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:484: syntax error, unexpected '=', expecting IDENTIFIER\n                                w_cnt_req_d = w_cnt_q - 1;\n                                            ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:486: syntax error, unexpected '=', expecting IDENTIFIER\n                                w_cnt_req_d = w_cnt_q;\n                                            ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:488: syntax error, unexpected '=', expecting IDENTIFIER\n                            w_state_d   = WAIT_DATA_W;\n                                        ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:491: syntax error, unexpected end\n                end\n                ^~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:504: syntax error, unexpected '=', expecting IDENTIFIER\n                            w_state_d    = FEEDTHROUGH_W;\n                                         ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:506: syntax error, unexpected '=', expecting IDENTIFIER\n                            w_data_d    = slv_w_data_i;\n                                        ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:513: syntax error, unexpected end\n                end else if (mst_w_valid_o && mst_w_ready_i && mst_w_last_o) begin\n                ^~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:525: syntax error, unexpected '=', expecting IDENTIFIER\n                        slv_w_ready_o = 1'b0;\n                                      ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:533: syntax error, unexpected '=', expecting IDENTIFIER\n                            w_state_d = FEEDTHROUGH_W;\n                                      ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:535: syntax error, unexpected '=', expecting IDENTIFIER\n                            w_state_d = SEND_W;\n                                      ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:538: syntax error, unexpected '=', expecting IDENTIFIER\n                        w_state_d = WAIT_CHANNEL_W;\n                                  ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:555: syntax error, unexpected '=', expecting IDENTIFIER\n                        w_state_d = FEEDTHROUGH_W;\n                                  ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:557: syntax error, unexpected '=', expecting IDENTIFIER\n                        w_state_d = SEND_W;\n                                  ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:598: syntax error, unexpected '=', expecting IDENTIFIER\n                                b_state_d = SEND_B;\n                                          ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:617: syntax error, unexpected '=', expecting IDENTIFIER\n                        b_state_d = FEEDTHROUGH_B;\n                                  ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:619: syntax error, unexpected '=', expecting IDENTIFIER\n                        b_state_d = SEND_B;\n                                  ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:639: syntax error, unexpected +=, expecting IDENTIFIER\n            w_cnt_d += 1;\n                    ^~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:642: syntax error, unexpected -=, expecting IDENTIFIER\n            w_cnt_d -= 1;\n                    ^~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:728: syntax error, unexpected '=', expecting IDENTIFIER\n                            slv_ar_ready_o  = 1'b0;\n                                            ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:744: syntax error, unexpected '=', expecting IDENTIFIER\n                                ar_state_d = SEND_AR;\n                                           ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:748: syntax error, unexpected '=', expecting IDENTIFIER\n                            ar_state_d   = WAIT_CHANNEL_AR;\n                                         ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:752: syntax error, unexpected end\n            end  \n            ^~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:772: syntax error, unexpected '=', expecting IDENTIFIER\n                        ar_state_d = FEEDTHROUGH_AR;\n                                   ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:775: syntax error, unexpected '=', expecting IDENTIFIER\n                        ar_state_d = SEND_AR;\n                                   ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:818: syntax error, unexpected '=', expecting IDENTIFIER\n                        r_state_d = WAIT_DATA_R;\n                                  ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:824: syntax error, unexpected '=', expecting IDENTIFIER\n                            mst_r_ready_o = 1'b0;\n                                          ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:834: syntax error, unexpected '=', expecting IDENTIFIER\n                                r_state_d = SEND_R;\n                                          ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:837: syntax error, unexpected '=', expecting IDENTIFIER\n                            r_state_d = WAIT_CHANNEL_R;\n                                      ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:840: syntax error, unexpected end\n                end\n                ^~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:855: syntax error, unexpected '=', expecting IDENTIFIER\n                        r_state_d = FEEDTHROUGH_R;\n                                  ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi_riscv_atomics/src/axi_riscv_amos.sv:858: syntax error, unexpected '=', expecting IDENTIFIER\n                        r_state_d = WAIT_CHANNEL_R;\n                                  ^\n%Error: Exiting due to too many errors encountered; --error-limit=50\n"
module axi_riscv_amos #(

    parameter int unsigned AXI_ADDR_WIDTH       = 0,
    parameter int unsigned AXI_DATA_WIDTH       = 0,
    parameter int unsigned AXI_ID_WIDTH         = 0,
    parameter int unsigned AXI_USER_WIDTH       = 0,

    parameter int unsigned AXI_MAX_WRITE_TXNS   = 0,



    parameter int unsigned RISCV_WORD_WIDTH     = 0,

    localparam int unsigned AXI_STRB_WIDTH      = AXI_DATA_WIDTH / 8
) (
    input  logic                        clk_i,
    input  logic                        rst_ni,


    input  logic [AXI_ADDR_WIDTH-1:0]   slv_aw_addr_i,
    input  logic [2:0]                  slv_aw_prot_i,
    input  logic [3:0]                  slv_aw_region_i,
    input  logic [5:0]                  slv_aw_atop_i,
    input  logic [7:0]                  slv_aw_len_i,
    input  logic [2:0]                  slv_aw_size_i,
    input  logic [1:0]                  slv_aw_burst_i,
    input  logic                        slv_aw_lock_i,
    input  logic [3:0]                  slv_aw_cache_i,
    input  logic [3:0]                  slv_aw_qos_i,
    input  logic [AXI_ID_WIDTH-1:0]     slv_aw_id_i,
    input  logic [AXI_USER_WIDTH-1:0]   slv_aw_user_i,
    output logic                        slv_aw_ready_o,
    input  logic                        slv_aw_valid_i,

    input  logic [AXI_ADDR_WIDTH-1:0]   slv_ar_addr_i,
    input  logic [2:0]                  slv_ar_prot_i,
    input  logic [3:0]                  slv_ar_region_i,
    input  logic [7:0]                  slv_ar_len_i,
    input  logic [2:0]                  slv_ar_size_i,
    input  logic [1:0]                  slv_ar_burst_i,
    input  logic                        slv_ar_lock_i,
    input  logic [3:0]                  slv_ar_cache_i,
    input  logic [3:0]                  slv_ar_qos_i,
    input  logic [AXI_ID_WIDTH-1:0]     slv_ar_id_i,
    input  logic [AXI_USER_WIDTH-1:0]   slv_ar_user_i,
    output logic                        slv_ar_ready_o,
    input  logic                        slv_ar_valid_i,

    input  logic [AXI_DATA_WIDTH-1:0]   slv_w_data_i,
    input  logic [AXI_STRB_WIDTH-1:0]   slv_w_strb_i,
    input  logic [AXI_USER_WIDTH-1:0]   slv_w_user_i,
    input  logic                        slv_w_last_i,
    output logic                        slv_w_ready_o,
    input  logic                        slv_w_valid_i,

    output logic [AXI_DATA_WIDTH-1:0]   slv_r_data_o,
    output logic [1:0]                  slv_r_resp_o,
    output logic                        slv_r_last_o,
    output logic [AXI_ID_WIDTH-1:0]     slv_r_id_o,
    output logic [AXI_USER_WIDTH-1:0]   slv_r_user_o,
    input  logic                        slv_r_ready_i,
    output logic                        slv_r_valid_o,

    output logic [1:0]                  slv_b_resp_o,
    output logic [AXI_ID_WIDTH-1:0]     slv_b_id_o,
    output logic [AXI_USER_WIDTH-1:0]   slv_b_user_o,
    input  logic                        slv_b_ready_i,
    output logic                        slv_b_valid_o,


    output logic [AXI_ADDR_WIDTH-1:0]   mst_aw_addr_o,
    output logic [2:0]                  mst_aw_prot_o,
    output logic [3:0]                  mst_aw_region_o,
    output logic [5:0]                  mst_aw_atop_o,
    output logic [7:0]                  mst_aw_len_o,
    output logic [2:0]                  mst_aw_size_o,
    output logic [1:0]                  mst_aw_burst_o,
    output logic                        mst_aw_lock_o,
    output logic [3:0]                  mst_aw_cache_o,
    output logic [3:0]                  mst_aw_qos_o,
    output logic [AXI_ID_WIDTH-1:0]     mst_aw_id_o,
    output logic [AXI_USER_WIDTH-1:0]   mst_aw_user_o,
    input  logic                        mst_aw_ready_i,
    output logic                        mst_aw_valid_o,

    output logic [AXI_ADDR_WIDTH-1:0]   mst_ar_addr_o,
    output logic [2:0]                  mst_ar_prot_o,
    output logic [3:0]                  mst_ar_region_o,
    output logic [7:0]                  mst_ar_len_o,
    output logic [2:0]                  mst_ar_size_o,
    output logic [1:0]                  mst_ar_burst_o,
    output logic                        mst_ar_lock_o,
    output logic [3:0]                  mst_ar_cache_o,
    output logic [3:0]                  mst_ar_qos_o,
    output logic [AXI_ID_WIDTH-1:0]     mst_ar_id_o,
    output logic [AXI_USER_WIDTH-1:0]   mst_ar_user_o,
    input  logic                        mst_ar_ready_i,
    output logic                        mst_ar_valid_o,

    output logic [AXI_DATA_WIDTH-1:0]   mst_w_data_o,
    output logic [AXI_STRB_WIDTH-1:0]   mst_w_strb_o,
    output logic [AXI_USER_WIDTH-1:0]   mst_w_user_o,
    output logic                        mst_w_last_o,
    input  logic                        mst_w_ready_i,
    output logic                        mst_w_valid_o,

    input  logic [AXI_DATA_WIDTH-1:0]   mst_r_data_i,
    input  logic [1:0]                  mst_r_resp_i,
    input  logic                        mst_r_last_i,
    input  logic [AXI_ID_WIDTH-1:0]     mst_r_id_i,
    input  logic [AXI_USER_WIDTH-1:0]   mst_r_user_i,
    output logic                        mst_r_ready_o,
    input  logic                        mst_r_valid_i,

    input  logic [1:0]                  mst_b_resp_i,
    input  logic [AXI_ID_WIDTH-1:0]     mst_b_id_i,
    input  logic [AXI_USER_WIDTH-1:0]   mst_b_user_i,
    output logic                        mst_b_ready_o,
    input  logic                        mst_b_valid_i
);

    localparam int unsigned OUTSTND_BURSTS_WIDTH = $clog2(AXI_MAX_WRITE_TXNS+1);
    localparam int unsigned AXI_ALU_RATIO        = AXI_DATA_WIDTH/RISCV_WORD_WIDTH;


    typedef enum logic [1:0] { FEEDTHROUGH_AW, WAIT_RESULT_AW, SEND_AW } aw_state_t;
    aw_state_t   aw_state_d, aw_state_q;

    typedef enum logic [2:0] { FEEDTHROUGH_W, WAIT_DATA_W, WAIT_RESULT_W, WAIT_CHANNEL_W, SEND_W } w_state_t;
    w_state_t    w_state_d, w_state_q;

    typedef enum logic [1:0] { FEEDTHROUGH_B, WAIT_COMPLETE_B, WAIT_CHANNEL_B, SEND_B } b_state_t;
    b_state_t    b_state_d, b_state_q;

    typedef enum logic [1:0] { FEEDTHROUGH_AR, WAIT_CHANNEL_AR, SEND_AR } ar_state_t;
    ar_state_t   ar_state_d, ar_state_q;

    typedef enum logic [1:0] { FEEDTHROUGH_R, WAIT_DATA_R, WAIT_CHANNEL_R, SEND_R } r_state_t;
    r_state_t    r_state_d, r_state_q;

    typedef enum logic [1:0] { NONE, INVALID, LOAD, STORE } atop_req_t;
    atop_req_t   atop_valid_d, atop_valid_q;



    logic [AXI_ADDR_WIDTH-1:0]          addr_d,         addr_q;
    logic [AXI_ID_WIDTH-1:0]            id_d,           id_q;
    logic [AXI_STRB_WIDTH-1:0]          strb_d,         strb_q;
    logic [2:0]                         size_d,         size_q;
    logic [5:0]                         atop_d,         atop_q;
    logic [3:0]                         cache_d,        cache_q;
    logic [2:0]                         prot_d,         prot_q;
    logic [3:0]                         qos_d,          qos_q;
    logic [3:0]                         region_d,       region_q;
    logic [1:0]                         r_resp_d,       r_resp_q;
    logic [AXI_USER_WIDTH-1:0]          aw_user_d,      aw_user_q,
                                        w_user_d,       w_user_q,
                                        r_user_d,       r_user_q;

    logic [AXI_DATA_WIDTH-1:0]          w_data_d,       w_data_q;
    logic [AXI_DATA_WIDTH-1:0]          r_data_d,       r_data_q;
    logic [AXI_DATA_WIDTH-1:0]          result_d,       result_q;
    logic                               w_d_valid_d,    w_d_valid_q,
                                        r_d_valid_d,    r_d_valid_q;

    logic [OUTSTND_BURSTS_WIDTH-1:0]    w_cnt_d,        w_cnt_q;
    logic [OUTSTND_BURSTS_WIDTH-1:0]    w_cnt_req_d,    w_cnt_req_q;
    logic [OUTSTND_BURSTS_WIDTH-1:0]    w_cnt_inj_d,    w_cnt_inj_q;

    logic                               adapter_ready;
    logic                               transaction_collision;
    logic                               aw_valid,       aw_ready,       aw_free,
                                        w_valid,        w_ready,        w_free,
                                        b_valid,        b_ready,        b_free,
                                        ar_valid,       ar_ready,       ar_free,
                                        r_valid,        r_ready,        r_free;

    logic [RISCV_WORD_WIDTH-1:0]                        alu_operand_a;
    logic [RISCV_WORD_WIDTH-1:0]                        alu_operand_b;
    logic [RISCV_WORD_WIDTH-1:0]                        alu_result;
    logic [AXI_DATA_WIDTH-1:0]                          alu_result_ext;
    logic [AXI_ALU_RATIO-1:0][RISCV_WORD_WIDTH-1:0]     op_a;
    logic [AXI_ALU_RATIO-1:0][RISCV_WORD_WIDTH-1:0]     op_b;
    logic [AXI_ALU_RATIO-1:0][RISCV_WORD_WIDTH-1:0]     op_a_sign_ext;
    logic [AXI_ALU_RATIO-1:0][RISCV_WORD_WIDTH-1:0]     op_b_sign_ext;
    logic [AXI_ALU_RATIO-1:0][RISCV_WORD_WIDTH-1:0]     res;
    logic [AXI_STRB_WIDTH-1:0][7:0]                     strb_ext;
    logic                                               sign_a;
    logic                                               sign_b;




    assign adapter_ready = (aw_state_q == FEEDTHROUGH_AW) &&
                           ( w_state_q == FEEDTHROUGH_W ) &&
                           ( b_state_q == FEEDTHROUGH_B ) &&
                           (ar_state_q == FEEDTHROUGH_AR) &&
                           ( r_state_q == FEEDTHROUGH_R );


    assign aw_free = ~aw_valid | aw_ready;
    assign  w_free = ~ w_valid |  w_ready;
    assign  b_free = ~ b_valid |  b_ready;
    assign ar_free = ~ar_valid | ar_ready;
    assign  r_free = ~ r_valid |  r_ready;

    always_ff @(posedge clk_i or negedge rst_ni) begin
        if(~rst_ni) begin
            aw_valid <= 0;
            aw_ready <= 0;
            w_valid  <= 0;
            w_ready  <= 0;
            b_valid  <= 0;
            b_ready  <= 0;
            ar_valid <= 0;
            ar_ready <= 0;
            r_valid  <= 0;
            r_ready  <= 0;
        end else begin
            aw_valid <= mst_aw_valid_o;
            aw_ready <= mst_aw_ready_i;
            w_valid  <= mst_w_valid_o;
            w_ready  <= mst_w_ready_i;
            b_valid  <= slv_b_valid_o;
            b_ready  <= slv_b_ready_i;
            ar_valid <= mst_ar_valid_o;
            ar_ready <= mst_ar_ready_i;
            r_valid  <= slv_r_valid_o;
            r_ready  <= slv_r_ready_i;
        end
    end




    assign transaction_collision = (slv_aw_addr_i < (     addr_q + (8'h01 <<      size_q))) &
                                   (     addr_q < (slv_aw_addr_i + (8'h01 << slv_aw_size_i)));

    always_comb begin : calc_atop_valid
        atop_valid_d = atop_valid_q;
        if (adapter_ready) begin
            atop_valid_d = NONE;
            if (slv_aw_valid_i && slv_aw_atop_i) begin

                atop_valid_d = INVALID;

                if ((slv_aw_atop_i      ==  axi_pkg::ATOP_ATOMICSWAP) ||
                    (slv_aw_atop_i[5:3] == {axi_pkg::ATOP_ATOMICLOAD , axi_pkg::ATOP_LITTLE_END})) begin
                    atop_valid_d = LOAD;
                end

                if (slv_aw_atop_i[5:3] == {axi_pkg::ATOP_ATOMICSTORE, axi_pkg::ATOP_LITTLE_END}) begin
                    atop_valid_d = STORE;
                end


                if (slv_aw_len_i | slv_aw_lock_i) begin
                    atop_valid_d = INVALID;
                end

                if (slv_aw_size_i > $clog2(RISCV_WORD_WIDTH/8)) begin
                    atop_valid_d = INVALID;
                end
            end
        end
    end

    always_ff @(posedge clk_i or negedge rst_ni) begin : proc_atop_valid
        if(~rst_ni) begin
            atop_valid_q <= NONE;
        end else begin
            atop_valid_q <= atop_valid_d;
        end
    end




    always_comb begin : axi_aw_channel

        mst_aw_id_o     = slv_aw_id_i;
        mst_aw_addr_o   = slv_aw_addr_i;
        mst_aw_len_o    = slv_aw_len_i;
        mst_aw_size_o   = slv_aw_size_i;
        mst_aw_burst_o  = slv_aw_burst_i;
        mst_aw_lock_o   = slv_aw_lock_i;
        mst_aw_cache_o  = slv_aw_cache_i;
        mst_aw_prot_o   = slv_aw_prot_i;
        mst_aw_qos_o    = slv_aw_qos_i;
        mst_aw_region_o = slv_aw_region_i;
        mst_aw_atop_o   = 6'b0;
        mst_aw_user_o   = slv_aw_user_i;

        addr_d          = addr_q;
        id_d            = id_q;
        size_d          = size_q;
        atop_d          = atop_q;
        cache_d         = cache_q;
        prot_d          = prot_q;
        qos_d           = qos_q;
        region_d        = region_q;
        aw_user_d       = aw_user_q;
        w_cnt_inj_d     = w_cnt_inj_q;

        aw_state_d      = aw_state_q;


        if (slv_aw_valid_i && slv_aw_atop_i) begin

            mst_aw_valid_o = 1'b0;
            slv_aw_ready_o = 1'b0;
        end else if (w_cnt_q == AXI_MAX_WRITE_TXNS) begin

            mst_aw_valid_o = 1'b0;
            slv_aw_ready_o = 1'b0;
        end else if (slv_aw_valid_i && transaction_collision && !adapter_ready) begin

            mst_aw_valid_o = 1'b0;
            slv_aw_ready_o = 1'b0;
        end else begin

            mst_aw_valid_o  = slv_aw_valid_i;
            slv_aw_ready_o  = mst_aw_ready_i;
        end


        if (w_cnt_inj_q && mst_w_valid_o && mst_w_ready_i && mst_w_last_o) begin
            w_cnt_inj_d = w_cnt_inj_q - 1;
        end

        unique case (aw_state_q)

            FEEDTHROUGH_AW: begin

                if (slv_aw_valid_i && slv_aw_atop_i && adapter_ready) begin

                    slv_aw_ready_o = 1'b1;

                    atop_d    = slv_aw_atop_i;
                    addr_d    = slv_aw_addr_i;
                    id_d      = slv_aw_id_i;
                    size_d    = slv_aw_size_i;
                    cache_d   = slv_aw_cache_i;
                    prot_d    = slv_aw_prot_i;
                    qos_d     = slv_aw_qos_i;
                    region_d  = slv_aw_region_i;
                    aw_user_d = slv_aw_user_i;

                    if (atop_valid_d != INVALID) begin
                        aw_state_d = WAIT_RESULT_AW;
                    end
                end

            end

            WAIT_RESULT_AW, SEND_AW: begin

                if ((r_d_valid_q && w_d_valid_q && aw_free) || (aw_state_q == SEND_AW)) begin

                    slv_aw_ready_o  = 1'b0;

                    mst_aw_valid_o  = 1'b1;
                    mst_aw_addr_o   = addr_q;
                    mst_aw_len_o    = 8'h00;
                    mst_aw_id_o     = id_q;
                    mst_aw_size_o   = size_q;
                    mst_aw_burst_o  = 2'b00;
                    mst_aw_lock_o   = 1'b0;
                    mst_aw_cache_o  = cache_q;
                    mst_aw_prot_o   = prot_q;
                    mst_aw_qos_o    = qos_q;
                    mst_aw_region_o = region_q;
                    mst_aw_user_o   = aw_user_q;

                    if (mst_aw_ready_i) begin
                        aw_state_d = FEEDTHROUGH_AW;
                    end else begin
                        aw_state_d = SEND_AW;
                    end

                    if (aw_state_q == WAIT_RESULT_AW) begin
                        if (w_cnt_q && mst_w_valid_o && mst_w_ready_i && mst_w_last_o) begin
                            w_cnt_inj_d = w_cnt_q - 1;
                        end else begin
                            w_cnt_inj_d = w_cnt_q;
                        end
                    end
                end
            end

            default: aw_state_d = FEEDTHROUGH_AW;

        endcase
    end


    always_comb begin : axi_w_channel

        mst_w_data_o = slv_w_data_i;
        mst_w_strb_o = slv_w_strb_i;
        mst_w_last_o = slv_w_last_i;
        mst_w_user_o = slv_w_user_i;

        strb_d       = strb_q;
        w_user_d     = w_user_q;
        w_data_d     = w_data_q;
        result_d     = result_q;
        w_d_valid_d  = w_d_valid_q;
        w_cnt_req_d  = w_cnt_req_q;

        w_state_d    = w_state_q;



        if (w_cnt_q == 0) begin

            slv_w_ready_o = 1'b0;
            mst_w_valid_o = 1'b0;
        end else begin
            mst_w_valid_o = slv_w_valid_i;
            slv_w_ready_o = mst_w_ready_i;
        end

        unique case (w_state_q)

            FEEDTHROUGH_W: begin
                if (adapter_ready) begin

                    w_d_valid_d = 1'b0;
                    result_d    = '0;

                    if (atop_valid_d != NONE) begin

                        if (w_cnt_q == 0) begin

                            mst_w_valid_o = 1'b0;

                            slv_w_ready_o  = 1'b1;
                            if (slv_w_valid_i) begin
                                if (atop_valid_d != INVALID) begin
                                    w_data_d    = slv_w_data_i;
                                    strb_d      = slv_w_strb_i;
                                    w_user_d    = slv_w_user_i;
                                    w_d_valid_d = 1'b1;
                                    w_state_d   = WAIT_RESULT_W;
                                end
                            end else begin
                                w_cnt_req_d = '0;
                                w_state_d   = WAIT_DATA_W;
                            end
                        end else begin

                            if (mst_w_valid_o && mst_w_ready_i && mst_w_last_o) begin
                                w_cnt_req_d = w_cnt_q - 1;
                            end else begin
                                w_cnt_req_d = w_cnt_q;
                            end
                            w_state_d   = WAIT_DATA_W;
                        end
                    end
                end
            end

            WAIT_DATA_W: begin

                if (w_cnt_req_q == 0) begin

                    mst_w_valid_o = 1'b0;

                    slv_w_ready_o = 1'b1;

                    if (slv_w_valid_i) begin
                        if (atop_valid_q == INVALID) begin
                            w_state_d    = FEEDTHROUGH_W;
                        end else begin
                            w_data_d    = slv_w_data_i;
                            strb_d      = slv_w_strb_i;
                            w_user_d    = slv_w_user_i;
                            w_d_valid_d = 1'b1;
                            w_state_d   = WAIT_RESULT_W;
                        end
                    end
                end else if (mst_w_valid_o && mst_w_ready_i && mst_w_last_o) begin
                    w_cnt_req_d = w_cnt_req_q - 1;
                end
            end

            WAIT_RESULT_W: begin

                if (r_d_valid_q && w_d_valid_q && aw_free) begin

                    result_d = alu_result_ext;
                    if (w_free && w_cnt_q == 0) begin

                        slv_w_ready_o = 1'b0;

                        mst_w_valid_o = 1'b1;
                        mst_w_data_o  = alu_result_ext;
                        mst_w_last_o  = 1'b1;
                        mst_w_strb_o  = strb_q;
                        mst_w_user_o  = w_user_q;
                        if (mst_w_ready_i) begin
                            w_state_d = FEEDTHROUGH_W;
                        end else begin
                            w_state_d = SEND_W;
                        end
                    end else begin
                        w_state_d = WAIT_CHANNEL_W;
                    end
                end
            end

            WAIT_CHANNEL_W, SEND_W: begin

                if ((w_free && w_cnt_inj_q == 0) || (w_state_q == SEND_W)) begin

                    slv_w_ready_o = 1'b0;

                    mst_w_valid_o = 1'b1;
                    mst_w_data_o  = result_q;
                    mst_w_last_o  = 1'b1;
                    mst_w_strb_o  = strb_q;
                    mst_w_user_o  = w_user_q;
                    if (mst_w_ready_i) begin
                        w_state_d = FEEDTHROUGH_W;
                    end else begin
                        w_state_d = SEND_W;
                    end
                end
            end

            default: w_state_d = FEEDTHROUGH_W;

        endcase
    end


    always_comb begin : axi_b_channel

        mst_b_ready_o = slv_b_ready_i;
        slv_b_id_o    = mst_b_id_i;
        slv_b_resp_o  = mst_b_resp_i;
        slv_b_user_o  = mst_b_user_i;
        slv_b_valid_o = mst_b_valid_i;

        b_state_d     = b_state_q;

        unique case (b_state_q)

            FEEDTHROUGH_B: begin
                if (adapter_ready) begin
                    if (atop_valid_d == LOAD || atop_valid_d == STORE) begin

                        b_state_d = WAIT_COMPLETE_B;
                    end else if (atop_valid_d == INVALID) begin

                        if (b_free) begin

                            mst_b_ready_o = 1'b0;

                            slv_b_valid_o = 1'b1;
                            slv_b_id_o    = slv_aw_id_i;
                            slv_b_resp_o  = axi_pkg::RESP_SLVERR;
                            slv_b_user_o  = '0;
                            if (!slv_b_ready_i) begin
                                b_state_d = SEND_B;
                            end
                        end else begin
                            b_state_d = WAIT_CHANNEL_B;
                        end
                    end
                end
            end

            WAIT_CHANNEL_B, SEND_B: begin
                if (b_free || (b_state_q == SEND_B)) begin

                    mst_b_ready_o = 1'b0;

                    slv_b_valid_o = 1'b1;
                    slv_b_id_o    = id_q;
                    slv_b_resp_o  = axi_pkg::RESP_SLVERR;
                    slv_b_user_o  = '0;
                    if (slv_b_ready_i) begin
                        b_state_d = FEEDTHROUGH_B;
                    end else begin
                        b_state_d = SEND_B;
                    end
                end
            end

            WAIT_COMPLETE_B: begin
                if (mst_b_valid_i && (mst_b_id_i == id_q)) begin
                    b_state_d = FEEDTHROUGH_B;
                end
            end

            default: b_state_d = FEEDTHROUGH_B;

        endcase
    end


    always_comb begin
        w_cnt_d = w_cnt_q;
        if (mst_aw_valid_o && mst_aw_ready_i) begin
            w_cnt_d += 1;
        end
        if (mst_w_valid_o && mst_w_ready_i && mst_w_last_o) begin
            w_cnt_d -= 1;
        end
    end

    always_ff @(posedge clk_i or negedge rst_ni) begin : axi_write_channel_ff
        if(~rst_ni) begin
            aw_state_q  <= FEEDTHROUGH_AW;
            w_state_q   <= FEEDTHROUGH_W;
            b_state_q   <= FEEDTHROUGH_B;
            w_cnt_q     <= '0;
            w_cnt_req_q <= '0;
            w_cnt_inj_q <= '0;
            addr_q      <= '0;
            id_q        <= '0;
            size_q      <= '0;
            strb_q      <= '0;
            cache_q     <= '0;
            prot_q      <= '0;
            qos_q       <= '0;
            region_q    <= '0;
            aw_user_q   <= '0;
            w_user_q    <= '0;
            w_data_q    <= '0;
            result_q    <= '0;
            w_d_valid_q <= '0;
            atop_q      <= 6'b0;
        end else begin
            aw_state_q  <= aw_state_d;
            w_state_q   <= w_state_d;
            b_state_q   <= b_state_d;
            w_cnt_q     <= w_cnt_d;
            w_cnt_req_q <= w_cnt_req_d;
            w_cnt_inj_q <= w_cnt_inj_d;
            addr_q      <= addr_d;
            id_q        <= id_d;
            size_q      <= size_d;
            strb_q      <= strb_d;
            cache_q     <= cache_d;
            prot_q      <= prot_d;
            qos_q       <= qos_d;
            region_q    <= region_d;
            aw_user_q   <= aw_user_d;
            w_user_q    <= w_user_d;
            w_data_q    <= w_data_d;
            result_q    <= result_d;
            w_d_valid_q <= w_d_valid_d;
            atop_q      <= atop_d;
        end
    end




    always_comb begin : axi_ar_channel

        mst_ar_id_o     = slv_ar_id_i;
        mst_ar_addr_o   = slv_ar_addr_i;
        mst_ar_len_o    = slv_ar_len_i;
        mst_ar_size_o   = slv_ar_size_i;
        mst_ar_burst_o  = slv_ar_burst_i;
        mst_ar_lock_o   = slv_ar_lock_i;
        mst_ar_cache_o  = slv_ar_cache_i;
        mst_ar_prot_o   = slv_ar_prot_i;
        mst_ar_qos_o    = slv_ar_qos_i;
        mst_ar_region_o = slv_ar_region_i;
        mst_ar_user_o   = slv_ar_user_i;
        mst_ar_valid_o  = 1'b0;
        slv_ar_ready_o  = 1'b0;

        ar_state_d      = ar_state_q;

        unique case (ar_state_q)

            FEEDTHROUGH_AR: begin

                mst_ar_valid_o = slv_ar_valid_i;
                slv_ar_ready_o = mst_ar_ready_i;

                if (adapter_ready) begin
                    if (atop_valid_d == LOAD | atop_valid_d == STORE) begin
                        if (ar_free) begin

                            slv_ar_ready_o  = 1'b0;

                            mst_ar_valid_o  = 1'b1;
                            mst_ar_addr_o   = slv_aw_addr_i;
                            mst_ar_id_o     = slv_aw_id_i;
                            mst_ar_len_o    = 8'h00;
                            mst_ar_size_o   = slv_aw_size_i;
                            mst_ar_burst_o  = 2'b00;
                            mst_ar_lock_o   = 1'h0;
                            mst_ar_cache_o  = slv_aw_cache_i;
                            mst_ar_prot_o   = slv_aw_prot_i;
                            mst_ar_qos_o    = slv_aw_qos_i;
                            mst_ar_region_o = slv_aw_region_i;
                            mst_ar_user_o   = slv_aw_user_i;
                            if (!mst_ar_ready_i) begin

                                ar_state_d = SEND_AR;
                            end
                        end else begin

                            ar_state_d   = WAIT_CHANNEL_AR;
                        end
                    end
                end
            end

            WAIT_CHANNEL_AR, SEND_AR: begin

                if (ar_free || (ar_state_q == SEND_AR)) begin

                    mst_ar_valid_o  = 1'b1;
                    mst_ar_addr_o   = addr_q;
                    mst_ar_id_o     = id_q;
                    mst_ar_len_o    = 8'h00;
                    mst_ar_size_o   = size_q;
                    mst_ar_burst_o  = 2'b00;
                    mst_ar_lock_o   = 1'h0;
                    mst_ar_cache_o  = cache_q;
                    mst_ar_prot_o   = prot_q;
                    mst_ar_qos_o    = qos_q;
                    mst_ar_region_o = region_q;
                    mst_ar_user_o   = aw_user_q;
                    if (mst_ar_ready_i) begin

                        ar_state_d = FEEDTHROUGH_AR;
                    end else begin

                        ar_state_d = SEND_AR;
                    end
                end else begin

                    mst_ar_valid_o = slv_ar_valid_i;
                    slv_ar_ready_o = mst_ar_ready_i;
                end
            end

            default: ar_state_d = FEEDTHROUGH_AR;

        endcase
    end


    always_comb begin : axi_r_channel

        mst_r_ready_o = slv_r_ready_i;
        slv_r_id_o    = mst_r_id_i;
        slv_r_data_o  = mst_r_data_i;
        slv_r_resp_o  = mst_r_resp_i;
        slv_r_last_o  = mst_r_last_i;
        slv_r_user_o  = mst_r_user_i;
        slv_r_valid_o = mst_r_valid_i;

        r_data_d      = r_data_q;
        r_resp_d      = r_resp_q;
        r_user_d      = r_user_q;
        r_d_valid_d   = r_d_valid_q;

        r_state_d     = r_state_q;

        unique case (r_state_q)

            FEEDTHROUGH_R: begin
                if (adapter_ready) begin

                    r_d_valid_d = 1'b0;

                    if (atop_valid_d == LOAD || atop_valid_d == STORE) begin

                        r_state_d = WAIT_DATA_R;
                    end else if (atop_valid_d == INVALID) begin

                        if (r_free) begin


                            mst_r_ready_o = 1'b0;

                            slv_r_valid_o = 1'b1;
                            slv_r_data_o  = '0;
                            slv_r_id_o    = slv_aw_id_i;
                            slv_r_last_o  = 1'b1;
                            slv_r_resp_o  = axi_pkg::RESP_SLVERR;
                            slv_r_user_o  = '0;
                            if (!slv_r_ready_i) begin

                                r_state_d = SEND_R;
                            end
                        end else begin
                            r_state_d = WAIT_CHANNEL_R;
                        end
                    end
                end
            end

            WAIT_DATA_R: begin

                if (mst_r_valid_i && (mst_r_id_i == id_q)) begin

                    mst_r_ready_o = 1'b1;
                    slv_r_valid_o = 1'b0;

                    r_data_d    = mst_r_data_i;
                    r_resp_d    = mst_r_resp_i;
                    r_user_d    = mst_r_user_i;
                    r_d_valid_d = 1'b1;
                    if (atop_valid_q == STORE) begin
                        r_state_d = FEEDTHROUGH_R;
                    end else begin

                        r_state_d = WAIT_CHANNEL_R;
                    end
                end
            end

            WAIT_CHANNEL_R, SEND_R: begin


                if ((r_free && (b_state_q != WAIT_COMPLETE_B)) || (r_state_q == SEND_R)) begin

                    mst_r_ready_o = 1'b0;

                    slv_r_valid_o = 1'b1;
                    slv_r_data_o  = r_data_q;
                    slv_r_id_o    = id_q;
                    slv_r_last_o  = 1'b1;
                    slv_r_resp_o  = r_resp_q;
                    slv_r_user_o  = r_user_q;
                    if (atop_valid_q == INVALID) begin
                        slv_r_data_o = '0;
                        slv_r_resp_o = axi_pkg::RESP_SLVERR;
                        slv_r_user_o = '0;
                    end
                    if (slv_r_ready_i) begin
                        r_state_d = FEEDTHROUGH_R;
                    end else begin
                        r_state_d = SEND_R;
                    end
                end
            end

            default: r_state_d = FEEDTHROUGH_R;

        endcase
    end

    always_ff @(posedge clk_i or negedge rst_ni) begin : axi_read_channel_ff
        if(~rst_ni) begin
            ar_state_q  <= FEEDTHROUGH_AR;
            r_state_q   <= FEEDTHROUGH_R;
            r_data_q    <= '0;
            r_resp_q    <= '0;
            r_user_q    <= '0;
            r_d_valid_q <= 1'b0;
        end else begin
            ar_state_q  <= ar_state_d;
            r_state_q   <= r_state_d;
            r_data_q    <= r_data_d;
            r_resp_q    <= r_resp_d;
            r_user_q    <= r_user_d;
            r_d_valid_q <= r_d_valid_d;
        end
    end



    assign op_a           = r_data_q & strb_ext;
    assign op_b           = w_data_q & strb_ext;
    assign sign_a         = |(op_a & ~(strb_ext >> 1));
    assign sign_b         = |(op_b & ~(strb_ext >> 1));
    assign alu_result_ext = res;

    generate
        if (AXI_ALU_RATIO == 1 && RISCV_WORD_WIDTH == 32) begin
            assign alu_operand_a  = op_a;
            assign alu_operand_b  = op_b;
            assign res            = alu_result;
        end else if (AXI_ALU_RATIO == 1 && RISCV_WORD_WIDTH == 64) begin
            assign res        = alu_result;
            always_comb begin
                op_a_sign_ext = op_a | ({AXI_ALU_RATIO*RISCV_WORD_WIDTH{sign_a}} & ~strb_ext);
                op_b_sign_ext = op_b | ({AXI_ALU_RATIO*RISCV_WORD_WIDTH{sign_b}} & ~strb_ext);

                if (atop_q[2:0] == axi_pkg::ATOP_SMAX || atop_q[2:0] == axi_pkg::ATOP_SMIN) begin

                    alu_operand_a = op_a_sign_ext;
                    alu_operand_b = op_b_sign_ext;
                end else begin

                    alu_operand_a = op_a;
                    alu_operand_b = op_b;
                end
            end
        end else begin
            always_comb begin
                op_a_sign_ext = op_a | ({AXI_ALU_RATIO*RISCV_WORD_WIDTH{sign_a}} & ~strb_ext);
                op_b_sign_ext = op_b | ({AXI_ALU_RATIO*RISCV_WORD_WIDTH{sign_b}} & ~strb_ext);

                if (atop_q[2:0] == axi_pkg::ATOP_SMAX || atop_q[2:0] == axi_pkg::ATOP_SMIN) begin

                    alu_operand_a = op_a_sign_ext[addr_q[$clog2(AXI_DATA_WIDTH/8)-1:$clog2(RISCV_WORD_WIDTH/8)]];
                    alu_operand_b = op_b_sign_ext[addr_q[$clog2(AXI_DATA_WIDTH/8)-1:$clog2(RISCV_WORD_WIDTH/8)]];
                end else begin

                    alu_operand_a = op_a[addr_q[$clog2(AXI_DATA_WIDTH/8)-1:$clog2(RISCV_WORD_WIDTH/8)]];
                    alu_operand_b = op_b[addr_q[$clog2(AXI_DATA_WIDTH/8)-1:$clog2(RISCV_WORD_WIDTH/8)]];
                end
                res = '0;
                res[addr_q[$clog2(AXI_DATA_WIDTH/8)-1:$clog2(RISCV_WORD_WIDTH/8)]] = alu_result;
            end
        end
    endgenerate

    generate
        for (genvar i = 0; i < AXI_STRB_WIDTH; i++) begin
            always_comb begin
                if (strb_q[i]) begin
                    strb_ext[i] = 8'hFF;
                end else begin
                    strb_ext[i] = 8'h00;
                end
            end
        end
    endgenerate

    axi_riscv_amos_alu #(
        .DATA_WIDTH ( RISCV_WORD_WIDTH )
    ) i_amo_alu (
        .amo_op_i           ( atop_q        ),
        .amo_operand_a_i    ( alu_operand_a ),
        .amo_operand_b_i    ( alu_operand_b ),
        .amo_result_o       ( alu_result    )
    );



`ifndef VERILATOR
    initial begin: validate_params
        assert (AXI_ADDR_WIDTH > 0)
            else $fatal(1, "AXI_ADDR_WIDTH must be greater than 0!");
        assert (AXI_DATA_WIDTH > 0)
            else $fatal(1, "AXI_DATA_WIDTH must be greater than 0!");
        assert (AXI_ID_WIDTH > 0)
            else $fatal(1, "AXI_ID_WIDTH must be greater than 0!");
        assert (AXI_MAX_WRITE_TXNS > 0)
            else $fatal(1, "AXI_MAX_WRITE_TXNS must be greater than 0!");
        assert (RISCV_WORD_WIDTH == 32 || RISCV_WORD_WIDTH == 64)
            else $fatal(1, "RISCV_WORD_WIDTH must be 32 or 64!");
        assert (RISCV_WORD_WIDTH <= AXI_DATA_WIDTH)
            else $fatal(1, "RISCV_WORD_WIDTH must not be greater than AXI_DATA_WIDTH!");
    end
`endif


endmodule
module axi_riscv_amos #(

    parameter int unsigned AXI_ADDR_WIDTH       = 0,
    parameter int unsigned AXI_DATA_WIDTH       = 0,
    parameter int unsigned AXI_ID_WIDTH         = 0,
    parameter int unsigned AXI_USER_WIDTH       = 0,

    parameter int unsigned AXI_MAX_WRITE_TXNS   = 0,



    parameter int unsigned RISCV_WORD_WIDTH     = 0,

    localparam int unsigned AXI_STRB_WIDTH      = AXI_DATA_WIDTH / 8
) (
    input  logic                        clk_i,
    input  logic                        rst_ni,


    input  logic [AXI_ADDR_WIDTH-1:0]   slv_aw_addr_i,
    input  logic [2:0]                  slv_aw_prot_i,
    input  logic [3:0]                  slv_aw_region_i,
    input  logic [5:0]                  slv_aw_atop_i,
    input  logic [7:0]                  slv_aw_len_i,
    input  logic [2:0]                  slv_aw_size_i,
    input  logic [1:0]                  slv_aw_burst_i,
    input  logic                        slv_aw_lock_i,
    input  logic [3:0]                  slv_aw_cache_i,
    input  logic [3:0]                  slv_aw_qos_i,
    input  logic [AXI_ID_WIDTH-1:0]     slv_aw_id_i,
    input  logic [AXI_USER_WIDTH-1:0]   slv_aw_user_i,
    output logic                        slv_aw_ready_o,
    input  logic                        slv_aw_valid_i,

    input  logic [AXI_ADDR_WIDTH-1:0]   slv_ar_addr_i,
    input  logic [2:0]                  slv_ar_prot_i,
    input  logic [3:0]                  slv_ar_region_i,
    input  logic [7:0]                  slv_ar_len_i,
    input  logic [2:0]                  slv_ar_size_i,
    input  logic [1:0]                  slv_ar_burst_i,
    input  logic                        slv_ar_lock_i,
    input  logic [3:0]                  slv_ar_cache_i,
    input  logic [3:0]                  slv_ar_qos_i,
    input  logic [AXI_ID_WIDTH-1:0]     slv_ar_id_i,
    input  logic [AXI_USER_WIDTH-1:0]   slv_ar_user_i,
    output logic                        slv_ar_ready_o,
    input  logic                        slv_ar_valid_i,

    input  logic [AXI_DATA_WIDTH-1:0]   slv_w_data_i,
    input  logic [AXI_STRB_WIDTH-1:0]   slv_w_strb_i,
    input  logic [AXI_USER_WIDTH-1:0]   slv_w_user_i,
    input  logic                        slv_w_last_i,
    output logic                        slv_w_ready_o,
    input  logic                        slv_w_valid_i,

    output logic [AXI_DATA_WIDTH-1:0]   slv_r_data_o,
    output logic [1:0]                  slv_r_resp_o,
    output logic                        slv_r_last_o,
    output logic [AXI_ID_WIDTH-1:0]     slv_r_id_o,
    output logic [AXI_USER_WIDTH-1:0]   slv_r_user_o,
    input  logic                        slv_r_ready_i,
    output logic                        slv_r_valid_o,

    output logic [1:0]                  slv_b_resp_o,
    output logic [AXI_ID_WIDTH-1:0]     slv_b_id_o,
    output logic [AXI_USER_WIDTH-1:0]   slv_b_user_o,
    input  logic                        slv_b_ready_i,
    output logic                        slv_b_valid_o,


    output logic [AXI_ADDR_WIDTH-1:0]   mst_aw_addr_o,
    output logic [2:0]                  mst_aw_prot_o,
    output logic [3:0]                  mst_aw_region_o,
    output logic [5:0]                  mst_aw_atop_o,
    output logic [7:0]                  mst_aw_len_o,
    output logic [2:0]                  mst_aw_size_o,
    output logic [1:0]                  mst_aw_burst_o,
    output logic                        mst_aw_lock_o,
    output logic [3:0]                  mst_aw_cache_o,
    output logic [3:0]                  mst_aw_qos_o,
    output logic [AXI_ID_WIDTH-1:0]     mst_aw_id_o,
    output logic [AXI_USER_WIDTH-1:0]   mst_aw_user_o,
    input  logic                        mst_aw_ready_i,
    output logic                        mst_aw_valid_o,

    output logic [AXI_ADDR_WIDTH-1:0]   mst_ar_addr_o,
    output logic [2:0]                  mst_ar_prot_o,
    output logic [3:0]                  mst_ar_region_o,
    output logic [7:0]                  mst_ar_len_o,
    output logic [2:0]                  mst_ar_size_o,
    output logic [1:0]                  mst_ar_burst_o,
    output logic                        mst_ar_lock_o,
    output logic [3:0]                  mst_ar_cache_o,
    output logic [3:0]                  mst_ar_qos_o,
    output logic [AXI_ID_WIDTH-1:0]     mst_ar_id_o,
    output logic [AXI_USER_WIDTH-1:0]   mst_ar_user_o,
    input  logic                        mst_ar_ready_i,
    output logic                        mst_ar_valid_o,

    output logic [AXI_DATA_WIDTH-1:0]   mst_w_data_o,
    output logic [AXI_STRB_WIDTH-1:0]   mst_w_strb_o,
    output logic [AXI_USER_WIDTH-1:0]   mst_w_user_o,
    output logic                        mst_w_last_o,
    input  logic                        mst_w_ready_i,
    output logic                        mst_w_valid_o,

    input  logic [AXI_DATA_WIDTH-1:0]   mst_r_data_i,
    input  logic [1:0]                  mst_r_resp_i,
    input  logic                        mst_r_last_i,
    input  logic [AXI_ID_WIDTH-1:0]     mst_r_id_i,
    input  logic [AXI_USER_WIDTH-1:0]   mst_r_user_i,
    output logic                        mst_r_ready_o,
    input  logic                        mst_r_valid_i,

    input  logic [1:0]                  mst_b_resp_i,
    input  logic [AXI_ID_WIDTH-1:0]     mst_b_id_i,
    input  logic [AXI_USER_WIDTH-1:0]   mst_b_user_i,
    output logic                        mst_b_ready_o,
    input  logic                        mst_b_valid_i
);


    localparam int unsigned OUTSTND_BURSTS_WIDTH = $clog2(AXI_MAX_WRITE_TXNS+1);
    localparam int unsigned AXI_ALU_RATIO        = AXI_DATA_WIDTH/RISCV_WORD_WIDTH;


    typedef enum logic [1:0] { FEEDTHROUGH_AW, WAIT_RESULT_AW, SEND_AW } aw_state_t;
    aw_state_t   aw_state_d, aw_state_q;

    typedef enum logic [2:0] { FEEDTHROUGH_W, WAIT_DATA_W, WAIT_RESULT_W, WAIT_CHANNEL_W, SEND_W } w_state_t;
    w_state_t    w_state_d, w_state_q;

    typedef enum logic [1:0] { FEEDTHROUGH_B, WAIT_COMPLETE_B, WAIT_CHANNEL_B, SEND_B } b_state_t;
    b_state_t    b_state_d, b_state_q;

    typedef enum logic [1:0] { FEEDTHROUGH_AR, WAIT_CHANNEL_AR, SEND_AR } ar_state_t;
    ar_state_t   ar_state_d, ar_state_q;

    typedef enum logic [1:0] { FEEDTHROUGH_R, WAIT_DATA_R, WAIT_CHANNEL_R, SEND_R } r_state_t;
    r_state_t    r_state_d, r_state_q;

    typedef enum logic [1:0] { NONE, INVALID, LOAD, STORE } atop_req_t;
    atop_req_t   atop_valid_d, atop_valid_q;



    logic [AXI_ADDR_WIDTH-1:0]          addr_d,         addr_q;
    logic [AXI_ID_WIDTH-1:0]            id_d,           id_q;
    logic [AXI_STRB_WIDTH-1:0]          strb_d,         strb_q;
    logic [2:0]                         size_d,         size_q;
    logic [5:0]                         atop_d,         atop_q;
    logic [3:0]                         cache_d,        cache_q;
    logic [2:0]                         prot_d,         prot_q;
    logic [3:0]                         qos_d,          qos_q;
    logic [3:0]                         region_d,       region_q;
    logic [1:0]                         r_resp_d,       r_resp_q;
    logic [AXI_USER_WIDTH-1:0]          aw_user_d,      aw_user_q,
                                        w_user_d,       w_user_q,
                                        r_user_d,       r_user_q;

    logic [AXI_DATA_WIDTH-1:0]          w_data_d,       w_data_q;
    logic [AXI_DATA_WIDTH-1:0]          r_data_d,       r_data_q;
    logic [AXI_DATA_WIDTH-1:0]          result_d,       result_q;
    logic                               w_d_valid_d,    w_d_valid_q,
                                        r_d_valid_d,    r_d_valid_q;

    logic [OUTSTND_BURSTS_WIDTH-1:0]    w_cnt_d,        w_cnt_q;
    logic [OUTSTND_BURSTS_WIDTH-1:0]    w_cnt_req_d,    w_cnt_req_q;
    logic [OUTSTND_BURSTS_WIDTH-1:0]    w_cnt_inj_d,    w_cnt_inj_q;

    logic                               adapter_ready;
    logic                               transaction_collision;
    logic                               aw_valid,       aw_ready,       aw_free,
                                        w_valid,        w_ready,        w_free,
                                        b_valid,        b_ready,        b_free,
                                        ar_valid,       ar_ready,       ar_free,
                                        r_valid,        r_ready,        r_free;

    logic [RISCV_WORD_WIDTH-1:0]                        alu_operand_a;
    logic [RISCV_WORD_WIDTH-1:0]                        alu_operand_b;
    logic [RISCV_WORD_WIDTH-1:0]                        alu_result;
    logic [AXI_DATA_WIDTH-1:0]                          alu_result_ext;
    logic [AXI_ALU_RATIO-1:0][RISCV_WORD_WIDTH-1:0]     op_a;
    logic [AXI_ALU_RATIO-1:0][RISCV_WORD_WIDTH-1:0]     op_b;
    logic [AXI_ALU_RATIO-1:0][RISCV_WORD_WIDTH-1:0]     op_a_sign_ext;
    logic [AXI_ALU_RATIO-1:0][RISCV_WORD_WIDTH-1:0]     op_b_sign_ext;
    logic [AXI_ALU_RATIO-1:0][RISCV_WORD_WIDTH-1:0]     res;
    logic [AXI_STRB_WIDTH-1:0][7:0]                     strb_ext;
    logic                                               sign_a;
    logic                                               sign_b;




    assign adapter_ready = (aw_state_q == FEEDTHROUGH_AW) &&
                           ( w_state_q == FEEDTHROUGH_W ) &&
                           ( b_state_q == FEEDTHROUGH_B ) &&
                           (ar_state_q == FEEDTHROUGH_AR) &&
                           ( r_state_q == FEEDTHROUGH_R );


    assign aw_free = ~aw_valid | aw_ready;
    assign  w_free = ~ w_valid |  w_ready;
    assign  b_free = ~ b_valid |  b_ready;
    assign ar_free = ~ar_valid | ar_ready;
    assign  r_free = ~ r_valid |  r_ready;

    always_ff @(posedge clk_i or negedge rst_ni) begin
        if(~rst_ni) begin
            aw_valid <= 0;
            aw_ready <= 0;
            w_valid  <= 0;
            w_ready  <= 0;
            b_valid  <= 0;
            b_ready  <= 0;
            ar_valid <= 0;
            ar_ready <= 0;
            r_valid  <= 0;
            r_ready  <= 0;
        end else begin
            aw_valid <= mst_aw_valid_o;
            aw_ready <= mst_aw_ready_i;
            w_valid  <= mst_w_valid_o;
            w_ready  <= mst_w_ready_i;
            b_valid  <= slv_b_valid_o;
            b_ready  <= slv_b_ready_i;
            ar_valid <= mst_ar_valid_o;
            ar_ready <= mst_ar_ready_i;
            r_valid  <= slv_r_valid_o;
            r_ready  <= slv_r_ready_i;
        end
    end




    assign transaction_collision = (slv_aw_addr_i < (     addr_q + (8'h01 <<      size_q))) &
                                   (     addr_q < (slv_aw_addr_i + (8'h01 << slv_aw_size_i)));

    always_comb begin : calc_atop_valid
        atop_valid_d = atop_valid_q;
        if (adapter_ready) begin
            atop_valid_d = NONE;
            if (slv_aw_valid_i && slv_aw_atop_i) begin

                atop_valid_d = INVALID;

                if ((slv_aw_atop_i      ==  axi_pkg::ATOP_ATOMICSWAP) ||
                    (slv_aw_atop_i[5:3] == {axi_pkg::ATOP_ATOMICLOAD , axi_pkg::ATOP_LITTLE_END})) begin
                    atop_valid_d = LOAD;
                end

                if (slv_aw_atop_i[5:3] == {axi_pkg::ATOP_ATOMICSTORE, axi_pkg::ATOP_LITTLE_END}) begin
                    atop_valid_d = STORE;
                end


                if (slv_aw_len_i | slv_aw_lock_i) begin
                    atop_valid_d = INVALID;
                end

                if (slv_aw_size_i > $clog2(RISCV_WORD_WIDTH/8)) begin
                    atop_valid_d = INVALID;
                end
            end
        end
    end

    always_ff @(posedge clk_i or negedge rst_ni) begin : proc_atop_valid
        if(~rst_ni) begin
            atop_valid_q <= NONE;
        end else begin
            atop_valid_q <= atop_valid_d;
        end
    end




    always_comb begin : axi_aw_channel

        mst_aw_id_o     = slv_aw_id_i;
        mst_aw_addr_o   = slv_aw_addr_i;
        mst_aw_len_o    = slv_aw_len_i;
        mst_aw_size_o   = slv_aw_size_i;
        mst_aw_burst_o  = slv_aw_burst_i;
        mst_aw_lock_o   = slv_aw_lock_i;
        mst_aw_cache_o  = slv_aw_cache_i;
        mst_aw_prot_o   = slv_aw_prot_i;
        mst_aw_qos_o    = slv_aw_qos_i;
        mst_aw_region_o = slv_aw_region_i;
        mst_aw_atop_o   = 6'b0;
        mst_aw_user_o   = slv_aw_user_i;

        addr_d          = addr_q;
        id_d            = id_q;
        size_d          = size_q;
        atop_d          = atop_q;
        cache_d         = cache_q;
        prot_d          = prot_q;
        qos_d           = qos_q;
        region_d        = region_q;
        aw_user_d       = aw_user_q;
        w_cnt_inj_d     = w_cnt_inj_q;

        aw_state_d      = aw_state_q;


        if (slv_aw_valid_i && slv_aw_atop_i) begin

            mst_aw_valid_o = 1'b0;
            slv_aw_ready_o = 1'b0;
        end else if (w_cnt_q == AXI_MAX_WRITE_TXNS) begin

            mst_aw_valid_o = 1'b0;
            slv_aw_ready_o = 1'b0;
        end else if (slv_aw_valid_i && transaction_collision && !adapter_ready) begin

            mst_aw_valid_o = 1'b0;
            slv_aw_ready_o = 1'b0;
        end else begin

            mst_aw_valid_o  = slv_aw_valid_i;
            slv_aw_ready_o  = mst_aw_ready_i;
        end


        if (w_cnt_inj_q && mst_w_valid_o && mst_w_ready_i && mst_w_last_o) begin
            w_cnt_inj_d = w_cnt_inj_q - 1;
        end

        unique case (aw_state_q)

            FEEDTHROUGH_AW: begin

                if (slv_aw_valid_i && slv_aw_atop_i && adapter_ready) begin

                    slv_aw_ready_o = 1'b1;

                    atop_d    = slv_aw_atop_i;
                    addr_d    = slv_aw_addr_i;
                    id_d      = slv_aw_id_i;
                    size_d    = slv_aw_size_i;
                    cache_d   = slv_aw_cache_i;
                    prot_d    = slv_aw_prot_i;
                    qos_d     = slv_aw_qos_i;
                    region_d  = slv_aw_region_i;
                    aw_user_d = slv_aw_user_i;

                    if (atop_valid_d != INVALID) begin
                        aw_state_d = WAIT_RESULT_AW;
                    end
                end

            end

            WAIT_RESULT_AW, SEND_AW: begin

                if ((r_d_valid_q && w_d_valid_q && aw_free) || (aw_state_q == SEND_AW)) begin

                    slv_aw_ready_o  = 1'b0;

                    mst_aw_valid_o  = 1'b1;
                    mst_aw_addr_o   = addr_q;
                    mst_aw_len_o    = 8'h00;
                    mst_aw_id_o     = id_q;
                    mst_aw_size_o   = size_q;
                    mst_aw_burst_o  = 2'b00;
                    mst_aw_lock_o   = 1'b0;
                    mst_aw_cache_o  = cache_q;
                    mst_aw_prot_o   = prot_q;
                    mst_aw_qos_o    = qos_q;
                    mst_aw_region_o = region_q;
                    mst_aw_user_o   = aw_user_q;

                    if (mst_aw_ready_i) begin
                        aw_state_d = FEEDTHROUGH_AW;
                    end else begin
                        aw_state_d = SEND_AW;
                    end

                    if (aw_state_q == WAIT_RESULT_AW) begin
                        if (w_cnt_q && mst_w_valid_o && mst_w_ready_i && mst_w_last_o) begin
                            w_cnt_inj_d = w_cnt_q - 1;
                        end else begin
                            w_cnt_inj_d = w_cnt_q;
                        end
                    end
                end
            end

            default: aw_state_d = FEEDTHROUGH_AW;

        endcase
    end


    always_comb begin : axi_w_channel

        mst_w_data_o = slv_w_data_i;
        mst_w_strb_o = slv_w_strb_i;
        mst_w_last_o = slv_w_last_i;
        mst_w_user_o = slv_w_user_i;

        strb_d       = strb_q;
        w_user_d     = w_user_q;
        w_data_d     = w_data_q;
        result_d     = result_q;
        w_d_valid_d  = w_d_valid_q;
        w_cnt_req_d  = w_cnt_req_q;

        w_state_d    = w_state_q;



        if (w_cnt_q == 0) begin

            slv_w_ready_o = 1'b0;
            mst_w_valid_o = 1'b0;
        end else begin
            mst_w_valid_o = slv_w_valid_i;
            slv_w_ready_o = mst_w_ready_i;
        end

        unique case (w_state_q)

            FEEDTHROUGH_W: begin
                if (adapter_ready) begin

                    w_d_valid_d = 1'b0;
                    result_d    = '0;

                    if (atop_valid_d != NONE) begin

                        if (w_cnt_q == 0) begin

                            mst_w_valid_o = 1'b0;

                            slv_w_ready_o  = 1'b1;
                            if (slv_w_valid_i) begin
                                if (atop_valid_d != INVALID) begin
                                    w_data_d    = slv_w_data_i;
                                    strb_d      = slv_w_strb_i;
                                    w_user_d    = slv_w_user_i;
                                    w_d_valid_d = 1'b1;
                                    w_state_d   = WAIT_RESULT_W;
                                end
                            end else begin
                                w_cnt_req_d = '0;
                                w_state_d   = WAIT_DATA_W;
                            end
                        end else begin

                            if (mst_w_valid_o && mst_w_ready_i && mst_w_last_o) begin
                                w_cnt_req_d = w_cnt_q - 1;
                            end else begin
                                w_cnt_req_d = w_cnt_q;
                            end
                            w_state_d   = WAIT_DATA_W;
                        end
                    end
                end
            end

            WAIT_DATA_W: begin

                if (w_cnt_req_q == 0) begin

                    mst_w_valid_o = 1'b0;

                    slv_w_ready_o = 1'b1;

                    if (slv_w_valid_i) begin
                        if (atop_valid_q == INVALID) begin
                            w_state_d    = FEEDTHROUGH_W;
                        end else begin
                            w_data_d    = slv_w_data_i;
                            strb_d      = slv_w_strb_i;
                            w_user_d    = slv_w_user_i;
                            w_d_valid_d = 1'b1;
                            w_state_d   = WAIT_RESULT_W;
                        end
                    end
                end else if (mst_w_valid_o && mst_w_ready_i && mst_w_last_o) begin
                    w_cnt_req_d = w_cnt_req_q - 1;
                end
            end

            WAIT_RESULT_W: begin

                if (r_d_valid_q && w_d_valid_q && aw_free) begin

                    result_d = alu_result_ext;
                    if (w_free && w_cnt_q == 0) begin

                        slv_w_ready_o = 1'b0;

                        mst_w_valid_o = 1'b1;
                        mst_w_data_o  = alu_result_ext;
                        mst_w_last_o  = 1'b1;
                        mst_w_strb_o  = strb_q;
                        mst_w_user_o  = w_user_q;
                        if (mst_w_ready_i) begin
                            w_state_d = FEEDTHROUGH_W;
                        end else begin
                            w_state_d = SEND_W;
                        end
                    end else begin
                        w_state_d = WAIT_CHANNEL_W;
                    end
                end
            end

            WAIT_CHANNEL_W, SEND_W: begin

                if ((w_free && w_cnt_inj_q == 0) || (w_state_q == SEND_W)) begin

                    slv_w_ready_o = 1'b0;

                    mst_w_valid_o = 1'b1;
                    mst_w_data_o  = result_q;
                    mst_w_last_o  = 1'b1;
                    mst_w_strb_o  = strb_q;
                    mst_w_user_o  = w_user_q;
                    if (mst_w_ready_i) begin
                        w_state_d = FEEDTHROUGH_W;
                    end else begin
                        w_state_d = SEND_W;
                    end
                end
            end

            default: w_state_d = FEEDTHROUGH_W;

        endcase
    end


    always_comb begin : axi_b_channel

        mst_b_ready_o = slv_b_ready_i;
        slv_b_id_o    = mst_b_id_i;
        slv_b_resp_o  = mst_b_resp_i;
        slv_b_user_o  = mst_b_user_i;
        slv_b_valid_o = mst_b_valid_i;

        b_state_d     = b_state_q;

        unique case (b_state_q)

            FEEDTHROUGH_B: begin
                if (adapter_ready) begin
                    if (atop_valid_d == LOAD || atop_valid_d == STORE) begin

                        b_state_d = WAIT_COMPLETE_B;
                    end else if (atop_valid_d == INVALID) begin

                        if (b_free) begin

                            mst_b_ready_o = 1'b0;

                            slv_b_valid_o = 1'b1;
                            slv_b_id_o    = slv_aw_id_i;
                            slv_b_resp_o  = axi_pkg::RESP_SLVERR;
                            slv_b_user_o  = '0;
                            if (!slv_b_ready_i) begin
                                b_state_d = SEND_B;
                            end
                        end else begin
                            b_state_d = WAIT_CHANNEL_B;
                        end
                    end
                end
            end

            WAIT_CHANNEL_B, SEND_B: begin
                if (b_free || (b_state_q == SEND_B)) begin

                    mst_b_ready_o = 1'b0;

                    slv_b_valid_o = 1'b1;
                    slv_b_id_o    = id_q;
                    slv_b_resp_o  = axi_pkg::RESP_SLVERR;
                    slv_b_user_o  = '0;
                    if (slv_b_ready_i) begin
                        b_state_d = FEEDTHROUGH_B;
                    end else begin
                        b_state_d = SEND_B;
                    end
                end
            end

            WAIT_COMPLETE_B: begin
                if (mst_b_valid_i && (mst_b_id_i == id_q)) begin
                    b_state_d = FEEDTHROUGH_B;
                end
            end

            default: b_state_d = FEEDTHROUGH_B;

        endcase
    end


    always_comb begin
        w_cnt_d = w_cnt_q;
        if (mst_aw_valid_o && mst_aw_ready_i) begin
            w_cnt_d += 1;
        end
        if (mst_w_valid_o && mst_w_ready_i && mst_w_last_o) begin
            w_cnt_d -= 1;
        end
    end

    always_ff @(posedge clk_i or negedge rst_ni) begin : axi_write_channel_ff
        if(~rst_ni) begin
            aw_state_q  <= FEEDTHROUGH_AW;
            w_state_q   <= FEEDTHROUGH_W;
            b_state_q   <= FEEDTHROUGH_B;
            w_cnt_q     <= '0;
            w_cnt_req_q <= '0;
            w_cnt_inj_q <= '0;
            addr_q      <= '0;
            id_q        <= '0;
            size_q      <= '0;
            strb_q      <= '0;
            cache_q     <= '0;
            prot_q      <= '0;
            qos_q       <= '0;
            region_q    <= '0;
            aw_user_q   <= '0;
            w_user_q    <= '0;
            w_data_q    <= '0;
            result_q    <= '0;
            w_d_valid_q <= '0;
            atop_q      <= 6'b0;
        end else begin
            aw_state_q  <= aw_state_d;
            w_state_q   <= w_state_d;
            b_state_q   <= b_state_d;
            w_cnt_q     <= w_cnt_d;
            w_cnt_req_q <= w_cnt_req_d;
            w_cnt_inj_q <= w_cnt_inj_d;
            addr_q      <= addr_d;
            id_q        <= id_d;
            size_q      <= size_d;
            strb_q      <= strb_d;
            cache_q     <= cache_d;
            prot_q      <= prot_d;
            qos_q       <= qos_d;
            region_q    <= region_d;
            aw_user_q   <= aw_user_d;
            w_user_q    <= w_user_d;
            w_data_q    <= w_data_d;
            result_q    <= result_d;
            w_d_valid_q <= w_d_valid_d;
            atop_q      <= atop_d;
        end
    end




    always_comb begin : axi_ar_channel

        mst_ar_id_o     = slv_ar_id_i;
        mst_ar_addr_o   = slv_ar_addr_i;
        mst_ar_len_o    = slv_ar_len_i;
        mst_ar_size_o   = slv_ar_size_i;
        mst_ar_burst_o  = slv_ar_burst_i;
        mst_ar_lock_o   = slv_ar_lock_i;
        mst_ar_cache_o  = slv_ar_cache_i;
        mst_ar_prot_o   = slv_ar_prot_i;
        mst_ar_qos_o    = slv_ar_qos_i;
        mst_ar_region_o = slv_ar_region_i;
        mst_ar_user_o   = slv_ar_user_i;
        mst_ar_valid_o  = 1'b0;
        slv_ar_ready_o  = 1'b0;

        ar_state_d      = ar_state_q;

        unique case (ar_state_q)

            FEEDTHROUGH_AR: begin

                mst_ar_valid_o = slv_ar_valid_i;
                slv_ar_ready_o = mst_ar_ready_i;

                if (adapter_ready) begin
                    if (atop_valid_d == LOAD | atop_valid_d == STORE) begin
                        if (ar_free) begin

                            slv_ar_ready_o  = 1'b0;

                            mst_ar_valid_o  = 1'b1;
                            mst_ar_addr_o   = slv_aw_addr_i;
                            mst_ar_id_o     = slv_aw_id_i;
                            mst_ar_len_o    = 8'h00;
                            mst_ar_size_o   = slv_aw_size_i;
                            mst_ar_burst_o  = 2'b00;
                            mst_ar_lock_o   = 1'h0;
                            mst_ar_cache_o  = slv_aw_cache_i;
                            mst_ar_prot_o   = slv_aw_prot_i;
                            mst_ar_qos_o    = slv_aw_qos_i;
                            mst_ar_region_o = slv_aw_region_i;
                            mst_ar_user_o   = slv_aw_user_i;
                            if (!mst_ar_ready_i) begin

                                ar_state_d = SEND_AR;
                            end
                        end else begin

                            ar_state_d   = WAIT_CHANNEL_AR;
                        end
                    end
                end
            end

            WAIT_CHANNEL_AR, SEND_AR: begin

                if (ar_free || (ar_state_q == SEND_AR)) begin

                    mst_ar_valid_o  = 1'b1;
                    mst_ar_addr_o   = addr_q;
                    mst_ar_id_o     = id_q;
                    mst_ar_len_o    = 8'h00;
                    mst_ar_size_o   = size_q;
                    mst_ar_burst_o  = 2'b00;
                    mst_ar_lock_o   = 1'h0;
                    mst_ar_cache_o  = cache_q;
                    mst_ar_prot_o   = prot_q;
                    mst_ar_qos_o    = qos_q;
                    mst_ar_region_o = region_q;
                    mst_ar_user_o   = aw_user_q;
                    if (mst_ar_ready_i) begin

                        ar_state_d = FEEDTHROUGH_AR;
                    end else begin

                        ar_state_d = SEND_AR;
                    end
                end else begin

                    mst_ar_valid_o = slv_ar_valid_i;
                    slv_ar_ready_o = mst_ar_ready_i;
                end
            end

            default: ar_state_d = FEEDTHROUGH_AR;

        endcase
    end


    always_comb begin : axi_r_channel

        mst_r_ready_o = slv_r_ready_i;
        slv_r_id_o    = mst_r_id_i;
        slv_r_data_o  = mst_r_data_i;
        slv_r_resp_o  = mst_r_resp_i;
        slv_r_last_o  = mst_r_last_i;
        slv_r_user_o  = mst_r_user_i;
        slv_r_valid_o = mst_r_valid_i;

        r_data_d      = r_data_q;
        r_resp_d      = r_resp_q;
        r_user_d      = r_user_q;
        r_d_valid_d   = r_d_valid_q;

        r_state_d     = r_state_q;

        unique case (r_state_q)

            FEEDTHROUGH_R: begin
                if (adapter_ready) begin

                    r_d_valid_d = 1'b0;

                    if (atop_valid_d == LOAD || atop_valid_d == STORE) begin

                        r_state_d = WAIT_DATA_R;
                    end else if (atop_valid_d == INVALID) begin

                        if (r_free) begin


                            mst_r_ready_o = 1'b0;

                            slv_r_valid_o = 1'b1;
                            slv_r_data_o  = '0;
                            slv_r_id_o    = slv_aw_id_i;
                            slv_r_last_o  = 1'b1;
                            slv_r_resp_o  = axi_pkg::RESP_SLVERR;
                            slv_r_user_o  = '0;
                            if (!slv_r_ready_i) begin

                                r_state_d = SEND_R;
                            end
                        end else begin
                            r_state_d = WAIT_CHANNEL_R;
                        end
                    end
                end
            end

            WAIT_DATA_R: begin

                if (mst_r_valid_i && (mst_r_id_i == id_q)) begin

                    mst_r_ready_o = 1'b1;
                    slv_r_valid_o = 1'b0;

                    r_data_d    = mst_r_data_i;
                    r_resp_d    = mst_r_resp_i;
                    r_user_d    = mst_r_user_i;
                    r_d_valid_d = 1'b1;
                    if (atop_valid_q == STORE) begin
                        r_state_d = FEEDTHROUGH_R;
                    end else begin

                        r_state_d = WAIT_CHANNEL_R;
                    end
                end
            end

            WAIT_CHANNEL_R, SEND_R: begin


                if ((r_free && (b_state_q != WAIT_COMPLETE_B)) || (r_state_q == SEND_R)) begin

                    mst_r_ready_o = 1'b0;

                    slv_r_valid_o = 1'b1;
                    slv_r_data_o  = r_data_q;
                    slv_r_id_o    = id_q;
                    slv_r_last_o  = 1'b1;
                    slv_r_resp_o  = r_resp_q;
                    slv_r_user_o  = r_user_q;
                    if (atop_valid_q == INVALID) begin
                        slv_r_data_o = '0;
                        slv_r_resp_o = axi_pkg::RESP_SLVERR;
                        slv_r_user_o = '0;
                    end
                    if (slv_r_ready_i) begin
                        r_state_d = FEEDTHROUGH_R;
                    end else begin
                        r_state_d = SEND_R;
                    end
                end
            end

            default: r_state_d = FEEDTHROUGH_R;

        endcase
    end

    always_ff @(posedge clk_i or negedge rst_ni) begin : axi_read_channel_ff
        if(~rst_ni) begin
            ar_state_q  <= FEEDTHROUGH_AR;
            r_state_q   <= FEEDTHROUGH_R;
            r_data_q    <= '0;
            r_resp_q    <= '0;
            r_user_q    <= '0;
            r_d_valid_q <= 1'b0;
        end else begin
            ar_state_q  <= ar_state_d;
            r_state_q   <= r_state_d;
            r_data_q    <= r_data_d;
            r_resp_q    <= r_resp_d;
            r_user_q    <= r_user_d;
            r_d_valid_q <= r_d_valid_d;
        end
    end



    assign op_a           = r_data_q & strb_ext;
    assign op_b           = w_data_q & strb_ext;
    assign sign_a         = |(op_a & ~(strb_ext >> 1));
    assign sign_b         = |(op_b & ~(strb_ext >> 1));
    assign alu_result_ext = res;

    generate
        if (AXI_ALU_RATIO == 1 && RISCV_WORD_WIDTH == 32) begin
            assign alu_operand_a  = op_a;
            assign alu_operand_b  = op_b;
            assign res            = alu_result;
        end else if (AXI_ALU_RATIO == 1 && RISCV_WORD_WIDTH == 64) begin
            assign res        = alu_result;
            always_comb begin
                op_a_sign_ext = op_a | ({AXI_ALU_RATIO*RISCV_WORD_WIDTH{sign_a}} & ~strb_ext);
                op_b_sign_ext = op_b | ({AXI_ALU_RATIO*RISCV_WORD_WIDTH{sign_b}} & ~strb_ext);

                if (atop_q[2:0] == axi_pkg::ATOP_SMAX || atop_q[2:0] == axi_pkg::ATOP_SMIN) begin

                    alu_operand_a = op_a_sign_ext;
                    alu_operand_b = op_b_sign_ext;
                end else begin

                    alu_operand_a = op_a;
                    alu_operand_b = op_b;
                end
            end
        end else begin
            always_comb begin
                op_a_sign_ext = op_a | ({AXI_ALU_RATIO*RISCV_WORD_WIDTH{sign_a}} & ~strb_ext);
                op_b_sign_ext = op_b | ({AXI_ALU_RATIO*RISCV_WORD_WIDTH{sign_b}} & ~strb_ext);

                if (atop_q[2:0] == axi_pkg::ATOP_SMAX || atop_q[2:0] == axi_pkg::ATOP_SMIN) begin

                    alu_operand_a = op_a_sign_ext[addr_q[$clog2(AXI_DATA_WIDTH/8)-1:$clog2(RISCV_WORD_WIDTH/8)]];
                    alu_operand_b = op_b_sign_ext[addr_q[$clog2(AXI_DATA_WIDTH/8)-1:$clog2(RISCV_WORD_WIDTH/8)]];
                end else begin

                    alu_operand_a = op_a[addr_q[$clog2(AXI_DATA_WIDTH/8)-1:$clog2(RISCV_WORD_WIDTH/8)]];
                    alu_operand_b = op_b[addr_q[$clog2(AXI_DATA_WIDTH/8)-1:$clog2(RISCV_WORD_WIDTH/8)]];
                end
                res = '0;
                res[addr_q[$clog2(AXI_DATA_WIDTH/8)-1:$clog2(RISCV_WORD_WIDTH/8)]] = alu_result;
            end
        end
    endgenerate

    generate
        for (genvar i = 0; i < AXI_STRB_WIDTH; i++) begin
            always_comb begin
                if (strb_q[i]) begin
                    strb_ext[i] = 8'hFF;
                end else begin
                    strb_ext[i] = 8'h00;
                end
            end
        end
    endgenerate

    axi_riscv_amos_alu #(
        .DATA_WIDTH ( RISCV_WORD_WIDTH )
    ) i_amo_alu (
        .amo_op_i           ( atop_q        ),
        .amo_operand_a_i    ( alu_operand_a ),
        .amo_operand_b_i    ( alu_operand_b ),
        .amo_result_o       ( alu_result    )
    );



`ifndef VERILATOR
    initial begin: validate_params
        assert (AXI_ADDR_WIDTH > 0)
            else $fatal(1, "AXI_ADDR_WIDTH must be greater than 0!");
        assert (AXI_DATA_WIDTH > 0)
            else $fatal(1, "AXI_DATA_WIDTH must be greater than 0!");
        assert (AXI_ID_WIDTH > 0)
            else $fatal(1, "AXI_ID_WIDTH must be greater than 0!");
        assert (AXI_MAX_WRITE_TXNS > 0)
            else $fatal(1, "AXI_MAX_WRITE_TXNS must be greater than 0!");
        assert (RISCV_WORD_WIDTH == 32 || RISCV_WORD_WIDTH == 64)
            else $fatal(1, "RISCV_WORD_WIDTH must be 32 or 64!");
        assert (RISCV_WORD_WIDTH <= AXI_DATA_WIDTH)
            else $fatal(1, "RISCV_WORD_WIDTH must not be greater than AXI_DATA_WIDTH!");
    end
`endif


endmodule