"undefined reference to `Xil_Out32'" vitisで発生したエラーの解決


目的(purpose)

vitisを扱っててビルドしたときに「undefined reference to `Xil_Out32'」というエラーが発生しました。
その原因と解決方法を探してみたのですが日本語の記事が見られなかったので今回まとめてみました。
(もしかして記事にするほど大したことないから記事になってないだけ?……いやそんなことないはず)


開発環境(Development environment)

OS:

  • Windows10 Home

ツール:

  • Vivado 2019.2
  • Vitis IDE
  • Tera Term
  • ZYBO Z7 (Zynq 7010)


ハードウェアの構成(Hardware configuration)

まず、ここで扱っているハードウェア部分の構成を載せます。

f:id:fetchkun:20200518185846p:plain

下のコードは自作IP(上図の赤丸で囲まれている部分)のコードです。


myip_v1_0_S00_AXI.v

`timescale 1 ns / 1 ps

	module myip_v1_0_S00_AXI #
	(
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                       省略
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	)
	(
		// Users to add ports here
		output wire OUT_SIGNAL,
		// User ports ends
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                      省略
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        );
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                     省略
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        // Add user logic here
	assign OUT_SIGNAL = slv_reg0[0];
	// User logic ends

	endmodule


myip_v1_0.v

`timescale 1 ns / 1 ps

	module myip_v1_0 #
	(
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                       省略
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	)
	(
		// Users to add ports here
		output wire out_signal,
		// User ports ends
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                      省略
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        );
       myip_v1_0_S00_AXI # ( 
		.C_S_AXI_DATA_WIDTH(C_S00_AXI_DATA_WIDTH),
		.C_S_AXI_ADDR_WIDTH(C_S00_AXI_ADDR_WIDTH)
	) myip_v1_0_S00_AXI_inst (
		.OUT_SIGNAL(out_signal),
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                          省略
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        );

	endmodule


解決方法(Solutions)

どうやらMYIP_mWriteRegで使われているXil_Out32xil_io.hの中で定義されているようです。
xil_io.hを認識していないため、undefined reference to `Xil_Out32'が発生したっぽい。
ちなみにMYIP_mWriteRegXPAR_MYIP_0_S00_AXI_BASEADDRMYIP_S00_AXI_SLV_REG0_OFFSETの名前は作成した際につけた名前によって変わるので以下のヘッダファイルで各自確認してください。

  • design_1_wrapper/hw/drivers/myip_v1_0/src/myip.h
  • design_1_wrapper/ps7_cortexa9_0/standalone_domain/bsp/ps7_cortexa9_0/include/xparameters.h


helloworld.c

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "myip.h"
#include "xparameters.h"
#include "sleep.h"
#include "xil_io.h"  // <= これを追加


int main()
{
    init_platform();

    print("Hello World\n\r");

    while(1) {
    	MYIP_mWriteReg(XPAR_MYIP_0_S00_AXI_BASEADDR, MYIP_S00_AXI_SLV_REG0_OFFSET, 1);
    	sleep(1);
    	MYIP_mWriteReg(XPAR_MYIP_0_S00_AXI_BASEADDR, MYIP_S00_AXI_SLV_REG0_OFFSET, 0);
    	sleep(1);
    }

    cleanup_platform();
    return 0;
}

これでビルドができるようになります。


最後に(Finally)

xil_io.hをincludeしなくてもビルドできるときもあります。
(というかMYIP_mWriteRegに使われているものまでメインのhelloworld.c内でインクルードしなければいけないのは不思議な感じがします。
なのでもしかしたら本来はxil_io.hをインクルードしなくてもビルドできるのが正常なのかも)
しかし、たまにこういったエラーが発生するので今回暫定処理としてまとめました。