LoginSignup
1
0

More than 1 year has passed since last update.

2021-12-27 「PYNQ を使って Python で手軽に FPGA を活用 (5)」をXSDK実装

Posted at

動作環境

  • Windows 10 Pro (v21H2)
  • Vivado v2019.1
  • FPGA基板: CORA Z7 Zynq-7000評価ボード(Z7-07S)

概要

PYNQ を使って Python で手軽に FPGA を活用 (5)
https://www.acri.c.titech.ac.jp/wordpress/archives/36

こちらで紹介されているものはPYNQで動作するように作られている。PYNQ動作だと特定のFPGA基板でしか動かないため、XSDK実装をしてみた (XSDKの実装勉強も兼ねて)。

Block Design

記事に従って作成した。

image.png (124.5 kB)

Address Editor

image.png (12.5 kB)

XSDK実装

記事のPYNQ用実装を参考にXSDK実装を作成した。
system.mssから作成可能なxbram_example.cxgpio_example.cも参考にした。

helloworld.c
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xbram.h"
#include "xgpio.h"


XBram Bram; // Bramドライバのインスタンス
#define BRAM_DEVICE_0_ID        (XPAR_AXI_BRAM_CTRL_0_DEVICE_ID)
#define BRAM_DEVICE_1_ID        (XPAR_AXI_BRAM_CTRL_1_DEVICE_ID)

#define GPIO_DEVICE_ID (XPAR_GPIO_0_DEVICE_ID)


/*
参考 :
1. xbram_example.c (system.mssのexampleから生成)
2. xgpio_example.c (system.mssのexampleから生成)
*/

#define NUM_LOOP (5) // Read/Write Valueのループ


int main()
{
    init_platform();

    XBram_Config *BramConfigPtr0;
    XBram_Config *BramConfigPtr1;
    XBram BramInst0; // インスタンス用
    XBram BramInst1; // インスタンス用
    XGpio_Config *GpioConfigPtr;
    XGpio GpioInst; // インスタンス用
    u32 data;
    int Status;
    printf("Hello 1145\r\n");


    // 1. Init ====================================

    BramConfigPtr0 = XBram_LookupConfig(BRAM_DEVICE_0_ID);
    if (BramConfigPtr0 == (XBram_Config *)NULL) {
        printf("BRAM0 Config error\r\n");
        return XST_FAILURE;
    }
    Status = XBram_CfgInitialize(&BramInst0, BramConfigPtr0, BramConfigPtr0->CtrlBaseAddress);
    if (Status != XST_SUCCESS) {
        printf("BRAM0 CfgInit error\r\n");
        return XST_FAILURE;
    }
    BramConfigPtr1 = XBram_LookupConfig(BRAM_DEVICE_1_ID);
    if (BramConfigPtr1 == (XBram_Config *)NULL) {
        printf("BRAM1 Config error\r\n");
        return XST_FAILURE;
    }
    Status = XBram_CfgInitialize(&BramInst1, BramConfigPtr1, BramConfigPtr1->CtrlBaseAddress);
    if (Status != XST_SUCCESS) {
        printf("BRAM1 CfgInit error\r\n");
        return XST_FAILURE;
    }
    printf("BRAM0,1 Init Pass\r\n");


    // 2. Read and Write BRAM ==========================

    for(int idx=0; idx < NUM_LOOP; idx++) {
        data = XBram_ReadReg(BramConfigPtr0->MemBaseAddress, 4*idx);
        printf("bram0 %d:%d\n", idx, (unsigned int)data);
    }
    for(int idx=0; idx < NUM_LOOP; idx++) {
        u32 wdata = idx + 20;
        XBram_WriteReg(BramConfigPtr0->MemBaseAddress, 4*idx, wdata);
        //printf("bram0 %d:%d\n", idx, data);
    }
    for(int idx=0; idx < NUM_LOOP; idx++) {
        data = XBram_ReadReg(BramConfigPtr0->MemBaseAddress, 4*idx);
        printf("bram0 %d:%d\n", idx, (unsigned int)data);
    }
    printf("<= not yet copied =>\r\n");
    for(int idx=0; idx < NUM_LOOP; idx++) {
        data = XBram_ReadReg(BramConfigPtr1->MemBaseAddress, 4*idx);
        printf("bram1 %d:%d\n", idx, (unsigned int)data);
    }


    // 3. GPIOによるCtrl制御 ==========================

    GpioConfigPtr = XGpio_LookupConfig(GPIO_DEVICE_ID);
    if (GpioConfigPtr == (XGpio_Config *)NULL) {
        printf("GPIO Config error\r\n");
        return XST_FAILURE;
    }
    Status = XGpio_CfgInitialize(&GpioInst, GpioConfigPtr, XPAR_AXI_GPIO_0_BASEADDR);
    if (Status != XST_SUCCESS) {
        printf("GPIO CfgInit error\r\n");
        return XST_FAILURE;
    }
    printf("GPIO Init Pass\r\n");

    XGpio_WriteReg(XPAR_AXI_GPIO_0_BASEADDR, 4, 0); // AXI GPIO経由でCTRLに書き込む準備
    XGpio_WriteReg(XPAR_AXI_GPIO_0_BASEADDR, 0, 1); // AXI GPIO経由でCTRLに書き込む

    XGpio_WriteReg(XPAR_AXI_GPIO_0_BASEADDR, 4, 0xFFFFFFFF); // AXI GPIO経由でステータスを読み込む準備
    for(int idx=0; idx < NUM_LOOP; idx++) {
        data = XGpio_ReadReg(XPAR_AXI_GPIO_0_BASEADDR, 0);
    }
    printf("<= copied =>\r\n");
    for(int idx=0; idx < NUM_LOOP; idx++) {
        data = XBram_ReadReg(BramConfigPtr1->MemBaseAddress, 4*idx);
        printf("bram1 %d:%d\n", idx, (unsigned int)data);
    }


    // 4. Cleanup ==========================

    cleanup_platform();
    return 0;
}

動作確認

image.png (12.9 kB)

Bram0に書き込んだ値がBram1に書き込まれることを確認できた。

この動作は「Program FPGA」をした直後だけ動作する。
helloworld.cにて書き込みする値を変更して二回目の実装をした場合は値は変わらない 。
(bram_copy.vとの関係もあるのだろう。現在はそれは重要でないため詳細は追わない。)

関連

情報感謝です。

その他

前準備

この記事は以下の実装をためそうとしている前段階として実施したもの。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0