data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl/axi2apb_64_32.sv
1: b'%Error: data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl/axi2apb_64_32.sv:210: Cannot find file containing module: \'axi_aw_buffer\'\n    axi_aw_buffer #(\n    ^~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl,data/full_repos/permissive/489147019/axi_aw_buffer\n             data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl,data/full_repos/permissive/489147019/axi_aw_buffer.v\n             data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl,data/full_repos/permissive/489147019/axi_aw_buffer.sv\n             axi_aw_buffer\n             axi_aw_buffer.v\n             axi_aw_buffer.sv\n             obj_dir/axi_aw_buffer\n             obj_dir/axi_aw_buffer.v\n             obj_dir/axi_aw_buffer.sv\n%Error: data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl/axi2apb_64_32.sv:247: Cannot find file containing module: \'axi_ar_buffer\'\n    axi_ar_buffer #(\n    ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl/axi2apb_64_32.sv:283: Cannot find file containing module: \'axi_w_buffer\'\n    axi_w_buffer #(\n    ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl/axi2apb_64_32.sv:304: Cannot find file containing module: \'axi_r_buffer\'\n    axi_r_buffer #(\n    ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl/axi2apb_64_32.sv:329: Cannot find file containing module: \'axi_b_buffer\'\n    axi_b_buffer #(\n    ^~~~~~~~~~~~\n%Warning-WIDTH: data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl/axi2apb_64_32.sv:388: Operator ASSIGN expects 12 bits on the Assign RHS, but Assign RHS\'s VARREF \'ARADDR\' generates 32 bits.\n                                                                                                   : ... In instance axi2apb_64_32\n                address   = ARADDR;\n                          ^\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Warning-WIDTH: data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl/axi2apb_64_32.sv:420: Operator ASSIGN expects 12 bits on the Assign RHS, but Assign RHS\'s VARREF \'AWADDR\' generates 32 bits.\n                                                                                                   : ... In instance axi2apb_64_32\n                address   = AWADDR;\n                          ^\n%Warning-WIDTH: data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl/axi2apb_64_32.sv:448: Operator ASSIGN expects 12 bits on the Assign RHS, but Assign RHS\'s VARREF \'ARADDR\' generates 32 bits.\n                                                                                                   : ... In instance axi2apb_64_32\n                    address   = ARADDR;\n                              ^\n%Warning-WIDTH: data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl/axi2apb_64_32.sv:479: Operator ASSIGN expects 12 bits on the Assign RHS, but Assign RHS\'s VARREF \'AWADDR\' generates 32 bits.\n                                                                                                   : ... In instance axi2apb_64_32\n                            address   = AWADDR;\n                                      ^\n%Warning-WIDTH: data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl/axi2apb_64_32.sv:517: Operator ASSIGN expects 12 bits on the Assign RHS, but Assign RHS\'s ADD generates 32 bits.\n                                                                                                   : ... In instance axi2apb_64_32\n                address    = AWADDR + 4;\n                           ^\n%Warning-WIDTH: data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl/axi2apb_64_32.sv:545: Operator ASSIGN expects 12 bits on the Assign RHS, but Assign RHS\'s VARREF \'AWADDR_Q\' generates 32 bits.\n                                                                                                   : ... In instance axi2apb_64_32\n                address    = AWADDR_Q;  \n                           ^\n%Warning-WIDTH: data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl/axi2apb_64_32.sv:569: Operator ASSIGN expects 12 bits on the Assign RHS, but Assign RHS\'s VARREF \'AWADDR_Q\' generates 32 bits.\n                                                                                                   : ... In instance axi2apb_64_32\n                address = AWADDR_Q;  \n                        ^\n%Warning-WIDTH: data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl/axi2apb_64_32.sv:595: Operator ASSIGN expects 12 bits on the Assign RHS, but Assign RHS\'s VARREF \'ARADDR_Q\' generates 32 bits.\n                                                                                                   : ... In instance axi2apb_64_32\n               address  = ARADDR_Q;\n                        ^\n%Warning-WIDTH: data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl/axi2apb_64_32.sv:622: Operator ASSIGN expects 12 bits on the Assign RHS, but Assign RHS\'s VARREF \'ARADDR_Q\' generates 32 bits.\n                                                                                                   : ... In instance axi2apb_64_32\n                address  = ARADDR_Q;\n                         ^\n%Warning-WIDTH: data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl/axi2apb_64_32.sv:646: Operator ASSIGN expects 12 bits on the Assign RHS, but Assign RHS\'s VARREF \'ARADDR_Q\' generates 32 bits.\n                                                                                                   : ... In instance axi2apb_64_32\n                address  = ARADDR_Q;\n                         ^\n%Warning-WIDTH: data/full_repos/permissive/489147019/Flows/ASAP7/ariane136/rtl/axi2apb_64_32.sv:675: Operator ASSIGN expects 12 bits on the Assign RHS, but Assign RHS\'s ADD generates 32 bits.\n                                                                                                   : ... In instance axi2apb_64_32\n                address        = ARADDR + 4;\n                               ^\n%Error: Exiting due to 5 error(s), 11 warning(s)\n'
module axi2apb_64_32 #(
    parameter int unsigned AXI4_ADDRESS_WIDTH = 32,
    parameter int unsigned AXI4_RDATA_WIDTH   = 64,
    parameter int unsigned AXI4_WDATA_WIDTH   = 64,
    parameter int unsigned AXI4_ID_WIDTH      = 16,
    parameter int unsigned AXI4_USER_WIDTH    = 10,
    parameter int unsigned AXI_NUMBYTES       = AXI4_WDATA_WIDTH/8,

    parameter int unsigned BUFF_DEPTH_SLAVE   = 4,
    parameter int unsigned APB_NUM_SLAVES     = 8,
    parameter int unsigned APB_ADDR_WIDTH     = 12
)
(
    input logic                           ACLK,
    input logic                           ARESETn,
    input logic                           test_en_i,




    input  logic [AXI4_ID_WIDTH-1:0]       AWID_i     ,
    input  logic [AXI4_ADDRESS_WIDTH-1:0]  AWADDR_i   ,
    input  logic [ 7:0]                    AWLEN_i    ,
    input  logic [ 2:0]                    AWSIZE_i   ,
    input  logic [ 1:0]                    AWBURST_i  ,
    input  logic                           AWLOCK_i   ,
    input  logic [ 3:0]                    AWCACHE_i  ,
    input  logic [ 2:0]                    AWPROT_i   ,
    input  logic [ 3:0]                    AWREGION_i ,
    input  logic [ AXI4_USER_WIDTH-1:0]    AWUSER_i   ,
    input  logic [ 3:0]                    AWQOS_i    ,
    input  logic                           AWVALID_i  ,
    output logic                           AWREADY_o  ,



    input  logic [AXI_NUMBYTES-1:0][7:0]   WDATA_i    ,
    input  logic [AXI_NUMBYTES-1:0]        WSTRB_i    ,
    input  logic                           WLAST_i    ,
    input  logic [AXI4_USER_WIDTH-1:0]     WUSER_i    ,
    input  logic                           WVALID_i   ,
    output logic                           WREADY_o   ,



    output logic   [AXI4_ID_WIDTH-1:0]     BID_o      ,
    output logic   [ 1:0]                  BRESP_o    ,
    output logic                           BVALID_o   ,
    output logic   [AXI4_USER_WIDTH-1:0]   BUSER_o    ,
    input  logic                           BREADY_i   ,



    input  logic [AXI4_ID_WIDTH-1:0]       ARID_i     ,
    input  logic [AXI4_ADDRESS_WIDTH-1:0]  ARADDR_i   ,
    input  logic [ 7:0]                    ARLEN_i    ,
    input  logic [ 2:0]                    ARSIZE_i   ,
    input  logic [ 1:0]                    ARBURST_i  ,
    input  logic                           ARLOCK_i   ,
    input  logic [ 3:0]                    ARCACHE_i  ,
    input  logic [ 2:0]                    ARPROT_i   ,
    input  logic [ 3:0]                    ARREGION_i ,
    input  logic [ AXI4_USER_WIDTH-1:0]    ARUSER_i   ,
    input  logic [ 3:0]                    ARQOS_i    ,
    input  logic                           ARVALID_i  ,
    output logic                           ARREADY_o  ,



    output  logic [AXI4_ID_WIDTH-1:0]      RID_o      ,
    output  logic [AXI4_RDATA_WIDTH-1:0]   RDATA_o    ,
    output  logic [ 1:0]                   RRESP_o    ,
    output  logic                          RLAST_o    ,
    output  logic [AXI4_USER_WIDTH-1:0]    RUSER_o    ,
    output  logic                          RVALID_o   ,
    input   logic                          RREADY_i   ,


    output logic                           PENABLE    ,
    output logic                           PWRITE     ,
    output logic [APB_ADDR_WIDTH-1:0]      PADDR      ,
    output logic                           PSEL       ,
    output logic [31:0]                    PWDATA     ,
    input  logic [31:0]                    PRDATA     ,
    input  logic                           PREADY     ,
    input  logic                           PSLVERR
);




    logic [AXI4_ID_WIDTH-1:0]      AWID;
    logic [AXI4_ADDRESS_WIDTH-1:0] AWADDR;
    logic [ 7:0]                   AWLEN;
    logic [ 2:0]                   AWSIZE;
    logic [ 1:0]                   AWBURST;
    logic                          AWLOCK;
    logic [ 3:0]                   AWCACHE;
    logic [ 2:0]                   AWPROT;
    logic [ 3:0]                   AWREGION;
    logic [ AXI4_USER_WIDTH-1:0]   AWUSER;
    logic [ 3:0]                   AWQOS;
    logic                          AWVALID;
    logic                          AWREADY;



    logic [1:0][31:0]              WDATA;
    logic [AXI_NUMBYTES-1:0]       WSTRB;
    logic                          WLAST;
    logic [AXI4_USER_WIDTH-1:0]    WUSER;
    logic                          WVALID;
    logic                          WREADY;



    logic [AXI4_ID_WIDTH-1:0]      BID;
    logic [ 1:0]                   BRESP;
    logic                          BVALID;
    logic [AXI4_USER_WIDTH-1:0]    BUSER;
    logic                          BREADY;



    logic [AXI4_ID_WIDTH-1:0]      ARID;
    logic [AXI4_ADDRESS_WIDTH-1:0] ARADDR;
    logic [ 7:0]                   ARLEN;
    logic [ 2:0]                   ARSIZE;
    logic [ 1:0]                   ARBURST;
    logic                          ARLOCK;
    logic [ 3:0]                   ARCACHE;
    logic [ 2:0]                   ARPROT;
    logic [ 3:0]                   ARREGION;
    logic [ AXI4_USER_WIDTH-1:0]   ARUSER;
    logic [ 3:0]                   ARQOS;
    logic                          ARVALID;
    logic                          ARREADY;



    logic [AXI4_ID_WIDTH-1:0]    RID;
    logic [1:0][31:0]            RDATA;
    logic [ 1:0]                 RRESP;
    logic                        RLAST;
    logic [AXI4_USER_WIDTH-1:0]  RUSER;
    logic                        RVALID;
    logic                        RREADY;

    enum logic [3:0] { IDLE,
                       SINGLE_RD, SINGLE_RD_64,
                       BURST_RD_1, BURST_RD, BURST_RD_64,
                       BURST_WR, BURST_WR_64,
                       SINGLE_WR,SINGLE_WR_64,
                       WAIT_R_PREADY, WAIT_W_PREADY
                      } CS, NS;

    logic        W_word_sel;

    logic [APB_ADDR_WIDTH-1:0] address;

    logic        read_req;
    logic        write_req;

    logic        sample_AR;
    logic [8:0]  ARLEN_Q;
    logic        decr_ARLEN;

    logic        sample_AW;
    logic [8:0]  AWLEN_Q;
    logic        decr_AWLEN;

    logic [AXI4_ADDRESS_WIDTH-1:0] ARADDR_Q;
    logic                          incr_ARADDR;

    logic [AXI4_ADDRESS_WIDTH-1:0] AWADDR_Q;
    logic                          incr_AWADDR;

    logic        sample_RDATA_0;
    logic        sample_RDATA_1;
    logic [31:0] RDATA_Q_0;
    logic [31:0] RDATA_Q_1;

    assign PENABLE = write_req | read_req;
    assign PWRITE  = write_req;
    assign PADDR   = address[APB_ADDR_WIDTH-1:0];

    assign PWDATA  = WDATA[W_word_sel];
    assign PSEL    = 1'b1;


    axi_aw_buffer #(
        .ID_WIDTH     ( AXI4_ID_WIDTH      ),
        .ADDR_WIDTH   ( AXI4_ADDRESS_WIDTH ),
        .USER_WIDTH   ( AXI4_USER_WIDTH    ),
        .BUFFER_DEPTH ( BUFF_DEPTH_SLAVE   )
    ) slave_aw_buffer_i (
       .clk_i           ( ACLK        ),
       .rst_ni          ( ARESETn     ),
       .test_en_i       ( test_en_i   ),
       .slave_valid_i   ( AWVALID_i   ),
       .slave_addr_i    ( AWADDR_i    ),
       .slave_prot_i    ( AWPROT_i    ),
       .slave_region_i  ( AWREGION_i  ),
       .slave_len_i     ( AWLEN_i     ),
       .slave_size_i    ( AWSIZE_i    ),
       .slave_burst_i   ( AWBURST_i   ),
       .slave_lock_i    ( AWLOCK_i    ),
       .slave_cache_i   ( AWCACHE_i   ),
       .slave_qos_i     ( AWQOS_i     ),
       .slave_id_i      ( AWID_i      ),
       .slave_user_i    ( AWUSER_i    ),
       .slave_ready_o   ( AWREADY_o   ),
       .master_valid_o  ( AWVALID     ),
       .master_addr_o   ( AWADDR      ),
       .master_prot_o   ( AWPROT      ),
       .master_region_o ( AWREGION    ),
       .master_len_o    ( AWLEN       ),
       .master_size_o   ( AWSIZE      ),
       .master_burst_o  ( AWBURST     ),
       .master_lock_o   ( AWLOCK      ),
       .master_cache_o  ( AWCACHE     ),
       .master_qos_o    ( AWQOS       ),
       .master_id_o     ( AWID        ),
       .master_user_o   ( AWUSER      ),
       .master_ready_i  ( AWREADY     )
    );

    axi_ar_buffer #(
        .ID_WIDTH       ( AXI4_ID_WIDTH      ),
        .ADDR_WIDTH     ( AXI4_ADDRESS_WIDTH ),
        .USER_WIDTH     ( AXI4_USER_WIDTH    ),
        .BUFFER_DEPTH   ( BUFF_DEPTH_SLAVE   )
    ) slave_ar_buffer_i (
       .clk_i           ( ACLK       ),
       .rst_ni          ( ARESETn    ),
       .test_en_i       ( test_en_i  ),
       .slave_valid_i   ( ARVALID_i  ),
       .slave_addr_i    ( ARADDR_i   ),
       .slave_prot_i    ( ARPROT_i   ),
       .slave_region_i  ( ARREGION_i ),
       .slave_len_i     ( ARLEN_i    ),
       .slave_size_i    ( ARSIZE_i   ),
       .slave_burst_i   ( ARBURST_i  ),
       .slave_lock_i    ( ARLOCK_i   ),
       .slave_cache_i   ( ARCACHE_i  ),
       .slave_qos_i     ( ARQOS_i    ),
       .slave_id_i      ( ARID_i     ),
       .slave_user_i    ( ARUSER_i   ),
       .slave_ready_o   ( ARREADY_o  ),
       .master_valid_o  ( ARVALID    ),
       .master_addr_o   ( ARADDR     ),
       .master_prot_o   ( ARPROT     ),
       .master_region_o ( ARREGION   ),
       .master_len_o    ( ARLEN      ),
       .master_size_o   ( ARSIZE     ),
       .master_burst_o  ( ARBURST    ),
       .master_lock_o   ( ARLOCK     ),
       .master_cache_o  ( ARCACHE    ),
       .master_qos_o    ( ARQOS      ),
       .master_id_o     ( ARID       ),
       .master_user_o   ( ARUSER     ),
       .master_ready_i  ( ARREADY    )
    );
    axi_w_buffer #(
        .DATA_WIDTH   ( AXI4_WDATA_WIDTH ),
        .USER_WIDTH   ( AXI4_USER_WIDTH  ),
        .BUFFER_DEPTH ( BUFF_DEPTH_SLAVE )
    ) slave_w_buffer_i (
         .clk_i          ( ACLK      ),
         .rst_ni         ( ARESETn   ),
         .test_en_i      ( test_en_i ),
         .slave_valid_i  ( WVALID_i  ),
         .slave_data_i   ( WDATA_i   ),
         .slave_strb_i   ( WSTRB_i   ),
         .slave_user_i   ( WUSER_i   ),
         .slave_last_i   ( WLAST_i   ),
         .slave_ready_o  ( WREADY_o  ),
         .master_valid_o ( WVALID    ),
         .master_data_o  ( WDATA     ),
         .master_strb_o  ( WSTRB     ),
         .master_user_o  ( WUSER     ),
         .master_last_o  ( WLAST     ),
         .master_ready_i ( WREADY    )
    );
    axi_r_buffer #(
         .ID_WIDTH     ( AXI4_ID_WIDTH    ),
         .DATA_WIDTH   ( AXI4_RDATA_WIDTH ),
         .USER_WIDTH   ( AXI4_USER_WIDTH  ),
         .BUFFER_DEPTH ( BUFF_DEPTH_SLAVE )
    ) slave_r_buffer_i (
         .clk_i          ( ACLK       ),
         .rst_ni         ( ARESETn    ),
         .test_en_i      ( test_en_i  ),
         .slave_valid_i  ( RVALID     ),
         .slave_data_i   ( RDATA      ),
         .slave_resp_i   ( RRESP      ),
         .slave_user_i   ( RUSER      ),
         .slave_id_i     ( RID        ),
         .slave_last_i   ( RLAST      ),
         .slave_ready_o  ( RREADY     ),
         .master_valid_o ( RVALID_o   ),
         .master_data_o  ( RDATA_o    ),
         .master_resp_o  ( RRESP_o    ),
         .master_user_o  ( RUSER_o    ),
         .master_id_o    ( RID_o      ),
         .master_last_o  ( RLAST_o    ),
         .master_ready_i ( RREADY_i   )
    );

    axi_b_buffer #(
        .ID_WIDTH       ( AXI4_ID_WIDTH    ),
        .USER_WIDTH     ( AXI4_USER_WIDTH  ),
        .BUFFER_DEPTH   ( BUFF_DEPTH_SLAVE )
    ) slave_b_buffer_i (
        .clk_i          ( ACLK      ),
        .rst_ni         ( ARESETn   ),
        .test_en_i      ( test_en_i ),

        .slave_valid_i  ( BVALID    ),
        .slave_resp_i   ( BRESP     ),
        .slave_id_i     ( BID       ),
        .slave_user_i   ( BUSER     ),
        .slave_ready_o  ( BREADY    ),

        .master_valid_o ( BVALID_o  ),
        .master_resp_o  ( BRESP_o   ),
        .master_id_o    ( BID_o     ),
        .master_user_o  ( BUSER_o   ),
        .master_ready_i ( BREADY_i  )
    );

    always_comb begin
        read_req   = 1'b0;
        write_req  = 1'b0;
        W_word_sel = 1'b0;

        sample_AW  = 1'b0;
        decr_AWLEN = 1'b0;
        sample_AR  = 1'b0;
        decr_ARLEN = 1'b0;

        incr_AWADDR = 1'b0;
        incr_ARADDR = 1'b0;

        sample_RDATA_0 = 1'b0;
        sample_RDATA_1 = 1'b0;

        ARREADY = 1'b0;
        AWREADY = 1'b0;
        WREADY  = 1'b0;
        RDATA   = '0;

        BVALID = 1'b0;
        BRESP  = `OKAY;
        BID    = AWID;
        BUSER  = AWUSER;

        RVALID = 1'b0;
        RLAST  = 1'b0;
        RID    = ARID;
        RUSER  = ARUSER;
        RRESP  = `OKAY;

        case(CS)

            WAIT_R_PREADY: begin
                sample_AR = 1'b0;
                read_req  = 1'b1;
                address   = ARADDR;

                if (PREADY == 1'b1) begin
                    if (ARLEN == 0) begin
                        case (ARSIZE)
                            3'h3: begin
                                NS = SINGLE_RD_64;
                                if (ARADDR[2:0] == 3'h4)
                                    sample_RDATA_1 = 1'b1;
                                else  sample_RDATA_0 = 1'b1;
                            end

                            default: begin
                                NS = SINGLE_RD;
                                if (ARADDR[2:0] == 3'h4)
                                    sample_RDATA_1 = 1'b1;
                                else
                                    sample_RDATA_0 = 1'b1;
                                end
                            endcase
                    end else begin
                       NS             = BURST_RD_64;
                       sample_RDATA_0 = 1'b1;
                       decr_ARLEN     = 1'b1;
                       incr_ARADDR    = 1'b1;
                    end
                end else begin
                    NS = WAIT_R_PREADY;
                end
            end

            WAIT_W_PREADY: begin
                address   = AWADDR;
                write_req = 1'b1;

                if (AWADDR[2:0] == 3'h4)
                    W_word_sel = 1'b1;
                else
                    W_word_sel = 1'b0;


                if (PREADY == 1'b1) begin
                    if (AWLEN == 0) begin
                        case (AWSIZE)
                            3'h3: NS = SINGLE_WR_64;
                            default: NS = SINGLE_WR;
                        endcase
                    end else begin
                        sample_AW = 1'b1;
                        NS        = BURST_WR_64;
                    end
                end else begin
                    NS = WAIT_W_PREADY;
                end
            end

            IDLE: begin
                if (ARVALID == 1'b1)  begin
                    sample_AR = 1'b1;
                    read_req  = 1'b1;
                    address   = ARADDR;

                    if (PREADY == 1'b1) begin
                        if (ARLEN == 0) begin
                            case (ARSIZE)
                                3'h3: begin
                                    NS = SINGLE_RD_64;
                                    if (ARADDR[2:0] == 4)
                                        sample_RDATA_1 = 1'b1;
                                    else
                                        sample_RDATA_0 = 1'b1;
                                end
                                default: begin
                                    NS = SINGLE_RD;
                                    if (ARADDR[2:0] == 4)
                                        sample_RDATA_1 = 1'b1;
                                    else
                                        sample_RDATA_0 = 1'b1;
                                    end
                            endcase end else begin
                            NS             = BURST_RD_64;
                            sample_RDATA_0 = 1'b1;
                        end
                    end else begin
                        NS = WAIT_R_PREADY;
                    end
                end else begin

                    if (AWVALID) begin
                        if (WVALID) begin
                            write_req = 1'b1;
                            address   = AWADDR;

                            if (AWADDR[2:0] == 3'h4)
                                W_word_sel = 1'b1;
                            else
                                W_word_sel = 1'b0;


                            if (PREADY == 1'b1) begin
                                  if(AWLEN == 0) begin
                                        case(AWSIZE)
                                            3'h3: NS = SINGLE_WR_64;
                                            default: NS = SINGLE_WR;
                                        endcase
                                  end else begin
                                        sample_AW   = 1'b1;
                                        if ((AWADDR[2:0] == 3'h4) && (WSTRB[7:4] == 0))
                                          incr_AWADDR = 1'b0;
                                        else
                                          incr_AWADDR = 1'b1;
                                        NS = BURST_WR_64;
                                  end
                            end else begin
                                NS = WAIT_W_PREADY;
                            end
                        end else begin
                            write_req = 1'b0;
                            address   = '0;
                            NS        = IDLE;
                        end
                    end else begin
                        NS = IDLE;
                        address =  '0;
                    end
                end
            end

            SINGLE_WR_64: begin
                address    = AWADDR + 4;
                W_word_sel = 1'b1;
                write_req  = WVALID;
                if (WVALID) begin
                    if (PREADY == 1'b1)
                        NS = SINGLE_WR;
                    else
                        NS = SINGLE_WR_64;
                end else begin
                    NS = SINGLE_WR_64;
                end
            end

            SINGLE_WR:  begin
                BVALID   = 1'b1;
                address  = '0;
                if (BREADY)  begin
                    NS      = IDLE;
                    AWREADY = 1'b1;
                    WREADY  = 1'b1;
                end else begin
                    NS = SINGLE_WR;
                end
            end

            BURST_WR_64: begin
                W_word_sel = 1'b1;
                write_req  = WVALID & (|WSTRB[7:4]);
                address    = AWADDR_Q;

                if (WVALID) begin
                    if (&WSTRB[7:4]) begin
                        if(PREADY == 1'b1) begin
                            NS          = BURST_WR;
                            WREADY      = 1'b1;
                            decr_AWLEN  = 1'b1;
                            incr_AWADDR = 1'b1;
                        end else begin
                            NS = BURST_WR_64;
                        end
                    end else begin
                        NS = BURST_WR;
                        WREADY      = 1'b1;
                        decr_AWLEN  = 1'b1;
                        incr_AWADDR = 1'b1;
                    end
                end else begin
                    NS = BURST_WR_64;
                end
            end

            BURST_WR: begin
                address = AWADDR_Q;
                if (AWLEN_Q == 0) begin
                    BVALID = 1'b1;
                    if (BREADY) begin
                      NS      = IDLE;
                      AWREADY = 1'b1;
                    end else
                      NS = BURST_WR;
                end else begin
                    W_word_sel = 1'b0;
                    write_req  = WVALID & (&WSTRB[3:0]);
                    if (WVALID) begin
                        if (PREADY == 1'b1) begin
                            NS          = BURST_WR_64;
                            incr_AWADDR = 1'b1;
                            decr_AWLEN  = 1'b1;
                          end else
                            NS = BURST_WR;
                    end else begin
                        NS = BURST_WR_64;
                    end
              end
            end

            BURST_RD_64: begin
               read_req = 1'b1;
               address  = ARADDR_Q;

                if (ARLEN_Q == 0) begin
                    NS      = IDLE;
                    ARREADY = 1'b1;
                end else begin
                    if (PREADY == 1'b1) begin
                        decr_ARLEN     = 1'b1;
                        sample_RDATA_1 = 1'b1;
                        NS = BURST_RD;

                        if (ARADDR_Q[2:0] == 3'h4)
                          incr_ARADDR = 1'b1;
                        else
                          incr_ARADDR = 1'b0;
                      end
                    else  begin
                        NS = BURST_RD_64;
                    end
                 end
            end

            BURST_RD: begin
                RVALID   = 1'b1;
                RDATA[0] = RDATA_Q_0;
                RDATA[1] = RDATA_Q_1;
                RLAST    = (ARLEN_Q == 0) ? 1'b1 : 1'b0;
                address  = ARADDR_Q;

                if (RREADY) begin
                    if (ARLEN_Q == 0) begin
                        NS      = IDLE;
                        ARREADY = 1'b1;
                    end else begin
                        read_req = 1'b1;
                        if (PREADY == 1'b1) begin
                            sample_RDATA_0 = 1'b1;
                            NS             = BURST_RD_64;
                            incr_ARADDR    = 1'b1;
                            decr_ARLEN     = 1'b1;
                        end else begin
                            NS = BURST_RD_1;
                        end
                    end
                end else begin
                    NS = BURST_RD;
                end
            end

            BURST_RD_1: begin
                read_req = 1'b1;
                address  = ARADDR_Q;

                if (PREADY == 1'b1) begin
                    sample_RDATA_0 = 1'b1;
                    NS             = BURST_RD_64;
                    incr_ARADDR    = 1'b1;
                    decr_ARLEN     = 1'b1;
                end else begin
                    NS = BURST_RD_1;
                end
            end

            SINGLE_RD: begin
                RVALID   = 1'b1;
                RDATA[0] = RDATA_Q_0;
                RDATA[1] = RDATA_Q_1;
                RLAST    = 1;
                address  = '0;

                if (RREADY) begin
                    NS      = IDLE;
                    ARREADY = 1'b1;
                end else begin
                    NS = SINGLE_RD;
                end
            end

            SINGLE_RD_64: begin
                read_req       = 1'b1;
                address        = ARADDR + 4;
                if (PREADY == 1'b1) begin
                    NS = SINGLE_RD;
                    if(ARADDR[2:0] == 3'h4)
                        sample_RDATA_0 = 1'b1;
                    else
                        sample_RDATA_1 = 1'b1;
                end else begin
                  NS = SINGLE_RD_64;
                end
            end

            default: begin
                NS      = IDLE;
                address = '0;
            end
        endcase
    end




    always_ff @(posedge ACLK, negedge ARESETn) begin
        if (ARESETn == 1'b0) begin
            CS        <= IDLE;

            ARLEN_Q   <= '0;
            AWADDR_Q  <= '0;

            AWLEN_Q   <= '0;
            RDATA_Q_0 <= '0;
            RDATA_Q_1 <= '0;
            ARADDR_Q  <= '0;
        end else  begin
            CS <= NS;

            if (sample_AR) begin
                ARLEN_Q <= {ARLEN,1'b0} + 2;
            end else if (decr_ARLEN) begin
                ARLEN_Q <= ARLEN_Q - 1;
            end

            if (sample_RDATA_0)
                RDATA_Q_0 <= PRDATA;

            if (sample_RDATA_1)
                RDATA_Q_1 <= PRDATA;

            case ({sample_AW, decr_AWLEN})
                2'b00: AWLEN_Q <= AWLEN_Q;
                2'b01: AWLEN_Q <= AWLEN_Q - 1;
                2'b10: AWLEN_Q <= {AWLEN, 1'b0} + 1;
                2'b11: AWLEN_Q <= {AWLEN, 1'b0};
            endcase

            case ({sample_AW, incr_AWADDR})
                2'b00: AWADDR_Q <= AWADDR_Q;
                2'b01: AWADDR_Q <= AWADDR_Q + 4;
                2'b10: AWADDR_Q <= {AWADDR[AXI4_ADDRESS_WIDTH-1:3], 3'b000};
                2'b11: AWADDR_Q <= {AWADDR[AXI4_ADDRESS_WIDTH-1:3], 3'b000} + 4;
            endcase

            case({sample_AR, incr_ARADDR})
                2'b00: ARADDR_Q <= ARADDR_Q;
                2'b01: ARADDR_Q <= ARADDR_Q + 4;
                2'b10: ARADDR_Q <= {ARADDR[AXI4_ADDRESS_WIDTH-1:3], 3'b000};
                2'b11: ARADDR_Q <= {ARADDR[AXI4_ADDRESS_WIDTH-1:3], 3'b000} + 4;
            endcase
        end
    end
endmodule
module axi2apb_64_32 #(
    parameter int unsigned AXI4_ADDRESS_WIDTH = 32,
    parameter int unsigned AXI4_RDATA_WIDTH   = 64,
    parameter int unsigned AXI4_WDATA_WIDTH   = 64,
    parameter int unsigned AXI4_ID_WIDTH      = 16,
    parameter int unsigned AXI4_USER_WIDTH    = 10,
    parameter int unsigned AXI_NUMBYTES       = AXI4_WDATA_WIDTH/8,

    parameter int unsigned BUFF_DEPTH_SLAVE   = 4,
    parameter int unsigned APB_NUM_SLAVES     = 8,
    parameter int unsigned APB_ADDR_WIDTH     = 12
)
(
    input logic                           ACLK,
    input logic                           ARESETn,
    input logic                           test_en_i,




    input  logic [AXI4_ID_WIDTH-1:0]       AWID_i     ,
    input  logic [AXI4_ADDRESS_WIDTH-1:0]  AWADDR_i   ,
    input  logic [ 7:0]                    AWLEN_i    ,
    input  logic [ 2:0]                    AWSIZE_i   ,
    input  logic [ 1:0]                    AWBURST_i  ,
    input  logic                           AWLOCK_i   ,
    input  logic [ 3:0]                    AWCACHE_i  ,
    input  logic [ 2:0]                    AWPROT_i   ,
    input  logic [ 3:0]                    AWREGION_i ,
    input  logic [ AXI4_USER_WIDTH-1:0]    AWUSER_i   ,
    input  logic [ 3:0]                    AWQOS_i    ,
    input  logic                           AWVALID_i  ,
    output logic                           AWREADY_o  ,



    input  logic [AXI_NUMBYTES-1:0][7:0]   WDATA_i    ,
    input  logic [AXI_NUMBYTES-1:0]        WSTRB_i    ,
    input  logic                           WLAST_i    ,
    input  logic [AXI4_USER_WIDTH-1:0]     WUSER_i    ,
    input  logic                           WVALID_i   ,
    output logic                           WREADY_o   ,



    output logic   [AXI4_ID_WIDTH-1:0]     BID_o      ,
    output logic   [ 1:0]                  BRESP_o    ,
    output logic                           BVALID_o   ,
    output logic   [AXI4_USER_WIDTH-1:0]   BUSER_o    ,
    input  logic                           BREADY_i   ,



    input  logic [AXI4_ID_WIDTH-1:0]       ARID_i     ,
    input  logic [AXI4_ADDRESS_WIDTH-1:0]  ARADDR_i   ,
    input  logic [ 7:0]                    ARLEN_i    ,
    input  logic [ 2:0]                    ARSIZE_i   ,
    input  logic [ 1:0]                    ARBURST_i  ,
    input  logic                           ARLOCK_i   ,
    input  logic [ 3:0]                    ARCACHE_i  ,
    input  logic [ 2:0]                    ARPROT_i   ,
    input  logic [ 3:0]                    ARREGION_i ,
    input  logic [ AXI4_USER_WIDTH-1:0]    ARUSER_i   ,
    input  logic [ 3:0]                    ARQOS_i    ,
    input  logic                           ARVALID_i  ,
    output logic                           ARREADY_o  ,



    output  logic [AXI4_ID_WIDTH-1:0]      RID_o      ,
    output  logic [AXI4_RDATA_WIDTH-1:0]   RDATA_o    ,
    output  logic [ 1:0]                   RRESP_o    ,
    output  logic                          RLAST_o    ,
    output  logic [AXI4_USER_WIDTH-1:0]    RUSER_o    ,
    output  logic                          RVALID_o   ,
    input   logic                          RREADY_i   ,


    output logic                           PENABLE    ,
    output logic                           PWRITE     ,
    output logic [APB_ADDR_WIDTH-1:0]      PADDR      ,
    output logic                           PSEL       ,
    output logic [31:0]                    PWDATA     ,
    input  logic [31:0]                    PRDATA     ,
    input  logic                           PREADY     ,
    input  logic                           PSLVERR
);





    logic [AXI4_ID_WIDTH-1:0]      AWID;
    logic [AXI4_ADDRESS_WIDTH-1:0] AWADDR;
    logic [ 7:0]                   AWLEN;
    logic [ 2:0]                   AWSIZE;
    logic [ 1:0]                   AWBURST;
    logic                          AWLOCK;
    logic [ 3:0]                   AWCACHE;
    logic [ 2:0]                   AWPROT;
    logic [ 3:0]                   AWREGION;
    logic [ AXI4_USER_WIDTH-1:0]   AWUSER;
    logic [ 3:0]                   AWQOS;
    logic                          AWVALID;
    logic                          AWREADY;



    logic [1:0][31:0]              WDATA;
    logic [AXI_NUMBYTES-1:0]       WSTRB;
    logic                          WLAST;
    logic [AXI4_USER_WIDTH-1:0]    WUSER;
    logic                          WVALID;
    logic                          WREADY;



    logic [AXI4_ID_WIDTH-1:0]      BID;
    logic [ 1:0]                   BRESP;
    logic                          BVALID;
    logic [AXI4_USER_WIDTH-1:0]    BUSER;
    logic                          BREADY;



    logic [AXI4_ID_WIDTH-1:0]      ARID;
    logic [AXI4_ADDRESS_WIDTH-1:0] ARADDR;
    logic [ 7:0]                   ARLEN;
    logic [ 2:0]                   ARSIZE;
    logic [ 1:0]                   ARBURST;
    logic                          ARLOCK;
    logic [ 3:0]                   ARCACHE;
    logic [ 2:0]                   ARPROT;
    logic [ 3:0]                   ARREGION;
    logic [ AXI4_USER_WIDTH-1:0]   ARUSER;
    logic [ 3:0]                   ARQOS;
    logic                          ARVALID;
    logic                          ARREADY;



    logic [AXI4_ID_WIDTH-1:0]    RID;
    logic [1:0][31:0]            RDATA;
    logic [ 1:0]                 RRESP;
    logic                        RLAST;
    logic [AXI4_USER_WIDTH-1:0]  RUSER;
    logic                        RVALID;
    logic                        RREADY;

    enum logic [3:0] { IDLE,
                       SINGLE_RD, SINGLE_RD_64,
                       BURST_RD_1, BURST_RD, BURST_RD_64,
                       BURST_WR, BURST_WR_64,
                       SINGLE_WR,SINGLE_WR_64,
                       WAIT_R_PREADY, WAIT_W_PREADY
                      } CS, NS;

    logic        W_word_sel;

    logic [APB_ADDR_WIDTH-1:0] address;

    logic        read_req;
    logic        write_req;

    logic        sample_AR;
    logic [8:0]  ARLEN_Q;
    logic        decr_ARLEN;

    logic        sample_AW;
    logic [8:0]  AWLEN_Q;
    logic        decr_AWLEN;

    logic [AXI4_ADDRESS_WIDTH-1:0] ARADDR_Q;
    logic                          incr_ARADDR;

    logic [AXI4_ADDRESS_WIDTH-1:0] AWADDR_Q;
    logic                          incr_AWADDR;

    logic        sample_RDATA_0;
    logic        sample_RDATA_1;
    logic [31:0] RDATA_Q_0;
    logic [31:0] RDATA_Q_1;

    assign PENABLE = write_req | read_req;
    assign PWRITE  = write_req;
    assign PADDR   = address[APB_ADDR_WIDTH-1:0];

    assign PWDATA  = WDATA[W_word_sel];
    assign PSEL    = 1'b1;


    axi_aw_buffer #(
        .ID_WIDTH     ( AXI4_ID_WIDTH      ),
        .ADDR_WIDTH   ( AXI4_ADDRESS_WIDTH ),
        .USER_WIDTH   ( AXI4_USER_WIDTH    ),
        .BUFFER_DEPTH ( BUFF_DEPTH_SLAVE   )
    ) slave_aw_buffer_i (
       .clk_i           ( ACLK        ),
       .rst_ni          ( ARESETn     ),
       .test_en_i       ( test_en_i   ),
       .slave_valid_i   ( AWVALID_i   ),
       .slave_addr_i    ( AWADDR_i    ),
       .slave_prot_i    ( AWPROT_i    ),
       .slave_region_i  ( AWREGION_i  ),
       .slave_len_i     ( AWLEN_i     ),
       .slave_size_i    ( AWSIZE_i    ),
       .slave_burst_i   ( AWBURST_i   ),
       .slave_lock_i    ( AWLOCK_i    ),
       .slave_cache_i   ( AWCACHE_i   ),
       .slave_qos_i     ( AWQOS_i     ),
       .slave_id_i      ( AWID_i      ),
       .slave_user_i    ( AWUSER_i    ),
       .slave_ready_o   ( AWREADY_o   ),
       .master_valid_o  ( AWVALID     ),
       .master_addr_o   ( AWADDR      ),
       .master_prot_o   ( AWPROT      ),
       .master_region_o ( AWREGION    ),
       .master_len_o    ( AWLEN       ),
       .master_size_o   ( AWSIZE      ),
       .master_burst_o  ( AWBURST     ),
       .master_lock_o   ( AWLOCK      ),
       .master_cache_o  ( AWCACHE     ),
       .master_qos_o    ( AWQOS       ),
       .master_id_o     ( AWID        ),
       .master_user_o   ( AWUSER      ),
       .master_ready_i  ( AWREADY     )
    );

    axi_ar_buffer #(
        .ID_WIDTH       ( AXI4_ID_WIDTH      ),
        .ADDR_WIDTH     ( AXI4_ADDRESS_WIDTH ),
        .USER_WIDTH     ( AXI4_USER_WIDTH    ),
        .BUFFER_DEPTH   ( BUFF_DEPTH_SLAVE   )
    ) slave_ar_buffer_i (
       .clk_i           ( ACLK       ),
       .rst_ni          ( ARESETn    ),
       .test_en_i       ( test_en_i  ),
       .slave_valid_i   ( ARVALID_i  ),
       .slave_addr_i    ( ARADDR_i   ),
       .slave_prot_i    ( ARPROT_i   ),
       .slave_region_i  ( ARREGION_i ),
       .slave_len_i     ( ARLEN_i    ),
       .slave_size_i    ( ARSIZE_i   ),
       .slave_burst_i   ( ARBURST_i  ),
       .slave_lock_i    ( ARLOCK_i   ),
       .slave_cache_i   ( ARCACHE_i  ),
       .slave_qos_i     ( ARQOS_i    ),
       .slave_id_i      ( ARID_i     ),
       .slave_user_i    ( ARUSER_i   ),
       .slave_ready_o   ( ARREADY_o  ),
       .master_valid_o  ( ARVALID    ),
       .master_addr_o   ( ARADDR     ),
       .master_prot_o   ( ARPROT     ),
       .master_region_o ( ARREGION   ),
       .master_len_o    ( ARLEN      ),
       .master_size_o   ( ARSIZE     ),
       .master_burst_o  ( ARBURST    ),
       .master_lock_o   ( ARLOCK     ),
       .master_cache_o  ( ARCACHE    ),
       .master_qos_o    ( ARQOS      ),
       .master_id_o     ( ARID       ),
       .master_user_o   ( ARUSER     ),
       .master_ready_i  ( ARREADY    )
    );
    axi_w_buffer #(
        .DATA_WIDTH   ( AXI4_WDATA_WIDTH ),
        .USER_WIDTH   ( AXI4_USER_WIDTH  ),
        .BUFFER_DEPTH ( BUFF_DEPTH_SLAVE )
    ) slave_w_buffer_i (
         .clk_i          ( ACLK      ),
         .rst_ni         ( ARESETn   ),
         .test_en_i      ( test_en_i ),
         .slave_valid_i  ( WVALID_i  ),
         .slave_data_i   ( WDATA_i   ),
         .slave_strb_i   ( WSTRB_i   ),
         .slave_user_i   ( WUSER_i   ),
         .slave_last_i   ( WLAST_i   ),
         .slave_ready_o  ( WREADY_o  ),
         .master_valid_o ( WVALID    ),
         .master_data_o  ( WDATA     ),
         .master_strb_o  ( WSTRB     ),
         .master_user_o  ( WUSER     ),
         .master_last_o  ( WLAST     ),
         .master_ready_i ( WREADY    )
    );
    axi_r_buffer #(
         .ID_WIDTH     ( AXI4_ID_WIDTH    ),
         .DATA_WIDTH   ( AXI4_RDATA_WIDTH ),
         .USER_WIDTH   ( AXI4_USER_WIDTH  ),
         .BUFFER_DEPTH ( BUFF_DEPTH_SLAVE )
    ) slave_r_buffer_i (
         .clk_i          ( ACLK       ),
         .rst_ni         ( ARESETn    ),
         .test_en_i      ( test_en_i  ),
         .slave_valid_i  ( RVALID     ),
         .slave_data_i   ( RDATA      ),
         .slave_resp_i   ( RRESP      ),
         .slave_user_i   ( RUSER      ),
         .slave_id_i     ( RID        ),
         .slave_last_i   ( RLAST      ),
         .slave_ready_o  ( RREADY     ),
         .master_valid_o ( RVALID_o   ),
         .master_data_o  ( RDATA_o    ),
         .master_resp_o  ( RRESP_o    ),
         .master_user_o  ( RUSER_o    ),
         .master_id_o    ( RID_o      ),
         .master_last_o  ( RLAST_o    ),
         .master_ready_i ( RREADY_i   )
    );

    axi_b_buffer #(
        .ID_WIDTH       ( AXI4_ID_WIDTH    ),
        .USER_WIDTH     ( AXI4_USER_WIDTH  ),
        .BUFFER_DEPTH   ( BUFF_DEPTH_SLAVE )
    ) slave_b_buffer_i (
        .clk_i          ( ACLK      ),
        .rst_ni         ( ARESETn   ),
        .test_en_i      ( test_en_i ),

        .slave_valid_i  ( BVALID    ),
        .slave_resp_i   ( BRESP     ),
        .slave_id_i     ( BID       ),
        .slave_user_i   ( BUSER     ),
        .slave_ready_o  ( BREADY    ),

        .master_valid_o ( BVALID_o  ),
        .master_resp_o  ( BRESP_o   ),
        .master_id_o    ( BID_o     ),
        .master_user_o  ( BUSER_o   ),
        .master_ready_i ( BREADY_i  )
    );

    always_comb begin
        read_req   = 1'b0;
        write_req  = 1'b0;
        W_word_sel = 1'b0;

        sample_AW  = 1'b0;
        decr_AWLEN = 1'b0;
        sample_AR  = 1'b0;
        decr_ARLEN = 1'b0;

        incr_AWADDR = 1'b0;
        incr_ARADDR = 1'b0;

        sample_RDATA_0 = 1'b0;
        sample_RDATA_1 = 1'b0;

        ARREADY = 1'b0;
        AWREADY = 1'b0;
        WREADY  = 1'b0;
        RDATA   = '0;

        BVALID = 1'b0;
        BRESP  = `OKAY;
        BID    = AWID;
        BUSER  = AWUSER;

        RVALID = 1'b0;
        RLAST  = 1'b0;
        RID    = ARID;
        RUSER  = ARUSER;
        RRESP  = `OKAY;

        case(CS)

            WAIT_R_PREADY: begin
                sample_AR = 1'b0;
                read_req  = 1'b1;
                address   = ARADDR;

                if (PREADY == 1'b1) begin
                    if (ARLEN == 0) begin
                        case (ARSIZE)
                            3'h3: begin
                                NS = SINGLE_RD_64;
                                if (ARADDR[2:0] == 3'h4)
                                    sample_RDATA_1 = 1'b1;
                                else  sample_RDATA_0 = 1'b1;
                            end

                            default: begin
                                NS = SINGLE_RD;
                                if (ARADDR[2:0] == 3'h4)
                                    sample_RDATA_1 = 1'b1;
                                else
                                    sample_RDATA_0 = 1'b1;
                                end
                            endcase
                    end else begin
                       NS             = BURST_RD_64;
                       sample_RDATA_0 = 1'b1;
                       decr_ARLEN     = 1'b1;
                       incr_ARADDR    = 1'b1;
                    end
                end else begin
                    NS = WAIT_R_PREADY;
                end
            end

            WAIT_W_PREADY: begin
                address   = AWADDR;
                write_req = 1'b1;

                if (AWADDR[2:0] == 3'h4)
                    W_word_sel = 1'b1;
                else
                    W_word_sel = 1'b0;


                if (PREADY == 1'b1) begin
                    if (AWLEN == 0) begin
                        case (AWSIZE)
                            3'h3: NS = SINGLE_WR_64;
                            default: NS = SINGLE_WR;
                        endcase
                    end else begin
                        sample_AW = 1'b1;
                        NS        = BURST_WR_64;
                    end
                end else begin
                    NS = WAIT_W_PREADY;
                end
            end

            IDLE: begin
                if (ARVALID == 1'b1)  begin
                    sample_AR = 1'b1;
                    read_req  = 1'b1;
                    address   = ARADDR;

                    if (PREADY == 1'b1) begin
                        if (ARLEN == 0) begin
                            case (ARSIZE)
                                3'h3: begin
                                    NS = SINGLE_RD_64;
                                    if (ARADDR[2:0] == 4)
                                        sample_RDATA_1 = 1'b1;
                                    else
                                        sample_RDATA_0 = 1'b1;
                                end
                                default: begin
                                    NS = SINGLE_RD;
                                    if (ARADDR[2:0] == 4)
                                        sample_RDATA_1 = 1'b1;
                                    else
                                        sample_RDATA_0 = 1'b1;
                                    end
                            endcase end else begin
                            NS             = BURST_RD_64;
                            sample_RDATA_0 = 1'b1;
                        end
                    end else begin
                        NS = WAIT_R_PREADY;
                    end
                end else begin

                    if (AWVALID) begin
                        if (WVALID) begin
                            write_req = 1'b1;
                            address   = AWADDR;

                            if (AWADDR[2:0] == 3'h4)
                                W_word_sel = 1'b1;
                            else
                                W_word_sel = 1'b0;


                            if (PREADY == 1'b1) begin
                                  if(AWLEN == 0) begin
                                        case(AWSIZE)
                                            3'h3: NS = SINGLE_WR_64;
                                            default: NS = SINGLE_WR;
                                        endcase
                                  end else begin
                                        sample_AW   = 1'b1;
                                        if ((AWADDR[2:0] == 3'h4) && (WSTRB[7:4] == 0))
                                          incr_AWADDR = 1'b0;
                                        else
                                          incr_AWADDR = 1'b1;
                                        NS = BURST_WR_64;
                                  end
                            end else begin
                                NS = WAIT_W_PREADY;
                            end
                        end else begin
                            write_req = 1'b0;
                            address   = '0;
                            NS        = IDLE;
                        end
                    end else begin
                        NS = IDLE;
                        address =  '0;
                    end
                end
            end

            SINGLE_WR_64: begin
                address    = AWADDR + 4;
                W_word_sel = 1'b1;
                write_req  = WVALID;
                if (WVALID) begin
                    if (PREADY == 1'b1)
                        NS = SINGLE_WR;
                    else
                        NS = SINGLE_WR_64;
                end else begin
                    NS = SINGLE_WR_64;
                end
            end

            SINGLE_WR:  begin
                BVALID   = 1'b1;
                address  = '0;
                if (BREADY)  begin
                    NS      = IDLE;
                    AWREADY = 1'b1;
                    WREADY  = 1'b1;
                end else begin
                    NS = SINGLE_WR;
                end
            end

            BURST_WR_64: begin
                W_word_sel = 1'b1;
                write_req  = WVALID & (|WSTRB[7:4]);
                address    = AWADDR_Q;

                if (WVALID) begin
                    if (&WSTRB[7:4]) begin
                        if(PREADY == 1'b1) begin
                            NS          = BURST_WR;
                            WREADY      = 1'b1;
                            decr_AWLEN  = 1'b1;
                            incr_AWADDR = 1'b1;
                        end else begin
                            NS = BURST_WR_64;
                        end
                    end else begin
                        NS = BURST_WR;
                        WREADY      = 1'b1;
                        decr_AWLEN  = 1'b1;
                        incr_AWADDR = 1'b1;
                    end
                end else begin
                    NS = BURST_WR_64;
                end
            end

            BURST_WR: begin
                address = AWADDR_Q;
                if (AWLEN_Q == 0) begin
                    BVALID = 1'b1;
                    if (BREADY) begin
                      NS      = IDLE;
                      AWREADY = 1'b1;
                    end else
                      NS = BURST_WR;
                end else begin
                    W_word_sel = 1'b0;
                    write_req  = WVALID & (&WSTRB[3:0]);
                    if (WVALID) begin
                        if (PREADY == 1'b1) begin
                            NS          = BURST_WR_64;
                            incr_AWADDR = 1'b1;
                            decr_AWLEN  = 1'b1;
                          end else
                            NS = BURST_WR;
                    end else begin
                        NS = BURST_WR_64;
                    end
              end
            end

            BURST_RD_64: begin
               read_req = 1'b1;
               address  = ARADDR_Q;

                if (ARLEN_Q == 0) begin
                    NS      = IDLE;
                    ARREADY = 1'b1;
                end else begin
                    if (PREADY == 1'b1) begin
                        decr_ARLEN     = 1'b1;
                        sample_RDATA_1 = 1'b1;
                        NS = BURST_RD;

                        if (ARADDR_Q[2:0] == 3'h4)
                          incr_ARADDR = 1'b1;
                        else
                          incr_ARADDR = 1'b0;
                      end
                    else  begin
                        NS = BURST_RD_64;
                    end
                 end
            end

            BURST_RD: begin
                RVALID   = 1'b1;
                RDATA[0] = RDATA_Q_0;
                RDATA[1] = RDATA_Q_1;
                RLAST    = (ARLEN_Q == 0) ? 1'b1 : 1'b0;
                address  = ARADDR_Q;

                if (RREADY) begin
                    if (ARLEN_Q == 0) begin
                        NS      = IDLE;
                        ARREADY = 1'b1;
                    end else begin
                        read_req = 1'b1;
                        if (PREADY == 1'b1) begin
                            sample_RDATA_0 = 1'b1;
                            NS             = BURST_RD_64;
                            incr_ARADDR    = 1'b1;
                            decr_ARLEN     = 1'b1;
                        end else begin
                            NS = BURST_RD_1;
                        end
                    end
                end else begin
                    NS = BURST_RD;
                end
            end

            BURST_RD_1: begin
                read_req = 1'b1;
                address  = ARADDR_Q;

                if (PREADY == 1'b1) begin
                    sample_RDATA_0 = 1'b1;
                    NS             = BURST_RD_64;
                    incr_ARADDR    = 1'b1;
                    decr_ARLEN     = 1'b1;
                end else begin
                    NS = BURST_RD_1;
                end
            end

            SINGLE_RD: begin
                RVALID   = 1'b1;
                RDATA[0] = RDATA_Q_0;
                RDATA[1] = RDATA_Q_1;
                RLAST    = 1;
                address  = '0;

                if (RREADY) begin
                    NS      = IDLE;
                    ARREADY = 1'b1;
                end else begin
                    NS = SINGLE_RD;
                end
            end

            SINGLE_RD_64: begin
                read_req       = 1'b1;
                address        = ARADDR + 4;
                if (PREADY == 1'b1) begin
                    NS = SINGLE_RD;
                    if(ARADDR[2:0] == 3'h4)
                        sample_RDATA_0 = 1'b1;
                    else
                        sample_RDATA_1 = 1'b1;
                end else begin
                  NS = SINGLE_RD_64;
                end
            end

            default: begin
                NS      = IDLE;
                address = '0;
            end
        endcase
    end




    always_ff @(posedge ACLK, negedge ARESETn) begin
        if (ARESETn == 1'b0) begin
            CS        <= IDLE;

            ARLEN_Q   <= '0;
            AWADDR_Q  <= '0;

            AWLEN_Q   <= '0;
            RDATA_Q_0 <= '0;
            RDATA_Q_1 <= '0;
            ARADDR_Q  <= '0;
        end else  begin
            CS <= NS;

            if (sample_AR) begin
                ARLEN_Q <= {ARLEN,1'b0} + 2;
            end else if (decr_ARLEN) begin
                ARLEN_Q <= ARLEN_Q - 1;
            end

            if (sample_RDATA_0)
                RDATA_Q_0 <= PRDATA;

            if (sample_RDATA_1)
                RDATA_Q_1 <= PRDATA;

            case ({sample_AW, decr_AWLEN})
                2'b00: AWLEN_Q <= AWLEN_Q;
                2'b01: AWLEN_Q <= AWLEN_Q - 1;
                2'b10: AWLEN_Q <= {AWLEN, 1'b0} + 1;
                2'b11: AWLEN_Q <= {AWLEN, 1'b0};
            endcase

            case ({sample_AW, incr_AWADDR})
                2'b00: AWADDR_Q <= AWADDR_Q;
                2'b01: AWADDR_Q <= AWADDR_Q + 4;
                2'b10: AWADDR_Q <= {AWADDR[AXI4_ADDRESS_WIDTH-1:3], 3'b000};
                2'b11: AWADDR_Q <= {AWADDR[AXI4_ADDRESS_WIDTH-1:3], 3'b000} + 4;
            endcase

            case({sample_AR, incr_ARADDR})
                2'b00: ARADDR_Q <= ARADDR_Q;
                2'b01: ARADDR_Q <= ARADDR_Q + 4;
                2'b10: ARADDR_Q <= {ARADDR[AXI4_ADDRESS_WIDTH-1:3], 3'b000};
                2'b11: ARADDR_Q <= {ARADDR[AXI4_ADDRESS_WIDTH-1:3], 3'b000} + 4;
            endcase
        end
    end
endmodule