Vengineerの妄想(準備期間)

人生は短いけど、長いです。人生を楽しみましょう!

Xilinx ZynqMP SoC VIP の中を調べる(その10)

はじめに

Xilinx ZynqMP SoC VIP の中を調べる(その10)

今回は、c++言語側の関数 dpi_main について、説明します

dpi_main

dpi_main 関数は、test.cpp というファイルの中で次のように定義しています。

dpi.h は、DPI-Cの export task のプロトタイプが宣言されているファイルです。DPI-C export task である、vip_read32 は zynq_read で、vip_write32 は zynq_writeで、vip_nop は wait_clock で ラップして使っています。 DPI-Cは、C言語の関数として宣言する必要があるので、各関数のプロトタイプ宣言を extern "C"{ と } で囲っています。

dpi_main 関数の中では、zynq_write/zynq_read にて、GPIOの0xa0000000 にアクセスしています。そして、最後に wait_clock(10) を呼んで、10クロック待つようにしています。

注意、dpi_main 関数の戻り値は、int 型の 0 です。何故? 戻り値が int 型なのは理由がありますが、ここでは説明しません。必要なら、SystemVerilogの仕様書を呼んで確認してください。または、このブログに最後に関連ブログを覗いてみてください。

#include <stdio.h>

#include "dpi.h"

unsigned int zynq_read(unsigned int addr) {
    unsigned int data;
    vip_read32(addr, &data);
    return data;
}

void zynq_write(unsigned int addr, unsigned int data) {
    vip_write32(addr, data);
}

void wait_clock(int count) {
    vip_nop(count);
}

extern "C" {

int dpi_main() {

  unsigned int addr, data, exp;

  printf("dpi_main : start\n");
  addr = 0xa0000000;
  data = 0xffffffff;
  exp = 0xf000000f;

  wait_clock(10);

  zynq_write(addr, data);
  data = zynq_read(addr);

  if(data != exp) {
    printf("<<ERR>> : unmatched DATA(0x%x) != EXP(0x%x)\n", data, exp);
  }


  wait_clock(10);

  printf("dpi_main : finish\n");
  return 0;
}

}

おわりに

今回は、C側の dpi_main 関数の中をみてみました。

次回は、C側のテストプログラムをどのように呼べばいいのかを説明します。

関連ブログ

vengineer.hatenablog.com