FC2カウンター FPGAの部屋 Vivado シミュレータでDPI-C を使用してZynq VIPを使う1

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

Vivado シミュレータでDPI-C を使用してZynq VIPを使う1

Vivado シミュレータのDPI-C その1”と”Vivado シミュレータのDPI-C その2”でVivado シミュレータでDPI-C を実行する方法をXilinx者のサンプルで見てきた。
それでは、Zynq VIP を使用するときにDPI-C を使用することができるかどうか?をやってみた。

今回使用するのは、”Vivado 2017.1 の新機能8(Zynq-7000 VIP)”で使用したBase Zynq サンプル・プロジェクトだ。

最初に使用したのはVirtualBox 上のUbuntu 16.04 にインストールしたVivado 2017.2 だ。
さて、Vivado 2017.2 でサンプル・プロジェクトをオープンして、Templates からBase Zynq を選択して、プロジェクトを生成する。
DPI_examples_12_170813.png

一度、Flow Navigator からSIMULATION -> Run Simulation -> Run Behavioral Simulation を選択して、論理シミュレーションを行っておく。
DPI_examples_13_170813.png

その時に、Scope の tb -> zynq_sys -> base_zynq_i を右クリックし、Add to Wave Window を選択して、wave window にAXI バスの信号線を追加しておこう。そして、wave window の tb_behav.wcfg をセーブしておく。

~/Vivado/zynq_base_ex_172/zynq_base_ex_172.sim/sim_1/behav を見た。
DPI_examples_14_170813.png

シミュレーション用のファイルがいろいろと生成されていた。
ここに zynq_dpi.c を追加した。
DPI_examples_15_170813.png

zynq_dpi.c を示す。

// zynq_dpi.c
// 2017/08/12 by marsee
//

#include "svdpi.h"

#define AXI_TRANS_CS_LIMIT 10
#define READ_STATE    1

const struct axi_trans_scenario {
    int r_w;
    int delay;
    int addr;
    int trans_bytes;
    int    data;
} axi_trans_sc[AXI_TRANS_CS_LIMIT] =
    {{000x4120000040xFFFFFFFF},
    {000x4000000040xDEADBEEF},
    {100x4000000040}, {00000}, {00000}, {00000}, 
    {00000}, {00000}, {00000}, {00000}};

static int i=0;
                
int write_axit(int * const delay, int * const addr, 
    int * const trans_bytes, int * const data){
    int r_w;
    
    r_w = axi_trans_sc[i].r_w;
    *delay = axi_trans_sc[i].delay;
    *addr = axi_trans_sc[i].addr;
    *trans_bytes = axi_trans_sc[i].trans_bytes;
    *data = axi_trans_sc[i].data;
    
    if(axi_trans_sc[i].trans_bytes != 0 && i<AXI_TRANS_CS_LIMIT){
        if(r_w == 0){
            i++;
            return(0);
        }else
            return(1);
    }else
        return(2);
}

int read_axit(int * const delay, int * const addr, 
    int * const trans_bytes){
    int r_w;
    
    r_w = axi_trans_sc[i].r_w;
    *delay = axi_trans_sc[i].delay;
    *addr = axi_trans_sc[i].addr;
    *trans_bytes = axi_trans_sc[i].trans_bytes;
    
    if(axi_trans_sc[i].trans_bytes != 0 && i<AXI_TRANS_CS_LIMIT){
        if(r_w == 1){
            i++;
            return(0);
        }else
            return(1);
    }else
        return(2);
}


ソースコードを見てお分かりの様に、zynq_dpi.c はアドレスや書き込みデータをSV テストベンチに渡す。

次に、~/Vivado/zynq_base_ex_172/zynq_base_ex_172.srcs/sim_1/imports/base_zynq ディレクトリに行くと、zynq_tb.v がある。それをコピー&ペーストして、zynq_tb_sv に名前を変更した。
zynq_tb_sv にコードを追加した。なお、zynq_tb_v はXilinx 社のコードなので、一部を貼っておくだけとする。
まずはwire や reg の宣言部分にDPI-C の宣言を記述して、DPI-C で使用する変数を宣言した。
DPI_examples_35_170813.png

    integer delay, trans_bytes, addr;
    integer    data;
    
    integer i;
    
    import "DPI-C" function int write_axit(
        output int delay,
        output int addr,
        output int trans_bytes,
        output int data);

    import "DPI-C" function int read_axit(
        output int delay,
        output int addr,
        output int trans_bytes);


write_axit() と read_axit() を使用するようにSystemVerilog ファイルを変更した。task も使用していないが実証コードということで。。。
DPI_examples_36_170813.png

        //This drives the LEDs on the GPIO output
        if(write_axit(delay, addr, trans_bytes, data) == 0) begin
            for(i=0; i<delay; i++) begin
                #1;
            end
            tb.zynq_sys.base_zynq_i.processing_system7_0.inst.write_data(addr,trans_bytes, data, resp);
        end
        $display ("LEDs are toggled, observe the waveform");
        
        //Write into the BRAM through GP0 and read back
        if(write_axit(delay, addr, trans_bytes, data) == 0) begin
            for(i=0; i<delay; i++) begin
                #1;
            end
            tb.zynq_sys.base_zynq_i.processing_system7_0.inst.write_data(addr,trans_bytes, data, resp);
        end

        if(read_axit(delay, addr, trans_bytes) == 0) begin
            for(i=0; i<delay; i++) begin
                #1;
            end
            tb.zynq_sys.base_zynq_i.processing_system7_0.inst.read_data(addr, trans_bytes, read_data, resp);
        end


Vivado シミュレータでDPI-C を使用してZynq VIPを使う2”に続く。
  1. 2017年08月14日 04:48 |
  2. シミュレーション
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
http://marsee101.blog19.fc2.com/tb.php/3883-29d906d9
この記事にトラックバックする(FC2ブログユーザー)