社員ブログ一覧

Xilinx AXI Verification IP (VIP) の Study

作成者:mou-mou

AXI Bus Functional Model (BFM)がXilinx社より提供されていましたが有償だったので使用していませんでしたが、最近調べてみるとAXI Verification IP (VIP)というものがVivado環境で無償提供されていましたので、少し雰囲気をつかむ為に動かしてみました。機能としては充実しているようで、使いこなすのには少し大変かもしれませんが、基本的なところの動きを見るまでなら非常に簡単に出来ました。ここでは、実際に動かしてみた手順などを紹介いたします。

VIVADOを起動しして、新規プロジェクトを作ります。

プロジェクト名は「AXI_VIP」としました。

AXI_VIPのブロックデザインを生成します。

BRAM ControllerのIPを置きます。

インターフェースを2から1に変更します。

自動配線を実行すると、BRAMが配置されます。

AXI Verification IPを置きます。

今回は、テスト用のAXI Master をおいて、AXI-BRAMのRead/Writeをおこなうので、MODEをMASTERにします。

aclk, aresetn, AXIを接続します。また、aclk, aresetn, rsta_busyのポートを生成します。

Address EditorでBRAMのAXIアドレスを割り付けます。

Address Mapを確認します。

Block Designのラッパーを生成します。

simの下にテストベンチファイルを作ります。

テストベンチ名は、AXI_VIP_TBとします。AXI VIPを使用する為にFile typeはSystem Verilogとします。

テストベンチファイルAXI_VIP_TB.svにコードを記述します。

import axi_vip_pkg::*;
import AXI_VIP_axi_vip_0_0_pkg::*;

module TB_AXI_VIP();

    localparam CLK_PERIOD = 100;
    localparam RST_PERIOD = 20;
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/05/12 17:39:17
// Design Name: 
// Module Name: AXI_VIP_TB
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
import axi_vip_pkg::*;
import AXI_VIP_axi_vip_0_0_pkg::*;

module TB_AXI_VIP();

    localparam CLK_PERIOD = 100;
    localparam RST_PERIOD = 20;

    logic aresetn = '0;
    logic aclk = '0;
    logic rsta_busy;

    AXI_VIP_wrapper dut(.*);

    initial begin
        #(RST_PERIOD);
        aresetn = '1;
    end

    always #(CLK_PERIOD/2)  aclk = ~aclk;

    task clk_dly(int n);
        repeat(n)   @(posedge aclk);
    endtask

    // VIP decreation
    AXI_VIP_axi_vip_0_0_mst_t   agent;

    task init_agent();
        agent = new("master vip agent", dut.AXI_VIP_i.axi_vip_0.inst.IF);
        agent.start_master();
    endtask

    task wr_tran();
        axi_transaction  wr_transaction;
        wr_transaction   = agent.wr_driver.create_transaction("write transaction");

        wr_transaction.set_write_cmd(32'h00000000, XIL_AXI_BURST_TYPE_INCR, 0, 0, xil_axi_size_t'(xil_clog2((32)/8)));
        wr_transaction.set_data_block(32'd1);
        agent.wr_driver.send(wr_transaction);

        wr_transaction.set_write_cmd(32'h00000004, XIL_AXI_BURST_TYPE_INCR, 0, 0, xil_axi_size_t'(xil_clog2((32)/8)));
        wr_transaction.set_data_block(32'd2);
        agent.wr_driver.send(wr_transaction);

        wr_transaction.set_write_cmd(32'h00000008, XIL_AXI_BURST_TYPE_INCR, 0, 0, xil_axi_size_t'(xil_clog2((32)/8)));
        wr_transaction.set_data_block(32'd3);
        agent.wr_driver.send(wr_transaction);

        wr_transaction.set_write_cmd(32'h0000000C, XIL_AXI_BURST_TYPE_INCR, 0, 0, xil_axi_size_t'(xil_clog2((32)/8)));
        wr_transaction.set_data_block(32'd4);
        agent.wr_driver.send(wr_transaction);

        wr_transaction.set_write_cmd(32'h00000010, XIL_AXI_BURST_TYPE_INCR, 0, 0, xil_axi_size_t'(xil_clog2((32)/8)));
        wr_transaction.set_data_block(32'd5);
        agent.wr_driver.send(wr_transaction);

        wr_transaction.set_write_cmd(32'h00000014, XIL_AXI_BURST_TYPE_INCR, 0, 0, xil_axi_size_t'(xil_clog2((32)/8)));
        wr_transaction.set_data_block(32'd6);
        agent.wr_driver.send(wr_transaction);

        wr_transaction.set_write_cmd(32'h00000018, XIL_AXI_BURST_TYPE_INCR, 0, 4, xil_axi_size_t'(xil_clog2((32)/8)));
        wr_transaction.set_data_block({32'd10,32'd9,32'd8,32'd7});
        agent.wr_driver.send(wr_transaction);
    endtask

    task rd_tran();
        axi_transaction  rd_transaction;
        rd_transaction   = agent.rd_driver.create_transaction("read transaction");
        RD_TRANSACTION_FAIL_1a:assert(rd_transaction.randomize());
        agent.rd_driver.send(rd_transaction);

        rd_transaction.set_read_cmd(32'h00000000, XIL_AXI_BURST_TYPE_INCR, 0, 0, xil_axi_size_t'(xil_clog2((32)/8)));
        agent.rd_driver.send(rd_transaction);

        rd_transaction.set_read_cmd(32'h00000004, XIL_AXI_BURST_TYPE_INCR, 0, 0, xil_axi_size_t'(xil_clog2((32)/8)));
        agent.rd_driver.send(rd_transaction);

        rd_transaction.set_read_cmd(32'h00000008, XIL_AXI_BURST_TYPE_INCR, 0, 0, xil_axi_size_t'(xil_clog2((32)/8)));
        agent.rd_driver.send(rd_transaction);

        rd_transaction.set_read_cmd(32'h0000000C, XIL_AXI_BURST_TYPE_INCR, 0, 0, xil_axi_size_t'(xil_clog2((32)/8)));
        agent.rd_driver.send(rd_transaction);

        rd_transaction.set_read_cmd(32'h00000010, XIL_AXI_BURST_TYPE_INCR, 0, 0, xil_axi_size_t'(xil_clog2((32)/8)));
        agent.rd_driver.send(rd_transaction);

        rd_transaction.set_read_cmd(32'h00000014, XIL_AXI_BURST_TYPE_INCR, 0, 0, xil_axi_size_t'(xil_clog2((32)/8)));
        agent.rd_driver.send(rd_transaction);
        
        rd_transaction.set_read_cmd(32'h00000018, XIL_AXI_BURST_TYPE_INCR, 0, 4, xil_axi_size_t'(xil_clog2((32)/8)));
        agent.rd_driver.send(rd_transaction);
    endtask

    enum  { init_agent_st, wr_tran_st, rd_tran_st } state;

    initial begin
        state = init_agent_st;     init_agent();     clk_dly(200);
        state = wr_tran_st;        wr_tran();        clk_dly(200);
        state = rd_tran_st;        rd_tran();        clk_dly(200);

        $finish;
    end

endmodule

Synthesisを実行します。

Simulationを実行します。

シミュレーション結果です。

トラックバックURL

URL:https://rightxlight.co.jp/achievements/xilinx-axi-verification-ip/trackback/

よく読まれている記事はこちら

ソフトウェアからハードウェアまで、
まずはお気軽にご相談下さい。

お電話はこちら

お電話はこちら 06-6309-7782

受付時間:9:00~18:00(土日祝は除く)

メールフォームからはこちら

お問い合わせお問い合わせ

Copyright (C) Since 2011 RIGHTxLIGHT Co., Ltd. All Rights Reserved.

PAGE TOP