MicroBlazeで実行時間を測定する方法

概要

MicroBlazeで命令の実行時間を測定する方法について考えました。
MicroBlazeではxtime_l.hが存在せず、sys/time.hのgettimeofday()が使えなかったため、
外部にAXI_Timer IPを入れることで実行時間を測定することにしました。

Vivadoプロジェクトの作成

全体図

ブロックデザインにMicroBlazeとAXI Timer、AXI UARTを入れました。
図にはAXI Interrupt Controllerが入っていますが、実際には必要ありませんでした。

AXI Timerの設定

AXI Timerの設定は32bitでTimer1のみを使う設定にしました。
クロックは100MHzを入れているので、42.9秒までは測れそうです。

SDKプロジェクトの作成

ソースコードは次のようにしました。
AXI Timerをフリーランニングした状態で、実行前と実行後にタイマの値を取得して実行時間を測定しています。

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xtmrctr.h"

XTmrCtr TimerCounterInst;

int init(){
	int Status;

	Status = XTmrCtr_Initialize(&TimerCounterInst, XPAR_AXI_TIMER_0_DEVICE_ID);
	if (Status != XST_SUCCESS) {
		printf("Timer Initialize Error\n\r");
        return XST_FAILURE;
	}

	XTmrCtr_SetOptions(&TimerCounterInst, 0, XTC_AUTO_RELOAD_OPTION);
	XTmrCtr_Start(&TimerCounterInst, 0);
}

int main()
{
    u32 tStart, tEnd;
    init_platform();

    init();

    tStart = XTmrCtr_GetValue(&TimerCounterInst, 0);
    print("Hello World\n\r");
    tEnd = XTmrCtr_GetValue(&TimerCounterInst, 0);

    printf("End - Start = %u\n\r", (unsigned int)(tEnd - tStart));
    printf("Time = %.2f us\n\r", 1.0 * (unsigned int)(tEnd - tStart) / 100000000 * 1000000);

    cleanup_platform();
    return 0;
}

実行結果

printfをした場合の結果

Hello World
End - Start = 1904
Time = 19.04 us

printfを外して、XTmrCtr_GetValueにかかる時間

End - Start = 201
Time = 2.01 us