module tb_axi_slv;
    reg           clk;
    reg           rst_n;

    reg           axi_s_awvalid;
    reg   [7:0]   axi_s_awlen;
    reg   [25:0]  axi_s_awaddr;
    wire          axi_s_awready;

    reg           axi_s_wvalid;
    reg           axi_s_wlast;
    reg   [63:0]  axi_s_wdata;
    wire          axi_s_wready;

    reg           axi_s_arvalid;
    reg   [7:0]   axi_s_arlen;
    reg   [25:0]  axi_s_araddr;
    wire          axi_s_arready;

    wire          axi_s_rvalid;
    wire          axi_s_rlast;
    wire  [63:0]  axi_s_rdata;

    wire          axi2array_frame_valid;
    wire  [152:0] axi2array_frame_data;
    reg           axi2array_frame_ready;

    reg           array2axi_rdata_valid;
    reg   [127:0] array2axi_rdata;

    reg   [1:0]   axi_bus_rw_priority;
    reg           mc_work_en;

axi_slv u_axi_slv(
	.clk            (clk),
    .rst_n          (rst_n),

    .axi_s_awvalid  (axi_s_awvalid),
    .axi_s_awlen    (axi_s_awlen),
    .axi_s_awaddr   (axi_s_awaddr),
    .axi_s_awready  (axi_s_awready),

    .axi_s_wvalid   (axi_s_wvalid),
    .axi_s_wlast    (axi_s_wlast),
    .axi_s_wdata    (axi_s_wdata),
    .axi_s_wready   (axi_s_wready),

    .axi_s_arvalid  (axi_s_arvalid),
    .axi_s_arlen    (axi_s_arlen),
    .axi_s_araddr   (axi_s_araddr),
    .axi_s_arready  (axi_s_arready),

    .axi_s_rvalid   (axi_s_rvalid),
    .axi_s_rlast    (axi_s_rlast),
    .axi_s_rdata    (axi_s_rdata),

    .axi2array_frame_valid  (axi2array_frame_valid),
    .axi2array_frame_data   (axi2array_frame_data),
    .axi2array_frame_ready  (axi2array_frame_ready),

    .array2axi_rdata_valid  (array2axi_rdata_valid),
    .array2axi_rdata        (array2axi_rdata),

    .axi_bus_rw_priority    (axi_bus_rw_priority),
    .mc_work_en             (mc_work_en)
);
    
    task aw;
        input [7:0]     awlen;
        input [25:0]    awaddr;
    begin
        @(posedge clk)  begin
            axi_s_awvalid <= 1'b1;
            axi_s_awaddr  <= awaddr;
            axi_s_awlen   <= awlen;
        end
        #1;
        wait(axi_s_awready);
        @(posedge clk)  begin
            axi_s_awvalid <= 1'b0;
        end
    end
    endtask

    task w;
        input [63:0]    wdata;
        input           wlast;
    begin
        @(posedge clk)  begin
            axi_s_wvalid  <= 1'b1;
            axi_s_wdata   <= wdata;
            axi_s_wlast   <= wlast;
        end
        #0.1;
        wait(axi_s_wready);
        @(posedge clk)  begin
            axi_s_wvalid <= 1'b0;
        end
    end
    endtask

    task ar;
        input [25:0]    araddr;
        input [7:0]     arlen;
    begin
        @(posedge clk)  begin
            axi_s_arvalid <= 1'b1;
            axi_s_araddr  <= araddr;
            axi_s_arlen   <= arlen;
        end
        #1;
        wait(axi_s_arready);
        @(posedge clk)  begin
            axi_s_arvalid <= 1'b0;
        end
    end
    endtask

    task arrayrdata;
        input [127:0]   rdata;
    begin
        @(posedge clk)  begin
            array2axi_rdata_valid <= 1'b1;
            array2axi_rdata <= rdata;
        end
        @(posedge clk)  begin
            array2axi_rdata_valid <= 1'b0;
        end
    end 
    endtask

    initial begin
        clk = 0;
        forever begin
            #1.25 clk = ~clk;
        end
    end

    initial begin
        rst_n = 'd0;
        axi_s_awvalid = 'd0;
        axi_s_awlen ='d0;
        axi_s_awaddr ='d0;

        axi_s_wvalid = 'd0;
        axi_s_wdata = 'd0;
        axi_s_wlast = 'd0;
        axi_s_arvalid = 'd0;
        axi_s_araddr = 'd0;
        axi_s_arlen = 'd0;
        
        array2axi_rdata ='d0;
        array2axi_rdata_valid = 'd0;
        axi2array_frame_ready = 1'd1;
        mc_work_en = 1'b1;
        axi_bus_rw_priority = 2'b10;
        @(posedge clk) begin
            rst_n = 1'b1;
        end
        aw(8'd5,{16'h0,6'h3f,4'h0});
        w(64'd1,0);
        w(64'd2,0);
        w(64'd3,0);
        w(64'd4,0);
        w(64'd5,0);
        w(64'd6,1);
        @(posedge clk) begin
            axi_s_wvalid <= 1'b0;
        end
        ar({16'h1,6'h3f,4'h0},8'd9);
        @(posedge clk);
        @(posedge clk);
        @(posedge clk);
        @(posedge clk);
        @(posedge clk);
        @(posedge clk);
        @(posedge clk);
        @(posedge clk);
        @(posedge clk);
        @(posedge clk);
        arrayrdata({64'h2,64'h1});
        arrayrdata({64'h4,64'h3});
        arrayrdata({64'h6,64'h5});
        arrayrdata({64'h8,64'h7});
        arrayrdata({64'ha,64'h9});
        #15;
        $finish;
    end

    initial begin
        $fsdbDumpfile("tb.fsdb");
        $fsdbDumpvars(0,tb_axi_slv,"+all");
        $vcdpluson;
        $vcdplusmemon;
    end

endmodule
