FC2カウンター FPGAの部屋 2021年11月
fc2ブログ

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

FPGAの部屋

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

KV260 で ikwzm さんのデバイスツリー・オーバーレイをテストする4

KV260 で ikwzm さんのデバイスツリー・オーバーレイをテストする3”の続き。

KV260 に ikwzm さんの Debian 11 をインストールした”で MicroSD カードに ikwzm さんの Debian 11 をインストールしたので、”KV260 で ikwzm さんのデバイスツリー・オーバーレイをテストする1”からやり直す。

bin ファイルを作成しよう。
ここからは、パソコン側の作業だ。
DMA_pow2_test/vitis_work/DMA_pow2_test_wrapper/hw ディレクトリに DMA_pow2_warpper.bif を作成した。
DMA_pow2_warpper.bif を示す。

all:
{
    [destination_device = pl] DMA_pow2_test_wrapper.bit
}


bootgen で bin ファイルに変換する。
bootgen -image DMA_pow2_test_wrapper.bif -arch zynqmp -w -o DMA_pow2_test_wrapper.bin

DMA_pow2_test_wrapper.bin ファイルが生成された。

KV260 で”KV260 に ikwzm さんの Debian 11 をインストールした”で作成した MicroSD カードで Debian を KV260 上で起動する。
geany を立ち上げて、 fpga-load.dts を作成した。
fpga-load.dts を示す。

/dts-v1/;
/ {
    fragment@0 {
        target-path = "/fpga-full";
        __overlay__ {
            firmware-name = "DMA_pow2_test_wrapper.bin";
        };
    };
};


ホスト・パソコンで FileZilla を起動して、 KV260 の Debian にログインして、 DMA_pow2_test_wrapper.bin を SFTP で KV260 の Debian に転送した。

bin ファイルを /lib/firmware/ にコピーする。
sudo cp DMA_pow2_test_wrapper.bin /lib/firmware/

dtc で fpga-load.dts をコンパイルした。
dtc -I dts -O dtb -o fpga-load.dtb fpga-load.dts

fpgaをコンフィグレーションした。
sudo mkdir /config/device-tree/overlays/fpga
sudo cp fpga-load.dtb /config/device-tree/overlays/fpga/dtbo


シリアル・コンソールに

[ 1037.001374] fpga_manager fpga0: writing DMA_pow2_test_wrapper.bin to Xilinx ZynqMP FPGA Manager
[ 1037.150992] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /fpga-full/firmware-name


と表示された。

fclk0-zynqmp.dts を示す。

/dts-v1/;/plugin/;
/ {
    fragment@0 {
        target-path = "/axi";
        __overlay__ {
            fclk0 {
                compatible    = "ikwzm,fclkcfg-0.10.a";
                clocks        = <&zynqmp_clk 0x47>;
                insert-rate   = "100000000";
                insert-enable = <1>;
                remove-rate   = "1000000";
                remove-enable = <0>;
            };
        };
    };
};


fclk0-zynqmp.dts をコンパイルした。
dtc -I dts -O dtb -o fclk0-zynqmp.dtb fclk0-zynqmp.dts

fclk0-zynqmp.dtb をロードした。
sudo mkdir /config/device-tree/overlays/fclk0
sudo cp fclk0-zynqmp.dtb /config/device-tree/overlays/fclk0/dtbo


コンソールに

[ 1279.312711] fclkcfg axi:fclk0: driver version : 1.7.2
[ 1279.317768] fclkcfg axi:fclk0: device name    : axi:fclk0
[ 1279.323166] fclkcfg axi:fclk0: clock  name    : pl0_ref
[ 1279.328390] fclkcfg axi:fclk0: clock  rate    : 99999999
[ 1279.333721] fclkcfg axi:fclk0: clock  enabled : 1
[ 1279.338424] fclkcfg axi:fclk0: remove rate    : 1000000
[ 1279.343650] fclkcfg axi:fclk0: remove enable  : 0
[ 1279.348354] fclkcfg axi:fclk0: driver installed.


が表示された。

uio と udmabuf のロードを行う。
DMA_pow2_test.dts を示す。

/dts-v1/;/plugin/;
/ {
    fragment@0 {
        target-path = "/axi";
        #address-cells = <2>;
        #size-cells = <2>;

        __overlay__ {
            #address-cells = <2>;
            #size-cells = <2>;

            dma_pow2-uio {
                compatible = "generic-uio";
                reg = <0x0 0x00A0000000 0x0 0x10000>;
            };
            
            dma_read-uio {
                compatible = "generic-uio";
                reg = <0x0 0x00A0010000 0x0 0x10000>;
            };
            
            dma_write-uio {
                compatible = "generic-uio";
                reg = <0x0 0x00A0020000 0x0 0x10000>;
            };
            
            dma_pow2-udmabuf4 {
                compatible  = "ikwzm,u-dma-buf";
                device-name = "udmabuf4";
                size = <0x00010000>;
            };
        };
    };
};


dtc で DMA_pow2_test.dts をコンパイルして、dtb に変換してから、ロードした。
dtc -I dts -O dtb -o DMA_pow2_test.dtb DMA_pow2_test.dts
sudo mkdir /config/device-tree/overlays/DMA_pow2_test
sudo cp DMA_pow2_test.dtb /config/device-tree/overlays/DMA_pow2_test/dtbo


コンパイル時には、ワーニングが表示された。

DMA_pow2_test.dts:12.26-15.15: Warning (unit_address_vs_reg): /fragment@0/__overlay__/dma_pow2-uio: node has a reg or ranges property, but no unit name
DMA_pow2_test.dts:17.26-20.15: Warning (unit_address_vs_reg): /fragment@0/__overlay__/dma_read-uio: node has a reg or ranges property, but no unit name
DMA_pow2_test.dts:22.27-25.15: Warning (unit_address_vs_reg): /fragment@0/__overlay__/dma_write-uio: node has a reg or ranges property, but no unit name
DMA_pow2_test.dts:3.16-34.7: Warning (avoid_unnecessary_addr_size): /fragment@0: unnecessary #address-cells/#size-cells without "ranges" or child "reg" property


コンソールに

[ 1763.979412] u-dma-buf udmabuf4: driver version = 3.2.4
[ 1763.984600] u-dma-buf udmabuf4: major number   = 242
[ 1763.989562] u-dma-buf udmabuf4: minor number   = 0
[ 1763.994351] u-dma-buf udmabuf4: phys address   = 0x000000006fd30000
[ 1764.000618] u-dma-buf udmabuf4: buffer size    = 65536
[ 1764.005754] u-dma-buf axi:dma_pow2-udmabuf4: driver installed.


が表示された。

ls -la で uio と udmabuf を見た。
uioは 0 から 6 まで実装されていた。
ls -la /dev/uio*
ls -la /dev/udmabuf*

ikwzm_Debian_kv260_180_211130.png

/sys/class/uio を見ると
uio4 の name が dma_pow2-uio
uio5 の name が dma_read-uio
uio6 の name が dma_write-uio
だった。
  1. 2021年11月30日 04:39 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

KV260 に ikwzm さんの Debian 11 をインストールした

Linux で DMA_read IP, DMA_write IP を試す前に KV260 に ikwzm さんの Debian 11 をインストールした。

ZynqMP-FPGA-Linux/doc/install/kv260.md に従ってやっていく。

git clone --depth=1 --branch v2021.1.1-rc4 git://github.com/ikwzm/ZynqMP-FPGA-Linux
cd ZynqMP-FPGA-Linux
git lfs pull

ikwzm_Debian_kv260_166_211128.png

MicroSD カードをパソコンに接続し、アンマウントした。
KV260 で ikwzm さんの ZynqMP-FPGA-Linux を試してみる2”を参考に MicroSD カードをフォーマットし、マウントした。

cp target/Kv260/boot/* /media/masaaki/boot/
sudo tar xfz debian11-rootfs-vanilla.tgz -C /media/masaaki/rootfs/
sync

ikwzm_Debian_kv260_167_211128.png

MicroSD カードの boot パーティションの様子を示す。
ikwzm_Debian_kv260_168_211128.png

MicroSD カードの rootfs パーティションを示す。
ikwzm_Debian_kv260_169_211128.png

mkdir /media/masaaki/rootfs/home/fpga/debian
cp linux-headers-5.10.0-xlnx-v2021.1-zynqmp-fpga_5.10.0-xlnx-v2021.1-zynqmp-fpga-4_arm64.deb /media/masaaki/rootfs/home/fpga/debian
cp linux-image-5.10.0-xlnx-v2021.1-zynqmp-fpga_5.10.0-xlnx-v2021.1-zynqmp-fpga-4_arm64.deb /media/masaaki/rootfs/home/fpga/debian
cp fclkcfg-5.10.0-xlnx-v2021.1-zynqmp-fpga_1.7.2-1_arm64.deb /media/masaaki/rootfs/home/fpga/debian
cp u-dma-buf-5.10.0-xlnx-v2021.1-zynqmp-fpga_3.2.4-0_arm64.deb /media/masaaki/rootfs/home/fpga/debian

ikwzm_Debian_kv260_170_211128.png

sudo mkdir /media/masaaki/rootfs/mnt/boot
ikwzm さんのコマンドでうまく行を追加できなかったので、 root で vi を起動して行を追加する。
sudo su
vi /media/masaaki/rootfs/etc/fstab

/dev/mmcblk1p1 /mnt/boot auto defaults 0 0


を追加した。
ikwzm_Debian_kv260_171_211128.png

MicroSD カードを KV260 に挿入して電源 ON した。
Debian 11 が起動した。
ikwzm_Debian_kv260_172_211128.png

ip addr show で IP アドレスを確認して、パソコンから ssh で KV260 の Debian 11 にログインした。
ssh 192.168.3.71 -X -l fpga

まずは sudo するときにでるメッセージを消す。
sudo sh -c 'echo 127.0.1.1 $(hostname) >> /etc/hosts'

パッケージをインストールした。
cd debian
sudo dpkg -i linux-image-5.10.0-xlnx-v2021.1-zynqmp-fpga_5.10.0-xlnx-v2021.1-zynqmp-fpga-4_arm64.deb
sudo dpkg -i linux-headers-5.10.0-xlnx-v2021.1-zynqmp-fpga_5.10.0-xlnx-v2021.1-zynqmp-fpga-4_arm64.deb
sudo dpkg -i fclkcfg-5.10.0-xlnx-v2021.1-zynqmp-fpga_1.7.2-1_arm64.deb
sudo dpkg -i u-dma-buf-5.10.0-xlnx-v2021.1-zynqmp-fpga_3.2.4-0_arm64.deb


インストール済みパッケージをアップデートした。
sudo apt update
sudo apt upgrade


X11 をインストールし、geany と nautilus をインストールした。
sudo apt install xbase-clients xterm x11-apps
sudo apt install nautilus geany


再起動して、nautilus を起動した。
ikwzm_Debian_kv260_173_211128.png

geany を起動した。
ikwzm_Debian_kv260_174_211128.png

なお、私の KV260 だけ、sudo reboot すると u-boot で止まってしまう。
なぜだろう?
ikwzm_Debian_kv260_178_211128.png

電源 ON からだと問題なく Debian 11 が起動する。謎だ?
原因が分かる方はコメントでお知らせください。よろしくお願いいたします。
  1. 2021年11月29日 04:10 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

デバイスツリー・オーバーレイをテストするための KV260 用の Vivado 2021.2 のプロジェクトを作成する4

デバイスツリー・オーバーレイをテストするための KV260 用の Vivado 2021.2 のプロジェクトを作成する3”の続き。

Vitis HLS 2021.2 で DMA_read IP を作成した”の DMA_read IP と”Vitis HLS 2021.2 で DMA_write IP を作成した”の DMA_write IP を”デバイスツリー・オーバーレイをテストするための KV260 用の Vivado 2021.2 のプロジェクトを作成する1”のブロック・デザインに追加して、論理合成、インプリメンテーション、ビットストリームの生成を行い、Vitis でデザインにあったアプリケーション・ソフトウェアを作成して動作を確認する。

まずは、DMA_pow2_test ディレクトリに DMA_read と DMA_write ディレクトリを作成して、それぞれの solution1/impl/export.zip を展開してコピーする。
ikwzm_Debian_kv260_158_211127.png

Vivado の IP Catalog に DMA_read IP と DMA_write IP を追加した。
ikwzm_Debian_kv260_159_211127.png

ブロック・デザインに DMA_read IP と DMA_write IP を追加した。
ikwzm_Debian_kv260_160_211127.png

Address Editor 画面を示す。
ikwzm_Debian_kv260_161_211127.png

セーブして、論理合成、インプリメンテーション、ビットストリームの生成を行って、成功した。
成功した時の DMA_pow2_test プロジェクトを示す。
ikwzm_Debian_kv260_162_211127.png

Project Summary を示す。
ikwzm_Debian_kv260_163_211127.png

ハードウェアをエクスポートして、Vitis で DMA_pow2_test_wrapper プラットフォームを右クリックし右クリックメニューから Update Hardware Specification を選択して、プラットフォームをアップデートした。
新たに test_dma_rw アプリケーション・プロジェクトを作成した。
test_dma_rw_system -> test_dma_rw -> src に test_dma_rw.c を作成した。
ikwzm_Debian_kv260_164_211128.png

test_dma_rw.c を作成した。貼っておく。

// test_dma_rw.c
// 2021/11/27 by marsee
//

#include <stdio.h>
#include "xdma_pow2.h"
#include "xdma_read.h"
#include "xdma_write.h"
#include "xparameters.h"

volatile int data[10] = {0,1,2,3,4,5,6,7,8.9};
volatile int result[10];

int main(){
    XDma_pow2 XDMA_pow2_ap;
    XDma_pow2_Config *XDMA_pow2_apPtr;
    XDma_read XDMA_read_ap;
    XDma_write XDMA_write_ap;
    int i;

    // Look Up the device configuration
    XDMA_pow2_apPtr = XDma_pow2_LookupConfig(0);
    if (!XDMA_pow2_apPtr){
        fprintf(stderr, "XDma_pow2 configuration failed.\n");
        return(-1);
    }

    // Initialize the Device
    int status = XDma_pow2_CfgInitialize(&XDMA_pow2_ap, XDMA_pow2_apPtr);
    if (status != XST_SUCCESS){
        fprintf(stderr, "Could not Initialize XDma_pow2\n");
        return(-1);
    }

    status = XDma_read_Initialize(&XDMA_read_ap, 0);
    if (status != XST_SUCCESS){
        fprintf(stderr, "Could not Initialize XDma_read\n");
        return(-1);
    }

    status = XDma_write_Initialize(&XDMA_write_ap, 0);
    if (status != XST_SUCCESS){
        fprintf(stderr, "Could not Initialize XDma_write\n");
        return(-1);
    }

    XDma_pow2_Set_in_r(&XDMA_pow2_ap, (u64)&data[0]);
    XDma_pow2_Set_out_r(&XDMA_pow2_ap, (u64)&result[0]);

    // DMA_write IPを使用してメモリに書き込む
    // キャッシュにデータがあってもメモリに書かれていないかも知れない?から
    for(int i=0; i<10; i++){
        XDma_write_Set_addr(&XDMA_write_ap, (u64)(&data[i]));
        XDma_write_Set_data(&XDMA_write_ap, (u32)i);
        XDma_write_Start(&XDMA_write_ap);
        while(!XDma_write_IsDone(&XDMA_write_ap));
    }

    XDma_pow2_Start(&XDMA_pow2_ap);

    while(!XDma_pow2_IsDone(&XDMA_pow2_ap)) ;

    // DMA_read IPを使用してDMAされたデータをCPUで読み込む
    // 読み込んだデータはCPUで同じメモリにもう一度書く。(キャッシュに書ける)
    for(int i=0; i<10; i++){
        XDma_read_Set_addr(&XDMA_read_ap, (u64)(&result[i]));
        XDma_read_Start(&XDMA_read_ap);
        while(!XDma_read_IsDone(&XDMA_read_ap));
        result[i] = XDma_read_Get_data(&XDMA_read_ap);
    }

    for(i=0; i<10; i++){
        printf("data[%d] = %d, result[%d] = %d\n", i, data[i], i, result[i]);
    }

    return 0;

}


FPGAをコンフィギュレーションし、アプリケーション・ソフトウェアを起動すると正常に演算が実行された。
(試行錯誤していたので、最後のデータが最終結果だ)
ikwzm_Debian_kv260_165_211128.png
  1. 2021年11月28日 03:51 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

Vitis HLS 2021.2 で DMA_write IP を作成した

Vitis HLS 2021.2 で DMA_read IP を作成した”の続き。

メモリに UIO 経由でメモリに直接 read/write する IP を作成しようと思うということで、前回は、DMA_read IP を作成した。今回は、DMA write IP を作成する。

Vitis HLS 2021.2 で DMA_write プロジェクトを作成した。
ソースコードの DMA_write.cpp 、テストベンチ・コードの DMA_write_tb.cpp を作成した。
ikwzm_Debian_kv260_149_211126.png

DMA_write.cpp を示す。

// DMA_write.cpp
// 2021/11/26 by marsee
//

#include <stdint.h>

int DMA_write(int32_t *addr, int32_t *data){
#pragma HLS INTERFACE mode=m_axi depth=1 port=addr offset=slave
#pragma HLS INTERFACE mode=s_axilite port=data
#pragma HLS INTERFACE mode=s_axilite port=return
    *addr = *data;

    return(0);
}


DMA_write_tb.cpp を示す。

// DMA_write_tb.cpp
// 2021/11/26 by marsee
//

#include <stdio.h>
#include <stdint.h>

int DMA_write(int32_t *addr, int32_t *data);

int main(){
    int32_t data[10];

    for(int i=0; i<10; i++){
        DMA_write(&(data[i]), &i);
        printf("i = %d, data = %d\n", i, data[i]);
    }
    return(0);
}


C シミュレーションを行った。結果を示す。
ikwzm_Debian_kv260_150_211127.png

C コードの合成を行った。結果を示す。
ikwzm_Debian_kv260_151_211127.png
ikwzm_Debian_kv260_152_211127.png

Latency は 7 クロックだった。

C/RTL 協調シミュレーションを行った。結果を示す。
インターバルは 61 クロックだった。
ikwzm_Debian_kv260_153_211127.png

AXI4-Lite インターフェースのレジスタマップを示す。

//------------------------Address Info-------------------
// 0x00 : Control signals
//        bit 0  - ap_start (Read/Write/COH)
//        bit 1  - ap_done (Read/COR)
//        bit 2  - ap_idle (Read)
//        bit 3  - ap_ready (Read/COR)
//        bit 7  - auto_restart (Read/Write)
//        others - reserved
// 0x04 : Global Interrupt Enable Register
//        bit 0  - Global Interrupt Enable (Read/Write)
//        others - reserved
// 0x08 : IP Interrupt Enable Register (Read/Write)
//        bit 0 - enable ap_done interrupt (Read/Write)
//        bit 1 - enable ap_ready interrupt (Read/Write)
//        bit 5 - enable ap_local_deadlock interrupt (Read/Write)
//        others - reserved
// 0x0c : IP Interrupt Status Register (Read/TOW)
//        bit 0 - ap_done (COR/TOW)
//        bit 1 - ap_ready (COR/TOW)
//        bit 5 - ap_local_deadlock (COR/TOW)
//        others - reserved
// 0x10 : Data signal of ap_return
//        bit 31~0 - ap_return[31:0] (Read)
// 0x18 : Data signal of addr
//        bit 31~0 - addr[31:0] (Read/Write)
// 0x1c : Data signal of addr
//        bit 31~0 - addr[63:32] (Read/Write)
// 0x20 : reserved
// 0x24 : Data signal of data
//        bit 31~0 - data[31:0] (Read/Write)
// 0x28 : reserved
// (SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake)


C/RTL 協調シミュレーションの波形を示す。
ikwzm_Debian_kv260_154_211127.png

最初の DMA Write の AXI4 Master アクセスを示す。0x18, 0x1C へのレジスタアクセスがあった。これは、 addr のアドレスの下位 32 ビット、上位 32 ビットを設定するアクセスだ。

前回に引き続き、次の波形では、やはり 0x18, 0x1C へのレジスタアクセスが無い。
ikwzm_Debian_kv260_155_211127.png

Export RTL を行った。
DMA_write/solution1/impl ディレクトリに export.zip が作成された。
ikwzm_Debian_kv260_156_211127.png

Implementation を行った。
結果を示すが、問題ないようだ。
ikwzm_Debian_kv260_157_211127.png
  1. 2021年11月27日 04:14 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

Vitis HLS 2021.2 で DMA_read IP を作成した

KV260 で ikwzm さんのデバイスツリー・オーバーレイをテストする3”で ZynqMP の S_AXI_HPC0_FPD を使用しても、キャッシュに読み書きできていないということが分かった。ikwzm さんにお聞きすると、キャッシュに読み書きさせるようにするのも、今の所難しいということだった。
そこで、キャッシュに読み書きするのではなく、メモリに UIO 経由でメモリに直接 read/write する IP を作成しようと思う。最初に DMA_read IP を作成する。

Vitis HLS 2021.2 で DMA_read プロジェクトを作成した。
ソースコードの DMA_read.cpp 、テストベンチ・コードの DMA_read_tb.cpp を作成した。
ikwzm_Debian_kv260_139_211126.png

DMA_read.cpp を示す。

// DMA_read.cpp
// 2021/11/25 by marsee
//

#include <stdint.h>

int DMA_read(int32_t *addr, int32_t *data){
#pragma HLS INTERFACE mode=m_axi depth=1 port=addr offset=slave
#pragma HLS INTERFACE mode=s_axilite port=data
#pragma HLS INTERFACE mode=s_axilite port=return
    *data = *addr;

    return(0);
}


テストベンチ・コードの DMA_read_tb.cpp を示す。

// DMA_read_tb.cpp
// 2021/11/25 by marsee
//

#include <stdio.h>
#include <stdint.h>

int DMA_read(int32_t *addr, int32_t *data);

int main(){
    int32_t data[10] = {0,1,2,3,4,5,6,7,8,9};
    int32_t read_data;

    for(int i=0; i<10; i++){
        DMA_read(&(data[i]), &read_data);
        printf("i = %d, read_data = %d\n", i, read_data);
    }
    return(0);
}


C シミュレーションを行った。結果を示す。結果は正しいようだ。
ikwzm_Debian_kv260_140_211126.png

C コードの合成を行った。結果を示す。
ikwzm_Debian_kv260_141_211126.png
ikwzm_Debian_kv260_142_211126.png
ikwzm_Debian_kv260_143_211126.png

C/RTL 協調シミュレーションを行った。結果を示す。
Latency は 15 クロックだった。
ikwzm_Debian_kv260_144_211126.png

AXI4-Lite インターフェースのレジスタマップを示す。

//------------------------Address Info-------------------
// 0x00 : Control signals
//        bit 0  - ap_start (Read/Write/COH)
//        bit 1  - ap_done (Read/COR)
//        bit 2  - ap_idle (Read)
//        bit 3  - ap_ready (Read/COR)
//        bit 7  - auto_restart (Read/Write)
//        others - reserved
// 0x04 : Global Interrupt Enable Register
//        bit 0  - Global Interrupt Enable (Read/Write)
//        others - reserved
// 0x08 : IP Interrupt Enable Register (Read/Write)
//        bit 0 - enable ap_done interrupt (Read/Write)
//        bit 1 - enable ap_ready interrupt (Read/Write)
//        bit 5 - enable ap_local_deadlock interrupt (Read/Write)
//        others - reserved
// 0x0c : IP Interrupt Status Register (Read/TOW)
//        bit 0 - ap_done (COR/TOW)
//        bit 1 - ap_ready (COR/TOW)
//        bit 5 - ap_local_deadlock (COR/TOW)
//        others - reserved
// 0x10 : Data signal of ap_return
//        bit 31~0 - ap_return[31:0] (Read)
// 0x18 : Data signal of addr
//        bit 31~0 - addr[31:0] (Read/Write)
// 0x1c : Data signal of addr
//        bit 31~0 - addr[63:32] (Read/Write)
// 0x20 : reserved
// 0x24 : Data signal of data
//        bit 31~0 - data[31:0] (Read)
// 0x28 : Control signal of data
//        bit 0  - data_ap_vld (Read/COR)
//        others - reserved
// (SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake)


C/RTL 協調シミュレーションの波形を示す。
ikwzm_Debian_kv260_145_211126.png

最初は、0x18, 0x1C へのレジスタアクセスがあった。これは、 addr のアドレスの下位 32 ビット、上位 32 ビットを設定するアクセスだ。

次の波形では、0x18, 0x1C へのレジスタアクセスが無い。これはバグじゃないだろうか?
ikwzm_Debian_kv260_146_211126.png

Export RTL を行った。
DMA_read/solution1/impl ディレクトリに export.zip が作成された。
ikwzm_Debian_kv260_147_211126.png

最後に Implementation を行った。結果を示すが、問題ないようだ。
ikwzm_Debian_kv260_148_211126.png
  1. 2021年11月26日 04:12 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

KV260 で ikwzm さんのデバイスツリー・オーバーレイをテストする3

KV260 で ikwzm さんのデバイスツリー・オーバーレイをテストする2”の続き。

KV260 で ikwzm さんの Debian をインストールしてきたが、Ultra96 でやったように DMA Readしたデータを2乗し、DMA Writeする KV260 用 IP を Vitis HLS 2021.2 で作って、Vivado で実装して KV260 の Debian に持っていて動作させてみよう。前回は、、ikwzm さんにお聞きして fclk0-zynqmp.dts を変更してクロックの設定を行い、u-dma-buf の設定を行った。今回は、アプリケーション・ソフトウェアの DMA_pow2_test.c を用意して、コンパイルし、FPGAに書いた DMA_pow2 回路の動作を確認しよう。

前回からの続きではあるが、KV260 は電源を OFF してあるので、FPGAのコンフィギュレーション、クロックの設定、u-dma-buf の設定を続けて行った。
cd examples/DMA_pow2_test/
sudo mkdir /config/device-tree/overlays/fpga
sudo cp fpga-load.dtb /config/device-tree/overlays/fpga/dtbo
sudo mkdir /config/device-tree/overlays/fclk0
sudo cp fclk0-zynqmp.dtb /config/device-tree/overlays/fclk0/dtbo
sudo mkdir /config/device-tree/overlays/DMA_pow2_test
sudo cp DMA_pow2_test.dtb /config/device-tree/overlays/DMA_pow2_test/dtbo
sudo chmod 666 /dev/uio*
sudo chmod 666 /dev/udmabuf*
ls -l /dev/uio*
ls -l /dev/udmabuf*


examples/DMA_pow2_test/ ディレクトリの下に build ディレクトリを作成した。
build ディレクトリに DMA_pow2_test.c を作成した。
ikwzm_Debian_kv260_130_211124.png

// DMA_pow2_test.c
// 2018/10/25 by marsee

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>

#include "xdma_pow2.h"

int main(){
    XDma_pow2 xdma_pow2_ap;
    volatile unsigned int *udmabuf4_buf;
    int udmabuf4_fd, fd_phys_addr;
    char  attr[1024];
    unsigned long  phys_addr;
    int Xdma_status;
    int i;
    
    // udmabuf4
    udmabuf4_fd = open("/dev/udmabuf4", O_RDWR); // frame_buffer, The chache is enabled. 
    if (udmabuf4_fd == -1){
        fprintf(stderr, "/dev/udmabuf4 open error\n");
        exit(-1);
    }
    udmabuf4_buf = (volatile unsigned int *)mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, udmabuf4_fd, 0);
    if (!udmabuf4_buf){
        fprintf(stderr, "udmabuf4_buf mmap error\n");
        exit(-1);
    }

    // phys_addr of udmabuf4
    fd_phys_addr = open("/sys/class/u-dma-buf/udmabuf4/phys_addr", O_RDONLY);
    if (fd_phys_addr == -1){
        fprintf(stderr, "/sys/class/u-dma-buf/udmabuf4/phys_addr open error\n");
        exit(-1);
    }
    read(fd_phys_addr, attr, 1024);
    sscanf(attr, "%lx", &phys_addr);  
    close(fd_phys_addr);
    printf("phys_addr = %x\n", (int)phys_addr);

    // data set
    for(i=0; i<10; i++){
        udmabuf4_buf[i] = i;
    }
        
    Xdma_status = XDma_pow2_Initialize(&xdma_pow2_ap, "dma_pow2-uio");
    if (Xdma_status != XST_SUCCESS){
        fprintf(stderr, "Could not Initialize XDMA_pow2\n");
        return(-1);
    }
    
    XDma_pow2_Set_in_r(&xdma_pow2_ap, (uint64_t)phys_addr);
    XDma_pow2_Set_out_r(&xdma_pow2_ap, (uint64_t)(phys_addr+10*sizeof(int)));

    XDma_pow2_Start(&xdma_pow2_ap);
    
    while(!XDma_pow2_IsDone(&xdma_pow2_ap));

    for(i=0; i<10; i++){
        printf("data[%d] = %d, result[%d] = %d\n", i, udmabuf4_buf[i], i, udmabuf4_buf[10+i]);
    }

    return(0);
}


同じく build ディレクトリに Makefile を作成した。
ikwzm_Debian_kv260_131_211124.png

# Makefile(DMA_pow2_test)
# Referred to http://www.ie.u-ryukyu.ac.jp/~e085739/c.makefile.tuts.html

PROGRAM = DMA_pow2_test
OBJS = DMA_pow2_test.o xdma_pow2_linux.o xdma_pow2.o

CC = gcc
CFLAGS = -Wall -O2

.SUFFIXES: .c .o

.PHONY: all

all: DMA_pow2_test

DMA_pow2_test: $(OBJS)
    $(CC) -Wall -o $@ $(OBJS)
    
.c.o:
    $(CC) $(CFLAGS) -c $<

    
.PHONY: clean
clean:
    $(RM) $(PROGRAM) $(OBJS)


なお、Makefile をコピペする場合は、タブの部分はスペース 4 個に変換してあるのだが、その部分を TAB にしてほしい。そうでないと、”*** missing separator. Stop.”と表示が出て make が止まってしまう。その対処方法は上に書いたようにスペース 4 個を TAB に変換することだ。”Makefileでmake時に 「*** missing separator. Stop.」 と出たときの対処法”参照。

build ディレクトリにVitis HLS 2021.2 で作成した DMA_pow2 IP のドライバの

xdma_pow2.c
xdma_pow2.h
xdma_pow2_hw.h
xdma_pow2_linux.h


を SFTP して KV260 の Debian にアップロードした。
ikwzm_Debian_kv260_132_211124.png

これで build ディレクトリにファイルがそろった。
ikwzm_Debian_kv260_133_211124.png

build ディレクトリで make を行った。
make
ikwzm_Debian_kv260_134_211124.png

ワーニングが出たが、make 成功した。
build ディレクトリを示す。
DMA_pow2_test ができている。
ikwzm_Debian_kv260_135_211124.png

examples/DMA_pow2_test ディレクトリに戻った。
DMA_pow2_test を起動した。
cd ..
./build/DMA_pow2_test

ikwzm_Debian_kv260_136_211124.png

result はすべて 0 だった。
やはり、データ・キャッシュ ON していて、キャッシュに書き込みした時に明示的にフラッシュしてなくて、DMA でメモリに書き込んだ時にインバリデートしていないからだと思う。
”UltraZed 向け Debian GNU/Linux で AXI HPC port を使う (実践編1)”の”boot.bin の説明”によるとステージ0でレジスタを設定すればよいのだが、KV260 は boot.scr なのだが、どうやれば良いのだろうか?

(追加)
printf() で値を表示する直前に

udmabuf4_buf[10] = 1;

を追加したところ、 result[6] 〜 result[9] は正常な値が表示できた。これからも DMA_pow2 回路が起動していないのではなく、キャッシュの問題ということが分かる。
ikwzm_Debian_kv260_137_211124.png

ikwzm_Debian_kv260_138_211124.png
  1. 2021年11月25日 04:15 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

KV260 で ikwzm さんのデバイスツリー・オーバーレイをテストする2

KV260 で ikwzm さんのデバイスツリー・オーバーレイをテストする1”の続き。

KV260 で ikwzm さんの Debian をインストールしてきたが、Ultra96 でやったように DMA Readしたデータを2乗し、DMA Writeする KV260 用 IP を Vitis HLS 2021.2 で作って、Vivado で実装して KV260 の Debian に持っていて動作させてみよう。前回は、”Ultra96 ボードでデバイスツリー・オーバーレイをテストする1”を参照しながら、デバイスツリー・オーバーレイをやって行ったのだが、デバイスツリー・オーバーレイでクロックの設定をしたところエラーになってしまった。今回は、ikwzm さんにお聞きして fclk0-zynqmp.dts を変更してクロックの設定を行い、u-dma-buf の設定を行った。

今回は、”Ultra96 ボードでデバイスツリー・オーバーレイをテストする2”を参照する。

FPGA Clock Configuration Device Driver”の資料を示す。
ikwzm さんにいろいろと教えていただいた。ありがとうございます。

まずは、”target-path”は”/axi”に変更になったそうだ。
ZynqMP-FPGA-Linux/target/Kv260/boot/devicetree-5.10.0-xlnx-v2021.1-zynqmp-fpga-kv260-revB.dts の 486 行目に記述されている。

次に、クロック・モジュールのシンボル名は”zynqmp_clk”に変更になったそうだ。
devicetree-5.10.0-xlnx-v2021.1-zynqmp-fpga-kv260-revB.dts の clock-controller の記述だ。
これらの変更を適用すると fclk0-zynqmp.dts はこうなった。
ikwzm_Debian_kv260_119_211123.png

/dts-v1/;/plugin/;
/ {
    fragment@0 {
        target-path = "/axi";
        __overlay__ {
            fclk0 {
                compatible    = "ikwzm,fclkcfg-0.10.a";
                clocks        = <&zynqmp_clk 0x47>;
                insert-rate   = "100000000";
                insert-enable = <1>;
                remove-rate   = "1000000";
                remove-enable = <0>;
            };
        };
    };
};


examples/DMA_pow2_test/ ディレクトリに入って、 fclk0-zynqmp.dts をコンパイルして、fpga-load.dtb と fclk0-zynqmp.dtb をロードした。
cd examples/DMA_pow2_test/
dtc -I dts -O dtb -o fclk0-zynqmp.dtb fclk0-zynqmp.dts
sudo mkdir /config/device-tree/overlays/fpga
sudo cp fpga-load.dtb /config/device-tree/overlays/fpga/dtbo
sudo mkdir /config/device-tree/overlays/fclk0
sudo cp fclk0-zynqmp.dtb /config/device-tree/overlays/fclk0/dtbo

ikwzm_Debian_kv260_120_211123.png

シリアル・コンソールにデバイスツリー・オーバーレイのメッセージが表示された。

[  194.275456] fpga_manager fpga0: writing DMA_pow2_test_wrapper.bin to Xilinx ZynqMP FPGA Manager
[  194.754483] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /fpga-full/firmware-name
[  207.119630] fclkcfg: loading out-of-tree module taints kernel.
[  207.127291] zynqmp_clk_divider_set_rate() set divider failed for pl0_ref_div1, ret = -13
[  207.135576] fclkcfg axi:fclk0: driver version : 1.7.2
[  207.140647] fclkcfg axi:fclk0: device name    : axi:fclk0
[  207.146042] fclkcfg axi:fclk0: clock  name    : pl0_ref
[  207.151280] fclkcfg axi:fclk0: clock  rate    : 99999999
[  207.156611] fclkcfg axi:fclk0: clock  enabled : 1
[  207.161312] fclkcfg axi:fclk0: remove rate    : 1000000
[  207.166536] fclkcfg axi:fclk0: remove enable  : 0
[  207.171240] fclkcfg axi:fclk0: driver installed.


ikwzm_Debian_kv260_121_211123.png

うまく行った。。。苦労しただけに嬉しい。。。

次に、uio と udmabuf のロードを行う。
Ultra96 ボードでデバイスツリー・オーバーレイをテストする2”の DMA_pow2_test.dts を変更した。
”target-path”は”/axi”に変更し、udmabuf は u-dma-buf に変更した。
u-dma-buf(User space mappable DMA Buffer) の資料を示す。

DMA_pow2_test.dts を示す。
ikwzm_Debian_kv260_122_211123.png

/dts-v1/;/plugin/;
/ {
    fragment@0 {
        target-path = "/axi";
        #address-cells = <2>;
        #size-cells = <2>;

        __overlay__ {
            #address-cells = <2>;
            #size-cells = <2>;

            dma_pow2-uio {
                compatible = "generic-uio";
                reg = <0x0 0x00A0000000 0x0 0x10000>;
            };

            dma_pow2-udmabuf4 {
                compatible  = "ikwzm,u-dma-buf";
                device-name = "udmabuf4";
                size = <0x00010000>;
            };
        };
    };
};


dtc で DMA_pow2_test.dts をコンパイルして、dtb に変換してから、ロードした。
dtc -I dts -O dtb -o DMA_pow2_test.dtb DMA_pow2_test.dts
sudo mkdir /config/device-tree/overlays/DMA_pow2_test
sudo cp DMA_pow2_test.dtb /config/device-tree/overlays/DMA_pow2_test/dtbo

ikwzm_Debian_kv260_123_211123.png

ワーニングが出ているが、シリアル・コンソールを見ると、 udmabuf4 がロードされているのが分かる。
ikwzm_Debian_kv260_128_211123.png

[ 1565.193308] u-dma-buf udmabuf4: driver version = 3.2.4
[ 1565.198458] u-dma-buf udmabuf4: major number   = 242
[ 1565.203431] u-dma-buf udmabuf4: minor number   = 0
[ 1565.208223] u-dma-buf udmabuf4: phys address   = 0x000000006fd30000
[ 1565.214490] u-dma-buf udmabuf4: buffer size    = 65536
[ 1565.219631] u-dma-buf axi:dma_pow2-udmabuf4: driver installed.


ls -la で uio と udmabuf を見た。
uioは 0 から 4 まで実装されていた。
ls -la /dev/uio*
ls -la /dev/udmabuf*

ikwzm_Debian_kv260_124_211123.png

uio4 が dma_pow2-uio なのか?確認してみる。
/sys/class/uio/uio4 を nautilus で確認した。
ikwzm_Debian_kv260_125_211123.png

name を見ると dma_pow2-uio が見えたので、uio4 が dma_pow2-uio で間違いない。
ikwzm_Debian_kv260_126_211123.png

fpga ユーザーでも uio と udmabuf を扱えるようにファイルのパーミッションを 666 にしておく。
sudo chmod 666 /dev/uio*
sudo chmod 666 /dev/udmabuf*

ikwzm_Debian_kv260_127_211123.png
  1. 2021年11月23日 05:21 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

KV260 で ikwzm さんのデバイスツリー・オーバーレイをテストする1

デバイスツリー・オーバーレイをテストするための KV260 用の Vivado 2021.2 のプロジェクトを作成する3”の続き。

KV260 で ikwzm さんの Debian をインストールしてきたが、Ultra96 でやったように DMA Readしたデータを2乗し、DMA Writeする KV260 用 IP を Vitis HLS 2021.2 で作って、Vivado で実装して KV260 の Debian に持っていて動作させてみよう。前回は、ハードウェアの動作を一応確認できた。今回は、”Ultra96 ボードでデバイスツリー・オーバーレイをテストする1”を参照しながら、デバイスツリー・オーバーレイをやってみよう。

bin ファイルを作成しよう。
ここからは、パソコン側の作業だ。
DMA_pow2_test/vitis_work/DMA_pow2_test_wrapper/hw ディレクトリに DMA_pow2_warpper.bif を作成した。
ikwzm_Debian_kv260_104_211121.png

ikwzm_Debian_kv260_105_211121.png

all:
{
    [destination_device = pl] DMA_pow2_test_wrapper.bit
}


bootgen で bin ファイルに変換する。
bootgen -image DMA_pow2_test_wrapper.bif -arch zynqmp -w -o DMA_pow2_test_wrapper.bin

bin ファイルが生成された。
ikwzm_Debian_kv260_106_211121.png

KV260 で”KV260 で ikwzm さんの ZynqMP-FPGA-Linux を試してみる3”で作成した MicroSD カードで Debian を KV260 上で起動する。
geany を立ち上げて、 fpga-load.dts を作成した。
ikwzm_Debian_kv260_107_211121.png

/dts-v1/;
/ {
    fragment@0 {
        target-path = "/fpga-full";
        __overlay__ {
            firmware-name = "DMA_pow2_test_wrapper.bin";
        };
    };
};


ホスト・パソコンで FileZilla を起動して、 KV260 の Debian にログインして、 DMA_pow2_test_wrapper.bin を SFTP で KV260 の Debian に転送する。
ikwzm_Debian_kv260_108_211121.png

bin ファイルを /lib/firmware/ にコピーする。
sudo cp DMA_pow2_test_wrapper.bin /lib/firmware/
ls -l /lib/firmware/DMA_pow2_wrapper.bin

ikwzm_Debian_kv260_109_211121.png

dtc で fpga-load.dts をコンパイルした。
dtc -I dts -O dtb -o fpga-load.dtb fpga-load.dts
ikwzm_Debian_kv260_110_211121.png

fpgaをコンフィグレーションする。
sudo mkdir /config/device-tree/overlays/fpga
sudo cp fpga-load.dtb /config/device-tree/overlays/fpga/dtbo

ikwzm_Debian_kv260_111_211121.png

シリアル・コンソールに

fpga_manager fpga0: writing DMA_pow2_test_wrapper.bin to Xilinx ZynqMP FPGA Manager
OF: overlay: WARNING: memory leak will occur if overlay removed, property: /fpga-full/firmware-name


と表示された。
ikwzm_Debian_kv260_112_211121.png

デバイスツリー・オーバーレイでクロックの設定を行う。
fclk0-zynqmp.dts を作成した。
ikwzm_Debian_kv260_113_211121.png

/dts-v1/;/plugin/;
/ {
    fragment@0 {
        target-path = "/amba";
        __overlay__ {
            fclk0 {
                compatible    = "ikwzm,fclkcfg-0.10.a";
                clocks        = <&clk 0x47>;
                insert-rate   = "100000000";
                insert-enable = <1>;
                remove-rate   = "1000000";
                remove-enable = <0>;
            };
        };
    };
};


デバイスツリーをコンパイルした。
dtc -I dts -O dtb -o fclk0-zynqmp.dtb fclk0-zynqmp.dts
ikwzm_Debian_kv260_114_211121.png

デバイスツリーをロードする。
sudo mkdir /config/device-tree/overlays/fclk0
sudo cp fclk0-zynqmp.dtb /config/device-tree/overlays/fclk0/dtbo

ikwzm_Debian_kv260_115_211121.png

エラーになってしまったようだ。
ikwzm_Debian_kv260_116_211121.png

OF: resolver: node label 'clk' not found in live devicetree symbols table
OF: resolver: overlay phandle fixup failed: -22
create_overlay: Failed to create overlay (err=-22)



最後に、sudo コマンドを実行すると”sudo: unable to resolve host debian-fpga: Name or service not known”が表示されてしまうので、”sudo: unable to resolve host の表示を止める”を参照して、このメッセージを止めることができた。
  1. 2021年11月22日 05:02 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

デバイスツリー・オーバーレイをテストするための KV260 用の Vivado 2021.2 のプロジェクトを作成する3

デバイスツリー・オーバーレイをテストするための KV260 用の Vivado 2021.2 のプロジェクトを作成する2”の続き。

KV260 で ikwzm さんの Debian をインストールしてきたが、Ultra96 でやったように DMA Readしたデータを2乗し、DMA Writeする KV260 用 IP を Vitis HLS 2021.2 で作って、Vivado で実装して KV260 の Debian に持っていて動作させてみよう。前回は、ハードウェアをエクスポートして、Vitis 2021.2 を立ち上げて、プラットフォームとアプリケーション・プロジェクトを作成して、実機で確かめてみたが、gtkterm に何も表示されなかった。今回は、gtkterm に何も表示されなかった原因を追求し、実機確認で動作を確認できたが、キャッシュに書き込むことはできなかった。

Vivado のブロック・デザインで Zynq UltraScale MPSoC をダブルクリックでダイアログを表示させてみたとこと、UART が有効になっていなかった。これが原因だ。KV260 のボード・ファイルを適用しているのだけど、UART が有効にならないのか?
仕方ないので、”MicroZed Chronicles: Kria & Raspberry Pi Camera”の Zynq UltraScale MPSoC を見ると、UART 1 が有効になっている。
早速、”MicroZed Chronicles: Kria & Raspberry Pi Camera”を真似て、UART 1 を有効にして、MIO 36 .. 37 にマップした。
ikwzm_Debian_kv260_98_211119.png

これで Zynq UltraScale MPSoC の UART 1 にチェックが付いた。
ikwzm_Debian_kv260_99_211119.png

これで、もぅ一度、論理合成、インプリメンテーション、ビットストリームの生成を行って、ハードウェアをエクスポートして、Vitis で Update Hardware Specification を行った。
test_dma.c のキャッシュ操作命令はコメントアウトしてある。これは、キャッシュに書けるようにハードウェアを構築してあって、”デバイスツリー・オーバーレイをテストするためのVivado 2018.2 のプロジェクトを作成する2”の時は、キャッシュに書くことができているためだ。
ikwzm_Debian_kv260_100_211119.png

これで、前回作成した Debugger_test_dma-Default を起動すると、result に 2 乗された結果ではなく、プロセッサで書いておいた値が表示されている。
どうやら、キャッシュに書けていないようである。
ikwzm_Debian_kv260_101_211119.png

次に、Xil_DCacheFlush() と Xil_DCacheInvalidate() のキャッシュ操作命令を適切と思われる場所に入れた。
ikwzm_Debian_kv260_102_211119.png

これで、Debugger_test_dma-Default を起動すると、result に 2 乗された結果が表示された。
やはり、キャッシュに書けていないようだ。
ikwzm_Debian_kv260_103_211119.png

UltraZed 向け Debian GNU/Linux で AXI HPC port を使う (実践編1)”を参考にして、 0xFF41A040 番地に 0x3 を書いてもキャッシュに書けなかった。
そういえば、KV260 は SD カードブート・モードで起動時にいろいろと起動しているので、それが、”デバイスツリー・オーバーレイをテストするためのVivado 2018.2 のプロジェクトを作成する2”と結果が違う原因じゃないのだろうか?

最後に test_dma.c を貼っておく。

// test_dma.c
// Created on: 2021/11/19
//      Author: masaaki

#include <stdio.h>
#include "xdma_pow2.h"
#include "xparameters.h"

volatile int data[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
volatile int result[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

void Xil_DCacheFlush(void);
void Xil_DCacheInvalidate(void);

int main(){
    XDma_pow2 XDMA_pow2_ap;
    XDma_pow2_Config *XDMA_pow2_apPtr;
    int i;

    // Look Up the device configuration
    XDMA_pow2_apPtr = XDma_pow2_LookupConfig(0);
    if (!XDMA_pow2_apPtr){
        fprintf(stderr, "XDma_pow2 configuration failed.\n");
        return(-1);
    }

    // Initialize the Device
    int Xlap_status = XDma_pow2_CfgInitialize(&XDMA_pow2_ap, XDMA_pow2_apPtr);
    if (Xlap_status != XST_SUCCESS){
        fprintf(stderr, "Could not Initialize XDma_pow2\n");
        return(-1);
    }

    XDma_pow2_Set_in_r(&XDMA_pow2_ap, (u64)&data[0]);
    XDma_pow2_Set_out_r(&XDMA_pow2_ap, (u64)&result[0]);

    Xil_DCacheFlush();

    XDma_pow2_Start(&XDMA_pow2_ap);

    while(!XDma_pow2_IsDone(&XDMA_pow2_ap)) ;

    Xil_DCacheInvalidate(); // Invalidate result[10]
    for(i=0; i<10; i++){
        printf("data[%d] = %d, result[%d] = %d\n", i, data[i], i, result[i]);
    }

    return 0;

}


  1. 2021年11月21日 04:12 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

デバイスツリー・オーバーレイをテストするための KV260 用の Vivado 2021.2 のプロジェクトを作成する2

デバイスツリー・オーバーレイをテストするための KV260 用の Vivado 2021.2 のプロジェクトを作成する1”の続き。

KV260 で ikwzm さんの Debian をインストールしてきたが、Ultra96 でやったように DMA Readしたデータを2乗し、DMA Writeする KV260 用 IP を Vitis HLS 2021.2 で作って、Vivado で実装して KV260 の Debian に持っていて動作させてみよう。前回は、DMA_pow2 IP を使用してVivado 2021.2 でDMA_pow2_test プロジェクトを作成し、ブロック・デザインを作成して、論理合成、インプリメンテーション、ビットストリームの生成を行った。今回は、ハードウェアをエクスポートして、Vitis 2021.2 を立ち上げて、プラットフォームとアプリケーション・プロジェクトを作成して、実機で確かめてみたが、gtkterm に何も表示されなかった。

今回の記事は、”デバイスツリー・オーバーレイをテストするためのVivado 2018.2 のプロジェクトを作成する2”を参照している。

Vivado 2021.2 の File メニューから Export -> Export Hardware... を選択して、ハードウェアをエクスポートする。
Output 画面では Include bitstream のラジオボタンをクリックした。その他はデフォルトで進めた。
ikwzm_Debian_kv260_87_211118.png

DMA_pow2_test ディレクトリに DMA_pow2_test_wrapper.xsa が生成された。
ikwzm_Debian_kv260_88_211118.png

Vivado の Tools メニューから Launch Vitis IDE を選択した。
Vitis IDE Launcher が立ち上がった。
DMA_pow2_test ディレクトリに vitis_work ディレクトリを新規作成して、そのディレクトリを選択して、Launch ボタンをクリックした。
ikwzm_Debian_kv260_89_211118.png

Vitis 2021.2 が立ち上がった。
DMA_pow2_test_wrapper.xsa を元にして DMA_pow2_test_wrapper プラットフォームを作成した。
test_dma アプリケーション・プロジェクトも作成した。
ikwzm_Debian_kv260_90_211119.png

test_dma.c を作成して、ビルド・ボタンをクリックしてビルドを行う。
ikwzm_Debian_kv260_91_211119.png

ビルドが成功して、test_dma.elf が生成された。
ikwzm_Debian_kv260_92_211119.png

Assistant ウインドウで test_dma_system -> test_dma -> Debug を右クリックし右クリックメニューから Run -> Run Configuration... を選択する。
ikwzm_Debian_kv260_93_211119.png

Run Configuration ダイアログが表示された。
ikwzm_Debian_kv260_94_211119.png

Single Application Debug をダブルクリックする。
Debugger_test_dma-Default が生成された。
ikwzm_Debian_kv260_95_211119.png

SD カード・ブートモードの Zynq UltraScale+ MPSoC で Vitis を使用してコンフィギュレーション、ソフトウェアを起動する”を参考にして、Target Setup タブの Use FSBL flow for initialization のチェックを外した。
ikwzm_Debian_kv260_96_211119.png

スーパーユーザー・モードで gtkterm を立ち上げて、 115200 bps で /dev/ttyUSB1 を指定した。
Debugger_test_dma-Default の Apply ボタンをクリックして、Run ボタンをクリックした。

FPGA がコンフィギュレーションされて、アプリケーション・ソフトウェアが起動したようだが、gtkterm には何も表示されなかった。 orz...
ikwzm_Debian_kv260_97_211119.png
  1. 2021年11月20日 17:28 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

デバイスツリー・オーバーレイをテストするための KV260 用の Vivado 2021.2 のプロジェクトを作成する1

Vitis HLS 2021.2 で DMA Readしたデータを2乗し、DMA Writeする KV260 用 IP を作成”の続き。

KV260 で ikwzm さんの Debian をインストールしてきたが、Ultra96 でやったように DMA Readしたデータを2乗し、DMA Writeする KV260 用 IP を Vitis HLS 2021.2 で作って、Vivado で実装して KV260 の Debian に持っていて動作させてみよう。前回は、Vitis HLS 2021.2 で DMA Read したデータを2乗し、DMA Writeする KV260 用 IP を Vitis HLS 2021.2 で作成した。今回は、その DMA_pow2 IP を使用してVivado 2021.2 でDMA_pow2_test プロジェクトを作成し、ブロック・デザインを作成して、論理合成、インプリメンテーション、ビットストリームの生成を行った。

Krira KV260 Vision AI starter Kit のボード・ファイルを使用して、Vivado 2021.2 の DMA_pow2_test プロジェクトを作成した。
ikwzm_Debian_kv260_76_211118.png

プロジェクト作成時に DMA_pow2_test ディレクトリが作成されているので、そのディレクトリの下に DMA_pow2 ディレクトリを作成して、”Vitis HLS 2021.2 で DMA Readしたデータを2乗し、DMA Writeする KV260 用 IP を作成”で作成した DMA_pow2 IP をコピーする。実際には、DMA_pow2/solution1/impl/export.zip を展開して、DMA_pow2 ディレクトリにコピーした。
ikwzm_Debian_kv260_77_211118.png

DMA_pow2_test プロジェクトで、Flow Navigator から IP Catalog をクリックして、IP Catalog を表示し、Add Repository でDMA pow2 IP をリポジトリに追加した。これで、DMA_pow2 IP がIP Integrator から使用することができる。
ikwzm_Debian_kv260_78_211118.png

次に、Create Block Design をクリックして、DMA_pow2_test ブロック・デザインを作成した。
完成したDMA_pow2_test ブロック・デザインを示す。
ikwzm_Debian_kv260_79_211118.png

Address Map を示す。
ikwzm_Debian_kv260_80_211118.png

Zynq UltraScale+ MPSoC の設定を示す。
AXI HPM0_FPD と AXI_HP0_FPD を使用している。
ikwzm_Debian_kv260_81_211118.png

PL への出力クロックは 100 MHz に設定されている。
ikwzm_Debian_kv260_82_211118.png

Vivado HLS 2018.2 で作成したDMP_pow2 IP のPROT value は "010" に、CACHE value は "1111" に設定した。(ikwzm さんの”UltraZed 向け Debian GNU/Linux で AXI HPC port を使う (実践編1)”を参照した)
ikwzm_Debian_kv260_83_211118.png

Validate Design を行ったところ、成功した。
ikwzm_Debian_kv260_84_211118.png

ブロック・デザインをセーブして、プロジェクト・トップとなる DMA_pow2_test.v を作成した。具体的には、source ウインドウで、ブロック・デザインの DMA_pow2_test_i を右クリックし右クリックメニューから Create HDL Wrapper... を選択した。
ikwzm_Debian_kv260_85_211118.png

今回はPS と PL で完結していて外にポートが出ていないので、制約ファイルの必要がない。
論理合成、インプリメンテーション、ビットストリームの生成を行った。成功した。Project Summary を示す。
ikwzm_Debian_kv260_86_211118.png
  1. 2021年11月19日 05:39 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

Vitis HLS 2021.2 で DMA Readしたデータを2乗し、DMA Writeする KV260 用 IP を作成

KV260 で ikwzm さんの ZynqMP-FPGA-Linux を試してみる5(OpenCV 4.5.4 をインストール、その2)”の続き。

KV260 で ikwzm さんの Debian をインストールしてきたが、Ultra96 でやったように DMA Readしたデータを2乗し、DMA Writeする KV260 用 IP を Vitis HLS 2021.2 で作って、Vivado で実装して KV260 の Debian に持っていて動作させてみよう。今回は手始めに Vitis HLS 2021.2 で DMA Read したデータを2乗し、DMA Writeする KV260 用 IP を Vitis HLS 2021.2 で作成する。(”Vivado HLS でDMA Readしたデータを2乗し、DMA WriteするUltra96ボード用 IP を作成”参照)

ソースコードの DMA_pow2.cpp を示す。

// DMA_pow2.cpp
// 2021/11/17 by marsee

#include <stdint.h>

int DMA_pow2(int32_t *in, int32_t *out){
#pragma HLS INTERFACE mode=m_axi depth=10 port=out offset=slave
#pragma HLS INTERFACE mode=m_axi depth=10 port=in offset=slave
#pragma HLS INTERFACE mode=s_axilite port=return
    for(int i=0; i<10; i++){
        out[i] = in[i] * in[i];
    }
    return(0);
}


テストベンチ・コードの DMA_pow2_tb.cpp を示す。

// DMA_pow2_tb.cpp
// 2021/11/17 by marsee
//

#include <iostream>
#include <stdint.h>

int DMA_pow2(int32_t *in, int32_t *out);

int main(){
    int32_t data[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int32_t result[10];

    DMA_pow2(data, result);

    for(int i=0; i<10; i++){
        std::cout << "data[" << i << "]= " << data[i] <<
                ", result[" << i << "] = " <<
                result[i] << std::endl;
    }
}


Vitis HLS 2021.2 の DMA_pow2 プロジェクトを示す。
Part Selection の Part に xck26-sfvc784-2LV-c を指定した。
ikwzm_Debian_kv260_66_211117.png

C シミュレーションを行った。結果を示す。
ikwzm_Debian_kv260_67_211117.png

C コードの合成を行った。結果を示す。
PIPELINE 指示子を付けなくても Interval は 1 クロックに収まっている。
ikwzm_Debian_kv260_68_211117.png
ikwzm_Debian_kv260_69_211117.png
ikwzm_Debian_kv260_70_211117.png
ikwzm_Debian_kv260_71_211117.png

C/RTL 協調シミュレーションを行った。結果を示す。
ikwzm_Debian_kv260_72_211117.png

C/RTL 協調シミュレーションの波形を示す。
性能的には問題ないようだ。Read も Write もバーストアクセスになっている。
ikwzm_Debian_kv260_73_211117.png

Export RTL を行った。
IP が生成されている。
ikwzm_Debian_kv260_74_211117.png

Implementation を行った。
一部の結果を示す。
ikwzm_Debian_kv260_75_211117.png

Zynq UltraScale+ MPSoCだから、動作周波数 100 MHz は余裕だね。
  1. 2021年11月18日 03:49 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

Vitis HLS 2021.2 での AXI4 Master インターフェースにおける volatile の扱い5(単発アクセス 3)

Vitis HLS 2021.2 での AXI4 Master インターフェースにおける volatile の扱い4(単発アクセス 2)”の続き。

Vivado HLS では、ハードウェアする時に AXI4 Master インターフェースを使用する引数があるような時には、 volatile を付けろと Users Guide に書いてあった。しかし、 Vitis HLS での volatile の扱いは違っているのかも知れない?それを検証してみようということで、前回は、関数の引数に volatile を付けて、その結果を確認したが、Write は 4 を書いてから、 8 書いているので、これはコードのままなのだが、 Read の方が 2 回ずつ計 4 回 Read しているはずなのに 2 回のみになっている。今回は、Read も 4 回アクセスがでるようにコードを修正してみよう。

Read アクセスが 4 回でるようにソースコードを修正する。
いろいろとやってみたが、関数内で宣言された変数の acc に volatile を付けると Read が 4 回になる。
修正した。ソースコードの pointer_stream_bad.cpp を示す。
volatile_36_211116.png

// pointer_stream_bad.cpp
// 2021/11/11

#include "stdint.h"

void pointer_stream_bed(volatile int32_t *d_o, volatile int32_t *d_i){
#pragma HLS INTERFACE mode=m_axi depth=1 port=d_i offset=slave
#pragma HLS INTERFACE mode=m_axi depth=1 port=d_o offset=slave
#pragma HLS INTERFACE mode=s_axilite port=return
    volatile int32_t acc = 0;

    acc += *d_i;
    acc += *d_i;
    *d_o = acc;
    acc += *d_i;
    acc += *d_i;
    *d_o = acc;
}


C コードの合成を行った。結果を示す。
volatile_37_211116.png
volatile_38_211116.png
volatile_39_211116.png

Latency が 32 クロックになっている。前回は、29 クロックだった。

C/RTL 協調シミュレーションを行った。結果を示す。
volatile_40_211116.png

Latency が 52 クロックになっている。前回は、49 クロックだった。

C/RTL 協調シミュレーションの波形を示す。
volatile_41_211116.png

Read 2 回行って、Write 1 回が 2 回ある想定通りの AXI4 Master アクセスになった。
つまり、このコードでは引数だけでなく、関数内で宣言された変数の acc に volatile を付ける必要があったようだ。覚えておこう。
  1. 2021年11月17日 03:36 |
  2. Vitis HLS
  3. | トラックバック:0
  4. | コメント:0

Vitis HLS 2021.2 での AXI4 Master インターフェースにおける volatile の扱い4(単発アクセス 2)

Vitis HLS 2021.2 での AXI4 Master インターフェースにおける volatile の扱い3(単発アクセス 1)”の続き。

Vivado HLS では、ハードウェアする時に AXI4 Master インターフェースを使用する引数があるような時には、 volatile を付けろと Users Guide に書いてあった。しかし、 Vitis HLS での volatile の扱いは違っているのかも知れない?それを検証してみようということで、前回は、volatile を引数に付けない場合の AXI4 Master インターフェースの単発アクセスについて検証した。結果は、Read、 Write 共に 1 回の AXI4 Master アクセスとなった。今回は、関数の引数に volatile を付けて、その結果を見てみよう。

pointer_stream_bed関数(ミススペルに気がついたが、そのまま行きます) d_o と d_i 引数に volatile を付けた。
volatile_30_211115.png

これで C コードの合成を行った。結果を示す。
volatile_31_211115.png
volatile_32_211115.png
volatile_33_211115.png

Latency は 29 クロックだった。

C/RTL 協調シミュレーションを行った。結果を示す。
Latency は 49 クロックだった。
volatile_34_211115.png

C/RTL 協調シミュレーションの波形を示す。
volatile_35_211115.png

Read も Write も 2 回ずつのアクセスが発生している。
Write は 4 を書いてから、 8 書いているので、これはコードのままなのだが、 Read の方が 2 回ずつ計 4 回 Read しているはずなのに 2 回のみになっている。
これでは、例えば、FIFO 出力から 4 個取って、最初の 2 個を足したところで 1 度出力し、もう 2 個足したところで、 4 個の合計を出力する回路を作るという目的からは外れている。それでは、ソースコード通りにアクセスを発生させるにはどうしたら良いだろうか? 次回はソースコード通りにアクセスを発生させてみよう。
  1. 2021年11月16日 04:11 |
  2. Vitis HLS
  3. | トラックバック:0
  4. | コメント:0

Microchip Technology Hello FPGAキットが来ました

Microchip Technology Hello FPGAキットが土曜日に来ました。

Mouser の Microchip Technology Hello FPGAキットのページです。
非揮発性、フラッシュベース、低消費電力SmartFusion2 SoC FPGA(M2S010)が乗っているようです。
Mouser の Microchip Technology Hello FPGAキットのページの特徴を引用します。

・制御ロジックとデータアクイジション、画像処理、信号処理、人工知能アプリケーションの開発に最適です。
・非揮発性、フラッシュベース、低消費電力SmartFusion2 SoC FPGA(M2S010)に基づいています。
・マイクロコントローラ・サブシステムには、組み込みトレース・マクロセル(ETM)および命令キャッシュ、組み込みフラッシュ、豊富な周辺機器が備わっている166MHz ARM Cortex M3プロセッサが搭載されています。
・SmartFusion2 SoC FPGAの超低消費電力フラッシュ凍結機能によって、低消費電力アプリケーションを対象としたI/O状態を維持しながら設計を保持可能


Libero SoC というのが Microchip の FPGA 用ツールで、Silver(Free) が無料のようです

MICROCHIPのSmart High-Level Synthesis (SmartHLS)はSmartHLS v2021.2 release requires a free stand-alone license.
ということで無料でライセンスもらえるよう
です。

Hello_FPGA_1_211115.jpg

Hello_FPGA_2_211115.jpg

Hello_FPGA_3_211115.jpg

Hello_FPGA_4_211115.jpg

Hello_FPGA_5_211115.jpg

Hello_FPGA_6_211115.jpg
  1. 2021年11月15日 05:24 |
  2. Hello FPGA
  3. | トラックバック:0
  4. | コメント:0

Vitis HLS 2021.2 での AXI4 Master インターフェースにおける volatile の扱い3(単発アクセス 1)

Vitis HLS 2021.2 での AXI4 Master インターフェースにおける volatile の扱い2(バーストアクセス 2)”の続き。

Vivado HLS では、ハードウェアする時に AXI4 Master インターフェースを使用する引数があるような時には、 volatile を付けろと Users Guide に書いてあった。しかし、 Vitis HLS での volatile の扱いは違っているのかも知れない?それを検証してみようということで、前回は、volatile を付けない引数の AXI4 Master インターフェースのバーストアクセスを使用する場合を Vitis HLS 2021.2 で検証した。結果は、volatile を付けない方が良いということだった。次に、AXI4 Master インターフェースで volatile を付けたほうが良い場合を検証していこう。今回は、volatile を引数に付けない場合の AXI4 Master インターフェースの単発アクセスについて検証する。

Vitis High-Level Synthesis User Guide UG1399 2021-10-27 2021.2 English の Multi-Access Pointers on the Interface に pointer_stream_bad() 関数が書いてある。その関数を自分で少し改変してソースコードとして引用する。(pointer_stream_bad.cpp)

// pointer_stream_bad.cpp
// 2021/11/11

#include "stdint.h"

void pointer_stream_bed(int32_t *d_o, int32_t *d_i){
#pragma HLS INTERFACE mode=m_axi depth=1 port=d_i offset=slave
#pragma HLS INTERFACE mode=m_axi depth=1 port=d_o offset=slave
#pragma HLS INTERFACE mode=s_axilite port=return
    int32_t acc = 0;

    acc += *d_i;
    acc += *d_i;
    *d_o = acc;
    acc += *d_i;
    acc += *d_i;
    *d_o = acc;
}


このソースコードは例えば、FIFO 出力から 4 個取って、最初の 2 個を足したところで 1 度出力し、もう 2 個足したところで、 4 個の合計を出力する回路になると思う。 FIFO 出力が AXI4 Lite インターフェースならば、バーストアクセスにならないで単発アクセスなので、ちょうど適合するかな?

テストベンチの pointer_stream_bad_tb.cpp は自分で作成した。

// pointer_stream_bad_tb.cpp
// 2021/11/11 by marsee

#include "stdint.h"
#include "stdio.h"

void pointer_stream_bed(int32_t *d_o, int32_t *d_i);

int main(){
    int32_t d_o = 0;
    int32_t d_i = 2;

    pointer_stream_bed(&d_o, &d_i);

    printf("d_o = %d, d_i = %d\n", (int)d_o, (int)d_i);
}



Vitis HLS 2021.2 で pointer_stream_bad プロジェクトを作成した。
volatile_23_211114.png

C シミュレーションを行った。
d_o は 2 を 4 回加算したので、8 になっている。
volatile_24_211114.png

C コードの合成を行った。結果を示す。
volatile_25_211114.png
volatile_26_211114.png
volatile_27_211114.png

C/RTL 協調シミュレーションを行った。結果を示す。
レイテンシは 24 クロックだった。
volatile_29_211114.png

C/RTL 協調シミュレーションの波形を確認する。
volatile_28_211114.png

AXI4 Master の Read も Write も 1 回のアクセスのみとなっている。
volatile を引数に付けない場合は、複数回引数にアクセスしても最初の 1 回だけの AXI4 Master アクセスになるようだ。
これは C や C++ として考えると当たり前のことかも知れない。ソフトウェアでは、最初に引数に値を与えて関数をコールし、返り値け結果の値を返すの普通だ。つまり、関数をコールしたら通常は同じ引数から値を得ることは無い。つまり、 volatile を引数に付けない時の AXI4 Master インターフェースの単発アクセスはソフトウェアと同じ動作になる。
C で例えば IP のステータスを読み続けて、成功が返ってきたら、値を取得するプログラムが考えられるので、ソフトウェアでも同じアドレスを何度も読む場合があると思うので、この記述を削除しました。
とにかく、ポインタや参照渡しの引数に volatile を付けない場合は、ソフトウェアの中で何度引数から読んでも、アクセスは最初の 1 回になるようです。書き込みも 1 回だけになるようです。
  1. 2021年11月14日 05:10 |
  2. Vitis HLS
  3. | トラックバック:0
  4. | コメント:0

Vitis HLS 2021.2 での AXI4 Master インターフェースにおける volatile の扱い2(バーストアクセス 2)

Vitis HLS 2021.2 での AXI4 Master インターフェースにおける volatile の扱い1(バーストアクセス 1)”の続き。

Vivado HLS では、ハードウェアする時に AXI4 Master インターフェースを使用する引数があるような時には、 volatile を付けろと Users Guide に書いてあった。しかし、 Vitis HLS での volatile の扱いは違っているのかも知れない?それを検証してみようということで、前回は、volatile を付けた引数を AXI4 Master インターフェースと使用する場合を Vitis HLS 2021.2 で検証した。今回は、前回から volatile を除いた場合について検証していこう。

s_squares_axim3.cpp ソースコードを示す。前回のソースコードから引数の volatile を削除した。
volatile_10_211112.png

#include <stdint.h>

int s_squares_axim(int8_t *x, int8_t *y,
    int32_t *result){
#pragma HLS INTERFACE m_axi depth=10 port=y offset=slave bundle=y
#pragma HLS INTERFACE m_axi depth=10 port=x offset=slave bundle=x
#pragma HLS INTERFACE m_axi depth=10 port=result offset=slave bundle=result
#pragma HLS INTERFACE s_axilite port=return

    for(int i=0; i<10; i++){
#pragma HLS PIPELINE II=1
        result[i] = x[i]*x[i] + y[i]*y[i];
    }

    return(0);
}


テストベンチの s_squares_axim_tb.cpp を示す。

#include <iostream>
#include <stdint.h>

int s_squares_axim(int8_t *x, int8_t *y,
    int32_t *result);

int main(){
    int8_t x[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int8_t y[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int32_t result[10];

    s_squares_axim(x, y, result);

    for(int i=0; i<10; i++){
        std::cout << "x[" << i << "]= " << (int)x[i] <<
                ", y[" << i << "] = " << (int)y[i] <<
                ", result[" << i << "] = " <<
                (int)result[i] << std::endl;
    }
}


C シミュレーションは前回と同じなので、C コードの合成からやってみよう。結果を示す。
volatile_11_211112.png

前回の Latency は 28 クロックだったが、今回の実装では、31 クロックになっている。
しかも Modules & Loops に s_squares_axim_Pipline_VITIS_LOOP_10_1 が増えている。
前回のFFは 2143 個、LUT は 2698 個だった。今回の FF は 2214 個、LUT は 3151 個だった。
残りの C コードの合成レポートを示す。
volatile_12_211112.png
volatile_18_211112.png

M_AXI Burst Information が変更になっている。
Inferred Burst Summary がきちんとレポートされている。
Inferred Burst and Widening Missed も表示されているが、volatile のじゃなくなっている。
残りの C コードの合成レポートを示す。
volatile_13_211112.png

C/RTL 協調シミュレーションの結果を示す。
前回のクロック数は 37 クロックで、前回と同じだった。
volatile_22_211113.png

C/RTL 協調シミュレーションの波形を示す。
これも前回と同じでバーストアクセスとなっている。
volatile_19_211112.png
volatile_20_211112.png

IMPLEMENTATION を行った。
これも、全く前回と一緒の結果になった。
volatile_21_211112.png

AXI4 Master インターフェースの引数から volatile を除いた場合は、C コードの合成では、異なる結果になった。実際に Verilog HDL のコードもファイルが増えていた。しかし、C/RTL 協調シミュレーションでの結果は前回と同じだった。IMPLEMENTATION の結果も前回と全く同じだった。つまり、Vivado で合成すると待った同じ回路になった。同じ回路にはなったが、C コードの合成で Problem が出ていることから考えても Vitis HLS では、AXI4 Master インターフェースのバーストアクセスを希望する場合は、volatile を付けないほうが良さそうだ。
Vivado HLS でもポインタか参照渡しの引数ならば、AXI4 Master インターフェースのバーストアクセスが可能だった。
  1. 2021年11月13日 04:59 |
  2. Vitis HLS
  3. | トラックバック:0
  4. | コメント:0

Vitis HLS 2021.2 での AXI4 Master インターフェースにおける volatile の扱い1(バーストアクセス 1)

Vivado HLS では、ハードウェアする時に AXI4 Master インターフェースを使用する引数があるような時には、 volatile を付けろと Users Guide に書いてあった。しかし、 Vitis HLS での volatile の扱いは違っているのかも知れない?それを検証してみよう。

Vivado HLS 2019.2 UG902 (v2019.2) 2020 年 1 月 13 日 の volatile の説明を引用する。
volatile_14_211112.png

Vitis HLS 2020.1 UG1399 (v2020.1) 2020 年 6 月 24 日 の volatile の説明を引用する。
volatile_15_211112.png
バーストアクセスなし等の文言が増えている。

さて、Vitis HLS 2021.2 で実際にやってみよう。

s_squares_axim3.cpp ソースコードを示す。これは Vivado HLS 時代からセミナの実装例として使用している。
AXI4 Master インターフェースを 3 個持ったデザインとなっている。ここでは、関数を読んだ時に複数個データを Read したり、データを Write したりしているので、 volatile を付けている。

#include <stdint.h>

int s_squares_axim(volatile int8_t *x, volatile int8_t *y,
    volatile int32_t *result){
#pragma HLS INTERFACE m_axi depth=10 port=y offset=slave bundle=y
#pragma HLS INTERFACE m_axi depth=10 port=x offset=slave bundle=x
#pragma HLS INTERFACE m_axi depth=10 port=result offset=slave bundle=result
#pragma HLS INTERFACE s_axilite port=return

    for(int i=0; i<10; i++){
#pragma HLS PIPELINE II=1
        result[i] = x[i]*x[i] + y[i]*y[i];
    }

    return(0);
}


テストベンチの s_squares_axim_tb.cpp を示す。

#include <iostream>
#include <stdint.h>

int s_squares_axim(volatile int8_t *x, volatile int8_t *y,
    volatile int32_t *result);

int main(){
    int8_t x[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int8_t y[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int32_t result[10];

    s_squares_axim(x, y, result);

    for(int i=0; i<10; i++){
        std::cout << "x[" << i << "]= " << (int)x[i] <<
                ", y[" << i << "] = " << (int)y[i] <<
                ", result[" << i << "] = " <<
                (int)result[i] << std::endl;
    }
}



s_squares_axim プロジェクトを示す。
volatile_1_211111.png

C シミュレーションを行った。結果を示す。
volatile_2_211111.png

C コードの合成を行った。結果を示す。
volatile_3_211111.png
volatile_4_211111.png
volatile_17_211112.png

M_AXI Burst Information に Volatile の Problem が出ているのが分かる。UG1399 でバーストアクセスなしになっているからだろう?
214-227 をクリックすると Burst Interface Failure 5 が表示された。
volatile_5_211111.png

つまり、volatile を削除しろと言っている。

volatile そのままで C/RTL 協調シミュレーションを行った。結果を示す。
Latency は 37 クロックだった。
volatile_6_211111.png

C/RTL 協調シミュレーションの波形を見た。
バーストアクセスなしとはなっていても、Read も Write もバーストアクセスしている。
volatile_7_211111.png
volatile_8_211111.png

Implementation の結果を示す。
volatile_9_211111.png

Vitis HLS 2021.2 では、引数に volatile を付けていてもバーストアクセスすることができている。しかし、C コードの合成で volatile を付けていることの Problem が出ている。
次回は、volatile を削除してやってみよう。
  1. 2021年11月12日 05:12 |
  2. Vitis HLS
  3. | トラックバック:0
  4. | コメント:0

KV260 で ikwzm さんの ZynqMP-FPGA-Linux を試してみる5(OpenCV 4.5.4 をインストール、その2)

KV260 で ikwzm さんの ZynqMP-FPGA-Linux を試してみる4(OpenCV 4.5.4 をインストール、その1)”の続き。

KV260 に ikwzm さんの ZynqMP-FPGA-Linux をインストールして、前回は、OpenCV 4.5.4 をインストールしようということで、cmake まで実行した。今回は、OpenCV 4.5.4 の残りのインストールを行う。

make -j4
で、4 個のプロセッサを使用して、make したが、74 % で止まってしまった。反応が相当遅くなっているみたいだ。
ikwzm_Debian_kv260_48_211110.png
ikwzm_Debian_kv260_49_211110.png

一旦リブートして、もう一度 2 プロセッサで make を実行した。
make -j2
ikwzm_Debian_kv260_50_211110.png
ikwzm_Debian_kv260_51_211110.png
ikwzm_Debian_kv260_52_211110.png

make が終了した。

sudo make install
ikwzm_Debian_kv260_53_211110.png

sudo ldconfig
ikwzm_Debian_kv260_54_211110.png

1 つ上のディレクトリに上がって、 samples/python ディレクトリに入った。
cd ../samples/python/
ls

ikwzm_Debian_kv260_55_211110.png

デモ・ソフトウェアを起動した。
python3 demo.py
ikwzm_Debian_kv260_56_211110.png

facedetect.py を Run した。
ikwzm_Debian_kv260_57_211110.png

ikwzm_Debian_kv260_58_211110.jpg

asift.py を Run した。
ikwzm_Debian_kv260_59_211110.png

ikwzm_Debian_kv260_60_211110.jpg

これもうまく行った。

画像を見るのに、 viewnior をインストールした。
sudo apt install viewnior
ikwzm_Debian_kv260_61_211110.png

calibrate.py を Run した。カメラのレンズの歪みを補正するソフトウェアのようだ。
ikwzm_Debian_kv260_62_211110.png

これが元画像。
ikwzm_Debian_kv260_63_211110.jpg

これが補正画像だ。
ikwzm_Debian_kv260_64_211110.jpg

find_oby.py を Run した。画像が何処にあるかを調べるソフトウェアのようだ。
ikwzm_Debian_kv260_65_211110.png

結果のウインドウ。
ikwzm_Debian_kv260_66_211110.jpg

OpenCV 4.5.4 はきちんと動作するようだ。
  1. 2021年11月11日 03:54 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

KV260 で ikwzm さんの ZynqMP-FPGA-Linux を試してみる4(OpenCV 4.5.4 をインストール、その1)

KV260 で ikwzm さんの ZynqMP-FPGA-Linux を試してみる3”の続き。

ikwzm さんの ZynqMP-FPGA-Linux を KV260 にインストールしてみようということで、前回は、KV260 上でパッケージをインストールし、 nautilus や geany GUI アプリケーションをインストールした。今回は、OpenCV 4.5.4 をインストールしよう。cmake までを書いた。

OpenCV 4.5.4 をインストールするために参考にしたサイトは”OpenCVが4.0になっていたのでcontribも含めてコンパイルしてみる。
それと、自分のブログの”Ultra96-V2 に ikwzm/ZynqMP-FPGA-Linux をインストール4(OpenCV 4.1.0 のインストール)

OpenCVが4.0になっていたのでcontribも含めてコンパイルしてみる。”を参考にして、必要なパッケージをインストールする。

sudo apt install build-essential
ikwzm_Debian_kv260_39_211110.png

sudo apt install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
ikwzm_Debian_kv260_40_211110.png

sudo apt install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libdc1394-22-dev
ikwzm_Debian_kv260_41_211110.png

OpenCV 4.5.4 を git clone する。
git clone https://github.com/opencv/opencv.git
ls
cd opencv
ls
git checkout -b 4.5.4 refs/tags/4.5.4

ikwzm_Debian_kv260_42_211110.png

Ultra96-V2 に ikwzm/ZynqMP-FPGA-Linux をインストール4(OpenCV 4.1.0 のインストール)”のパッケージをインストールする。

sudo apt install python3-tk libgtk2.0-dev pkg-config
ikwzm_Debian_kv260_43_211110.png

sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
ikwzm_Debian_kv260_44_211110.png

sudo apt-get install libcanberra-gtk-module
ikwzm_Debian_kv260_45_211110.png

build ディレクトリを作成した。build ディレクトリに入った。
cmake を行った。
mkdri build
cd build
cmake -DCMAKE_BUILD_TYPE=RELEASE \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DINSTALL_PYTHON_EXAMPLES=ON \
-DINSTALL_C_EXAMPLES=ON \
-DPYTHON_EXECUTABLE=/usr/bin/python3 \
-DBUILD_EXAMPLES=ON \
-DWITH_GTK=ON \
-DWITH_FFMPEG=ON ..

ikwzm_Debian_kv260_46_211110.png

ikwzm_Debian_kv260_47_211110.png

-- General configuration for OpenCV 4.5.4 =====================================
--   Version control:               4.5.4
-- 
--   Platform:
--     Timestamp:                   2021-11-09T19:34:09Z
--     Host:                        Linux 5.10.0-xlnx-v2021.1-zynqmp-fpga aarch64
--     CMake:                       3.13.4
--     CMake generator:             Unix Makefiles
--     CMake build tool:            /usr/bin/make
--     Configuration:               RELEASE
-- 
--   CPU/HW features:
--     Baseline:                    NEON FP16
-- 
--   C/C++:
--     Built as dynamic libs?:      YES
--     C++ standard:                11
--     C++ Compiler:                /usr/bin/c++  (ver 8.3.0)
--     C++ flags (Release):         -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections    -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG  -DNDEBUG
--     C++ flags (Debug):           -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections    -fvisibility=hidden -fvisibility-inlines-hidden -g  -O0 -DDEBUG -D_DEBUG
--     C Compiler:                  /usr/bin/cc
--     C flags (Release):           -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections    -fvisibility=hidden -O3 -DNDEBUG  -DNDEBUG
--     C flags (Debug):             -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections    -fvisibility=hidden -g  -O0 -DDEBUG -D_DEBUG
--     Linker flags (Release):      -Wl,--gc-sections -Wl,--as-needed  
--     Linker flags (Debug):        -Wl,--gc-sections -Wl,--as-needed  
--     ccache:                      NO
--     Precompiled headers:         NO
--     Extra dependencies:          dl m pthread rt
--     3rdparty dependencies:
-- 
--   OpenCV modules:
--     To be built:                 calib3d core dnn features2d flann gapi highgui imgcodecs imgproc ml objdetect photo python2 python3 stitching ts video videoio
--     Disabled:                    world
--     Disabled by dependency:      -
--     Unavailable:                 java
--     Applications:                tests perf_tests examples apps
--     Documentation:               NO
--     Non-free algorithms:         NO
-- 
--   GUI:                           GTK2
--     GTK+:                        YES (ver 2.24.32)
--       GThread :                  YES (ver 2.58.3)
--       GtkGlExt:                  NO
--     VTK support:                 NO
-- 
--   Media I/O: 
--     ZLib:                        /usr/lib/aarch64-linux-gnu/libz.so (ver 1.2.11)
--     JPEG:                        /usr/lib/aarch64-linux-gnu/libjpeg.so (ver 62)
--     WEBP:                        build (ver encoder: 0x020f)
--     PNG:                         /usr/lib/aarch64-linux-gnu/libpng.so (ver 1.6.36)
--     TIFF:                        /usr/lib/aarch64-linux-gnu/libtiff.so (ver 42 / 4.1.0)
--     JPEG 2000:                   build (ver 2.4.0)
--     OpenEXR:                     build (ver 2.3.0)
--     HDR:                         YES
--     SUNRASTER:                   YES
--     PXM:                         YES
--     PFM:                         YES
-- 
--   Video I/O:
--     DC1394:                      YES (2.2.5)
--     FFMPEG:                      YES
--       avcodec:                   YES (58.35.100)
--       avformat:                  YES (58.20.100)
--       avutil:                    YES (56.22.100)
--       swscale:                   YES (5.3.100)
--       avresample:                NO
--     GStreamer:                   NO
--     v4l/v4l2:                    YES (linux/videodev2.h)
-- 
--   Parallel framework:            pthreads
-- 
--   Trace:                         YES (with Intel ITT)
-- 
--   Other third-party libraries:
--     Lapack:                      NO
--     Eigen:                       NO
--     Custom HAL:                  YES (carotene (ver 0.0.1))
--     Protobuf:                    build (3.5.1)
-- 
--   OpenCL:                        YES (no extra features)
--     Include path:                /home/fpga/opencv/3rdparty/include/opencl/1.2
--     Link libraries:              Dynamic load
-- 
--   Python 2:
--     Interpreter:                 /usr/bin/python2.7 (ver 2.7.16)
--     Libraries:                   /usr/lib/aarch64-linux-gnu/libpython2.7.so (ver 2.7.16)
--     numpy:                       /usr/lib/python2.7/dist-packages/numpy/core/include (ver 1.16.2)
--     install path:                lib/python2.7/dist-packages/cv2/python-2.7
-- 
--   Python 3:
--     Interpreter:                 /usr/bin/python3 (ver 3.7.3)
--     Libraries:                   /usr/lib/aarch64-linux-gnu/libpython3.7m.so (ver 3.7.3)
--     numpy:                       /usr/lib/python3/dist-packages/numpy/core/include (ver 1.16.2)
--     install path:                lib/python3.7/dist-packages/cv2/python-3.7
-- 
--   Python (for build):            /usr/bin/python2.7
-- 
--   Java:                          
--     ant:                         NO
--     JNI:                         NO
--     Java wrappers:               NO
--     Java tests:                  NO
-- 
--   Install to:                    /usr/local
-- -----------------------------------------------------------------
-- 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/fpga/opencv/build

  1. 2021年11月10日 05:11 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

KV260 で ikwzm さんの ZynqMP-FPGA-Linux を試してみる3

KV260 で ikwzm さんの ZynqMP-FPGA-Linux を試してみる2”の続き。

ikwzm さんの ZynqMP-FPGA-Linux を KV260 にインストールしてみようということで、前回は、Micro SD カードをフォーマットし、各種ファイルをコピー、設定を行った。 Micro SD カードを KV260 に挿入して、 Debian 10 を起動することができた。今回は、 KV260 上でパッケージをインストールし、 nautilus や geany GUI アプリケーションをインストールした。

ZynqMP-FPGA-Linux/doc/install/kv260.md の続きを参照しながらパッケージをインストールする。

ssh でログインして、 debian ディレクトリに入る。
ssh 192.168.3.48 -X -l fpga
なんか毎回 IP アドレスが違うようだ。
ikwzm_Debian_kv260_21_211109.png

Linux イメージ・パッケージをインストールする。
cd debian
ls
sudo dpkg -i linux-image-5.10.0-xlnx-v2021.1-zynqmp-fpga_5.10.0-xlnx-v2021.1-zynqmp-fpga-2_arm64.deb

ikwzm_Debian_kv260_22_211109.png

Linux ヘッダ・パッケージをインストールする。
sudo dpkg -i linux-headers-5.10.0-xlnx-v2021.1-zynqmp-fpga_5.10.0-xlnx-v2021.1-zynqmp-fpga-2_arm64.deb
ikwzm_Debian_kv260_23_211109.png
ikwzm_Debian_kv260_24_211109.png
ikwzm_Debian_kv260_25_211109.png

fclkcfg デバイス・ドライバとサービス・パッケージをインストールする。
sudo dpkg -i fclkcfg-5.10.0-xlnx-v2021.1-zynqmp-fpga_1.7.2-1_arm64.deb
ikwzm_Debian_kv260_26_211109.png

u-dma-buf デバイス・ドライバとサービス・パッケージをインストールする。
sudo dpkg -i u-dma-buf-5.10.0-xlnx-v2021.1-zynqmp-fpga_3.2.4-0_arm64.deb
ikwzm_Debian_kv260_27_211109.png

X11をインストールして、 nautilus, geany の GUI アプリケーションをインストールする。(”Ultra96-V2 に ikwzm/ZynqMP-FPGA-Linux をインストール3(GUIアプリのインストール)”参照)

最初に現在の環境をアップデートする。
sudo apt update
ikwzm_Debian_kv260_28_211109.png
ikwzm_Debian_kv260_29_211109.png

sudo apt upgrade
ikwzm_Debian_kv260_30_211109.png
ikwzm_Debian_kv260_31_211109.png

X11関連のパッケージをインストールする。
sudo apt install xbase-clients xterm x11-apps
ikwzm_Debian_kv260_32_211109.png

GUI アプリ(nautilus と geany)をインストールする。
sudo apt install nautilus geany
ikwzm_Debian_kv260_33_211109.png

ここで KV260 をリブートした。

もう一度 ssh でログインしてから、
nautilus &
でファイル・マネージャーを起動した。
ikwzm_Debian_kv260_34_211109.png

ikwzm_Debian_kv260_35_211109.png

nautilus が起動した。

geany &
で geany テキスト・エディタを起動した。
ikwzm_Debian_kv260_36_211109.png

ikwzm_Debian_kv260_37_211109.png

geany が起動した。

日本語フォントをインストールするのを忘れていたので、インストールした。
sudo apt install fonts-vlgothic fonts-horai-umefont fonts-umeplus
ikwzm_Debian_kv260_38_211109.png
  1. 2021年11月09日 04:52 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

KV260 で ikwzm さんの ZynqMP-FPGA-Linux を試してみる2

KV260 で ikwzm さんの ZynqMP-FPGA-Linux を試してみる1”の続き。

ikwzm さんの ZynqMP-FPGA-Linux を KV260 にインストールしてみようということで、ZynqMP-FPGA-Linux/doc/install/kv260.md を参照しながら、 KV260 用の Debian 10 の SD カードを作成しているが、前回は、 ikwzm さんの ZynqMP-FPGA-Linux を git clone して Micro SD カードをアンマウントした。今回は、 Micro SD カードをフォーマットし、各種ファイルをコピー、設定を行った。 Micro SD カードを KV260 に挿入して、 Debian 10 を起動することができた。

なお、 OS は Ubuntu 18.04 LTS を使用している。
Micro SD カードをフォーマットする。
sudo fdisk /dev/sdf (/dev/sdf の部分は自分のマシンにマウントされた Micro SD カードのデバイス名を使用してください)
p コマンドで状態を確認した。
ikwzm_Debian_kv260_7_211107.png

d コマンド、 d コマンドでパーティションを 2 個削除した。
p コマンドで状態を確認した。
ikwzm_Debian_kv260_8_211107.png

プライマリ・ディスクのパーティション番号1に100MBの領域を確保
n コマンドで新たにパーティションを作製した
p を押して、primary パーティションを指定した
パーティション番号を 1 にセット
First sectorで、Enterキーを入力した
Last sectorで、+100M を入力して、100MBの領域を確保した

プライマリ・ディスクのパーティション番号2に残りの領域を確保
n コマンドで新たにパーティションを作製した
p を押して、primary パーティションを指定した。
パーティション番号を 2 にセット
最初セクタで、Enterキーを入力した。
Lastセクタで、Enterキーを入力した。
p コマンドでパーティションを表示した

プライマリ・ディスクのパーティション番号1をFAT32にして、ブート可能フラグを付ける
t コマンドを入力した
パーティション番号に 1 を入力した
16進コードに、b を入力した(W95 FAT32)
a コマンドを入力して、ブート可能フラグを付ける
パーティション番号に 1 を入力した

設定が終了したので、 w コマンドで Micro SD カードにパーティション・テーブルを書き込んだ。
ikwzm_Debian_kv260_9_211107.png

fdisk が終了したので、もう一度起動して、状況を表示した。
ikwzm_Debian_kv260_10_211107.png

ファイル・システムを構築する
第 1 パーティションのファイル・システムを構築した。
sudo mkfs.msdos -n boot /dev/sdf1
第 2 パーティションのファイル・システムを構築した。
sudo mkfs.ext3 -L rootfs /dev/sdf2
ikwzm_Debian_kv260_11_211107.png

ファイルマネージャーに boot と rootfs の表示が出てきた。
boot と rootfs をクリックして、マウントする。
ikwzm_Debian_kv260_12_211107.png

ikwzm_Debian_kv260_13_211107.png

ZynqMP-FPGA-Linux/target/Kv260/boot ディレクトリのファイルを boot ドライブにコピーする
cp target/Kv260/boot/* /media/masaaki/boot/
ikwzm_Debian_kv260_14_211107.png

ROOT_FS を Micro SD カードの rootfs パーティションに書き込む
sudo tar xfz debian10-rootfs-vanilla.tgz -C /media/masaaki/rootfs/
sync

sync しないと書き込みの終わりが分からないので、した方が良いと思う。
ikwzm_Debian_kv260_15_211107.png

rootfs ドライブの /home/fpga ディレクトリに debian ディレクトリを作成して、 deb ファイルをコピーする。
mkdir /media/masaaki/rootfs/home/fpga/debian
cp linux-image-5.10.0-xlnx-v2021.1-zynqmp-fpga_5.10.0-xlnx-v2021.1-zynqmp-fpga-2_arm64.deb /media/masaaki/rootfs/home/fpga/debian
cp linux-headers-5.10.0-xlnx-v2021.1-zynqmp-fpga_5.10.0-xlnx-v2021.1-zynqmp-fpga-2_arm64.deb /media/masaaki/rootfs/home/fpga/debian
cp fclkcfg-5.10.0-xlnx-v2021.1-zynqmp-fpga_1.7.2-1_arm64.deb /media/masaaki/rootfs/home/fpga/debian
cp u-dma-buf-5.10.0-xlnx-v2021.1-zynqmp-fpga_3.2.4-0_arm64.deb /media/masaaki/rootfs/home/fpga/debian

ikwzm_Debian_kv260_16_211107.png

/mnt に boot ディレクトリを作成する。
sudo mkdir /media/masaaki/rootfs/mnt/boot

ikwzm さんのコマンドでうまく行を追加できなかったので、 root で vi を起動して行を追加する。
sudo su
vi /media/masaaki/rootfs/etc/fstab

/dev/mmcblk1p1 /mnt/boot auto defaults 0 0

を追加した。
ikwzm_Debian_kv260_17_211107.png

vi /media/masaaki/rootfs/etc/securetty

ttyPS1

を追加した。
ikwzm_Debian_kv260_18_211107.png

ファイルマネージャーで rootfs をアンマウントした。
boot もアンマウントされた。
ikwzm_Debian_kv260_19_211107.png

Micro SD カードを KV260 に挿入して電源 ON した。
Debian 10 が起動した。
ikwzm_Debian_kv260_20_211107.png

Debian 10 起動ログを示す。

�Xilinx Zynq MP First Stage Boot Loader 
Release 2020.2   Apr 22 2021  -  17:48:34
MultiBootOffset: 0x40
Reset Mode  :   System Reset
Platform: Silicon (4.0), Running on A53-0 (64-bit) Processor, Device Name: XCZUUNKNEG
QSPI 32 bit Boot Mode 
FlashID=0x20 0xBB 0x20
8��UjT�'$HP�� running on XCK26/silicon v4/RTL5.1 at 0xfffea000
NOTICE:  BL31: v2.2(release):xilinx-v2020.2.2-k26
NOTICE:  BL31: Built : 17:45:02, Apr 22 2021


U-Boot 2020.01 (Apr 22 2021 - 17:47:18 +0000)

Model: ZynqMP SMK-K26 Rev1/B/A
Board: Xilinx ZynqMP
DRAM:  4 GiB
PMUFW:  v1.1
Xilinx I2C FRU format at nvmem0:
 Manufacturer Name: XILINX
 Product Name: SMK-K26-XCL2G
 Serial No: XFL1LECE1JTG
 Part Number: 5057-01  
 File ID: 0x0
 Revision Number: 1
Xilinx I2C FRU format at nvmem1:
 Manufacturer Name: XILINX
 Product Name: SCK-KV-G        
 Serial No: XFL1KO3R1GNH
 Part Number: 5066-01  
 File ID: 0x0
 Revision Number: 1
EL Level:   EL2
Chip ID:    xck26
NAND:  0 MiB
MMC:   mmc@ff170000: 1
In:    serial@ff010000
Out:   serial@ff010000
Err:   serial@ff010000
Bootmode: QSPI_MODE
Reset reason:   SOFT 
Net:   No ethernet found.
Hit any key to stop autoboot:  0 


  *** U-Boot Boot Menu ***

     Auto-Select - 1.CC boot 2.SOM boot
     Carrier Card (CC) boot device
     System on Module (SOM) boot device
     U-Boot console


  Press UP/DOWN to move, ENTER to select






















switch to partitions #0, OK
mmc1 is current device
Scanning mmc 1:1...
Found U-Boot script /boot.scr
2594 bytes read in 16 ms (158.2 KiB/s)
## Executing script at 20000000
Trying to load boot images from mmc1
2287 bytes read in 16 ms (138.7 KiB/s)
Importing environment(uEnv.txt) from mmc1...
Running uenvcmd ...
20617728 bytes read in 2303 ms (8.5 MiB/s)
42339 bytes read in 20 ms (2 MiB/s)
## Flattened Device Tree blob at 00100000
   Booting using the fdt blob at 0x100000
   Loading Device Tree to 000000000fff2000, end 000000000ffff562 ... OK

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[    0.000000] Linux version 5.10.0-xlnx-v2021.1-zynqmp-fpga (ichiro@Jabberwock) (aarch64-linux-gnu-gcc (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0, GNU ld (GNU Binutils for Ubuntu) 2.30) #2 SMP Fri Nov 5 07:40:48 JST 2021
[    0.000000] Machine model: ZynqMP SMK-K26 Rev1/B/A
[    0.000000] efi: UEFI not found.
[    0.000000] cma: Reserved 256 MiB at 0x000000006fc00000
[    0.000000] Zone ranges:
[    0.000000]   DMA32    [mem 0x0000000000000000-0x00000000ffffffff]
[    0.000000]   Normal   [mem 0x0000000100000000-0x000000087fffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000000000000-0x000000007fefffff]
[    0.000000]   node   0: [mem 0x0000000800000000-0x000000087fffffff]
[    0.000000] Zeroed struct page in unavailable ranges: 256 pages
[    0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x000000087fffffff]
[    0.000000] psci: probing for conduit method from DT.
[    0.000000] psci: PSCIv1.1 detected in firmware.
[    0.000000] psci: Using standard PSCI v0.2 function IDs
[    0.000000] psci: MIGRATE_INFO_TYPE not supported.
[    0.000000] psci: SMC Calling Convention v1.1
[    0.000000] percpu: Embedded 22 pages/cpu s49496 r8192 d32424 u90112
[    0.000000] Detected VIPT I-cache on CPU0
[    0.000000] CPU features: detected: ARM erratum 845719
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 1033987
[    0.000000] Kernel command line: console=ttyPS1,115200 root=/dev/mmcblk1p2 rw rootwait systemd.unit=multi-user.target cpuidle.off=1 1000M uio_pdrv_genirq.of_id=generic-uio
[    0.000000] Dentry cache hash table entries: 524288 (order: 10, 4194304 bytes, linear)
[    0.000000] Inode-cache hash table entries: 262144 (order: 9, 2097152 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] software IO TLB: mapped [mem 0x000000006bc00000-0x000000006fc00000] (64MB)
[    0.000000] Memory: 3772196K/4193280K available (13312K kernel code, 870K rwdata, 3788K rodata, 2048K init, 576K bss, 158940K reserved, 262144K cma-reserved)
[    0.000000] rcu: Hierarchical RCU implementation.
[    0.000000] rcu:     RCU event tracing is enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] GIC: Adjusting CPU interface base to 0x00000000f902f000
[    0.000000] GIC: Using split EOI/Deactivate mode
[    0.000000] random: get_random_bytes called from start_kernel+0x320/0x560 with crng_init=0
[    0.000000] arch_timer: cp15 timer(s) running at 99.99MHz (phys).
[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x171015c90f, max_idle_ns: 440795203080 ns
[    0.000003] sched_clock: 56 bits at 99MHz, resolution 10ns, wraps every 4398046511101ns
[    0.000293] Console: colour dummy device 80x25
[    0.000318] Calibrating delay loop (skipped), value calculated using timer frequency.. 199.99 BogoMIPS (lpj=399996)
[    0.000329] pid_max: default: 32768 minimum: 301
[    0.000450] Mount-cache hash table entries: 8192 (order: 4, 65536 bytes, linear)
[    0.000465] Mountpoint-cache hash table entries: 8192 (order: 4, 65536 bytes, linear)
[    0.001256] rcu: Hierarchical SRCU implementation.
[    0.001455] EFI services will not be available.
[    0.001572] smp: Bringing up secondary CPUs ...
[    0.001871] Detected VIPT I-cache on CPU1
[    0.001907] CPU1: Booted secondary processor 0x0000000001 [0x410fd034]
[    0.002240] Detected VIPT I-cache on CPU2
[    0.002262] CPU2: Booted secondary processor 0x0000000002 [0x410fd034]
[    0.002558] Detected VIPT I-cache on CPU3
[    0.002580] CPU3: Booted secondary processor 0x0000000003 [0x410fd034]
[    0.002622] smp: Brought up 1 node, 4 CPUs
[    0.002636] SMP: Total of 4 processors activated.
[    0.002642] CPU features: detected: 32-bit EL0 Support
[    0.002647] CPU features: detected: CRC32 instructions
[    0.002681] CPU: All CPU(s) started at EL2
[    0.002695] alternatives: patching kernel code
[    0.003706] devtmpfs: initialized
[    0.008214] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[    0.008227] futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
[    0.014056] pinctrl core: initialized pinctrl subsystem
[    0.014651] NET: Registered protocol family 16
[    0.015716] DMA: preallocated 512 KiB GFP_KERNEL pool for atomic allocations
[    0.015804] DMA: preallocated 512 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
[    0.015836] audit: initializing netlink subsys (disabled)
[    0.015963] audit: type=2000 audit(0.012:1): state=initialized audit_enabled=0 res=1
[    0.016398] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
[    0.016449] ASID allocator initialised with 65536 entries
[    0.033012] HugeTLB registered 1.00 GiB page size, pre-allocated 0 pages
[    0.033024] HugeTLB registered 32.0 MiB page size, pre-allocated 0 pages
[    0.033029] HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages
[    0.033034] HugeTLB registered 64.0 KiB page size, pre-allocated 0 pages
[    1.024588] DRBG: Continuing without Jitter RNG
[    1.100709] raid6: neonx8   gen()  2532 MB/s
[    1.168760] raid6: neonx8   xor()  1850 MB/s
[    1.236817] raid6: neonx4   gen()  2503 MB/s
[    1.304868] raid6: neonx4   xor()  1792 MB/s
[    1.372926] raid6: neonx2   gen()  2415 MB/s
[    1.440975] raid6: neonx2   xor()  1665 MB/s
[    1.509034] raid6: neonx1   gen()  1882 MB/s
[    1.577089] raid6: neonx1   xor()  1355 MB/s
[    1.645143] raid6: int64x8  gen()  1353 MB/s
[    1.713187] raid6: int64x8  xor()   839 MB/s
[    1.781247] raid6: int64x4  gen()  1875 MB/s
[    1.849298] raid6: int64x4  xor()   942 MB/s
[    1.917371] raid6: int64x2  gen()  1569 MB/s
[    1.985420] raid6: int64x2  xor()   845 MB/s
[    2.053477] raid6: int64x1  gen()  1170 MB/s
[    2.121527] raid6: int64x1  xor()   597 MB/s
[    2.121532] raid6: using algorithm neonx8 gen() 2532 MB/s
[    2.121536] raid6: .... xor() 1850 MB/s, rmw enabled
[    2.121541] raid6: using neon recovery algorithm
[    2.121948] iommu: Default domain type: Translated 
[    2.122139] SCSI subsystem initialized
[    2.122279] usbcore: registered new interface driver usbfs
[    2.122307] usbcore: registered new interface driver hub
[    2.122334] usbcore: registered new device driver usb
[    2.122386] mc: Linux media interface: v0.10
[    2.122404] videodev: Linux video capture interface: v2.00
[    2.122446] EDAC MC: Ver: 3.0.0
[    2.122875] zynqmp-ipi-mbox mailbox@ff990400: Registered ZynqMP IPI mbox with TX/RX channels.
[    2.123045] FPGA manager framework
[    2.123161] Advanced Linux Sound Architecture Driver Initialized.
[    2.123440] Bluetooth: Core ver 2.22
[    2.123459] NET: Registered protocol family 31
[    2.123464] Bluetooth: HCI device and connection manager initialized
[    2.123472] Bluetooth: HCI socket layer initialized
[    2.123478] Bluetooth: L2CAP socket layer initialized
[    2.123490] Bluetooth: SCO socket layer initialized
[    2.123834] clocksource: Switched to clocksource arch_sys_counter
[    2.123922] VFS: Disk quotas dquot_6.6.0
[    2.123964] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[    2.127593] NET: Registered protocol family 2
[    2.127928] tcp_listen_portaddr_hash hash table entries: 2048 (order: 3, 32768 bytes, linear)
[    2.127969] TCP established hash table entries: 32768 (order: 6, 262144 bytes, linear)
[    2.128155] TCP bind hash table entries: 32768 (order: 7, 524288 bytes, linear)
[    2.128510] TCP: Hash tables configured (established 32768 bind 32768)
[    2.128579] UDP hash table entries: 2048 (order: 4, 65536 bytes, linear)
[    2.128646] UDP-Lite hash table entries: 2048 (order: 4, 65536 bytes, linear)
[    2.128779] NET: Registered protocol family 1
[    2.129042] RPC: Registered named UNIX socket transport module.
[    2.129047] RPC: Registered udp transport module.
[    2.129051] RPC: Registered tcp transport module.
[    2.129055] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    2.129609] PCI: CLS 0 bytes, default 64
[    2.130070] hw perfevents: no interrupt-affinity property for /pmu, guessing.
[    2.130218] hw perfevents: enabled with armv8_pmuv3 PMU driver, 7 counters available
[    2.130949] Initialise system trusted keyrings
[    2.131031] workingset: timestamp_bits=62 max_order=20 bucket_order=0
[    2.131600] NFS: Registering the id_resolver key type
[    2.131613] Key type id_resolver registered
[    2.131617] Key type id_legacy registered
[    2.131635] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[    2.131652] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[    2.163531] NET: Registered protocol family 38
[    2.163540] xor: measuring software checksum speed
[    2.167297]    8regs           :  2630 MB/sec
[    2.170348]    32regs          :  3234 MB/sec
[    2.173861]    arm64_neon      :  2808 MB/sec
[    2.173866] xor: using function: 32regs (3234 MB/sec)
[    2.173875] Key type asymmetric registered
[    2.173880] Asymmetric key parser 'x509' registered
[    2.173901] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 248)
[    2.173906] io scheduler mq-deadline registered
[    2.173911] io scheduler kyber registered
[    2.197192] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[    2.200335] cacheinfo: Unable to detect cache hierarchy for CPU 0
[    2.204258] brd: module loaded
[    2.208108] loop: module loaded
[    2.208702] mtdoops: mtd device (mtddev=name/number) must be supplied
[    2.209933] libphy: Fixed MDIO Bus: probed
[    2.210874] tun: Universal TUN/TAP device driver, 1.6
[    2.210952] CAN device driver interface
[    2.211606] usbcore: registered new interface driver asix
[    2.211642] usbcore: registered new interface driver ax88179_178a
[    2.211663] usbcore: registered new interface driver cdc_ether
[    2.211684] usbcore: registered new interface driver net1080
[    2.211706] usbcore: registered new interface driver cdc_subset
[    2.211726] usbcore: registered new interface driver zaurus
[    2.211756] usbcore: registered new interface driver cdc_ncm
[    2.212569] usbcore: registered new interface driver uas
[    2.212601] usbcore: registered new interface driver usb-storage
[    2.213247] rtc_zynqmp ffa60000.rtc: registered as rtc0
[    2.213267] rtc_zynqmp ffa60000.rtc: setting system clock to 1970-01-01T00:00:07 UTC (7)
[    2.213312] i2c /dev entries driver
[    2.214597] usbcore: registered new interface driver uvcvideo
[    2.214602] USB Video Class driver (1.1.1)
[    2.215388] Bluetooth: HCI UART driver ver 2.3
[    2.215395] Bluetooth: HCI UART protocol H4 registered
[    2.215400] Bluetooth: HCI UART protocol BCSP registered
[    2.215417] Bluetooth: HCI UART protocol LL registered
[    2.215422] Bluetooth: HCI UART protocol ATH3K registered
[    2.215437] Bluetooth: HCI UART protocol Three-wire (H5) registered
[    2.215469] Bluetooth: HCI UART protocol Intel registered
[    2.215484] Bluetooth: HCI UART protocol QCA registered
[    2.215510] usbcore: registered new interface driver bcm203x
[    2.215538] usbcore: registered new interface driver bpa10x
[    2.215562] usbcore: registered new interface driver bfusb
[    2.215586] usbcore: registered new interface driver btusb
[    2.215623] usbcore: registered new interface driver ath3k
[    2.215698] EDAC MC: ECC not enabled
[    2.215847] EDAC DEVICE0: Giving out device to module zynqmp-ocm-edac controller zynqmp_ocm: DEV ff960000.memory-controller (INTERRUPT)
[    2.216108] failed to register cpuidle driver
[    2.216247] sdhci: Secure Digital Host Controller Interface driver
[    2.216251] sdhci: Copyright(c) Pierre Ossman
[    2.216256] sdhci-pltfm: SDHCI platform and OF driver helper
[    2.216581] ledtrig-cpu: registered to indicate activity on CPUs
[    2.216626] zynqmp_firmware_probe Platform Management API v1.1
[    2.216632] zynqmp_firmware_probe Trustzone version v1.0
[    2.238714] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: zynqmp pinctrl initialized
[    2.275258] alg: No test for xilinx-zynqmp-aes (zynqmp-aes)
[    2.275280] zynqmp_aes firmware:zynqmp-firmware:zynqmp-aes: AES Successfully Registered
[    2.275446] alg: No test for xilinx-keccak-384 (zynqmp-keccak-384)
[    2.275610] alg: No test for xilinx-zynqmp-rsa (zynqmp-rsa)
[    2.275749] usbcore: registered new interface driver usbhid
[    2.275754] usbhid: USB HID core driver
[    2.278326] fpga_manager fpga0: Xilinx ZynqMP FPGA Manager registered
[    2.278671] usbcore: registered new interface driver snd-usb-audio
[    2.279420] pktgen: Packet Generator for packet performance testing. Version: 2.75
[    2.279872] Initializing XFRM netlink socket
[    2.279950] NET: Registered protocol family 10
[    2.280315] Segment Routing with IPv6
[    2.280441] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[    2.280755] NET: Registered protocol family 17
[    2.280769] NET: Registered protocol family 15
[    2.280807] can: controller area network core
[    2.280833] NET: Registered protocol family 29
[    2.280839] can: raw protocol
[    2.280843] can: broadcast manager protocol
[    2.280850] can: netlink gateway - max_hops=1
[    2.280922] Bluetooth: RFCOMM TTY layer initialized
[    2.280931] Bluetooth: RFCOMM socket layer initialized
[    2.280944] Bluetooth: RFCOMM ver 1.11
[    2.280952] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[    2.280956] Bluetooth: BNEP filters: protocol multicast
[    2.280963] Bluetooth: BNEP socket layer initialized
[    2.280967] Bluetooth: HIDP (Human Interface Emulation) ver 1.2
[    2.280974] Bluetooth: HIDP socket layer initialized
[    2.281079] 9pnet: Installing 9P2000 support
[    2.281098] Key type dns_resolver registered
[    2.281372] registered taskstats version 1
[    2.281377] Loading compiled-in X.509 certificates
[    2.282224] Btrfs loaded, crc32c=crc32c-generic
[    2.289592] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 36
[    2.289659] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 37
[    2.290061] ff010000.serial: ttyPS1 at MMIO 0xff010000 (irq = 48, base_baud = 6249999) is a xuartps
[    3.562006] printk: console [ttyPS1] enabled
[    3.566785] of-fpga-region fpga-full: FPGA Region probed
[    3.572858] xilinx-zynqmp-dma fd500000.dma: ZynqMP DMA driver Probe success
[    3.580031] xilinx-zynqmp-dma fd510000.dma: ZynqMP DMA driver Probe success
[    3.587182] xilinx-zynqmp-dma fd520000.dma: ZynqMP DMA driver Probe success
[    3.594334] xilinx-zynqmp-dma fd530000.dma: ZynqMP DMA driver Probe success
[    3.601488] xilinx-zynqmp-dma fd540000.dma: ZynqMP DMA driver Probe success
[    3.608632] xilinx-zynqmp-dma fd550000.dma: ZynqMP DMA driver Probe success
[    3.615782] xilinx-zynqmp-dma fd560000.dma: ZynqMP DMA driver Probe success
[    3.622938] xilinx-zynqmp-dma fd570000.dma: ZynqMP DMA driver Probe success
[    3.630156] xilinx-zynqmp-dma ffa80000.dma: ZynqMP DMA driver Probe success
[    3.637309] xilinx-zynqmp-dma ffa90000.dma: ZynqMP DMA driver Probe success
[    3.644463] xilinx-zynqmp-dma ffaa0000.dma: ZynqMP DMA driver Probe success
[    3.651613] xilinx-zynqmp-dma ffab0000.dma: ZynqMP DMA driver Probe success
[    3.658765] xilinx-zynqmp-dma ffac0000.dma: ZynqMP DMA driver Probe success
[    3.665918] xilinx-zynqmp-dma ffad0000.dma: ZynqMP DMA driver Probe success
[    3.673071] xilinx-zynqmp-dma ffae0000.dma: ZynqMP DMA driver Probe success
[    3.680228] xilinx-zynqmp-dma ffaf0000.dma: ZynqMP DMA driver Probe success
[    3.687619] xilinx-zynqmp-dpdma fd4c0000.dma-controller: Xilinx DPDMA engine is probed
[    3.696388] zynqmp-display fd4a0000.display: vtc bridge property not present
[    3.706393] xilinx-dp-snd-codec fd4a0000.display:zynqmp_dp_snd_codec0: Xilinx DisplayPort Sound Codec probed
[    3.716518] xilinx-dp-snd-pcm zynqmp_dp_snd_pcm0: Xilinx DisplayPort Sound PCM probed
[    3.724625] xilinx-dp-snd-pcm zynqmp_dp_snd_pcm1: Xilinx DisplayPort Sound PCM probed
[    3.733433] xilinx-dp-snd-card fd4a0000.display:zynqmp_dp_snd_card: Xilinx DisplayPort Sound Card probed
[    3.742988] OF: graph: no port node found in /axi/display@fd4a0000
[    3.749389] zynqmp_pll_disable() clock disable failed for dpll_int, ret = -13
[    3.756615] xlnx-drm xlnx-drm.0: bound fd4a0000.display (ops 0xffffffc010dd30c0)
[    4.012127] Console: switching to colour frame buffer device 240x67
[    4.035033] zynqmp-display fd4a0000.display: [drm] fb0: xlnxdrmfb frame buffer device
[    4.043051] [drm] Initialized xlnx 1.0.0 20130509 for fd4a0000.display on minor 0
[    4.050552] zynqmp-display fd4a0000.display: ZynqMP DisplayPort Subsystem driver probed
[    4.060603] spi-nor spi0.0: trying to lock already unlocked area
[    4.066608] spi-nor spi0.0: mt25qu512a (65536 Kbytes)
[    4.071715] 16 fixed-partitions partitions found on MTD device spi0.0
[    4.078143] Creating 16 MTD partitions on "spi0.0":
[    4.083016] 0x000000000000-0x000000080000 : "Image Selector"
[    4.089393] 0x000000080000-0x000000100000 : "Image Selector Golden"
[    4.096275] 0x000000100000-0x000000120000 : "Persistent Register"
[    4.102959] 0x000000120000-0x000000140000 : "Persistent Register Backup"
[    4.110257] 0x000000140000-0x000000200000 : "Open_1"
[    4.115805] 0x000000200000-0x000000f00000 : "Image A (FSBL, PMU, ATF, U-Boot)"
[    4.123616] 0x000000f00000-0x000000f80000 : "ImgSel Image A Catch"
[    4.130390] 0x000000f80000-0x000001c80000 : "Image B (FSBL, PMU, ATF, U-Boot)"
[    4.138205] 0x000001c80000-0x000001d00000 : "ImgSel Image B Catch"
[    4.142609] random: fast init done
[    4.144975] 0x000001d00000-0x000001e00000 : "Open_2"
[    4.153312] 0x000001e00000-0x000002000000 : "Recovery Image"
[    4.159550] 0x000002000000-0x000002200000 : "Recovery Image Backup"
[    4.166398] 0x000002200000-0x000002220000 : "U-Boot storage variables"
[    4.173519] 0x000002220000-0x000002240000 : "U-Boot storage variables backup"
[    4.181252] 0x000002240000-0x000002250000 : "SHA256"
[    4.186807] 0x000002250000-0x000004000000 : "User"
[    4.193123] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 64
[    4.202368] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 65
[    4.211609] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 66
[    4.220853] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 67
[    4.230101] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 68
[    4.239344] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 69
[    4.248587] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 70
[    4.257831] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 71
[    4.267079] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 72
[    4.276319] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 73
[    4.285562] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 74
[    4.294807] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 75
[    4.304229] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 76
[    4.313488] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 77
[    4.322954] macb ff0e0000.ethernet: Not enabling partial store and forward
[    4.329867] macb ff0e0000.ethernet: invalid hw address, using random
[    4.337001] libphy: MACB_mii_bus: probed
[    4.341581] macb ff0e0000.ethernet eth0: Cadence GEM rev 0x50070106 at 0xff0e0000 irq 37 (3a:49:ed:1c:d9:d6)
[    4.351871] xilinx-axipmon ffa00000.perf-monitor: Probed Xilinx APM
[    4.358441] xilinx-axipmon fd0b0000.perf-monitor: Probed Xilinx APM
[    4.364955] xilinx-axipmon fd490000.perf-monitor: Probed Xilinx APM
[    4.371464] xilinx-axipmon ffa10000.perf-monitor: Probed Xilinx APM
[    4.378571] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 53
[    4.387817] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 54
[    4.397059] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 55
[    4.406302] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 56
[    4.415546] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 57
[    4.424793] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 58
[    4.434041] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 59
[    4.443280] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 60
[    4.452528] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 61
[    4.461768] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 62
[    4.471015] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 63
[    4.498428] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
[    4.503918] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 1
[    4.511661] xhci-hcd xhci-hcd.1.auto: hcc params 0x0238f625 hci version 0x100 quirks 0x0000000002010810
[    4.521065] xhci-hcd xhci-hcd.1.auto: irq 54, io mem 0xfe200000
[    4.527163] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 5.10
[    4.535422] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    4.542633] usb usb1: Product: xHCI Host Controller
[    4.547502] usb usb1: Manufacturer: Linux 5.10.0-xlnx-v2021.1-zynqmp-fpga xhci-hcd
[    4.555064] usb usb1: SerialNumber: xhci-hcd.1.auto
[    4.560197] hub 1-0:1.0: USB hub found
[    4.563963] hub 1-0:1.0: 1 port detected
[    4.568054] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
[    4.573542] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 2
[    4.581198] xhci-hcd xhci-hcd.1.auto: Host supports USB 3.0 SuperSpeed
[    4.587817] usb usb2: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 5.10
[    4.596070] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    4.603280] usb usb2: Product: xHCI Host Controller
[    4.608154] usb usb2: Manufacturer: Linux 5.10.0-xlnx-v2021.1-zynqmp-fpga xhci-hcd
[    4.615712] usb usb2: SerialNumber: xhci-hcd.1.auto
[    4.620809] hub 2-0:1.0: USB hub found
[    4.624566] hub 2-0:1.0: 1 port detected
[    4.629371] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 24
[    4.638635] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 25
[    4.648333] at24 1-0050: supply vcc not found, using dummy regulator
[    4.654973] at24 1-0050: 8192 byte 24c64 EEPROM, writable, 1 bytes/write
[    4.661805] at24 1-0051: supply vcc not found, using dummy regulator
[    4.668424] at24 1-0051: 8192 byte 24c64 EEPROM, writable, 1 bytes/write
[    4.692008] cdns-i2c ff030000.i2c: 400 kHz mmio ff030000 irq 39
[    4.699379] cdns-wdt fd4d0000.watchdog: Xilinx Watchdog Timer with timeout 60s
[    4.706857] cdns-wdt ff150000.watchdog: Xilinx Watchdog Timer with timeout 10s
[    4.715537] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 39
[    4.724810] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 40
[    4.734079] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 41
[    4.743343] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 42
[    4.752604] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 46
[    4.761867] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 47
[    4.771127] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 48
[    4.780389] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 49
[    4.789652] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 50
[    4.798915] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 51
[    4.808175] zynqmp-pinctrl firmware:zynqmp-firmware:pinctrl: Invalid IO Standard requested for pin 45
[    4.818322] tpm tpm0: tpm_relinquish_locality: : error -1
[    4.820641] gpio-keys gpio-keys: Button without keycode
[    4.823812] tpm_tis_spi spi2.0: 2.0 TPM (device-id 0x1B, rev-id 22)
[    4.828938] gpio-keys: probe of gpio-keys failed with error -22
[    4.837427] tpm tpm0: A TPM error (256) occurred attempting the self test
[    4.841166] of_cfs_init
[    4.847881] tpm tpm0: starting up the TPM manually
[    4.850332] of_cfs_init: OK
[    4.851298] mmc1: SDHCI controller on ff170000.mmc [ff170000.mmc] using ADMA 64-bit
[    4.865641] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[    4.892735] mmc1: new high speed SDHC card at address aaaa
[    4.898569] mmcblk1: mmc1:aaaa SB32G 29.7 GiB 
[    4.907006]  mmcblk1: p1 p2
[    4.935845] usb 1-1: new high-speed USB device number 2 using xhci-hcd
[    4.995541] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
[    5.003226] ALSA device list:
[    5.006187]   #0: DisplayPort monitor
[    5.010139] platform regulatory.0: Direct firmware load for regulatory.db failed with error -2
[    5.018748] cfg80211: failed to load regulatory.db
[    5.088289] usb 1-1: New USB device found, idVendor=0424, idProduct=2744, bcdDevice= 2.21
[    5.096474] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[    5.103618] usb 1-1: Product: USB2744
[    5.107281] usb 1-1: Manufacturer: Microchip Tech
[    5.163874] hub 1-1:1.0: USB hub found
[    5.167648] hub 1-1:1.0: 5 ports detected
[    5.227785] usb 2-1: new SuperSpeed Gen 1 USB device number 2 using xhci-hcd
[    5.252192] usb 2-1: New USB device found, idVendor=0424, idProduct=5744, bcdDevice= 2.21
[    5.260362] usb 2-1: New USB device strings: Mfr=2, Product=3, SerialNumber=0
[    5.267484] usb 2-1: Product: USB5744
[    5.271138] usb 2-1: Manufacturer: Microchip Tech
[    5.339850] hub 2-1:1.0: USB hub found
[    5.343747] hub 2-1:1.0: 4 ports detected
[    5.515837] usb 1-1.5: new high-speed USB device number 3 using xhci-hcd
[    5.620502] usb 1-1.5: New USB device found, idVendor=0424, idProduct=2740, bcdDevice= 2.00
[    5.628853] usb 1-1.5: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[    5.636163] usb 1-1.5: Product: Hub Controller
[    5.640604] usb 1-1.5: Manufacturer: Microchip Tech
[    6.864241] tpm tpm0: Operation Timed out
[    8.868079] tpm tpm0: tpm_try_transmit: send(): error -62
[    9.626597] tpm tpm0: tpm_relinquish_locality: : error -1
[    9.632104] tpm_tis_spi: probe of spi2.0 failed with error -62
[    9.640804] EXT4-fs (mmcblk1p2): mounting ext3 file system using the ext4 subsystem
[    9.695437] EXT4-fs (mmcblk1p2): mounted filesystem with ordered data mode. Opts: (null)
[    9.703552] VFS: Mounted root (ext3 filesystem) on device 179:2.
[    9.718294] devtmpfs: mounted
[    9.721893] Freeing unused kernel memory: 2048K
[    9.726529] Run /sbin/init as init process
[    9.957410] random: crng init done
[   10.333889] systemd[1]: System time before build time, advancing clock.
[   10.375673] systemd[1]: systemd 241 running in system mode. (+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN2 +IDN -PCRE2 default-hierarchy=hybrid)
[   10.397269] systemd[1]: Detected architecture arm64.

Welcome to Debian GNU/Linux 10 (buster)!

[   10.426644] systemd[1]: Set hostname to <debian-fpga>.
[   10.517542] systemd-system-update-generator[137]: Offline system update overridden by kernel command line systemd.unit= setting
[   10.640111] systemd[1]: File /lib/systemd/system/systemd-journald.service:12 configures an IP firewall (IPAddressDeny=any), but the local system does not support BPF/cgroup based firewalling.
[   10.657153] systemd[1]: Proceeding WITHOUT firewalling in effect! (This warning is only shown for the first loaded unit using IP firewalling.)
[   10.793565] systemd[1]: /lib/systemd/system/smbd.service:9: PIDFile= references path below legacy directory /var/run/, updating /var/run/samba/smbd.pid → /run/samba/smbd.pid; please update the unit file accordingly.
[   10.818284] systemd[1]: /lib/systemd/system/nmbd.service:9: PIDFile= references path below legacy directory /var/run/, updating /var/run/samba/nmbd.pid → /run/samba/nmbd.pid; please update the unit file accordingly.
[   10.865269] systemd[1]: Started Dispatch Password Requests to Console Directory Watch.
[  OK  ] Started Dispatch Password …ts to Console Directory Watch.
[   10.888064] systemd[1]: Listening on initctl Compatibility Named Pipe.
[  OK  ] Listening on initctl Compatibility Named Pipe.
[   10.912333] systemd[1]: Created slice system-getty.slice.
[  OK  ] Created slice system-getty.slice.
[  OK  ] Reached target System Time Synchronized.
[  OK  ] Listening on Syslog Socket.
[  OK  ] Listening on udev Kernel Socket.
[  OK  ] Created slice system-serial\x2dgetty.slice.
[  OK  ] Listening on Journal Audit Socket.
[  OK  ] Reached target Remote File Systems.
[  OK  ] Reached target Swap.
[  OK  ] Listening on udev Control Socket.
[  OK  ] Listening on Journal Socket (/dev/log).
[  OK  ] Created slice User and Session Slice.
[  OK  ] Reached target Slices.
[  OK  ] Listening on Journal Socket.
         Starting Load Kernel Modules...
         Starting Remount Root and Kernel File Systems...
         Mounting Huge Pages File System...
         Mounting Kernel Debug File System...
         Mounting POSIX Message Queue File System...
         Starting Nameserver information manager...
[  OK  ] Started Forward Password R…uests to Wall Directory Watch.
[  OK  ] Reached target Local Encrypted Volumes.
[  OK  ] Reached target Paths.
         Starting udev Coldplug all Devices...
         Starting Journal Service...
[  OK  ] Started Load Kernel Modules.
[  OK  ] Started Remount Root and Kernel File Systems.
[  OK  ] Mounted Huge Pages File System.
[  OK  ] Mounted Kernel Debug File System.
[  OK  ] Mounted POSIX Message Queue File System.
         Starting Load/Save Random Seed...
         Starting Create System Users...
         Starting Apply Kernel Variables...
         Mounting Kernel Configuration File System...
[  OK  ] Started Journal Service.
[  OK  ] Started Nameserver information manager.
[  OK  ] Started Load/Save Random Seed.
[  OK  ] Started Create System Users.
[  OK  ] Started Apply Kernel Variables.
[  OK  ] Mounted Kernel Configuration File System.
         Starting Create Static Device Nodes in /dev...
         Starting Flush Journal to Persistent Storage...
[  OK  ] Started Create Static Device Nodes in /dev.
[  OK  ] Reached target Local File Systems (Pre).
         Mounting /config...
         Starting udev Kernel Device Manager...
[  OK  ] Mounted /config.
[   11.624657] systemd-journald[149]: Received request to flush runtime journal from PID 1
[  OK  ] Started Flush Journal to Persistent Storage.
[  OK  ] Started udev Kernel Device Manager.
[  OK  ] Started udev Coldplug all Devices.
         Starting Helper to synchronize boot up for ifupdown...
[  OK  ] Started Helper to synchronize boot up for ifupdown.
[  OK  ] Found device /dev/ttyPS1.
[  OK  ] Found device /dev/mmcblk1p1.
         Mounting /mnt/boot...
[  OK  ] Listening on Load/Save RF …itch Status /dev/rfkill Watch.
[  OK  ] Reached target Sound Card.
[  OK  ] Mounted /mnt/boot.
[  OK  ] Reached target Local File Systems.
         Starting Create Volatile Files and Directories...
[  OK  ] Started ifup for eth0.
         Starting Raise network interfaces...
[  OK  ] Started Create Volatile Files and Directories.
         Starting Update UTMP about System Boot/Shutdown...
[  OK  ] Started Update UTMP about System Boot/Shutdown.
[  OK  ] Reached target System Initialization.
[  OK  ] Started Daily apt download activities.
[  OK  ] Listening on D-Bus System Message Bus Socket.
[  OK  ] Started Daily Cleanup of Temporary Directories.
[  OK  ] Listening on Avahi mDNS/DNS-SD Stack Activation Socket.
[  OK  ] Reached target Sockets.
[  OK  ] Started Daily rotation of log files.
[  OK  ] Reached target Basic System.
[  OK  ] Started D-Bus System Message Bus.
         Starting WPA supplicant...
[  OK  ] Started Daily apt upgrade and clean activities.
[  OK  ] Reached target Timers.
         Starting Login Service...
[  OK  ] Started Regular background program processing daemon.
         Starting System Logging Service...
         Starting Avahi mDNS/DNS-SD Stack...
[  OK  ] Started Raise network interfaces.
[   14.348459] macb ff0e0000.ethernet eth0: PHY [ff0e0000.ethernet-ffffffff:01] driver [TI DP83867] (irq=POLL)
[   14.358247] macb ff0e0000.ethernet eth0: configuring for phy/rgmii-id link mode
[  OK  ] Started System Logging Service.
[  OK  ] Started Login Service.
[  OK  ] Started Avahi mDNS/DNS-SD Stack.
[  OK  ] Started WPA supplicant.
[  OK  ] Reached target Network.
         Starting Network Time Service...
         Starting OpenBSD Secure Shell server...
         Starting Permit User Sessions...
[  OK  ] Reached target Network is Online.
         Starting Samba NMB Daemon...
[  OK  ] Started Permit User Sessions.
[  OK  ] Started Serial Getty on ttyPS1.
[  OK  ] Started Getty on tty1.
[  OK  ] Reached target Login Prompts.
[  OK  ] Started Network Time Service.
[  OK  ] Started OpenBSD Secure Shell server.
[   18.469493] macb ff0e0000.ethernet eth0: Link is Up - 1Gbps/Full - flow control off
[   18.477174] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready

Debian GNU/Linux 10 debian-fpga ttyPS1

debian-fpga login: 

  1. 2021年11月08日 04:30 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

KV260 で ikwzm さんの ZynqMP-FPGA-Linux を試してみる1

ikwzm さんの ZynqMP-FPGA-Linux を KV260 にインストールしてみよう。

ZynqMP-FPGA-Linux/doc/install/kv260.md を参照しながら、 KV260 用の Debian 10 の SD カードを作成する。

ikwzm さんの ZynqMP-FPGA-Linux を git clone する。
git clone --depth=1 --branch v2021.1.1-rc1 git://github.com/ikwzm/ZynqMP-FPGA-Linux
ikwzm_Debian_kv260_1_211107.png

cd ZynqMP-FPGA-Linux
git lfs pull

ikwzm_Debian_kv260_2_211107.png

ZynqMP-FPGA-Linux ディレクトリのファイルを示す。
ikwzm_Debian_kv260_3_211107.png

ZynqMP-FPGA-Linux/target/Kv260/boot ディレクトリの内容を示す。
ikwzm_Debian_kv260_4_211107.png

32 GB の MicroSD カードをマウントした。使ったことがあるので、 2 つのパーミッションに分かれている。
lsblk
sdf1, sdf2
ikwzm_Debian_kv260_5_211107.png

アンマウントする。
sudo umount /dev/sdf1
lsblk

ikwzm_Debian_kv260_6_211107.png
  1. 2021年11月07日 22:08 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

ガウシアン・フィルタとメディアン・フィルタを”MicroZed Chronicles: Kria & Raspberry Pi Camera”のブロック・デザインに追加する2

ガウシアン・フィルタとメディアン・フィルタを”MicroZed Chronicles: Kria & Raspberry Pi Camera”のブロック・デザインに追加する1”の続き。

MicroZed Chronicles: Kria & Raspberry Pi Camera”のブロック・デザインにガウシアン・フィルタメディアン・フィルタを追加しようということで、前回は、Vivado 2021.1 のブロック・デザインにガウシアン・フィルタとメディアン・フィルタを追加して、論理合成、インプリメンテーション、ビットストリームの生成を行った。今回は、ハードウェアをエクスポートし、Vitis でプラットフォームを更新して、ソースコードを変更してビルドした。そして、実機にビットストリームをダウンロードして、アプリケーション・ソフトウェアを起動した。カメラ画像が表示され、フィルタも動作した(たぶん)。

Vivado の File メニューから Exprot -> Export Hardware... を選択して、XSA ファイルを更新した。

Vitis の左上のウインドウの kria_n プラットフォームを右クリックし右クリックメニューから Update Hardware Specification を選択する。
Update Hardware Specification ダイアログが開く。
デフォルトの XSA ファイルは正しいので、 OK ボタンをクリックする。
kira_PCAM_gm_7_211105.png

kria_n プラットフォームがアップデートされた。
kira_PCAM_gm_8_211105.png

Vitis の画面を示す。
kira_PCAM_gm_9_211105.png

helloworld.c のソーベル・フィルタも含めた変更点を示す。
ソーベル・フィルタ、ガウシアン・フィルタ、メディアン・フィルタのヘッダファイルのインクルード文を追加した。

#include "xsobel_filter_axis.h"
#include "xgaussian_filter_axis.h"
#include "xmedian_filter_axis.h"


ソーベル・フィルタ、ガウシアン・フィルタ、メディアン・フィルタの構造体を定義した。
status_display() 関数のプロトタイプ宣言を追加した。
kira_PCAM_gm_10_211106.png

main() 関数に u32 の val を追加した。
kira_PCAM_gm_11_211106.png

ソーベル・フィルタ、ガウシアン・フィルタ、メディアン・フィルタ各 IP の初期化を行った。
kira_PCAM_gm_12_211106.png

    // Sobel filter settings
    XSobel_filter_axis_Initialize(&sobelf, 0);
    XSobel_filter_axis_Set_function_r(&sobelf, 0); // Pass through camera data
    XSobel_filter_axis_Start(&sobelf);
    XSobel_filter_axis_EnableAutoRestart(&sobelf);

    // gaussian_fitler settings
    XGaussian_filter_axis_Initialize(&gaussf, 0);
    XGaussian_filter_axis_Set_function_r(&gaussf, 0); // Pass through camera data
    XGaussian_filter_axis_Start(&gaussf);
    XGaussian_filter_axis_EnableAutoRestart(&gaussf);

    // median_filter settings
    XMedian_filter_axis_Initialize(&medianf, 0);
    XMedian_filter_axis_Set_function_r(&medianf, 0); // Pass through camera data
    XMedian_filter_axis_Start(&medianf);
    XMedian_filter_axis_EnableAutoRestart(&medianf);


フィルタを ON/OFF する無限ループを変更した。
kira_PCAM_gm_13_211106.png

     status_display();
     while(1){
         xil_printf("Please input 0 to 3. 0: Pass through camera data   1: Sobel filtering ON/OFF\n\r");
         xil_printf("                     2: Gaussian filtering ON/OFF  3: Median filtering ON/OFF");
         int chr = inbyte();
         switch(chr){
         case '0':
             xil_printf("0\n\r");
             XSobel_filter_axis_Set_function_r(&sobelf, 0); // Pass through camera data
             XGaussian_filter_axis_Set_function_r(&gaussf, 0); // Pass through camera data
             XMedian_filter_axis_Set_function_r(&medianf, 0); // Pass through camera data
             break;
         case '1':
             xil_printf("1\n\r");
             val = XSobel_filter_axis_Get_function_r(&sobelf);
             if(val == 0)
                 XSobel_filter_axis_Set_function_r(&sobelf, 1); // Sobel filtering ON
             else
                 XSobel_filter_axis_Set_function_r(&sobelf, 0); // Sobel filtering OFF
             break;
         case '2':
             xil_printf("2\n\r");
             val = XGaussian_filter_axis_Get_function_r(&gaussf);
             if(val == 0)
                 XGaussian_filter_axis_Set_function_r(&gaussf, 1); // Gaussian filtering ON
             else
                 XGaussian_filter_axis_Set_function_r(&gaussf, 0); // Gaussian filtering OFF
             break;
         case '3':
             xil_printf("3\n\r");
             val = XMedian_filter_axis_Get_function_r(&medianf);
             if(val == 0)
                 XMedian_filter_axis_Set_function_r(&medianf, 1); // Median filtering ON
             else
                 XMedian_filter_axis_Set_function_r(&medianf, 0); // Median filtering OFF
             break;
         case 'q':
             xil_printf("q\n\r");
             break;
         default:
             xil_printf("\n\r");
             break;
         }
         status_display();
         if(chr=='q')
             break;
     }


status_display() 関数のコードを示す。
kira_PCAM_gm_14_211106.png

int status_display(){
    u32 son, gon, mon;

    son = XSobel_filter_axis_Get_function_r(&sobelf);
    xil_printf("Sobel filter is ");
    if(son == 0)
        xil_printf("OFF  ");
    else
        xil_printf("ON   ");

    gon = XGaussian_filter_axis_Get_function_r(&gaussf);
    xil_printf("Gaussian filter is ");
    if(gon == 0)
        xil_printf("OFF  ");
    else
        xil_printf("ON   ");

    mon = XMedian_filter_axis_Get_function_r(&medianf);
    xil_printf("Median filter is ");
    if(mon == 0)
        xil_printf("OFF  \r\n");
    else
        xil_printf("ON   \r\n");
    xil_printf("\n\r");
    return(0);
}


現在の Vitis のプロジェクトを示す。
kira_PCAM_gm_15_211106.png

Vitis の Assistant ウインドウの display_port_appn_system -> display_port_appn -> Debug を右クリックし右クリックメニューから Run -> Debugger_display_port _appn-Default (Single Application Debug) を選択して、 FPGA をコンフィギュレーションし、アプリケーション・ソフトウェアを起動する。

gtkterm にログが表示される。
フィルタの ON/OFF を切り替える表示がでるので、数字を入力するとソーベル・フィルタ、ガウシアン・フィルタ、メディアン・フィルタを個別に ON/OFF することができる。
kira_PCAM_gm_17_211106.png
kira_PCAM_gm_16_211106.png

アプリケーション・ソフトウェアを起動するとカメラ画像が表示された。
Kria_PCAM_125_211026.jpg

1 キーを押すと、ソーベル・フィルタ画像も表示された。
Kria_PCAM_126_211026.jpg

でも、ガウシアン・フィルタとメディアン・フィルタはこのままでは効果が良く分からない?
工夫してみようか?
  1. 2021年11月06日 04:45 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

ガウシアン・フィルタとメディアン・フィルタを”MicroZed Chronicles: Kria & Raspberry Pi Camera”のブロック・デザインに追加する1

MicroZed Chronicles: Kria & Raspberry Pi Camera”のブロック・デザインにガウシアン・フィルタメディアン・フィルタを追加しよう。

現在使用している Vivado のバージョンは 2021.1

Kira_PCAM/myporj ディレクトリに gaussian_filter_axis_RBG、 median_filter_axis_RBG ディレクトリを作成した。それぞれの Vitis HLS 2021.1 プロジェクトの solution1/impl/export.zip を解凍したファイルをそれぞれのディレクトリに入れた。
kira_PCAM_gm_1_211104.png

Flow Navigator の PROJECT MANAGER -> IP Catalog をクリックし、 IP Catalog ウインドウを表示させた。
IP Catalog ウインドウ内で右クリックし、右クリックメニューから Add Repository... を選択して、 gaussian_filter_axis_RBG、 median_filter_axis_RBG ディレクトリを指定した。
Gaussian_filter_axis と Median_filter_axis が IP Catalog に登録された。
kira_PCAM_gm_2_211104.png

ブロック・デザインに Gaussian_filter_axis と Median_filter_axis を追加した。ビデオ用 AXI4-Stream のソーベル・フィルタの前に挿入した。
kira_PCAM_gm_3_211104.png

論理合成、インプリメンテーション、ビットストリームの生成を行った。
Project Summary を示す。
kira_PCAM_gm_4_211104.png

タイミング・エラーが出ている。
インプリメンテーション・デザインを開くと、やはり hidden へのパスのようだ。
kira_PCAM_gm_5_211104.png

とりあえず、そのタイミング・エラーは無視しよう。
ハードウェアをエクスポートして、もう一度、 design_1_wrapper.xsa を出力した。
kira_PCAM_gm_6_211104.png
  1. 2021年11月05日 04:12 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

RBG 24 ビット・データ入出力対応のメディアン・フィルタを Vitis HLS 2021.1 で作成する4

RBG 24 ビット・データ入出力対応のメディアン・フィルタを Vitis HLS 2021.1 で作成する3”の続き。

メディアン・フィルタを実装してみたくなった、ということで、前回は、メディアン・フィルタの演算部分、主にバブルソートの C コードの合成の様子をみた。今回は、 C/RTL 協調シミュレーションを行い、 Export RTL で IP 化、 Implementation で Vivado での合成レポートを確認しよう。

C/RTL 協調シミュレーションを行った。結果を示す。
median_kv260_20_211103.png

Avg II, Max II, Min II 共に 921655 クロックだった。 Max Latency は 921617 クロック、 Min Latency は 921612 クロックだった。
総画素数は 1280 x 720 = 921600 ピクセルなので、ほぼ 1 ピクセルを 1 クロックで処理できている。事実、 LOOP_Y_LOOP_X の II は 1 クロックとなっている。

C/RTL 協調シミュレーションの波形を見てみよう。
median_kv260_21_211103.png

ins_TREADY、 outs_TVALID 共に最初以外はずーと 1 でアクティブのままとなっていることが分かる。

Export RTL を行った。
median_filter_axis_RBG/solution1/impl に export.zip が生成された。ここに IP が凍結されている。
median_kv260_25_211104.png

IMPLEMENTATION を行った。
RTL Synthesis, Place & Route ラジオボタンをクリックして行った。
結果を示す。
median_kv260_21_211104.png

LUT が 1654 個、 FF が 1418 個、 SRL が 5 個、 CLB は 380 個だった。
CP achieved post-implementation は 4.887 ns で大丈夫そうだ。

Resource を示す。
median_kv260_22_211104.png

やはり、 grep_median_fil_fu_312 のリソース使用量が多い。

Fail Fast を示す。
median_kv260_23_211104.png

Timing Paths を示す。
median_kv260_24_211104.png

こっちもやはり、 grep_median_fil_fu_312 が関係している。あれだけ値を比較したり、セレクタ並べたりすれば、そうなるよね。。。
  1. 2021年11月04日 04:56 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

RBG 24 ビット・データ入出力対応のメディアン・フィルタを Vitis HLS 2021.1 で作成する3

RBG 24 ビット・データ入出力対応のメディアン・フィルタを Vitis HLS 2021.1 で作成する2”の続き。

メディアン・フィルタを実装してみたくなった、ということで、前回は、 C シミュレーションと C コードの合成を行った。今回は、メディアン・フィルタの演算部分、主にバブルソートの C コードの合成の様子を見ていこうと思う。

median_filter_axis_RBG/solution1/syn/verilog ディレクトリに生成されている Verilog HDL ファイルの中で median_filter_axis_median_fil.v がメディアン・フィルタの演算部分のようだ。
median_kv260_12_211103.png

C コードの合成時の C コードの合成時の Function Call Graph を見ると、 median_fil の情報が表示されている。それによると II = 1 クロックで LATENCY = 3 クロックのようだ。
median_kv260_11_211102.png

median_filter_axis_median_fil.v の中身を見てみよう。総行数は 1054 行だった。
median_kv260_13_211103.png

540 行から 718 行まで値を比較している。ソートを力技でしているのだろうか?
median_kv260_14_211103.png

720 行から 1032 行まで、セレクタが並んでいる。これもソートを力技でしているっぽい。
median_kv260_15_211103.png

C/RTL 協調シミュレーションを Wave Debug オプション付きでやってみよう。つまり、Vivado シミュレーターが起動する。
median_kv260_16_211103.png

Vivado シミュレーターが起動したので適当なところでストップする。
median_kv260_17_211103.png

median_filter_axis_median_fil.v の入出力ポートを波形に追加した。
588,547.530 ns の ins_TDATA は eceff7 だった。これが、 median_filter_axis_median_fil.v の入力ポートに入ったのが、 3 クロック後だった。(p_read8 に入った時)
median_kv260_18_211103.png

この時のソートを手動で計算してみた。
------ の前が入力、後がソートした結果を示す。

b5 b7 c1
a6 a8 b2
d1 d5 de
a1 a3 ad
ba bc c6
e5 e8 f0
a9 ac b4
a5 a8 b0
ec ef f7
---------
a1 a3 ad
a5 a8 b0
a6 a8 b2
a9 ac b4
b5 b7 c1
ba bc c6
d1 d5 de
e5 e8 f0
ec ef f7


中央値は b5 b7 c1 なので、 median_filter_axis_median_fil.v の ap_return が b5 b7 c1 の時を探すと 4 クロック後だった。
median_kv260_19_211103.png

つまり median_filter_axis_median_fil.v のレイテンシは 4 クロックということになる。 ap_ce がずっと 1 で 1 クロック毎に ap_return が出ているので、 1 クロック毎にソート結果を出力できているようだ。
  1. 2021年11月03日 06:56 |
  2. Vitis HLS
  3. | トラックバック:0
  4. | コメント:1

RBG 24 ビット・データ入出力対応のメディアン・フィルタを Vitis HLS 2021.1 で作成する2

RBG 24 ビット・データ入出力対応のメディアン・フィルタを Vitis HLS 2021.1 で作成する1”の続き。

メディアン・フィルタを実装してみたくなった、ということで、前回は、ソースコードとテストベンチコードを貼って、 Vitis HLS 2021.1 で median_filter_axis_RBG プロジェクトを作成した。今回は、 C シミュレーションと C コードの合成を行った。

C シミュレーションを行った。結果を示す。
median_kv260_4_211101.png

median_filter_axis_RBG/solution1/csim/build に org.jpg と median.jpg が生成されている。
median_kv260_5_211102.png

org.jpg を示す。これが元の画像だ。
median_kv260_6_211102.jpg

メディアン・フィルタ処理後の median.jpg を示す。とっても良くノイズが取れている。
median_kv260_7_211102.jpg

ガウシアン・フィルタ処理後の画像を示す。メディアン・フィルタ処理後の画像に比べて、ノイズが除去されていない。
gaussian_kv260_7_211028.jpg

ガウシアン・フィルタよりもメディアン・フィルタの方がノイズ除去という点では優れているようだ。

次に、注目の C コードの合成を行った。結果を示す。
LOOP_Y_LOOP_X が Interval = 1 クロックで合成できていることだ。バブルソートをインターバル 1 クロックで合成できている。 Iteration Latency = 7 クロックだが。
median_kv260_8_211102.png

たぶん、シンプルなソートのほうが合成時の性能が良いのかも知れない。演算器たくさん実装できるし。
後の合成結果を示す。
median_kv260_9_211102.png
median_kv260_10_211102.png

C コードの合成時の Function Call Graph を示す。
グラフの意味が良く分からないのだが、今までのユーザーズガイドにも記載が無いし、良く分からない。今度の 2021.2 でユーザーズガイドに記載されるかな?
median_kv260_11_211102.png

下のウインドウの Latency や リソース使用量の表は分かりやすいと思う。
  1. 2021年11月02日 04:42 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0

RBG 24 ビット・データ入出力対応のメディアン・フィルタを Vitis HLS 2021.1 で作成する1

RBG 24 ビット・データ入出力対応のガウシアン・フィルタを Vitis HLS 2021.1 で作成する1
RBG 24 ビット・データ入出力対応のガウシアン・フィルタを Vitis HLS 2021.1 で作成する2
RBG 24 ビット・データ入出力対応のガウシアン・フィルタを Vitis HLS 2021.1 で作成する3
でガウシアン・フィルタを作ってきたが、ガウシアン・フィルタのノイズ除去性能は以前 OpenCV で実装したメディアン・フィルタの性能を下回っている。そこで、メディアン・フィルタも自分で実装してみたくなった。

メディアン・フィルタは中央値フィルタで、3 x 3 のカーネル内のピクセルの中央の値を取るフィルタだ。

カラー画像は RGB の 3 個の値があるので、中央値はどうやって取るんだろう?ということで、輝度を求めて、その中央値のインデックスの画素を選んでいた。しかし、ツィッターで tomoaki_teshima さんに RGB それぞれ中央値を取って、それを合わせて RGB にするということを教えていただいた。ありがとうございます。
考えてみれば、色がノイズで全く変わっているけど、輝度は同じという時に対応できないと思ったので、教えていただいた実装にした。
なお、ソートはバブルソートで”メジアン(中央値)、範囲(レンジ)、ヒストグラムを求める”を参照した。

それでは、ヘッダファイルの median_filter_axis_RBG.h から貼っておく。

// median_filter_axis_RBG.h
// 2021/10/29 by marsee
//

#ifndef __MEDIAN_FILTER_AXIS_RBG10_H__
#define __MEDIAN_FILTER_AXIS_RBG10_H__

#define HORIZONTAL 0
#define VERTICAL 1

#define HD_720

#ifdef HD_RES
#define DISPLAY_WIDTH 1920
#define DISPLAY_HIGHT 1080
#endif

#ifdef HD_720
#define DISPLAY_WIDTH 1280
#define DISPLAY_HIGHT 720
#endif

#ifdef SVGA_RES
#define DISPLAY_WIDTH 800
#define DISPLAY_HIGHT 600
#endif

#ifdef SMALL_RES
#define DISPLAY_WIDTH 64
#define DISPLAY_HIGHT 48
#endif

#define ALL_PIXEL_VALUE (HORIZONTAL_PIXEL_WIDTH*VERTICAL_PIXEL_WIDTH)

#define ORIGINAL_IMAGE 0
#define MEDIAN_FILTER 1

#endif


次に median_filter_axis_RBG.cpp を示す。

// median_filter_axis_RBG.cpp
// 2021/10/29 by marsee
//

#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>

#include "median_filter_axis_RBG.h"

constexpr int size = 3;

void median_fil(ap_int<32> (&pix_mat)[size][size], ap_uint<24> &result);
ap_int<32> pixel_sort(ap_int<32> *y);
ap_int<32> separate_rbg(ap_int<32> rbg, ap_int<32> &r, ap_int<32> &b, ap_int<32> &g);

int median_filter_axis(hls::stream<ap_axiu<24,1,1,1> >& ins,
        hls::stream<ap_axiu<24,1,1,1> >& outs, int function){
#pragma HLS INTERFACE s_axilite port=function
#pragma HLS INTERFACE axis register_mode=both register port=outs
#pragma HLS INTERFACE axis register_mode=both register port=ins
#pragma HLS INTERFACE s_axilite port=return

    ap_axiu<24,1,1,1> pix;
    ap_axiu<24,1,1,1> median;
    ap_uint<24> val;

    ap_int<32> line_buf[2][DISPLAY_WIDTH];
#pragma HLS array_partition variable=line_buf block factor=2 dim=1
#pragma HLS resource variable=line_buf core=RAM_2P

    ap_int<32> pix_mat[size][size];
#pragma HLS array_partition variable=pix_mat complete

    LOOP_WAIT_USER : do {   // user が 1になった時にフレームがスタートする
#pragma HLS LOOP_TRIPCOUNT min=1 max=1 avg=1
        ins >> pix;
    } while(pix.user == 0);

    LOOP_Y: for(int y=0; y<DISPLAY_HIGHT; y++){
        LOOP_X: for(int x=0; x<DISPLAY_WIDTH; x++){
#pragma HLS PIPELINE II=1
            if (!(x==0 && y==0))    // 最初の入力はすでに入力されている
                ins >> pix; // AXI4-Stream からの入力

            LOOP_PIX_MAT_K: for(int k=0; k<3; k++){
                LOOP_PIX_MAT_M: for(int m=0; m<2; m++){
                    pix_mat[k][m] = pix_mat[k][m+1];
                }
            }
            pix_mat[0][2] = line_buf[0][x];
            pix_mat[1][2] = line_buf[1][x];
            ap_int<32> y_val = pix.data;
            pix_mat[2][2] = y_val;

            line_buf[0][x] = line_buf[1][x];    // 行の入れ替え
            line_buf[1][x] = y_val;

            median_fil(pix_mat, val);
            median.data = val;

            if(x<2 || y<2)
                median.data = 0;

            if(x==0 && y==0) // 最初のピクセル
                median.user = 1;
            else
                median.user = 0;
            if(x == (DISPLAY_WIDTH-1)) // 行の最後
                median.last = 1;
            else
                median.last = 0;

            if(function == MEDIAN_FILTER)
                outs << median;
            else
                outs << pix;
        }
    }
    return(0);
}

// median filter
//
// x0y0 x1y0 x2y0
// x0y1 x1y1 x2y1
// x0y2 x1y2 x2y2
//
void median_fil(ap_int<32> (&pix_mat)[size][size], ap_uint<24> &result){
    ap_int<32> pix_1d_r[9], pix_1d_b[9], pix_1d_g[9];
    ap_int<32> y_r, y_b, y_g, y;

    for(int i=0; i<9; i++){
        separate_rbg(pix_mat[i/3][i%3], pix_1d_r[i], pix_1d_b[i], pix_1d_g[i]);
    }

    y_r = pixel_sort(pix_1d_r);
    y_b = pixel_sort(pix_1d_b);
    y_g = pixel_sort(pix_1d_g);

    result = (y_r << 16) + (y_b << 8) + y_g;
}

// pixel_sort()
// bubble sort
// ”メジアン(中央値)、範囲(レンジ)、ヒストグラムを求める”参照
// https://cgengo.sakura.ne.jp/arg04.html
ap_int<32> pixel_sort(ap_int<32> *y){
#pragma HLS ARRAY_PARTITION variable=y dim=1 complete
    ap_int<32> tmp;

    for(int i=1; i<9; i++){
        for(int j=0; j<9-i; j++){
            if(y[j] < y[j+1]){
                tmp = y[j];
                y[j] = y[j+1];
                y[j+1] = tmp;
            }
        }
    }
    return(y[4]);
}

// separate_rbg
// RGBを分離する
// RBGのフォーマットは、{R(8bits), B(8bits), G(8bits)}, 1pixel = 32bits
//
ap_int<32> separate_rbg(ap_int<32> rbg, ap_int<32> &r, ap_int<32> &b, ap_int<32> &g){
    b = (rbg>>8) & 0xff;
    g = rbg & 0xff;
    r = (rbg>>16) & 0xff;
    return(0);
}


テストベンチの median_filter_axis_RBG_tb.cpp を示す。

// median_filter_axis_RBG_tb.cpp
// 2021/10/29 by marsee
//

#include <stdio.h>
#include <stdint.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgcodecs/imgcodecs.hpp"

#include "median_filter_axis_RBG.h"

constexpr int size = 3;

int median_filter_axis(hls::stream<ap_axiu<24,1,1,1> >& ins, hls::stream<ap_axiu<24,1,1,1> >& outs, int function);
int median_filter_axis_soft(hls::stream<ap_axiu<24,1,1,1> >& ins,
        hls::stream<ap_axiu<24,1,1,1> >& outs, int function);
void median_fil_soft(ap_int<32> (&pix_mat)[size][size], ap_uint<24> &result);
ap_int<32> pixel_sort_soft(ap_int<32> *y);
ap_int<32> separate_rbg_soft(ap_int<32> rbg, ap_int<32> &r, ap_int<32> &b, ap_int<32> &g);

const char INPUT_JPG_FILE[] = "test2.jpg";
const char OUTPUT_JPG_FILE[] = "median.jpg";
const char ORG_OUT_JPG_FILE[] = "org.jpg";

int main(){
    hls::stream<ap_axiu<24,1,1,1> > ins, ins2;
    hls::stream<ap_axiu<24,1,1,1> > ins_soft;
    hls::stream<ap_axiu<24,1,1,1> > outs, outs2;
    hls::stream<ap_axiu<24,1,1,1> > outs_soft;
    ap_axiu<24,1,1,1> pix;
    ap_axiu<24,1,1,1> vals, vals_soft;

    // JPG ファイルをMat に読み込む
    cv::Mat img = cv::imread(INPUT_JPG_FILE);

    // ピクセルを入れる領域の確保
    std::vector<int32_t> rd_bmp(sizeof(int32_t)*img.cols*img.rows);
    std::vector<int32_t> hw_median(sizeof(int32_t)*(img.cols)*(img.rows));
    std::vector<int32_t> sw_median(sizeof(int32_t)*(img.cols)*(img.rows));

    // rd_bmp にJPGのピクセルを代入
    cv::Mat_<cv::Vec3b> dst_vec3b = cv::Mat_<cv::Vec3b>(img);
    for (int y=0; y<img.rows; y++){
        for (int x=0; x<img.cols; x++){
            cv::Vec3b pixel;
            pixel = dst_vec3b(y,x);
            rd_bmp[y*img.cols+x] = (pixel[1] & 0xff) | ((pixel[0] & 0xff)<<8) | ((pixel[2] & 0xff)<<16); // RBG 8 bits
            // blue - pixel[0]; green - pixel[1]; red - pixel[2];
        }
    }

    // ins に入力データを用意する
    for(int i=0; i<5; i++){ // dummy data
        pix.user = 0;
        pix.data = i;
        ins << pix;
    }

    for(int j=0; j < img.rows; j++){
        for(int i=0; i < img.cols; i++){
            pix.data = (int32_t)rd_bmp[(j*img.cols)+i];

            if (j==0 && i==0)   // 最初のデータの時に TUSER を 1 にする
                pix.user = 1;
            else
                pix.user = 0;

            if (i == img.cols-1) // 行の最後でTLASTをアサートする
                pix.last = 1;
            else
                pix.last = 0;

            ins << pix;
            ins2 << pix;
            ins_soft << pix;
        }
    }

    median_filter_axis(ins, outs, MEDIAN_FILTER); // ハードウェアのメディアンフィルタ
    median_filter_axis_soft(ins_soft, outs_soft, MEDIAN_FILTER);  // ソフトウェアのメディアンフィルタ

    // ハードウェアとソフトウェアのメディアンフィルタの値のチェック
    for (int y=0; y<img.rows; y++){ // 結果の画像サイズはx-2, y-2
        for (int x=0; x<img.cols; x++){
            outs >> vals;
            outs_soft >> vals_soft;
            ap_uint<32> val = vals.data;
            hw_median[y*img.cols+x] = (int32_t)val;
            if (val != vals_soft.data){
                printf("ERROR HW and SW results mismatch x = %ld, y = %ld, HW = %x, SW = %x\n",
                        x, y, val, vals_soft.data);
                //return(1);
            }
        }
    }
    printf("Success HW and SW results match\n");

    const int median_row = img.rows;
    const int median_cols = img.cols;
    cv::Mat wbmpf(median_row, median_cols, CV_8UC3);
    // wbmpf にmedian フィルタ処理後の画像を入力
    cv::Mat_<cv::Vec3b> sob_vec3b = cv::Mat_<cv::Vec3b>(wbmpf);
    for (int y=0; y<wbmpf.rows; y++){
        for (int x=0; x<wbmpf.cols; x++){
            cv::Vec3b pixel;
            pixel = sob_vec3b(y,x);
            int32_t rbg = hw_median[y*wbmpf.cols+x];
            pixel[0] = ((rbg >> 8) & 0xff); // blue
            pixel[1] = (rbg & 0xff); // green
            pixel[2] = ((rbg >> 16) & 0xff); // red
            sob_vec3b(y,x) = pixel;
        }
    }

    // ハードウェアのメディアンフィルタの結果を jpg ファイルへ出力する
    cv::imwrite(OUTPUT_JPG_FILE, wbmpf);

    median_filter_axis(ins2, outs2, ORIGINAL_IMAGE); // 元画像出力

    cv::Mat wbmpf2(median_row, median_cols, CV_8UC3);
    // wbmpf2 に元画像を入力
    sob_vec3b = cv::Mat_<cv::Vec3b>(wbmpf2);
    for (int y=0; y<wbmpf.rows; y++){
        for (int x=0; x<wbmpf.cols; x++){
            cv::Vec3b pixel;
            pixel = sob_vec3b(y,x);
            outs2 >> vals;
            int32_t val = vals.data;
            pixel[0] = ((val >> 8) & 0xff); // blue
            pixel[1] = (val & 0xff); // green
            pixel[2] = ((val >> 16) & 0xff); // red
            sob_vec3b(y,x) = pixel;
        }
    }

    // 元画像を jpg ファイルへ出力する
    cv::imwrite(ORG_OUT_JPG_FILE, wbmpf2);

    return(0);
}

int median_filter_axis_soft(hls::stream<ap_axiu<24,1,1,1> >& ins,
        hls::stream<ap_axiu<24,1,1,1> >& outs, int function){

ap_axiu<24,1,1,1> pix;
ap_axiu<24,1,1,1> median;
ap_uint<24> val;

ap_int<32> line_buf[2][DISPLAY_WIDTH];

ap_int<32> pix_mat[size][size];

LOOP_WAIT_USER : do {   // user が 1になった時にフレームがスタートする
    ins >> pix;
} while(pix.user == 0);

LOOP_Y: for(int y=0; y<DISPLAY_HIGHT; y++){
    LOOP_X: for(int x=0; x<DISPLAY_WIDTH; x++){
        if (!(x==0 && y==0))    // 最初の入力はすでに入力されている
            ins >> pix; // AXI4-Stream からの入力

        LOOP_PIX_MAT_K: for(int k=0; k<3; k++){
            LOOP_PIX_MAT_M: for(int m=0; m<2; m++){
                pix_mat[k][m] = pix_mat[k][m+1];
            }
        }
        pix_mat[0][2] = line_buf[0][x];
        pix_mat[1][2] = line_buf[1][x];
        ap_int<32> y_val = pix.data;
        pix_mat[2][2] = y_val;

        line_buf[0][x] = line_buf[1][x];    // 行の入れ替え
        line_buf[1][x] = y_val;

        median_fil_soft(pix_mat, val);
        median.data = val;

        if(x<2 || y<2)
            median.data = 0;

        if(x==0 && y==0) // 最初のピクセル
            median.user = 1;
        else
            median.user = 0;
        if(x == (DISPLAY_WIDTH-1)) // 行の最後
            median.last = 1;
        else
            median.last = 0;

        if(function == MEDIAN_FILTER)
            outs << median;
        else
            outs << pix;
        }
    }
    return(0);
}

// median filter
//
// x0y0 x1y0 x2y0
// x0y1 x1y1 x2y1
// x0y2 x1y2 x2y2
//
void median_fil_soft(ap_int<32> (&pix_mat)[size][size], ap_uint<24> &result){
    ap_int<32> pix_1d_r[9], pix_1d_b[9], pix_1d_g[9];
    ap_int<32> y_r, y_b, y_g, y;

    for(int i=0; i<9; i++){
        separate_rbg_soft(pix_mat[i/3][i%3], pix_1d_r[i], pix_1d_b[i], pix_1d_g[i]);
    }

    y_r = pixel_sort_soft(pix_1d_r);
    y_b = pixel_sort_soft(pix_1d_b);
    y_g = pixel_sort_soft(pix_1d_g);

    result = (y_r << 16) + (y_b << 8) + y_g;
}

// pixel_sort()
// bubble sort
// ”メジアン(中央値)、範囲(レンジ)、ヒストグラムを求める”参照
// https://cgengo.sakura.ne.jp/arg04.html
ap_int<32> pixel_sort_soft(ap_int<32> *y){
    ap_int<32> tmp;

    for(int i=1; i<9; i++){
        for(int j=0; j<9-i; j++){
            if(y[j] < y[j+1]){
                tmp = y[j];
                y[j] = y[j+1];
                y[j+1] = tmp;
            }
        }
    }
    return(y[4]);
}

// separate_rbg
// RGBを分離する
// RBGのフォーマットは、{R(8bits), B(8bits), G(8bits)}, 1pixel = 32bits
//
ap_int<32> separate_rbg_soft(ap_int<32> rbg, ap_int<32> &r, ap_int<32> &b, ap_int<32> &g){
    b = (rbg>>8) & 0xff;
    g = rbg & 0xff;
    r = (rbg>>16) & 0xff;
    return(0);
}


画像は、ガウシアン・フィルタと同じファイル(test2.jpg)を使用している。このファイルでは、ノイズ除去の様子を見るために、画像ソフトの Pinta でノイズを加えた。
gaussian_kv260_1_211028.jpg

ソースコードやヘッダファイル、テストベンチを入れた median_filter_axis_RBG プロジェクトを示す。
median_kv260_1_211101.png

今回のテストベンチ・コードでは OpenCV ライブラリを使用している。
Vitis HLS 2021.1 には内蔵された OpenCV は無いので、別にインストールした OpenCV を指定する。
Vitis HLS の Project メニューから Project Settings... を選択して、Project Settings ダイアログを開いた。
Simulation タブを開いて、median_filter_axis_RBG_tb.cpp の CFLAGS に

-I/usr/local/include

を設定した。
inker Flags に

-L/usr/local/lib -lopencv_core -lopencv_imgcodecs -lopencv_imgproc

を設定した。
median_kv260_2_211101.png

更に、 Synthesis をクリックして、 Top Function に median_filter_axis を指定した。
median_kv260_3_211101.png
  1. 2021年11月01日 05:06 |
  2. KRIA KV260 Vision AI Starter Kit
  3. | トラックバック:0
  4. | コメント:0