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

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

FPGAの部屋

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

hls4ml を Vitis HLS 2021.1 でやってみる

hls4ml はVivado HLS を使用して機械学習をハードウェア化するフレームワークだ。以前、FPGAの部屋でもやってみたが、ロボットカーの曲がる方向を示すニューラルネットワークを構築しようとして、large runtime and excessive memory usage エラーで止まっていた。(”hls4mlをやってみた7(自分で学習したネットワークをhls4mlでハードウェア化2)”参照)これを Vitis HLS 2021.1 でやり直してみようと思う。
現在の hls4ml は fastmachinelearning/hls4ml にあるようだ。
hls4ml-tutorial もある。Docker での構築もできるようだ。

さて、すでに keras_curve_cnn2_line_VitisH が作ってあったので、 Vitis HLS 2021.1 で 開いた。hls4ml_1_210630.png

重みやソースコード、テストベンチ・ファイルは firmware ディレクトリにある。
hls4ml_5_210630.png

このプロジェクトは Ultra96V2 ボード用だった。
hls4ml_3_210630.png

C シミュレーションを行った。
hls4ml_2_210630.png

C コードの合成を行ったが、エラーになってしまった。
hls4ml_4_210630.png

エラー内容を示す。

ERROR: [XFORM 203-103] Array 'mult.V.1' (/home/masaaki/DNN/hls4ml/nnet_utils/nnet_dense.h:56): partitioned elements number (15600) has exeeded the threshold (1024), which may cause long run-time.
ERROR: [HLS 200-1715] Encountered problem during source synthesis
ERROR: [HLS 200-70] Pre-synthesis failed.



このエラーは Vivado HLS の時の”” ARRAY_PARTITION COMPLETE has exceeded the threshold (1024)”の解決策”でやったはず。。。。

Vitis HLS 2021.1 の Solution メニューから Solution Settings... を選択して、 Solution Settings (solution1) を開いたが、 maximum_size の項目がなかった。。。 orz
hls4ml_6_210630.png

エラーの回避方法は無いのだろうか?
  1. 2021年06月30日 05:05 |
  2. Vitis HLS
  3. | トラックバック:0
  4. | コメント:0

”(目標)Vivado HLSで1クロック毎に結果を出力できるNNを作る”を Vitis HLS 2021.1 でやってみる

”(目標)Vivado HLSで1クロック毎に結果を出力できるNNを作る”を Vitis HLS 2020.2 でやってみる”で”large runtime and excessive memory usage”でうまく行かなかった”(目標)Vivado HLSで1クロック毎に結果を出力できるNNを作る”を Vitis HLS 2021.1 で、もう一度やってみよう。

元ネタは、以下の記事だ。
(目標)Vivado HLSで1クロック毎に結果を出力できるNNを作る1(学習編)
(目標)Vivado HLSで1クロック毎に結果を出力できるNNを作る2(ソースコード)
(目標)Vivado HLSで1クロック毎に結果を出力できるNNを作る3(Vivado HLS)
(目標)Vivado HLSで1クロック毎に結果を出力できるNNを作る4(チューンナップ1)
(目標)Vivado HLSで1クロック毎に結果を出力できるNNを作る5(チューンナップ2)

Vitis HLS 2021.1 で all_deploy_afnet4mnist2_211 プロジェクトを作成した。
プロジェクトに入れているソースコードは”(目標)Vivado HLSで1クロック毎に結果を出力できるNNを作る4(チューンナップ1)”の普通の MNIST の 784 入力をプロジェクトに入れている。
all_deploy_afnet4mnist2_211_1_210628.jpg

Part は Ultra96V2 用に xczu3eg-sbva484-1-e に設定した。
all_deploy_afnet4mnist2_211_2_210628.jpg

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

(目標)Vivado HLSで1クロック毎に結果を出力できるNNを作る3(Vivado HLS)”の結果と同じだった。

C コードの合成を行った。
C Synthesis ダイアログがデフォルトで OK ボタンをクリックした。
all_deploy_afnet4mnist2_211_4_210628.jpg

何と合成が終了した。
凄いぞ Vitis HLS 2021.1 。。。
結果を示す。
all_deploy_afnet4mnist2_211_5_210628.jpg

レイテンシは 842 クロックだった。
DSP は 803 個、 FF は 146850 個、LUT は 177705 個使用している。リソース使用量が多すぎると思うが、ともかくコンパイルできたのは嬉しい。。。

変換された Verilog HDL のファイルを示す。
all_deploy_afnet4mnist2_211_8_210628.png

Function Call Graph を示す。
all_deploy_afnet4mnist2_211_6_210628.png

次に NUM_ITERATIONS を 100 から 2 に変更して、C/RTL 協調シミュレーションを行う。
all_deploy_afnet4mnist2_211_7_210628.png

C/RTL 協調シミュレーションが終了した。結果を示す。
all_deploy_afnet4mnist2_211_9_210628.png

Avg Latency は 848 クロック、 Max Latency は 858 クロック、 Min Latency は 838 クロックだった。

Export RTL を行って成功した。
IP 化できた。
all_deploy_afnet4mnist2_211_10_210628.png

Run Implementation を行った。
現在、進行中。
  1. 2021年06月29日 04:40 |
  2. Vitis HLS
  3. | トラックバック:0
  4. | コメント:0

Windows 10 のVivado 2021.1 と Vitis 2021.1 で Vitis HLS 2021.1 の AXI4-Liteを使用した IP を実装する2

Windows 10 のVivado 2021.1 と Vitis 2021.1 で Vitis HLS 2021.1 の AXI4-Liteを使用した IP を実装する1”の続き。

2020.2 の時は、”Windows 10 版の Vitis HLS 2020.2 で作成した AXI4Lite インターフェースの IP を使用した回路は Vitis 2020.2 でプラットフォームがビルドできない”の記事のように Windows 10 では、Vitis 2020.2 でアプリケーション・プロジェクトをビルドするときにビルド・エラーになっていた。

2021.1 ではどうだろうか?
前回は、”Vitis HLS 2021.1 を使ってみる(DMA_pow2)”の DMA_pow2 IP を Vivado 2021.1 でブロックデザイン上に実装して、論理合成、インプリメンテーション、ビットストリームの生成を行った。そして、XSAファイルを生成した。
今回は、Vitis 2021.1 を立ち上げて、プラットフォームとアプリケーション・プロジェクトを作成して、ビルドを行い、ZYBO Z7-10 で動作させてみよう。

Vivado 2021.1 で Tools メニューから Launch Vitis IDE を選択して、Vitis 2021.1 を起動した。
Vitis IDE Launcher ダイアログが表示された。
Workspace の Browse... ボタンをクリックする。
DMA_pow2_test フォルダに行って、vitis_work フォルダを作成する。
DMA_pow2_test_17_210626.png

Workspace に vitis_work フォルダを指定した。
Launch ボタンをクリックする。
DMA_pow2_test_18_210626.png

Vitis IDE が起動した。
Create Application Project をクリックして、プラットフォームとアプリケーション・プロジェクトを作成する。
DMA_pow2_test_19_210627.png

New Application Project ダイアログが表示された。
Create a new Vivado Project画面が表示される。Next>ボタンをクリックする。
DMA_pow2_test_20_210627.png

Platform 画面では、Create a new platform hardware (XSA) タブをクリックする。
XSA_file の Browse... ボタンをクリックして、DMA_pow2_test プロジェクトの DMA_pow2_test_wrapper.xsa を選択する。
Next>ボタンをクリックする。
DMA_pow2_test_21_210627.png

Application Project Details 画面。
Application Project Name に DMA_pow2_test と入力する。
Next>ボタンをクリックする。
DMA_pow2_test_22_210627.png

Domain 画面。
デフォルトのままとする。
Next>ボタンをクリックする。
DMA_pow2_test_23_210627.png

Templates 画面。
Empty Application(C) をクリックする。
Finish ボタンをクリックする。
DMA_pow2_test_24_210627.png

DMA_pow2_test_wrapper プラットフォームと DMA_pow2_test アプリケーション・プロジェクトが作成された。
DMA_pow2_test_25_210627.png

WSL2 上で動作する Vitis 2020.2 で ZYBO Z7-10 をコンフィグレーションして、アプリケーション・ソフトウェアを走らせる”から、test_dma.c を DMA_pow2_test_system -> DMA_pow2_test -> src フォルダにコピーした。
DMA_pow2_test_26_210627.png

トンカチマークをクリックして、ビルドを行ったところ、成功してビルドできて、elf ファイルが生成された。
DMA_pow2_test_27_210627.png

2020.2 の時は、”Windows 10 版の Vitis HLS 2020.2 で作成した AXI4Lite インターフェースの IP を使用した回路は Vitis 2020.2 でプラットフォームがビルドできない”の記事のように Windows 10 では、Vitis 2020.2 でアプリケーション・プロジェクトをビルドするときにビルド・エラーになっていたが、Vitis 2021.1 ではビルドが成功した。バグがフィックスしているようだ。

それでは ZYBO Z7-10 でテストしてみよう。
ZYBO Z7-10 を USB で接続し、電源を ON した。
Trea Term を起動して設定を行った。(シリアル接続、115200 bps, 8 bit, 1stop bit)
Vitis の Assistant ウインドウの DMA_pow2_test_system -> DMA_pow2_test -> Debug を右クリックし、右クリックメニューから Run -> Launch Hardware (Single Application Debug) を選択する。
DMA_pow2_test_28_210627.png

Trea Term に正しく結果が表示された。
DMA_pow2_test_29_210627.png
  1. 2021年06月28日 04:21 |
  2. Vitis
  3. | トラックバック:0
  4. | コメント:0

Windows 10 のVivado 2021.1 と Vitis 2021.1 で Vitis HLS 2021.1 の AXI4-Liteを使用した IP を実装する1

2020.2 の時は、”Windows 10 版の Vitis HLS 2020.2 で作成した AXI4Lite インターフェースの IP を使用した回路は Vitis 2020.2 でプラットフォームがビルドできない”の記事のように Windows 10 では、Vitis 2020.2 でアプリケーション・プロジェクトをビルドするときにビルド・エラーになっていた。

2021.1 ではどうだろうか?
今回は、”Vitis HLS 2021.1 を使ってみる(DMA_pow2)”の DMA_pow2 IP を Vivado 2021.1 でブロックデザイン上に実装して、論理合成、インプリメンテーション、ビットストリームの生成を行う。そして、XSAファイルを生成する。

最初に、ZYBO Z7-10 用の DMA_pow2_test プロジェクトを Vivado 2021.1 で作成した。
DMA_pow2_test_1_210626.png

Flow Navigator で IP Catalog をクリックして、IP Catalog のウインドウを表示させた。
IP Catalog のウインドウ内で右クリックし右クリックメニューから Add Repository... をクリックする。
DMA_pow2_test_2_210626.png

Repositories ダイアログで、”Vitis HLS 2021.1 を使ってみる(DMA_pow2)”のフォルダの solution1/impl/ip フォルダを選択する。
DMA_pow2_test_3_210626.png

Add Repository ダイアログが表示された。
DMA_pow2_test_4_210626.png

IP Catalog に Dma_pow2 IP が追加された。これで、DMA pow2 IP を使えるようになった。
DMA_pow2_test_5_210626.png

Flow Navigator で Create Block Design をクリックして、ブロックデザインを作成する。
Create Block Design ダイアログが表示された。
Design name に DMA_pow2_test と入力した。
DMA_pow2_test_6_210626.png

ZYNQ7 Processing System と DMA_pow2 IP を Add IP してブロックデザインを作成した。
DMA_pow2_test_7_210626.png

processing_system7_0 の設定画面を示す。
S_AXI_HP0 インターフェースを活かした。
DMA_pow2_test_8_210626.png

FCLK_CLK0 を 100 MHz に設定した。
DMA_pow2_test_9_210626.png

HDL Wrapper ファイルを生成した。
DMA_pow2_test_10_210626.png

Flow Navigator から Generate Bitstream をクリックして、論理合成、インプリメンテーション、ビットストリームの生成を行った。
エラーなしで成功した。
Project Summary を示す。
DMA_pow2_test_11_210626.png

XSAファイルを生成する。
File メニューから Export -> Export Hardware... を選択する。
Export Hardware Platform ダイアログが表示された。
DMA_pow2_test_12_210626.png

Output 画面で、Include bitstream ラジオボタンをクリックした。
DMA_pow2_test_13_210626.png

Files はデフォルトのまま、Next>ボタンをクリックする。
DMA_pow2_test_14_210626.png

Exporting Hardware Platform 画面で、Finish ボタンをクリックした。
DMA_pow2_test_15_210626.png

DMA_pow2_test_wrapper.xsa ファイルが生成された。
DMA_pow2_test_16_210626.png
  1. 2021年06月27日 04:23 |
  2. Vitis
  3. | トラックバック:0
  4. | コメント:0

Vitis HLS 2021.1 を使ってみる(DMA_pow2)

Vitis HLS 2021.1 が出たので、使ってみることにした。
題材は DMA_pow2 で、入力を 2 乗して出力する AXI4 Master 入出力の IP だ。
なお、今回は訳あって、Windows 10 の Vitis HLS 2021.1 を使用している。

Vitis HLS 2021.1 の DMA_pow2 プロジェクトを示す。
左下の Window が新しくなって、Flow Navigator になったようだ。
Vitis_HLS_211_1_210626.png

ソース・ファイルの DMA_pow2n.cpp を示す。

// DMA_pow2.cpp
// 2018/05/08 by marsee
//

int DMA_pow2(volatile int *in, volatile int *out){
#pragma HLS INTERFACE s_axilite port=out
#pragma HLS INTERFACE s_axilite port=in
#pragma HLS INTERFACE m_axi depth=10 port=out offset=slave
#pragma HLS INTERFACE m_axi depth=10 port=in offset=slave
#pragma HLS INTERFACE mode=s_axilite port=return

    for (int i=0; i<10; i++){
        int temp = in[i];
        out[i] = temp * temp;
    }

    return(0);
}


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

// DMA_pow2_tb.cpp
// 2018/05/08 by marsee
//

#include <iostream>

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

int main(){
    int data[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int 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;
    }
}


Solution メニューから Synthesis を選択する。
プロジェクトの Part は xc7z010clg400-1 にした。ZYBO Z7-10 に使用する。
Vitis_HLS_211_2_210626.png

ZYBO Z7-10 に使用するので、General の config_interface の m_axi_addr64 のチェックは外した。つまり AXI4 Master のアドレスは 32 ビットとした。
Vitis_HLS_211_3_210626.png

C シミュレーションを行う。
Flow Navigator の Run CSimulation をクリックしても、C シミュレーションが走る。
Vitis_HLS_211_4_210626.png

C シミュレーションの結果を示す。この辺りは前のバージョンと変わらない。
Vitis_HLS_211_5_210626.png

Flow Navigator で C SYNTHESIS の Run C Synthesis をクリックする。
C コードの合成時にもダイアログが表示されるようになった。
Vitis_HLS_211_6_210626.png

C コードの合成が終了した。
Vitis_HLS_211_7_210626.png

C コードの合成結果を示す。
Performance & Resource Estimates の VITIS_LOOP_12_1 を見ると、PIPELINE 指示子が書いてないのに、Interval が 1 になっていて、パイプラインされているのが分かる。
Vitis_HLS_211_8_210626.png
Vitis_HLS_211_9_210626.png

Open Function Call Graph → Synthesis を選択する。
Vitis_HLS_211_10_210626.png

Function Call Graph が表示された。
簡単なコードなので、良く分からない?もっと複雑なコードをやってみた方が良さそうだ。
Vitis_HLS_211_11_210626.png

C/RTL協調シミュレーションを行った。
C/RTL Co-simulation Dialog で Dump Trace を all に変更した。このダイアログは 2020.2 から変更点が無さそう?
Vitis_HLS_211_12_210626.png

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

Open Function Call Graph → Cosimulation を見た。
こちらも複雑なモデルで見た方が良さそうだ。
Vitis_HLS_211_14_210626.png

Export RTL を行った。
Export RTL のダイアログを示す。そのまま OK ボタンをクリックした。
Vitis_HLS_211_15_210626.png

Export RTL が終了した。
Vitis_HLS_211_16_210626.png

次に Flow Navigator から Run Implementation をクリックする。
Run Implementation ダイアログが表示された。
RTL Synthesis のラジオボタンがクリックされていた。
Vitis_HLS_211_17_210626.png

RTL Synthesis, Place & Route ラジオボタンに変更して、OKボタンをクリックした。
Vitis_HLS_211_18_210626.png

結果を示す。
Vitis_HLS_211_19_210626.png
Vitis_HLS_211_20_210626.png

solution1 -> impl の export.zip に IP が圧縮されている。
Vitis_HLS_211_21_210626.png
  1. 2021年06月26日 13:12 |
  2. Vitis HLS
  3. | トラックバック:0
  4. | コメント:0

WSL2 上の Vitis 2020.2 と Vivado 2020.2 でデバックを行う

WSL2 上で動作する Vitis 2020.2 で ZYBO Z7-10 をコンフィグレーションして、アプリケーション・ソフトウェアを走らせる”で、WSL2 上で動作する Linux 版の Vitis 2020.2 から Windows 10 上で動作する hw_server に接続している ZYBO Z7-10 にコンフィギュレーションし、更にアプリケーション・ソフトウェアを起動して動作させることができた。
今回は、”WSL2 上で動作する Vitis 2020.2 で ZYBO Z7-10 をコンフィグレーションして、アプリケーション・ソフトウェアを走らせる”の環境を使用して、デバックを行ってみよう。

最初に Vivado 2020.2 の DMA_pow2_test プロジェクトのブロックデザインで DMA_pow2_0 の s_axi_control AXI4-Liteインターフェースと m_axi_gmem AXI4 インターフェースを選択して、右クリックし、右クリックメニューから Debug を選んで System ila を追加した。
WSL2_29_210624.png

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

Vitis 2020.2 で Assistant ウインドウのDMA_pow2_test_system -> DMA_pow2_test -> Debug を右クリックし、右クリックメニューから Debug -> Debugger_DMA_pow2_test-Default (前回作成した Debug Configuration)を選択した。
WSL2_39_210624.png

Vitis がデバックモードになって、最初の C コードで停止している。
WSL2_31_210624.png

最初にデバックモードで起動するのは、クロックが出力されないからだ。クロックは PS から PL に供給されているので、最初のブート・ソフトウェアが走らないとクロックが PL に供給されない。

Vivado で PROGRAM AND DEBUG -> Open Hardware Manager -> Open Target をクリックして出てきたメニューの内の Resent Target -> 192.168.3.32.Xilinx_tcf/Digilent/... を選択する。
WSL2_32_210624.png

すると、ILA デフォルト・ダッシュボードが表示されて、波形を見ることができる。
WSL2_33_210624.png

ILA デフォルト・ダッシュボードをフローとして、トリガボタンをクリックし、トリガ待ちにした。
なお、トリガ条件は DMA_pow2_0_m_axi_gmem : ARVALID の立ち上がりとした。
WSL2_34_210624.png

Vitis に戻って Resume ボタンをクリックして、アプリケーション・ソフトウェアを走らせる。
WSL2_35_210624.png

アプリケーション・ソフトウェアが走って、ILA デフォルト・ダッシュボードに波形が表示された。
WSL2_36_210624.png

真ん中を拡大した。
AXI4 インターフェースの Read で 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 を Read した。
WSL2_37_210624.png

AXI4 インターフェースの Write で Read した値を 2 乗した数を Write しているのが分かる。
WSL2_38_210624.png

最後に Tera Term の画面を示す。
WSL2_40_210624.png
  1. 2021年06月25日 04:31 |
  2. WSL2
  3. | トラックバック:0
  4. | コメント:0

WSL2 上で動作する Vitis 2020.2 で ZYBO Z7-10 をコンフィグレーションして、アプリケーション・ソフトウェアを走らせる

WSL2 上で動作する Vivado 2020.2 で ZYBO Z7-10 をコンフィグレーションする”では WSL 上で動作する Linux 版の Vivado 2020.2 から Windows 10 上で動作する hw_server に接続している ZYBO Z7-10 にコンフィギュレーションすることができた。
今回は、WSL2 上で動作する Linux 版の Vitis 2020.2 から Windows 10 上で動作する hw_server に接続している ZYBO Z7-10 にコンフィギュレーションし、更にアプリケーション・ソフトウェアを起動して動作させてみよう。

最初に WSL2 上で Vitis HLS 2020.2 の DMA_pow2 プロジェクトを作成して、DMA pow2 IP を作成する。

WSL2 上の Vitis HLS 2020.2 の DMA_pow2 プロジェクトを示す。
WSL2_15_210622.png

DMA_pow2n.cpp のソース・ファイルを貼っておく。

// DMA_pow2.cpp
// 2018/05/08 by marsee
//

int DMA_pow2(volatile int *in, volatile int *out){
#pragma HLS INTERFACE s_axilite port=out
#pragma HLS INTERFACE s_axilite port=in
#pragma HLS INTERFACE m_axi depth=10 port=out offset=slave
#pragma HLS INTERFACE m_axi depth=10 port=in offset=slave
#pragma HLS INTERFACE s_axilite port=return

    for (int i=0; i<10; i++){
        int temp = in[i];
        out[i] = temp * temp;
    }

    return(0);
}



C コードの合成結果を示す。
WSL2_16_210623.png

Export RTL 結果を示す。
WSL2_17_210623.png

WSL2 上の Vivado 2020.2 で DMA_pow2_test プロジェクトを作成した。
下の図は、論理合成、インプリメンテーション、ビットストリームの生成が終了した状態だ。
WSL2_18_210623.png

DMA_pow2_test ブロックデザインを示す。
WSL2_19_210623.png

Address Map を示す。
WSL2_20_210623.png

Project Summary を示す。
WSL2_21_210623.png

ハードウェアをエクスポートして、XSAファイルを作成した。

Vivado 2020.2 の Tools メニューから Launch Vitis IDE を選択して、Vitis 2020.2 を起動する。

Vitis 2020.2 が起動して Workspace を設定するので、DMA_pow2_test フォルダに vitis_work フォルダを新規作成して、Workspace
として設定した。

DMA_pow2_test アプリケーション・プロジェクトの作成時に、DMA_pow2_test_wrapper プラットフォームを作成した。

tset_dma.c を作成して、DMA_pow2_test アプリケーション・プロジェクトの src フォルダに入れた。

DMA_pow2_test アプリケーション・プロジェクトのビルドを行って成功した。
WSL2_22_210623.png

Assistant ウインドウで、DMA_pow2_test_system -> DMA_pow2_test -> Debug を右クリックし、Run -> Run Configuration... を選択する。
Run Configuration ダイアログが開いた。
Single Application Debug を右クリックし、右クリックメニューから New Configuration を選択する。
WSL2_23_210623.png

Dubugger_DMA_pow2_test-Default コンフィグレーションが生成された。
Connection の New ボタンをクリックする。
WSL2_24_210624.png

Target Connection Details ダイアログが表示された。
ここで New Target Connection を作成して Test Connection ボタンをクリックして、テストしたのだが、パケットが届かないというダイアログばかりが表示された。(実際は届いていたようだ)
なお、Windows 10 のファイヤー・ウォールで、3121 TCPポートは開けてある。”WSL2 上で動作する Vivado 2020.2 で ZYBO Z7-10 をコンフィグレーションする”を参照。

いろいろと試行錯誤したときに”AR# 64759: SDK - リモート ターゲット デバッグ用の設定”を見つけた。これによると、PowerShell で hw_server を起動するのではなく、XSCT コンソールから hw_server を起動している。
XSCT コンソールを使用すると、2020.2 のインストール・フォルダに行く必要がないので、この方が良さそうだ。
XSCT コンソールはWindows 10 のスタートボタンをクリックし、Xilinx Design Tools -> Xilinx Software Commandline Tool (XSCT) v2020.2.2 で起動することができる。

XSCT コンソールで hw_server を起動した。
WSL2_25_210624.png

Target Connection Details ダイアログで、Target Name と Host に IP アドレスを入れて、Advanced ボタンをクリックすると Zybo Z7 が出ているので大丈夫そうだ。
OKボタンをクリックする。
クリック後にまた、パケット届いていないというダイアログが出るが無視して良いようだ。
WSL2_26_210624.png

Tera Term を立ち上げて、ZYBO Z7-10のシリアルポートに接続する。

Run Configuration ダイアログで、Apply ボタンをクリックし、Run ボタンをクリックした。
WSL2_27_210624.png

Tera Term に演算の結果が表示された。成功だ。
WSL2_28_210624.png

test_dma.c を貼っておく。
このコードのバグにフィックスでは、IDA さんにお世話になりました。ありがとうございます。

/* * test_dma.c * *  Created on: 2017/12/02 *      Author: masaaki */

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

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

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;
    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, (u32)&data[0]);
    XDma_pow2_Set_out_r(&XDMA_pow2_ap, (u32)&result[0]);

    Xil_DCacheFlush(); // Flush data[10] cache to memory

    XDma_pow2_Start(&XDMA_pow2_ap);

    while(!XDma_pow2_IsDone(&XDMA_pow2_ap)) ;

    Xil_DCacheInvalidate(); // Flush result[10] cache to memory

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

    return 0;

}


しかし、パケットが届いていないというダイアログが出ているのに、パケットが届いているとはどういう訳だろう。。。
人騒がせなバグだ。だいぶ時間をロスしてしまった。。。
  1. 2021年06月24日 05:14 |
  2. WSL2
  3. | トラックバック:0
  4. | コメント:0

Vivado ML 2021.1 でボード・ファイルをインストールする

Vivado ML 2021.1 で ZYBO Z7 などのボード・ファイルをインストールしようとしたが、Vivado\2021.1\data\boards フォルダに board_files フォルダが無かった。
どうやって、ボード・ファイルをインストールするのか?を探ってみた。

Vivado ML 2021.1 の File メニューから Project -> New... を選択して、Create a new Vivado Project ダイアログで新しいプロジェクトを作成していくが、その途中で Default Part 画面がある。
Default Part 画面の Refresh ボタンをクリックすると、利用可能なボードが出てくるようだ。
Vivado2021-1_11_210623.png

Refresh ボタンをクリックすると、Refresh Catalog が出てきてカタログをダウンロードしている。
Vivado2021-1_12_210623.png

ZYBO Z7-20 や ZYBO Z7-10 などが出てきた。
Status の Install ボタンをクリックすると、ボード・ファイルがインストールされるようだ。
Vivado2021-1_13_210623.png

ボード・ファイルがインストールされた。
これで ZYBO Z7-10 のボード・ファイルが反映される。
Vivado2021-1_14_210623.png
  1. 2021年06月23日 20:28 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:0

Vivado ML 2021.1 が出ました

Vivado ML 2021.1 が出ています。

Vivado の新機能です。
特に、”DFX の BDC”の”IP インテグレーターでリリースされた DFX 用のブロック デザイン コンテナー (BDC)”、”ブロック デザインの中にブロック デザインを配置して、DFX デザインを作成/処理する”をやってみたいです。

Vivado ML を見ると、

Vivado ML のスタンダード版は無償でダウンロード可能です。

ということなので、従来の WebPACK が Vivado ML のスタンダード版になったようです。

さて、早速、ウエブインストーラーをダウンロードしてインストールを始めました。

Xilinx Unified 2021.1 Installer の Welcome 画面です。
Vivado2021-1_1_210623.png

Select Install Type 画面です。
ここでは登録した E-mail アドレスとパスワードを入れます。
Vivado2021-1_2_210623.png

Select Product to Install 画面。
Vitis を選びました。
Vivado2021-1_3_210623.png

Vitis Unified Software Platform 画面。
Vivado ML のスタンダード版でサポートされているデバイスを選びました。
Vivado2021-1_4_210623.png

Accept License Agreements 画面。
全てのライセンス条件にチェックを入れました。
Vivado2021-1_5_210623.png

Select Destination Directory 画面。
インストール・フォルダを設定しました。
Vivado2021-1_6_210623.png

Installation Summary 画面。
Install ボタンをクリックしました。
Vivado2021-1_7_210623.png

インストールがスタートして、ダウンロードしています。
Vivado2021-1_8_210623.png

まだダウンロード中です。インストール終了して使ってみるのが楽しみですね。。。

インストール中に WinPcap がインストールされます。
Vivado2021-1_9_210623.png

インストールが終了しました。
Vivado 2021.1 を起動しました。これは Windows 10 版です。
Vivado2021-1_10_210623.png
  1. 2021年06月23日 04:32 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:0

WSL2 上で動作する Vivado 2020.2 で ZYBO Z7-10 をコンフィグレーションする

WSL2 上で動作する Linux 用 Vivado 2020.2 で ZYBO Z7-10 をコンフィグレーションすることにした。
WSL2 上で動作する Linux 用 Vivado 2020.2 では、USB が使えないので、コンフィグレーションすることができないそうだ。そのため、Vivado でコンフィグレーションするときに Remote Server を指定して、Windows 上で動作する hw_server と接続し、ZYBO Z7-10 をコンフィギュレーションする。

なお、これらをやる際には、ツィッターのタイムラインの方々にはとてもお世話になった。特に IDA さんにお世話になりました。ありがとうございます。

WSL2 上の Vivado 2020.2 で ZYBO Z7-10 の LED_test プロジェクトを作成した。
WSL2_5_210622.png

LED_test.v を示す。SW0 と LD0 を接続しただけだ。

module LED_test(
    input SW0,
    output LD0
    );
    wire SW0;
    wire LD0;
    
    assign LD0 = SW0;
endmodule


制約ファイルの LED_test.xdc を示す。

set_property PACKAGE_PIN M14 [get_ports LD0]
set_property PACKAGE_PIN G15 [get_ports SW0]
set_property IOSTANDARD LVCMOS33 [get_ports LD0]
set_property IOSTANDARD LVCMOS33 [get_ports SW0]


論理合成、インプリメンテーション、ビットストリームの生成を行って、成功した。

Windows 10 で PowerShell を立ち上がて、Vivado 2020.2 の bin フォルダに行って、hw_server.bat を起動した。
.\hw_server.bat
WSL2_6_210622.png

PROGRAM AND DEBUG -> Open Hardware Manager -> Open Target -> open New Target... を選択した。
WSL2_7_210622.png

Open New Hardware Target ダイアログが表示された。
WSL2_8_210622.png

Hardware Server Settings 画面で Remote server を選択して、Host name に IP アドレスを入れる。
WSL2_9_210622.png

Windows 10 でもう 1 つ PowerShell を立ち上げて、ipconfig /all で IP アドレスを確認した。
WSL2_10_210622.png

確認した IP アドレスを Host name に入れた。
WSL2_11_210622.png

しかし、これで接続できなかった。
Windows 10 のファイヤー・ウォールではじかれていると思って、”Windows10で特定のポートを開放する”を参考にして、 3121 番 TCP 受信ポートを開けた。
WSL2_12_210622.png

すると、Windows 10 の hw_server に接続できた。
WSL2_13_210622.png

Open Hardware Target Summary 画面が表示された。Finish ボタンをクリックした。
WSL2_14_210622.png

Program device をクリックした。
WSL2_15_210622.png

Program device ダイアログが表示された。
Bitstream file に LED_test.bit が表示されている。
Program ボタンをクリックして、コンフィギュレーションを行った。
WSL2_16_210622.png

コンフィギュレーションができて、SW0 を ON/OFF すると LD0 が点灯・消灯した。
WSL2_17_210622.png
  1. 2021年06月22日 20:49 |
  2. WSL2
  3. | トラックバック:0
  4. | コメント:0

”Vitis-AI 1.3 Flow for Avnet VITIS Platforms”をやってみる1

Vitis-AI 1.3 Flow for Avnet VITIS Platforms”を参照しながら、Vitis-AI 1.3 をやってみることにした。

私の所有している Ultra96-V2 でやってみよう。そのために”Ultra96-V2 の PMIC をアップデートして Vitis-AI 1.3 を実行できるようにする”で PMIC の設定をアップデートしておいた。

最初に http://avnet.me/avnet-u96v2_sbc_base-vitis-ai-1.3-image をダウンロードした。
Avnet-u96v2_sbc-Vitis-AI-1-3-2021-02-23.zip がダウンロードできた。
Vitis-AI_15_210619.png

balenaEtchar を立ち上げて Avnet-u96v2_sbc-Vitis-AI-1-3-2021-02-23.zip を読み込んで、 16 GB の MicroSD カードにイメージを書き込む。
Vitis-AI_16_210619.png

イメージ書き込みが終了した。
Vitis-AI_17_210619.png

sudo resize2fs -f /dev/sdf2
を実行したが、またダメだったようだ。
Vitis-AI_18_210619.png

MicroSD カードを Ultra96-V2 に挿して電源ON すると、PetaLinux が立ち上がった。
ID: root, PASSWORD: root でログインできた。
Vitis-AI_19_210619.png

Ultra96-V2 の USB ポートに PLANEX GU-1000T (USB - LAN 変換)が接続されている。そのため、IP アドレスを取得できている。
ifconfig の結果を示す。
Vitis-AI_20_210619.png
Vitis-AI_21_210619.png

ネットワークが接続されているので、ターミナルから
ssh <IP アドレス> -l root
で Ultra96-V2 の PetaLinux にログインした。

Vitis-AI 1.3 Flow for Avnet VITIS Platforms”の”Step 2 - Execute the AI applications on hardware”の設定を initset.sh ファイルにまとめた。
Vitis-AI_22_210619.png

#!/usr/bin/env bash
cd ~/dpu_sw_optimize/zynqmp
source ./zynqmp_dpu_optimize.sh
dmesg -D
dmesg -E
dexplorer --whoami
DISPLAY=:0.0
export DISPLAY
xrandr --output DP-1 --mode 640x480
cd


source ./initset.sh
を実行した。
Vitis-AI_23_210619.png
Vitis-AI_24_210619.png

adas_detection application
cd ~/Vitis-AI/demo/VART/adas_detection
./adas_detection ./video/adas.avi /usr/share/vitis_ai_library/models/yolov3_adas_pruned_0_9/yolov3_adas_pruned_0_9.xmodel

Vitis-AI_25_210619.png

Ultra96-V2 の DisplayPort に接続した Display に車の認識の画像が表示された。(動画です)
Vitis-AI_26_210619.jpg

gtkterm の表示画像を示す。
Vitis-AI_27_210619.png

pose_detection application
cd ~/Vitis-AI/demo/VART/pose_detection
./pose_detection ./video/pose.mp4 /usr/share/vitis_ai_library/models/sp_net/sp_net.xmodel /usr/share/vitis_ai_library/models/ssd_pedestrian_pruned_0_97/ssd_pedestrian_pruned_0_97.xmodel

Vitis-AI_28_210619.png

ポーズの検出画像が表示された。(動画です)
Vitis-AI_29_210619.jpg

gtkterm の表示画像を示す。
Vitis-AI_30_210619.png
  1. 2021年06月21日 04:57 |
  2. Vitis-AI
  3. | トラックバック:0
  4. | コメント:0

Ultra96-V2 の PMIC をアップデートして Vitis-AI 1.3 を実行できるようにする

Ultra96-V2 で Vitis-AI 1.3 を実行すると、PMIC の電流制限に引っかかって Linux がリブートしてしまう。それを回避するために、”Updating PMIC on Ultra96-V2 through the 2020.1 BSP!”に従って、Ultra96-V2 の PMIC をアップデートしてみよう。

Updating PMIC on Ultra96-V2 through the 2020.1 BSP!”によると、 avnet.me の 2020.1/Vitis_PreBuilt_Example から 2020p1_ULTRA96V2_vadd.tar.gz をダウンロードした。
Vitis-AI_1_210619.png

work ディレクトリに解凍した。
sd_card.img が今回 MicroSD カードに書くイメージだ。
Vitis-AI_2_210619.png

balenaEtchar を起動して、 sd_card.img とマウントした MicroSD カードを指定して、書き込む。
Vitis-AI_3_210619.png

書き込み中。
Vitis-AI_4_210619.png

書き込み終了。
Vitis-AI_5_210619.png

lsblk でみると MicroSD カードは sdf にマウントされているようだ。
Vitis-AI_6_210619.png

sudo resize2fs -f /dev/sdf2
を実行して、リサイズしてみたがダメなようだった。
Vitis-AI_7_210619.png

MicroSD カードを Ultra96-V2 に入れて、電源ON した。
PetaLinux が起動して gtkterm にメッセージが出た。
ID: root , Password: root でログインできた。
Vitis-AI_8_210619.png

Updating PMIC on Ultra96-V2 through the 2020.1 BSP!”に従ってコマンドを入れていく。
cd pmic-prog/
cd pmic-configs/
ls

Vitis-AI_9_210619.png

cd ..
./pmic_prog detect 6

Vitis-AI_10_210619.png

Device 0x13 programming
./pmic_prog program 6 0x13 -i ./pmic-configs/U96V2_5401_0x13_191030.txt
Vitis-AI_11_210619.png

Device 0x14 programming
./pmic_prog program 6 0x14 -i ./pmic-configs/U96V2_5401_0x14_191030.txt
Vitis-AI_12_210619.png

Programming Verification
./pmic_prog read-registers 6 0x13 -o 0x13.txt -i ./pmic-configs/U96V2_5401_0x13_191030.txt
Vitis-AI_13_210619.png

./pmic_prog read-registers 6 0x14 -o 0x14.txt -i ./pmic-configs/U96V2_5401_0x14_191030.txt
Vitis-AI_14_210619.png

これで、 Ultra96-V2 の PMIC の電流制限を変更できたはず。。。
  1. 2021年06月20日 04:36 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Vivado 2020.2 で ZYBO Z7-20 の Pcam5C を使ってカメラ画像を表示する4

Vivado 2020.2 で ZYBO Z7-20 の Pcam5C を使ってカメラ画像を表示する3”の続き。

Zybo Z7 Pcam 5C DemoをVivado 2020.02で動作させてみた”で、 Vivado 2020.2 で ZYBO Z7-20 の Pcam5C を使ってカメラ画像を表示させていたので、私もやってみたということで、前回は、Vitis 2020.2 でプラットフォームとアプリケーション・プロジェクトを作成し、アプリケーション・ソフトウェアをビルドした。今回は、実機を接続して、カメラ画像を表示させてみよう。

ZYBO Z7-20 に Pcam5C を接続し、USB のケーブルでパソコンと接続し、HDMI ポートからディスプレイに接続して、電源ON した。

Ubuntu 18.04 で Gtkterm を起動して、 115200 bps , 8bit, 1stop bit に設定した。
Vitis で Run ボタンをクリックして、アプリケーション・ソフトウェアを実行した。
ZYBO_Z7_20_Pcam2002_38_210618.png

Gtkterm にメニューが表示された。
ZYBO_Z7_20_Pcam2002_39_210618.png

カメラ画像がディスプレイに表示された。カメラをぶら下げているので、画像が上下反対になっている。
ZYBO_Z7_20_Pcam2002_44_210619.jpg

Gtkterm で設定を変えようと思うが、うまく入らない。というか、Enter キーを押さないと、getchar() でキー入力を取り込んでくれないが、キー入力を取得できるのは最後の Enter キーだけの 0x0D になってしまっているようだ。
ZYBO_Z7_20_Pcam2002_41_210618.png

そこで、 getchar() を inbyte() に変更して、ビルドした。
ZYBO_Z7_20_Pcam2002_42_210618.png

こうすると楽に設定が変更できるようになった。
ZYBO_Z7_20_Pcam2002_43_210618.png

Vivado 2020.2 での ZYBO Z7-20 + Pcam5C でのカメラ画像のディスプレイ出力に成功した。良かった。。。
  1. 2021年06月19日 03:17 |
  2. ZYBO Z7
  3. | トラックバック:0
  4. | コメント:0

Vivado 2020.2 で ZYBO Z7-20 の Pcam5C を使ってカメラ画像を表示する3

Vivado 2020.2 で ZYBO Z7-20 の Pcam5C を使ってカメラ画像を表示する2”の続き。

Zybo Z7 Pcam 5C DemoをVivado 2020.02で動作させてみた”で、 Vivado 2020.2 で ZYBO Z7-20 の Pcam5C を使ってカメラ画像を表示させていたので、私もやってみたということで、前回は、ハードウェアをエクスポートした。今回は、Vitis 2020.2 でプラットフォームとアプリケーション・プロジェクトを作成し、アプリケーション・ソフトウェアをビルドする。

Vivado 2020.2 の Tools メニューから Launch Vitis IDE を選択する。
Vitis IDE Launcher ダイアログが表示された。
Browse... ボタンをクリックする。
ZYBO_Z7_20_Pcam2002_22_210616.png

Zybo-Z7-20-pcam-5c-2019.1 (後で、Zybo-Z7-20-pcam-5c-2020.2 に改名する)ディレクトリの下に vitis_work ディレクトリを作成した。
ZYBO_Z7_20_Pcam2002_23_210616.png

vitis_work ディレクトリの中に入って”開く”ボタンをクリックした。
ZYBO_Z7_20_Pcam2002_24_210616.png

Zybo-Z7-20-pcam-5c-2019.1/vitis_work が Workspace に指定されたので、 Launch ボタンをクリックする。
ZYBO_Z7_20_Pcam2002_25_210616.png

Vitis IDE が立ち上がった。
ZYBO_Z7_20_Pcam2002_26_210616.png

Create Application Project をクリックする。

New Application Project ダイアログが表示された。 Next > ボタンをクリックする。
ZYBO_Z7_20_Pcam2002_27_210616.png

Platform 画面が表示された。
Create a new platform hardware (XSA) タブをクリックする。
Browse... ボタンをクリックして、XSA ファイルを指定する。
system_wrapper.xsa ファイルを選択する。
XSA File に system_wrapper.xsa ファイルが表示された状態で、Next > ボタンをクリックする。
ZYBO_Z7_20_Pcam2002_28_210616.png

Application Project Details 画面が表示された。
Application Project name に pcam_vdma_hdmi と入力した。
Next > ボタンをクリックする。
ZYBO_Z7_20_Pcam2002_29_210616.png

Domain 画面はそのまま、Next > ボタンをクリックする。
ZYBO_Z7_20_Pcam2002_30_210616.png

Templates 画面では、Empty Applicaiton (C++) を選択した。
Finish ボタンをクリックした。
ZYBO_Z7_20_Pcam2002_31_210616.png

system_wrapper プラットフォームと pcam_vdma_hdmi_system アプリケーション・プロジェクトが作成された。
ZYBO_Z7_20_Pcam2002_32_210616.png

pcam_vdma_hdmi_system/pcam_vdma_hdmi/src を右クリックし、右クリックメニューから Import sources... を選択した。
Import Sources ダイアログが表示された。
From directory: の Browse... ボタンをクリックして、Zybo-Z7-20-pcam-5c-2019.1/sdk_appsrc/pcam_vdma_hdmi ディレクトリを指定した。
main.cc にチェックを入れて、Finish ボタンをクリックした。
ZYBO_Z7_20_Pcam2002_33_210616.png

pcam_vdma_hdmi_system/pcam_vdma_hdmi/src に main.cc がインポートされた。
ZYBO_Z7_20_Pcam2002_34_210616.png

後は、pcam_vdma_hdmi_system/pcam_vdma_hdmi/src ディレクトリに Zybo-Z7-20-pcam-5c-2019.1/sdk_appsrc/pcam_vdma_hdmi ディレクトリ の hdmi 、 ov5640 、 platform ディレクトリをファイルマネージャーでコピーした。
ZYBO_Z7_20_Pcam2002_35_210616.png

すると、 Vitis IDE に hdmi 、 ov5640 、 platform ディレクトリが入った。
ZYBO_Z7_20_Pcam2002_36_210616.png

トンカチ・ボタンをクリックして、ビルドした。

ビルドが成功した。
ZYBO_Z7_20_Pcam2002_37_210616.png

Linux だとビルドが成功するようだ。

なお、事前にWindows 版の Vitis 2020.2 ではビルドが通らないかもと思っていた。
それは、”Windows 10 版の Vitis HLS 2020.2 で作成した AXI4Lite インターフェースの IP を使用した回路は Vitis 2020.2 でプラットフォームがビルドできない”を経験していたからだ。ぜひ、Vitis 2021.1 では治っていて欲しいと思う。
  1. 2021年06月18日 04:55 |
  2. ZYBO Z7
  3. | トラックバック:0
  4. | コメント:0

Vivado 2020.2 で ZYBO Z7-20 の Pcam5C を使ってカメラ画像を表示する2

Vivado 2020.2 で ZYBO Z7-20 の Pcam5C を使ってカメラ画像を表示する1”の続き。

Zybo Z7 Pcam 5C DemoをVivado 2020.02で動作させてみた”で、 Vivado 2020.2 で ZYBO Z7-20 の Pcam5C を使ってカメラ画像を表示させていたので、私もやってみたということで、前回は、 Vivado 2019.2 の Zybo-Z7-20-pcam-5c プロジェクトを Vivado 2020.2 のプロジェクトにアップグレードして、論理合成、インプリメンテーション、ビットストリームの生成を行って、タイミング・エラーがあるが成功した。今回は、ハードウェアをエクスポートする。今日は寝坊して時間が無くなってしまったので、明日に Vitis 編を書くことにする。なお、Ubutnu 18.04 の Vitis 2020.2 では、ビルドのエラーは発生しない。 Windows 版の Vitis 2020.2 だけのバグのようだ。

さて、 Vivado 2020.2 で File メニューから Export -> Export Hardware... を選択して、XSA ファイルを作成する。
Export Hardware Platform ダイアログが表示された。
ZYBO_Z7_20_Pcam2002_17_210616.png

Output 画面では、 Include bitstream のラジオボタンをクリックする。
ZYBO_Z7_20_Pcam2002_18_210616.png

Files 画面はデフォルトのままとする。
ZYBO_Z7_20_Pcam2002_19_210616.png

Exproting Hardware Platform 画面。Finish ボタンをクリックする。
ZYBO_Z7_20_Pcam2002_20_210616.png

XSA ファイルが生成された。
ZYBO_Z7_20_Pcam2002_21_210616.png
  1. 2021年06月17日 05:21 |
  2. ZYBO Z7
  3. | トラックバック:0
  4. | コメント:0

Vivado 2020.2 で ZYBO Z7-20 の Pcam5C を使ってカメラ画像を表示する1

Zybo Z7 Pcam 5C DemoをVivado 2020.02で動作させてみた”を見たので、私も Vivado 2020.2 で ZYBO Z7-20 の Pcam5C を使ってカメラ画像を表示させてみたくなったので、やってみることにした。私の使用している OS は Ubuntu 18.04 LTS となっている。

Zybo Z7 Pcam 5C DemoをVivado 2020.02で動作させてみた”では、 Vivado 2019.1 のコンパイル結果を使っているが、私は Vivado 2020.2 にアップグレードしてみようと思う。

まずは、”Digilent/Zybo-Z7-20-pcam-5c”から Zybo-Z7-20-pcam-5c-2019.1.zip をダウンロードした。

ZIP ファイルをダウブルクリックして開いた。
sdk_appsrc と Zybo-Z7-20-pcam-5c-2019.1 ディレクトリがあるので、Zybo-Z7-20-pcam-5c-2019.1 ディレクトリを展開した。
ZYBO_Z7_20_Pcam2002_1_210615.png

Vivado 2020.2 を起動して Zybo-Z7-20-pcam-5c-2019.1/vivado_proj ディレクトリの Zybo-Z7-20-pcam_5c.xpr を開く。
ZYBO_Z7_20_Pcam2002_2_210615.png

Older Project Version ダイアログが表示された。
Automatically upgrade to the current version のラジオボタンがクリックされているので、そのまま OK ボタンをクリックした。
ZYBO_Z7_20_Pcam2002_3_210615.png

Project Upgraded ダイアログが表示された。
Report IP Status ボタンをクリックした。
ZYBO_Z7_20_Pcam2002_4_210615.png

Vivado 2020.2 の Zybo-Z7-20-pcam_5c プロジェクトが開かれた。
IP Status が表示されている。
Upgrade Selected ボタンをクリックした。
ZYBO_Z7_20_Pcam2002_6_210615.png

Upgrade IP ダイアログが表示された。
OK ボタンをクリックした。
ZYBO_Z7_20_Pcam2002_7_210615.png

IP の Upgrade が成功した。
ZYBO_Z7_20_Pcam2002_8_210615.png

続いて、Generate Output Products ダイアログが表示された。
Generate ボタンをクリックした。
ZYBO_Z7_20_Pcam2002_9_210615.png

Critical Messages が表示された。
ZYBO_Z7_20_Pcam2002_10_210615.png

Generate Output Products が完了した。
ZYBO_Z7_20_Pcam2002_11_210615.png

ブロックデザインを示す。
ZYBO_Z7_20_Pcam2002_14_210616.png
ZYBO_Z7_20_Pcam2002_15_210616.png

Address Map を示す。
ZYBO_Z7_20_Pcam2002_16_210616.png

論理合成、インプリメンテーション、ビットストリームの生成を行った。
タイミング・エラーがでている。
ZYBO_Z7_20_Pcam2002_12_210615.png

Open Implementation Design をクリックして、Timing を表示させた。
タイミング・エラーは dpy_hs_clock_p で発生していた。
ZYBO_Z7_20_Pcam2002_13_210616.png

これは以前解析した Zybo-Z7-20-pcam-5c プロジェクトのタイミング・エラーと同じだ。
ZYBO Z7-20でPcam 5Cを使用する4(タイミングエラーの検討)”を参照のこと。
よって、タイミング・エラーは無視することにする。
  1. 2021年06月16日 04:37 |
  2. ZYBO Z7
  3. | トラックバック:0
  4. | コメント:0

Verilator をもう一度試してみる12(multi_axim を試す4)

Verilator をもう一度試してみる11(multi_axim を試す3)”の続き。

Vivado HLS の multi_axim を Verilator で検証してみようということで、前回は、Vivado 2020.2 の multi_axim_pj プロジェクトを作成して、multi_axim と axi_slave_BFM を IP インテグレーターで接続した回路を Verilator でシミュレーションして成功した。今回は、その回路をスタートさせて動作を見てみよう。

まずは、multi_axim は Vivado HLS で作成した回路なので、動作はレジスタを設定してから、0 番地に 1 を書くと 1 回、回路が動作する。
multi_axim_AXILiteS_s_axi.v の Address Info を引用する。

//------------------------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)
//        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  - Channel 0 (ap_done)
//        bit 1  - Channel 1 (ap_ready)
//        others - reserved
// 0x0c : IP Interrupt Status Register (Read/TOW)
//        bit 0  - Channel 0 (ap_done)
//        bit 1  - Channel 1 (ap_ready)
//        others - reserved
// 0x10 : Data signal of ap_return
//        bit 31~0 - ap_return[31:0] (Read)
// 0x18 : Data signal of x
//        bit 31~0 - x[31:0] (Read/Write)
// 0x1c : reserved
// 0x20 : Data signal of y
//        bit 31~0 - y[31:0] (Read/Write)
// 0x24 : reserved
// (SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake)


0x18 番地の x のアドレス(0 を設定)を設定して、 0x20 番地の y のアドレス(0x10を設定)を設定して、 0x00 番地に 1 を書けば回路が動作する。
その様に、 multi_axim_top_wrapper_sc.cpp を書き直した。

// multi_axim_top_wrapper_sc.cpp
// 2021/06/10 by marsee
//

#include "verilated_vcd_sc.h"
#include "Vmulti_axim_top_wrapper.h"

int sc_main(int argc, char **argv) {

    Verilated::commandArgs(argc, argv);

    sc_clock ap_clk ("ap_clk", 10, SC_NS);
    sc_signal<bool> ap_rst_n;
    sc_signal<bool> arready, arvalid;
    sc_signal<bool> awready, awvalid;
    sc_signal<bool> bready, bvalid;
    sc_signal<bool> rready, rvalid;
    sc_signal<bool> wready, wvalid;
    sc_signal<uint32_t> araddr, awaddr;
    sc_signal<uint32_t> rdata, wdata;
    sc_signal<uint32_t> bresp;
    sc_signal<uint32_t> rresp;
    sc_signal<uint32_t> wstrb;
    Vmulti_axim_top_wrapper *top;

    top = new Vmulti_axim_top_wrapper("top");

    top->ap_rst_n_0(ap_rst_n);        // Set some inputs
    top->ap_clk_0(ap_clk);
    top->s_axi_AXILiteS_0_araddr(araddr);
    top->s_axi_AXILiteS_0_arvalid(arvalid);
    top->s_axi_AXILiteS_0_arready(arready);
    top->s_axi_AXILiteS_0_awaddr(awaddr);
    top->s_axi_AXILiteS_0_awvalid(awvalid);
    top->s_axi_AXILiteS_0_awready(awready);
    top->s_axi_AXILiteS_0_bready(bready);
    top->s_axi_AXILiteS_0_bresp(bresp);
    top->s_axi_AXILiteS_0_bvalid(bvalid);
    top->s_axi_AXILiteS_0_rdata(rdata);
    top->s_axi_AXILiteS_0_rready(rready);
    top->s_axi_AXILiteS_0_rresp(rresp);
    top->s_axi_AXILiteS_0_rvalid(rvalid);
    top->s_axi_AXILiteS_0_wdata(wdata);
    top->s_axi_AXILiteS_0_wready(wready);
    top->s_axi_AXILiteS_0_wstrb(wstrb);
    top->s_axi_AXILiteS_0_wvalid(wvalid);

    Verilated::traceEverOn(true);
    VerilatedVcdSc* tfp = new VerilatedVcdSc;
    top->trace (tfp, 99);
    tfp->open ("simx.vcd");

    ap_rst_n = 0;        // Set some inputs
    araddr = 0;
    arvalid = 0;
    awaddr = 0;
    awvalid = 0;
    bready = 0;
    rready = 0;
    wdata = 0;
    wstrb = 0;
    wvalid = 0;

    sc_start(10, SC_NS);    // 1nsずらす
    ap_rst_n = 1;

    sc_start(10, SC_NS);

    int clk_count;
    // AXI4 Lite IF Write
    awaddr = 0x18;
    wdata = 0x0;
    wstrb = 0xf;
    awvalid = 1;
    wvalid = 1;
    for(clk_count=0; clk_count<20; clk_count++){
        sc_start(10, SC_NS);
        if(awready)
            awvalid = 0;
        if(wready)
            wvalid = 0;
        if(awvalid==0 && wvalid==0)
            break;
    }
    sc_start(10, SC_NS);
    bready = 1;
    for(clk_count=0; clk_count<20; clk_count++){
        sc_start(10, SC_NS);
        if(bvalid)
            break;
    }
    sc_start(10, SC_NS);
    bready = 0;
    sc_start(10, SC_NS);

    // AXI4 Lite IF Read
    araddr = 0x18;
    arvalid = 1;
    for(clk_count=0; clk_count<20; clk_count++){
        sc_start(10, SC_NS);
        if(arready){
            arvalid = 0;
            break;
        }
    }
    sc_start(10, SC_NS);
    rready = 1;
    for(clk_count=0; clk_count<20; clk_count++){
        sc_start(10, SC_NS);
        if(rvalid){
            rready = 0;
            break;
        }
    }
    sc_start(10, SC_NS);

    // AXI4 Lite IF Write
    awaddr = 0x20;
    wdata = 0x10;
    wstrb = 0xf;
    awvalid = 1;
    wvalid = 1;
    for(clk_count=0; clk_count<20; clk_count++){
        sc_start(10, SC_NS);
        if(awready)
            awvalid = 0;
        if(wready)
            wvalid = 0;
        if(awvalid==0 && wvalid==0)
            break;
    }
    sc_start(10, SC_NS);
    bready = 1;
    for(clk_count=0; clk_count<20; clk_count++){
        sc_start(10, SC_NS);
        if(bvalid)
            break;
    }
    sc_start(10, SC_NS);
    bready = 0;
    sc_start(10, SC_NS);

    // AXI4 Lite IF Write
    awaddr = 0x0;
    wdata = 0x1;
    wstrb = 0xf;
    awvalid = 1;
    wvalid = 1;
    for(clk_count=0; clk_count<20; clk_count++){
        sc_start(10, SC_NS);
        if(awready)
            awvalid = 0;
        if(wready)
            wvalid = 0;
        if(awvalid==0 && wvalid==0)
            break;
    }
    sc_start(10, SC_NS);
    bready = 1;
    for(clk_count=0; clk_count<20; clk_count++){
        sc_start(10, SC_NS);
        if(bvalid)
            break;
    }
    sc_start(10, SC_NS);
    bready = 0;
    sc_start(10, SC_NS);

    sc_start(400, SC_NS);

    tfp->close();
    delete top;
    
    exit(0);        // シミュレーション終了
}


Verilator でコンパイルして実行する。
verilator -f multi_axim.cmd
cd obj_dir
make -j -f Vmulti_axim_top_wrapper.mk Vmulti_axim_top_wrapper
./Vmulti_axim_top_wrapper


GTKWave を起動した。
gtkwave simx.vcd
Verilator_82_210615.png
Verilator_83_210615.png
Verilator_84_210615.png

multi_axim が動作しているのが確認できた。
axi_slave_bfm の Write に Wait が入っているのは、 axi_slave_bfm.v のパラメータで”WRITE_RANDOM_WAIT = 1”に設定されていて Write 時にランダムな Wait が入るように設定されているからだ。
  1. 2021年06月15日 04:47 |
  2. シミュレーション
  3. | トラックバック:0
  4. | コメント:0

Verilator をもう一度試してみる11(multi_axim を試す3)

Verilator をもう一度試してみる10(multi_axim を試す2)”の続き。

Vivado HLS の multi_axim を Verilator で検証してみようということで、前回は、 Vivado 2020.2 の multi_axim_pj プロジェクトを作成して、multi_axim と axi_slave_BFM を IP インテグレーターで接続した。今回は、 Verilator を使用してシミュレーションを行う。

まずは、SystemC のテストベンチの multi_axim_top_wrapper_sc.cpp を作成した。
Verilator_79_210614.png

multi_axim_top_wrapper_sc.cpp のコードを示す。
今回のコードでは、AXI4 Lite の Write アクセス、 AXI4 Lite の Read アクセスをそのまま書いてしまったが、Verilog HDL の task の様に書く SystemC での書き方を教えてください。よろしくお願いします。

// multi_axim_top_wrapper_sc.cpp
// 2021/06/10 by marsee
//

#include "verilated_vcd_sc.h"
#include "Vmulti_axim_top_wrapper.h"

/*int AXI4L_Write(Vmulti_axim_top_wrapper *top){
    int clk_count;

    top->s_axi_AXILiteS_0_awvalid = true;
    top->s_axi_AXILiteS_0_wvalid = true;
    for(clk_count=0; clk_count<20; clk_count++){
        sc_start(10, SC_NS);
        if(top->s_axi_AXILiteS_0_awready)
            top->s_axi_AXILiteS_0_awvalid = false;
        if(top->s_axi_AXILiteS_0_wready)
            top->s_axi_AXILiteS_0_wvalid = false;
        if(top->s_axi_AXILiteS_0_awvalid==false && top->s_axi_AXILiteS_0_wvalid==false)
            break;
    }
    sc_start(10, SC_NS);
    top->s_axi_AXILiteS_0_bready = true;
    for(clk_count=0; clk_count<20; clk_count++){
        sc_start(10, SC_NS);
        if(top->s_axi_AXILiteS_0_bvalid)
            break;
    }
    sc_start(10, SC_NS);
    top->s_axi_AXILiteS_0_bready = false;
    sc_start(10, SC_NS);

    return(0);
} */

int sc_main(int argc, char **argv) {

    Verilated::commandArgs(argc, argv);

    sc_clock ap_clk ("ap_clk", 10, SC_NS);
    sc_signal<bool> ap_rst_n;
    sc_signal<bool> arready, arvalid;
    sc_signal<bool> awready, awvalid;
    sc_signal<bool> bready, bvalid;
    sc_signal<bool> rready, rvalid;
    sc_signal<bool> wready, wvalid;
    sc_signal<uint32_t> araddr, awaddr;
    sc_signal<uint32_t> rdata, wdata;
    sc_signal<uint32_t> bresp;
    sc_signal<uint32_t> rresp;
    sc_signal<uint32_t> wstrb;
    Vmulti_axim_top_wrapper *top;

    top = new Vmulti_axim_top_wrapper("top");

    top->ap_rst_n_0(ap_rst_n);        // Set some inputs
    top->ap_clk_0(ap_clk);
    top->s_axi_AXILiteS_0_araddr(araddr);
    top->s_axi_AXILiteS_0_arvalid(arvalid);
    top->s_axi_AXILiteS_0_arready(arready);
    top->s_axi_AXILiteS_0_awaddr(awaddr);
    top->s_axi_AXILiteS_0_awvalid(awvalid);
    top->s_axi_AXILiteS_0_awready(awready);
    top->s_axi_AXILiteS_0_bready(bready);
    top->s_axi_AXILiteS_0_bresp(bresp);
    top->s_axi_AXILiteS_0_bvalid(bvalid);
    top->s_axi_AXILiteS_0_rdata(rdata);
    top->s_axi_AXILiteS_0_rready(rready);
    top->s_axi_AXILiteS_0_rresp(rresp);
    top->s_axi_AXILiteS_0_rvalid(rvalid);
    top->s_axi_AXILiteS_0_wdata(wdata);
    top->s_axi_AXILiteS_0_wready(wready);
    top->s_axi_AXILiteS_0_wstrb(wstrb);
    top->s_axi_AXILiteS_0_wvalid(wvalid);

    Verilated::traceEverOn(true);
    VerilatedVcdSc* tfp = new VerilatedVcdSc;
    top->trace (tfp, 99);
    tfp->open ("simx.vcd");

    ap_rst_n = 0;        // Set some inputs
    araddr = 0;
    arvalid = 0;
    awaddr = 0;
    awvalid = 0;
    bready = 0;
    rready = 0;
    wdata = 0;
    wstrb = 0;
    wvalid = 0;

    sc_start(10, SC_NS);    // 1nsずらす
    ap_rst_n = 1;

    sc_start(10, SC_NS);

    int clk_count;
    // AXI4 Lite IF Write
    awaddr = 0x18;
    wdata = 0x12345678;
    wstrb = 0xf;
    awvalid = 1;
    wvalid = 1;
    for(clk_count=0; clk_count<20; clk_count++){
        sc_start(10, SC_NS);
        if(awready)
            awvalid = 0;
        if(wready)
            wvalid = 0;
        if(awvalid==0 && wvalid==0)
            break;
    }
    sc_start(10, SC_NS);
    bready = 1;
    for(clk_count=0; clk_count<20; clk_count++){
        sc_start(10, SC_NS);
        if(bvalid)
            break;
    }
    sc_start(10, SC_NS);
    bready = 0;
    sc_start(10, SC_NS);

    // AXI4 Lite IF Read
    araddr = 0x18;
    arvalid = 1;
    for(clk_count=0; clk_count<20; clk_count++){
        sc_start(10, SC_NS);
        if(arready){
            arvalid = 0;
            break;
        }
    }
    sc_start(10, SC_NS);
    rready = 1;
    for(clk_count=0; clk_count<20; clk_count++){
        sc_start(10, SC_NS);
        if(rvalid){
            rready = 0;
            break;
        }
    }
    sc_start(10, SC_NS);

    tfp->close();
    delete top;
    
    exit(0);        // シミュレーション終了
}


次に Verilator のコマンド・ファイルを作成した。
multi_axim.cmd を示す。
Verilator_74_210614.png

-Wno-lint
--trace
-sc
multi_axim_pj/multi_axim_pj.gen/sources_1/bd/multi_axim_top/hdl/multi_axim_top_wrapper.v
multi_axim_pj/multi_axim_pj.gen/sources_1/bd/multi_axim_top/synth/multi_axim_top.v
verilog/multi_axim.v
verilog/multi_axim_gmem_m_axi.v
verilog/multi_axim_AXILiteS_s_axi.v
verilog/multi_axim_mul_32s_32s_32_6.v
axi_slave_bfm/axi_slave_bfm.srcs/sources_1/imports/new/sync_fifo.v
axi_slave_bfm/axi_slave_bfm.srcs/sources_1/imports/new/axi_slave_bfm.v
--exe multi_axim_top_wrapper_sc.cpp


multi_axim ディレクトリを示す。
Verilator_73_210614.png

Verilator で .v を .cpp に変換し、コンパイルする。
verilator -f multi_axim.cmd
cd obj_dir
make -j -f Vmulti_axim_top_wrapper.mk Vmulti_axim_top_wrapper

Verilator_75_210614.png
Verilator_76_210614.png

Vmulti_axim_top_wrapper を実行する。
./Vmulti_axim_top_wrapper
Verilator_77_210614.png

simx.vcd ファイルが生成された。
Verilator_78_210614.png

GTKWave を実行する。
gtkwave simx.vcd

multi_axim_top_wrapper の信号を表示した。
AXI4 Lite の Write アクセスと Read アクセスが表示されている。
Verilator_80_210614.png

multi_axim_top_wrapper/multi_axim_top_i/axi_slave_bfm_0 の信号を検索したが、 ram_array の信号がなかった。
RAM は無いのかな?
Verilator_81_210614.png
  1. 2021年06月14日 04:49 |
  2. シミュレーション
  3. | トラックバック:0
  4. | コメント:0

Verilator をもう一度試してみる10(multi_axim を試す2)

Verilator をもう一度試してみる9(multi_axim を試す1)”の続き。

Vivado HLS の multi_axim を Verilator で検証してみようということで、前回は、 AXI4 Slave Bus Functional Model の axi_slave_BFM.v を合成できるように修正した。今回は、Vivado 2020.2 の multi_axim_pj プロジェクトを作成して、multi_axim と axi_slave_BFM を IP インテグレーターで接続しよう。

multi_axim ディレクトリを作成して、 multi_axim/solution1/syn/verilog/ のファイルをディレクトリごとコピーした。
Verilator_66_210612.png

axi_slave_bfm.v と sync_fifo.v は IP にしてあるのだが、Verilog HDL ファイルのみ使用する。
Verilator_65_210612.png

Vivado 2020.2 の multi_axim_pj プロジェクトを作成して、 multi_axim/solution1/syn/verilog/ のファイルと axi_slave_BFM.v と sync_fifo.v を登録した。
Verilator_67_210612.png

multi_axim_top ブロックデザインを作成し、 multi_axim.v と axi_slave_BFM.v をドラック&ドロップした。すると RTL IP になる。
Verilator_68_210612.png

multi_axim_0 と axi_slave_bfm_0 が生成された。
2 個の RTL IP を配線した。今回は、AXI Interconnect は使用していない。
そして multi_axim_top ブロックデザインに HDL ラッパーファイルを作成した。
Verilator_69_210612.png

multi_axim_top.v が multi_axim_pj/multi_axim_pj.gen/sources_1/bd/multi_axim_top/sim と multi_axim_pj/multi_axim_pj.gen/sources_1/bd/multi_axim_top/synth に生成されている。
その内の multi_axim_pj/multi_axim_pj.gen/sources_1/bd/multi_axim_top/synth/multi_axim_top.v を Verilator のシミュレーションに都合良いように書き換える。
multi_axim_pj/multi_axim_pj.gen/sources_1/bd/multi_axim_top/synth/multi_axim_top.v を示す。
Verilator_70_210612.png

multi_axim_top_axi_slave_bfm_0_0 がモジュール名なので、これを axi_slave_bfm に書き換えた。
Verilator_71_210612.png

multi_axim も同様に書き換えて、セーブした。
Verilator_72_210612.png

今回の multi_axim_pj は axi_slave_bfm.v と multi_axim.v の接続だけに使っているので、問題ない。
  1. 2021年06月13日 05:51 |
  2. シミュレーション
  3. | トラックバック:0
  4. | コメント:0

Verilator をもう一度試してみる9(multi_axim を試す1)

Verilator をもう一度試してみる8(SystemCモード2:dice_state_machine.v のテストベンチ)”の続き。

Verilator をやっていたのは、Vitis HLS での C/RTL 協調シミュレーションを短い時間で終了したいという欲求からだった。そこで、”DSF2015 C-6 でのVivado HLS で生成したAXI4-Master IPの簡単な例について”で示した Vivado HLS の multi_axim を Verilator で検証してみよう。
なお、Vivado HLS のプロジェクトは marsee101/multi_axim にアップロードしてある。

Vivado HLS のソースコードの multi_axim.c は x 配列のある値とそれを +1 した値を乗算して、 y 配列に出力するコードになっている。入力と出力は AXI4 Master アクセスだ。そのために、AXI4 インターフェースのメモリを追加することにした。

AXI4 インターフェースのメモリとしては、”AXI4 Slave Bus Functional Model のVerilog HDL版4”の AXI4 Slave Bus Functional Model を使用することにした。
ただ、今回は、合成するので、axi_slave_BFM.v の 114 行目の”32'hxxxxxxxx;”を”32'h00000000;”に変更した。
Verilator_63_210612.png

最後に RAM を初期化するコードを追加した。

initial begin
    for(i=0; i<SLAVE_ADDR_NUMBER-1; i=i+1)
        ram_array[i] = i;
end


(2021/06/15:修正 integer i; の宣言がすでにされていたので、削除した)
Verilator_64_210612.png

multi_axim.v と axi_slave_BFM.v を接続するのは、Vivado の IPI で接続しようと思う。IPI で接続して、出力された Verilog HDL ファイルを加工して使用する。

今まで述べてきたファイルと、C++ のテストベンチ・ファイル(multi_axim_top_wrapper_sc.cpp)を使用して Verilator でシミュレーションしてみよう。
  1. 2021年06月12日 04:57 |
  2. シミュレーション
  3. | トラックバック:0
  4. | コメント:0

Verilator をもう一度試してみる8(SystemCモード2:dice_state_machine.v のテストベンチ)

Verilator をもう一度試してみる7(再度 Verilator をインストール)”の続き。

以前の FPGAの部屋のブログ記事”Verilatorを試してみる6(SystemCモード2:dice_state_machine.v のテストベンチ)”が動作するかどうか?を確かめてみよう。

dice_state_machine.v はすでにあるので、それを ex1sc ディレクトリにコピーした。
テストベンチの dsm_sc_vcd.cpp は以前の FPGAの部屋のブログ記事”Verilatorを試してみる6(SystemCモード2:dice_state_machine.v のテストベンチ)”からのコピー & ペーストでファイルを作成した。

verilator -Wno-lint --trace -sc dice_state_machine.v --exe dsm_sc_vcd.cpp
cd obj_dir
make -j -f Vdice_state_machine.mk Vdice_state_machine
./Vdice_state_machine.exe

Verilator_58_210611.png
Verilator_59_210611.png
Verilator_60_210611.png
Verilator_61_210611.png

シミュレーションの出力結果を貼っておく。

(base) masaaki@masaaki-H110M4-M01:/media/masaaki/Ubuntu_Disk/Verilator/examples/ex1sc/obj_dir$ ./Vdice_state_machine 

        SystemC 2.3.3-Accellera --- Jun  9 2021 16:42:07
        Copyright (c) 1996-2018 by all Contributors,
        ALL RIGHTS RESERVED
roll_ena = 0 spots = 1
roll_ena = 1 spots = 1
roll_ena = 0 spots = 2
roll_ena = 1 spots = 2
roll_ena = 0 spots = 3
roll_ena = 1 spots = 3
roll_ena = 0 spots = 4
roll_ena = 1 spots = 4
roll_ena = 0 spots = 5
roll_ena = 1 spots = 5
roll_ena = 0 spots = 6
roll_ena = 1 spots = 6
roll_ena = 0 spots = 1
roll_ena = 1 spots = 1
roll_ena = 0 spots = 2
roll_ena = 1 spots = 2
roll_ena = 0 spots = 3
roll_ena = 1 spots = 3
roll_ena = 0 spots = 4
roll_ena = 1 spots = 4


simx.vcd ファイルを GTKWave で見た結果を示す。
Verilator_62_210611.png
  1. 2021年06月11日 05:17 |
  2. シミュレーション
  3. | トラックバック:0
  4. | コメント:0

Verilator をもう一度試してみる7(再度 Verilator をインストール)

Verilator をもう一度試してみる6(SystemCモード1:SystemCのインストール2)”の続き。

前回は、SystemC 2.3.3 を /usr/local にインストールした。今回は、 Vengineer さんの”VerilatorとSystemC”に従って、Verilator を再度インストールする。

まずは、以前インストールした Verilator を削除して、再度 git clone した。
rm -rf Verilator/
git clone -b v4.202 https://github.com/verilator/verilator.git

Verilator_49_210609.png

cd verilator
export SYSTEMC_INCLUDE=/usr/local/systemc/2.3.3/include
autoconf
./configure --prefix=/usr/local/verilator/v4.202

Verilator_50_210609.png
Verilator_51_210609.png

make -j2
Verilator_52_210609.png

sudo make install
Verilator_53_210609.png

Verilator のインストールは成功した。

/usr/local ディレクトリに systemc と verilator のディレクトリが生成されている。
Verilator_54_210610.png

Verilator の make_hello_sc サンプルを実行してみよう。
verilator/examples/make_hello_sc ディレクトリに移動した。
make を実行した。
make
Verilator_55_210610.png

obj_dir/Vtop: error while loading shared libraries: libsystemc-2.3.3.so: cannot open shared object file: No such file or directory

エラーがでてしまった。
このエラーを検索したところ、”Error while loading shared libraries: libsystemc-2.3.0.so”が検索できた。
それによると、LD_LIBRARY_PATH に SystemC のライブラリ・ディレクトリを追加すれば良いようだ。
export LD_LIBRARY_PATH=/usr/local/systemc/2.3.3/lib-linux64:$LD_LIBRARY_PATH
これで、
make
したところ、成功した。

Hello World!

が表示された。
Verilator_56_210610.png

.bashrc に

export PATH="/usr/local/verilator/v4.202/bin:$PATH"
export PKG_CONFIG_PATH="/usr/local/verilator/v4.202/share/pkgconfig:$PKG_CONFIG_PATH"
export SYSTEMC_INCLUDE=/usr/local/systemc/2.3.3/include
export LD_LIBRARY_PATH=/usr/local/systemc/2.3.3/lib-linux64:$LD_LIBRARY_PATH

を追加した。
Verilator_57_210610.png
  1. 2021年06月10日 04:36 |
  2. シミュレーション
  3. | トラックバック:0
  4. | コメント:0

Verilator をもう一度試してみる6(SystemCモード1:SystemCのインストール2)

Verilator をもう一度試してみる5(SystemCモード1:SystemCのインストール)”の続き。

前回、SystemC-2.3.3 を自分のディレクトリの下にインストールした。しかし、やはり、 /usr/local ディレクトリにインストールしたいということでインストールをやり直した。

cd system-2.3.3/
cd objdir/
export CXX=g++
../configure --prefix=/usr/local/systemc/2.3.3

SystemC233_1_210609.png
SystemC233_2_210609.png

gmake clean
SystemC233_3_210609.png
SystemC233_4_210609.png

gmake
SystemC233_5_210609.png
SystemC233_6_210609.png

sudo gmake install
SystemC233_7_210609.png
SystemC233_8_210609.png

/usr/local/systemc/2.3.3 ディレクトリにインストールされている。
SystemC233_9_210609.png
  1. 2021年06月09日 20:52 |
  2. シミュレーション
  3. | トラックバック:0
  4. | コメント:0

FPGAの部屋のまとめサイトの更新(2021年6月9日)

FPGAの部屋のまとめサイトを更新しました。 PICマイコンを追加して、2021 年 6 月 9 日までの記事を更新しました。
  1. 2021年06月09日 04:36 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:0

Verilator をもう一度試してみる5(SystemCモード1:SystemCのインストール)

親父の葬式が終わって一息ついたので、”Verilator をもう一度試してみる4(C++モード4:diceプロジェクト)”の続きを書く。

Verilator 勉強会に参加して Verilator を再びやってみようということで、前回は、dice プロジェクトの複数のファイルを Verilator でシミュレーションした。今回は、”Verilatorを試してみる5(SystemCモード1:SystemCのインストール)”を参考にして、 SystemC 2.3.3 をインストールしてみよう。

まずは、SystemC のページから 2.3.3 をZIP 形式でダウンロードした。

ZIP ファイルを解凍すると systemc-2.3.3 ディレクトリが解凍できた。
Verilator_38_210607.png

INSTALL ファイルの指示に従って、SystemC 2.3.3 をインストールしていく。

systemc-2.3.3 ディレクトリに行って、 objdir を作成する。
objdir に行って、CCX 環境変数に g++ を設定する。
cd systemc-2.3.3/
mkdir objdir
cd objdir
export CXX=g++

Verilator_39_210607.png

../configure
Verilator_40_210607.png

gmake
Verilator_41_210607.png

gmake check
Verilator_42_210607.png
Verilator_43_210607.png

gmake install
Verilator_44_210607.png
Verilator_45_210607.png

gmake check で examples をコンパイルしてあるので、systemc-2.3.3/objdir/examples/sysc/simple_bus ディレクトリの example を動かしてみよう。
test が実行ファイルのようだ。
./test
Verilator_46_210608.png
Verilator_47_210608.png
Verilator_48_210608.png

動作しているようだ。
  1. 2021年06月08日 04:46 |
  2. シミュレーション
  3. | トラックバック:0
  4. | コメント:0

Verilator をもう一度試してみる4(C++モード4:diceプロジェクト)

Verilator をもう一度試してみる3(C++モード3:VCDファイルを出力)”の続き。

Verilator 勉強会に参加して Verilator を再びやってみようということで、前回は、”Verilatorを試してみる3(C++モード3:VCDファイルを出力)”をやって成功した。今回は、”Verilatorを試してみる4(C++モード4:diceプロジェクト)”をやってみるが、Verilog HDL ファイルが離れたディレクトリにある場合についてやってみよう。

Verilator をもう一度試してみる3(C++モード3:VCDファイルを出力)”の dice_state_machine.v をそのまま使用して、それ以外のファイルを”Verilatorを試してみる4(C++モード4:diceプロジェクト)”から調達して、 Verlator/ex2 ディレクトリにセーブした。(すでに obj_dir があるのは無視して欲しい)
Verilator_33_210604.png

Verlator/ex2 ディレクトリで下のコマンドを実行した。
verilator --cc --trace -Wno-lint dice_top.v --exe dice_top_tb.cpp
Verilator_26_210604.png

dice_state_machine が無いと言われるので、相対パスで ex1 の dice_state_machine.v をコマンド・ラインに追加した。
verilator --cc --trace -Wno-lint dice_top.v ../ex1/dice_state_machine.v --exe dice_top_tb.cpp

これだとコンパイルが成功した。

次に make を行うが、 printf() 文がエラーになるので、コメントアウトした。
Verilator_27_210604.png

cd obj_dir/
make -j -f Vdice_top.mk Vdice_top

Verilator_28_210604.png
Verilator_29_210604.png

Vdice_top 実行形式ファイルができた。

./Vdice_top
を実行すると simx.vcd が作成された。
Verilator_30_210604.png

gtkwave を実行した。
gtkwave simx.vcd
いろいろと設定を行った結果のタイミングチャートを示す。
Verilator_31_210604.png
Verilator_32_210604.png

  1. 2021年06月04日 19:53 |
  2. シミュレーション
  3. | トラックバック:0
  4. | コメント:0

昨日、親父が亡くなりました

昨日、親父が亡くなりました。
ここ5年位は透析していたのですが、40日前から誤嚥性肺炎で病院に入院していました。
昨日、病院からお昼頃呼び出しがあり、今、心臓マッサージ中だと言うことでした。
13時10頃、私が病院に駆けつけると心電図波形はフラットでした。医者が死亡確認をしてくれました。
88歳で親父が永眠しました。
今度の日曜日にお葬式ですが、コロナ禍でもあり、家族葬でこじんまりとやりたいと思います。
今週はブログ書けないかも知れませんが、よろしくお願いいたします。
  1. 2021年06月03日 05:00 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

Verilator をもう一度試してみる3(C++モード3:VCDファイルを出力)

Verilator をもう一度試してみる2(C++ モード1)”の続き。

Verilator 勉強会に参加して Verilator を再びやってみようということで、前回は、過去の FPGA の部屋のブログ記事”Verilatorを試してみる1(C++モード1)”をもう一度やってみて成功した。今回は、”Verilatorを試してみる3(C++モード3:VCDファイルを出力)”をやってみよう。

Verilatorを試してみる3(C++モード3:VCDファイルを出力)”のテストベンチ・ファイル dsm_test.cpp をコピーした。

ex1 ディレクトリに行って、--trace コマンドを追加して Verilatorでコンパイルを行った。
verilator --cc --trace -Wno-lint dice_state_machine.v --exe dsm_test.cpp

obj_dir ディレクトリが生成された。
obj_dir ディレクトリに cd した。
cd obj_dir/
Verilator_16_210602.png

make した。
make -j -f Vdice_state_machine.mk Vdice_state_machine
Verilator_17_210602.png
Verilator_18_210602.png

printf 文の top->v__DOT__current_state の部分でエラーが出ている。

テストベンチ・ファイル dsm_test.cpp を編集する。
printf 分全体をコメントアウトした。
Verilator_19_210602.png

ex1 ディレクトリに戻って、もう一度コンパイルした。
obj_dir ディレクトリに行った。
Verilator_20_210602.png

make すると今度は成功した。
実行ファイル Vdice_state_machine ができている。
Verilator_21_210602.png

Vdice_state_machine を実行した。
./Vdice_state_machine

実行後に simx.vcd ができていた。
Verilator_22_210602.png

gtkwave を立ち上げて simx.vcd を確認した。
gtkwave simx.vcd
Verilator_23_210602.png

gtkwave の GUI が立ち上がった。
左下のウインドウで、すべての信号を選択して、Append ボタンをクリックすると波形が表示された。
Verilator_24_210602.png

なお、最初の DICE_STATE は最初は数字を表示していたが、DICE_STATE を右クリックし、右クリックメニューから Data Format -> ASCII を選択すると文字で表示された。
Verilator_25_210602.png
  1. 2021年06月03日 04:49 |
  2. シミュレーション
  3. | トラックバック:0
  4. | コメント:0

Verilator をもう一度試してみる2(C++ モード1)

Verilator をもう一度試してみる1(インストール)”の続き。

Verilator 勉強会に参加して Verilator を再びやってみようということで、 前回は Verilator Ver. 4.200 をインストールすることができた。今回は、過去の FPGA の部屋のブログ記事”Verilatorを試してみる1(C++モード1)”をもう一度やってみよう。この記事は、 2011 年 5 月なので、ちょうど 10 年前の記事になる。

DUT は電子サイコロをチュートリアル用に作ったときのdice_stat_machine.v で、テストベンチは、dsm_test.cpp を使用する。2 つのファイルは、コードが”Verilatorを試してみる1(C++モード1)”に載っているので、それを使用する。

2つのファイルをフォルダに置いて、Verilatorでコンパイルを行った。
verilator --cc -Wno-lint dice_state_machine.v --exe dsm_test.cpp

現在のフォルダ上にobj_dirフォルダができる。cdコマンドを使用して、obj_dirフォルダに移る。
cd obj_dir/

make を行った。
make -j -f Vdice_state_machine.mk Vdice_state_machine
Verilator_12_210601.png
Verilator_13_210601.png

Vdice_state_machine 実行ファイルが生成されている。

実行ファイルを実行した。
./Vdice_state_machine
Verilator_14_210601.png
Verilator_15_210601.png

成功だ。
実行結果を貼っておく。

(base) masaaki@masaaki-H110M4-M01:/media/masaaki/Ubuntu_Disk/Verilator/examples/ex1/obj_dir$ ./Vdice_state_machine 
Time 0 : clk = 1 roll_ena = 0 spots = 0
Time 1 : clk = 1 roll_ena = 0 spots = 0
Time 2 : clk = 1 roll_ena = 0 spots = 0
Time 3 : clk = 1 roll_ena = 0 spots = 0
Time 4 : clk = 1 roll_ena = 0 spots = 0
Time 5 : clk = 0 roll_ena = 0 spots = 0
Time 6 : clk = 0 roll_ena = 0 spots = 0
Time 7 : clk = 0 roll_ena = 0 spots = 0
Time 8 : clk = 0 roll_ena = 0 spots = 0
Time 9 : clk = 0 roll_ena = 0 spots = 0
Time 10 : clk = 1 roll_ena = 0 spots = 1
Time 11 : clk = 1 roll_ena = 1 spots = 1
Time 12 : clk = 1 roll_ena = 1 spots = 1
Time 13 : clk = 1 roll_ena = 1 spots = 1
Time 14 : clk = 1 roll_ena = 1 spots = 1
Time 15 : clk = 0 roll_ena = 1 spots = 1
Time 16 : clk = 0 roll_ena = 1 spots = 1
Time 17 : clk = 0 roll_ena = 1 spots = 1
Time 18 : clk = 0 roll_ena = 1 spots = 1
Time 19 : clk = 0 roll_ena = 1 spots = 1
Time 20 : clk = 1 roll_ena = 1 spots = 1
Time 21 : clk = 1 roll_ena = 0 spots = 1
Time 22 : clk = 1 roll_ena = 0 spots = 1
Time 23 : clk = 1 roll_ena = 0 spots = 1
Time 24 : clk = 1 roll_ena = 0 spots = 1
Time 25 : clk = 0 roll_ena = 0 spots = 1
Time 26 : clk = 0 roll_ena = 0 spots = 1
Time 27 : clk = 0 roll_ena = 0 spots = 1
Time 28 : clk = 0 roll_ena = 0 spots = 1
Time 29 : clk = 0 roll_ena = 0 spots = 1
Time 30 : clk = 1 roll_ena = 0 spots = 1
Time 31 : clk = 1 roll_ena = 1 spots = 1
Time 32 : clk = 1 roll_ena = 1 spots = 1
Time 33 : clk = 1 roll_ena = 1 spots = 1
Time 34 : clk = 1 roll_ena = 1 spots = 1
Time 35 : clk = 0 roll_ena = 1 spots = 1
Time 36 : clk = 0 roll_ena = 1 spots = 1
Time 37 : clk = 0 roll_ena = 1 spots = 1
Time 38 : clk = 0 roll_ena = 1 spots = 1
Time 39 : clk = 0 roll_ena = 1 spots = 1
Time 40 : clk = 1 roll_ena = 1 spots = 1
Time 41 : clk = 1 roll_ena = 0 spots = 1
Time 42 : clk = 1 roll_ena = 0 spots = 1
Time 43 : clk = 1 roll_ena = 0 spots = 1
Time 44 : clk = 1 roll_ena = 0 spots = 1
Time 45 : clk = 0 roll_ena = 0 spots = 1
Time 46 : clk = 0 roll_ena = 0 spots = 1
Time 47 : clk = 0 roll_ena = 0 spots = 1
Time 48 : clk = 0 roll_ena = 0 spots = 1
Time 49 : clk = 0 roll_ena = 0 spots = 1
Time 50 : clk = 1 roll_ena = 0 spots = 2
Time 51 : clk = 1 roll_ena = 1 spots = 2
Time 52 : clk = 1 roll_ena = 1 spots = 2
Time 53 : clk = 1 roll_ena = 1 spots = 2
Time 54 : clk = 1 roll_ena = 1 spots = 2
Time 55 : clk = 0 roll_ena = 1 spots = 2
Time 56 : clk = 0 roll_ena = 1 spots = 2
Time 57 : clk = 0 roll_ena = 1 spots = 2
Time 58 : clk = 0 roll_ena = 1 spots = 2
Time 59 : clk = 0 roll_ena = 1 spots = 2
Time 60 : clk = 1 roll_ena = 1 spots = 2
Time 61 : clk = 1 roll_ena = 0 spots = 2
Time 62 : clk = 1 roll_ena = 0 spots = 2
Time 63 : clk = 1 roll_ena = 0 spots = 2
Time 64 : clk = 1 roll_ena = 0 spots = 2
Time 65 : clk = 0 roll_ena = 0 spots = 2
Time 66 : clk = 0 roll_ena = 0 spots = 2
Time 67 : clk = 0 roll_ena = 0 spots = 2
Time 68 : clk = 0 roll_ena = 0 spots = 2
Time 69 : clk = 0 roll_ena = 0 spots = 2
Time 70 : clk = 1 roll_ena = 0 spots = 3
Time 71 : clk = 1 roll_ena = 1 spots = 3
Time 72 : clk = 1 roll_ena = 1 spots = 3
Time 73 : clk = 1 roll_ena = 1 spots = 3
Time 74 : clk = 1 roll_ena = 1 spots = 3
Time 75 : clk = 0 roll_ena = 1 spots = 3
Time 76 : clk = 0 roll_ena = 1 spots = 3
Time 77 : clk = 0 roll_ena = 1 spots = 3
Time 78 : clk = 0 roll_ena = 1 spots = 3
Time 79 : clk = 0 roll_ena = 1 spots = 3
Time 80 : clk = 1 roll_ena = 1 spots = 3
Time 81 : clk = 1 roll_ena = 0 spots = 3
Time 82 : clk = 1 roll_ena = 0 spots = 3
Time 83 : clk = 1 roll_ena = 0 spots = 3
Time 84 : clk = 1 roll_ena = 0 spots = 3
Time 85 : clk = 0 roll_ena = 0 spots = 3
Time 86 : clk = 0 roll_ena = 0 spots = 3
Time 87 : clk = 0 roll_ena = 0 spots = 3
Time 88 : clk = 0 roll_ena = 0 spots = 3
Time 89 : clk = 0 roll_ena = 0 spots = 3
Time 90 : clk = 1 roll_ena = 0 spots = 4
Time 91 : clk = 1 roll_ena = 1 spots = 4
Time 92 : clk = 1 roll_ena = 1 spots = 4
Time 93 : clk = 1 roll_ena = 1 spots = 4
Time 94 : clk = 1 roll_ena = 1 spots = 4
Time 95 : clk = 0 roll_ena = 1 spots = 4
Time 96 : clk = 0 roll_ena = 1 spots = 4
Time 97 : clk = 0 roll_ena = 1 spots = 4
Time 98 : clk = 0 roll_ena = 1 spots = 4
Time 99 : clk = 0 roll_ena = 1 spots = 4
Time 100 : clk = 1 roll_ena = 1 spots = 4
Time 101 : clk = 1 roll_ena = 0 spots = 4
Time 102 : clk = 1 roll_ena = 0 spots = 4
Time 103 : clk = 1 roll_ena = 0 spots = 4
Time 104 : clk = 1 roll_ena = 0 spots = 4
Time 105 : clk = 0 roll_ena = 0 spots = 4
Time 106 : clk = 0 roll_ena = 0 spots = 4
Time 107 : clk = 0 roll_ena = 0 spots = 4
Time 108 : clk = 0 roll_ena = 0 spots = 4
Time 109 : clk = 0 roll_ena = 0 spots = 4
Time 110 : clk = 1 roll_ena = 0 spots = 5
Time 111 : clk = 1 roll_ena = 1 spots = 5
Time 112 : clk = 1 roll_ena = 1 spots = 5
Time 113 : clk = 1 roll_ena = 1 spots = 5
Time 114 : clk = 1 roll_ena = 1 spots = 5
Time 115 : clk = 0 roll_ena = 1 spots = 5
Time 116 : clk = 0 roll_ena = 1 spots = 5
Time 117 : clk = 0 roll_ena = 1 spots = 5
Time 118 : clk = 0 roll_ena = 1 spots = 5
Time 119 : clk = 0 roll_ena = 1 spots = 5
Time 120 : clk = 1 roll_ena = 1 spots = 5
Time 121 : clk = 1 roll_ena = 0 spots = 5
Time 122 : clk = 1 roll_ena = 0 spots = 5
Time 123 : clk = 1 roll_ena = 0 spots = 5
Time 124 : clk = 1 roll_ena = 0 spots = 5
Time 125 : clk = 0 roll_ena = 0 spots = 5
Time 126 : clk = 0 roll_ena = 0 spots = 5
Time 127 : clk = 0 roll_ena = 0 spots = 5
Time 128 : clk = 0 roll_ena = 0 spots = 5
Time 129 : clk = 0 roll_ena = 0 spots = 5
Time 130 : clk = 1 roll_ena = 0 spots = 6
Time 131 : clk = 1 roll_ena = 1 spots = 6
Time 132 : clk = 1 roll_ena = 1 spots = 6
Time 133 : clk = 1 roll_ena = 1 spots = 6
Time 134 : clk = 1 roll_ena = 1 spots = 6
Time 135 : clk = 0 roll_ena = 1 spots = 6
Time 136 : clk = 0 roll_ena = 1 spots = 6
Time 137 : clk = 0 roll_ena = 1 spots = 6
Time 138 : clk = 0 roll_ena = 1 spots = 6
Time 139 : clk = 0 roll_ena = 1 spots = 6
Time 140 : clk = 1 roll_ena = 1 spots = 6
Time 141 : clk = 1 roll_ena = 0 spots = 6
Time 142 : clk = 1 roll_ena = 0 spots = 6
Time 143 : clk = 1 roll_ena = 0 spots = 6
Time 144 : clk = 1 roll_ena = 0 spots = 6
Time 145 : clk = 0 roll_ena = 0 spots = 6
Time 146 : clk = 0 roll_ena = 0 spots = 6
Time 147 : clk = 0 roll_ena = 0 spots = 6
Time 148 : clk = 0 roll_ena = 0 spots = 6
Time 149 : clk = 0 roll_ena = 0 spots = 6
Time 150 : clk = 1 roll_ena = 0 spots = 1
Time 151 : clk = 1 roll_ena = 1 spots = 1
Time 152 : clk = 1 roll_ena = 1 spots = 1
Time 153 : clk = 1 roll_ena = 1 spots = 1
Time 154 : clk = 1 roll_ena = 1 spots = 1
Time 155 : clk = 0 roll_ena = 1 spots = 1
Time 156 : clk = 0 roll_ena = 1 spots = 1
Time 157 : clk = 0 roll_ena = 1 spots = 1
Time 158 : clk = 0 roll_ena = 1 spots = 1
Time 159 : clk = 0 roll_ena = 1 spots = 1
Time 160 : clk = 1 roll_ena = 1 spots = 1
Time 161 : clk = 1 roll_ena = 0 spots = 1
Time 162 : clk = 1 roll_ena = 0 spots = 1
Time 163 : clk = 1 roll_ena = 0 spots = 1
Time 164 : clk = 1 roll_ena = 0 spots = 1
Time 165 : clk = 0 roll_ena = 0 spots = 1
Time 166 : clk = 0 roll_ena = 0 spots = 1
Time 167 : clk = 0 roll_ena = 0 spots = 1
Time 168 : clk = 0 roll_ena = 0 spots = 1
Time 169 : clk = 0 roll_ena = 0 spots = 1
Time 170 : clk = 1 roll_ena = 0 spots = 2
Time 171 : clk = 1 roll_ena = 1 spots = 2
Time 172 : clk = 1 roll_ena = 1 spots = 2
Time 173 : clk = 1 roll_ena = 1 spots = 2
Time 174 : clk = 1 roll_ena = 1 spots = 2
Time 175 : clk = 0 roll_ena = 1 spots = 2
Time 176 : clk = 0 roll_ena = 1 spots = 2
Time 177 : clk = 0 roll_ena = 1 spots = 2
Time 178 : clk = 0 roll_ena = 1 spots = 2
Time 179 : clk = 0 roll_ena = 1 spots = 2
Time 180 : clk = 1 roll_ena = 1 spots = 2
Time 181 : clk = 1 roll_ena = 0 spots = 2
Time 182 : clk = 1 roll_ena = 0 spots = 2
Time 183 : clk = 1 roll_ena = 0 spots = 2
Time 184 : clk = 1 roll_ena = 0 spots = 2
Time 185 : clk = 0 roll_ena = 0 spots = 2
Time 186 : clk = 0 roll_ena = 0 spots = 2
Time 187 : clk = 0 roll_ena = 0 spots = 2
Time 188 : clk = 0 roll_ena = 0 spots = 2
Time 189 : clk = 0 roll_ena = 0 spots = 2
Time 190 : clk = 1 roll_ena = 0 spots = 3
Time 191 : clk = 1 roll_ena = 1 spots = 3
Time 192 : clk = 1 roll_ena = 1 spots = 3
Time 193 : clk = 1 roll_ena = 1 spots = 3
Time 194 : clk = 1 roll_ena = 1 spots = 3
Time 195 : clk = 0 roll_ena = 1 spots = 3
Time 196 : clk = 0 roll_ena = 1 spots = 3
Time 197 : clk = 0 roll_ena = 1 spots = 3
Time 198 : clk = 0 roll_ena = 1 spots = 3
Time 199 : clk = 0 roll_ena = 1 spots = 3
Time 200 : clk = 1 roll_ena = 1 spots = 3
Time 201 : clk = 1 roll_ena = 0 spots = 3

  1. 2021年06月02日 04:06 |
  2. シミュレーション
  3. | トラックバック:0
  4. | コメント:0

AXI4-Lite インターフェースの I2C Master Core を使用して 3 軸加速度度センサーの値を収集する4(NMJ2884U1を使用してスレーブ側の電源をON/OFFする)

AXI4-Lite インターフェースの I2C Master Core を使用して 3 軸加速度度センサーの値を収集する3”の続き。

ストロベリーリナックスさんの”LTC4331 絶縁型I2C延長モジュール(2個セット) ”のスレーブ側に付けるストロベリーリナックスさんの”ADXL355 超低ノイズ3軸加速度センサモジュール”は同じ値をずっと出力して、リセットが効かないことがある。そこで、秋月電子の低飽和型レギュレーター 3.3V500mA NJM2884U1-33 を使用して、スレーブ側の電源を GPIO で ON/OFF できるようにした。
下図にそのブロック図を示す。
i2cm_axi4ls_17_210601.png

ZYBO Z7-20 の Vivado 2020.2 プロジェクトの acc_sensor_pow_202 を示す。
i2cm_axi4ls_18_210601.png

ブロックデザインを示す。
i2cm_axi4ls_19_210601.png

ZYBO Z7-20 のスライドスイッチの SW0 で NJM2884U1-33 の CONTROL 端子を制御する。

Address Map を示す。
i2cm_axi4ls_20_210601.png

制約ファイルを示す。

set_property IOSTANDARD LVCMOS33 [get_ports iic_0_scl_io]
set_property IOSTANDARD LVCMOS33 [get_ports iic_0_sda_io]
set_property PACKAGE_PIN V8 [get_ports iic_0_scl_io]
set_property PACKAGE_PIN W8 [get_ports iic_0_sda_io]

set_property PACKAGE_PIN G15 [get_ports {SW0[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {SW0[0]}]
set_property PACKAGE_PIN V12 [get_ports {POW_CONTROL[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {POW_CONTROL[0]}]


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

ハードウェアをエクスポートして、Vitis を立ち上げた。
Vitis でプラットフォームとアプリケーション・プロジェクトを作成し、アプリケーション・ソフトウェアを作成して、ZYBO Z7-20 で確かめてみたところ、SW0 を ON した 0.5 秒後に 3軸加速度センサーの計測がスタートした。SW0 を OFF すると 3軸加速度センサーの計測が止まった。何度やっても ON/OFF することができた。成功だ。
i2cm_axi4ls_22_210601.png

実際の実験の様子を示す。ピンクの丸で囲った部分が NJM2884U1-33 だ。
i2cm_axi4ls_23_210601.jpg

アプリケーション・ソフトウェア acc_sensor_pow.c を示す。

// acc_sensor_pow.c
// 2021/05/28 by marsee
// コード中のコメント部分は”OpenCores.org の I2C controller core ”のマニュアルから引用した
// https://opencores.org/projects/i2c

#include <stdio.h>
#include <stdint.h>
#include "xil_io.h"
#include "xparameters.h"
#include <unistd.h>
#include "xtime_l.h"
#include "xgpio.h"

#define I2CM_PRER_LO    XPAR_I2CM_AXI4LS_0_BASEADDR
#define I2CM_PRER_HI    (XPAR_I2CM_AXI4LS_0_BASEADDR+0x4)
#define I2CM_CTR        (XPAR_I2CM_AXI4LS_0_BASEADDR+0x8)
#define I2CM_RXR        (XPAR_I2CM_AXI4LS_0_BASEADDR+0xc)
#define I2CM_TXR        (XPAR_I2CM_AXI4LS_0_BASEADDR+0xc)
#define I2CM_CR         (XPAR_I2CM_AXI4LS_0_BASEADDR+0x10)
#define I2CM_SR         (XPAR_I2CM_AXI4LS_0_BASEADDR+0x10)

#define CR_STA      0x80    // generate (repeated) start condition
#define CR_STO      0x40    // generate stop condition
#define CR_RD       0x20    // read from slave
#define CR_WR       0x10    // write from slave
#define CR_NACK     0x08    //  when a receiver, sent ACK (ACK = ‘0’) or NACK (ACK = ‘1’)
#define CR_IACK     0x01    // Interrupt acknowledge. When set, clears a pending interrupt.

#define SR_RxACK    0x80    // Received acknowledge from slave.This flag represents acknowledge from  the addressed slave.
                            // ‘1’ = No acknowledge received , ‘0’ = Acknowledge received
#define SR_Busy     0x40    // I2C bus busy
                            // ‘1’ after START signal detected , ‘0’ after STOP signal detected
#define SR_AL       0x20    // Arbitration lost. This bit is set when the core lost arbitration. Arbitration is lost when:
                            // * a STOP signal is detected, but non requested , * The master drives SDA high, but SDA is low.
#define SR_TIP      0x02    // Transfer in progress.
                            // ‘1’ when transferring data , ‘0’ when transfer complete
#define SR_IF       0x01    //  Interrupt Flag. This bit is set when an interrupt is pending, which
                            //  will cause a processor interrupt request if the IEN bit is set.
                            //  The Interrupt Flag is set when:
                            // *  one byte transfer has been completed , *  arbitration is lost

#define SW0_GPIO            1
#define POW_CONTROL_GPIO    2

void idle_check(){
    while(Xil_In32(I2CM_SR) & SR_TIP); // TIP bit is clear
}
void acc_sensor_write(uint8_t dev_addr, uint8_t waddr, uint8_t wdata){
    dev_addr &= 0xfe;
    idle_check();

    Xil_Out32(I2CM_TXR, (u32)dev_addr);
    Xil_Out32(I2CM_CR, (u32)(CR_STA|CR_WR));
    idle_check();

    Xil_Out32(I2CM_TXR, (u32)waddr);
    Xil_Out32(I2CM_CR, (u32)CR_WR);
    idle_check();

    Xil_Out32(I2CM_TXR, (u32)wdata);
    Xil_Out32(I2CM_CR, (u32)(CR_STO|CR_WR));
    idle_check();
}
uint8_t acc_sensor_read1(uint8_t dev_addr, uint8_t raddr){
    const uint8_t devw_addr = dev_addr & 0xfe;

    dev_addr |= 0x01;
    idle_check();

    Xil_Out32(I2CM_TXR, (u32)devw_addr);
    Xil_Out32(I2CM_CR, (u32)(CR_STA|CR_WR));
    idle_check();

    Xil_Out32(I2CM_TXR, (u32)raddr);
    Xil_Out32(I2CM_CR, (u32)CR_WR);
    idle_check();

    Xil_Out32(I2CM_TXR, (u32)dev_addr);
    Xil_Out32(I2CM_CR, (u32)(CR_STA|CR_WR));
    idle_check();

    Xil_Out32(I2CM_CR, (u32)(CR_STO|CR_RD|CR_NACK));
    idle_check();

    uint8_t rdata8 = (uint8_t)(Xil_In32(I2CM_RXR) & 0xff);
    return(rdata8);
}
void acc_sensor_read3(uint8_t dev_addr, uint8_t raddr, int32_t *rdata){
    uint8_t rdata8a[3];
    const uint8_t devw_addr = dev_addr & 0xfe;

    dev_addr |= 0x01;
    idle_check();

    Xil_Out32(I2CM_TXR, (u32)devw_addr);
    Xil_Out32(I2CM_CR, (u32)(CR_STA|CR_WR));
    idle_check();

    Xil_Out32(I2CM_TXR, (u32)raddr);
    Xil_Out32(I2CM_CR, (u32)CR_WR);
    idle_check();

    Xil_Out32(I2CM_TXR, (u32)dev_addr);
    Xil_Out32(I2CM_CR, (u32)(CR_STA|CR_WR));
    idle_check();

    Xil_Out32(I2CM_CR, (u32)CR_RD);
    idle_check();
    rdata8a[0] = (uint8_t)(Xil_In32(I2CM_RXR) & 0xff);

    Xil_Out32(I2CM_CR, (u32)CR_RD);
    idle_check();
    rdata8a[1] = (uint8_t)(Xil_In32(I2CM_RXR) & 0xff);

    Xil_Out32(I2CM_CR, (u32)(CR_STO|CR_RD|CR_NACK));
    idle_check();
    rdata8a[2] = (uint8_t)(Xil_In32(I2CM_RXR) & 0xff);

    *rdata = (((int32_t)rdata8a[0])<<12) + (((int32_t)rdata8a[1])<<4) + (((int32_t)(rdata8a[2] & 0xf0))>>4);
    if(*rdata & 0x80000) // Is the 19th bit 1?
        *rdata |= 0xfff00000; // sign extension
}

void initialize_code(){
    // I2C I2C operating frequency setting 433KHz/100MHz, 415kHz/96MHz
    Xil_Out32(I2CM_PRER_LO, (u32)0x29);
    Xil_Out32(I2CM_PRER_HI, (u32)0x0);

    Xil_Out32(I2CM_CTR, 0x80); // enable core

    acc_sensor_write(0x3a, 0x2c, 0x83); // I2C speed is Hi speed, +-8g
    acc_sensor_write(0x3a, 0x1e, 0x00); // OFFSET_X_H
    acc_sensor_write(0x3a, 0x1f, 0x00); // OFFSET_X_L
    acc_sensor_write(0x3a, 0x20, 0x00); // OFFSET_Y_H
    acc_sensor_write(0x3a, 0x21, 0x00); // OFFSET_Y_L
    acc_sensor_write(0x3a, 0x22, 0x00); // OFFSET_Z_H
    acc_sensor_write(0x3a, 0x23, 0x00); // OFFSET_Z_L

    acc_sensor_write(0x3a, 0x2d, 0x00); // stanby clear
}

int main(){
    uint8_t read_data, read_rdy;
    int32_t dataX, dataY, dataZ;
    XTime cur_time;
    XGpio XGpio_ap;
    int status;

    // GPIOの初期化
    status = XGpio_Initialize(&XGpio_ap, XPAR_AXI_GPIO_0_BASEADDR);
    if (status != XST_SUCCESS) return XST_FAILURE;
    XGpio_SetDataDirection(&XGpio_ap, SW0_GPIO, 1); // input
    XGpio_SetDataDirection(&XGpio_ap, POW_CONTROL_GPIO, 0); // output
    uint8_t sw0_state = XGpio_DiscreteRead(&XGpio_ap, SW0_GPIO);
    XGpio_DiscreteWrite(&XGpio_ap, POW_CONTROL_GPIO, sw0_state);
    if((sw0_state & 1) == 0){
        do {
            sw0_state = XGpio_DiscreteRead(&XGpio_ap, SW0_GPIO);
            XGpio_DiscreteWrite(&XGpio_ap, POW_CONTROL_GPIO, sw0_state);
            usleep(500000); // 500 ms Wait
        }while((sw0_state & 1) == 0);
    }

    initialize_code();

    while(1){
        do{
            read_data = acc_sensor_read1(0x3b, 0x04);
            read_rdy = read_data & 0x01;
        }while(read_rdy != 0x01);

        acc_sensor_read3(0x3b, 0x08, &dataX);
        acc_sensor_read3(0x3b, 0x0b, &dataY);
        acc_sensor_read3(0x3b, 0x0e, &dataZ);

        XTime_GetTime(&cur_time);
        printf("%lf,%x,%x,%x\n", (double)((long long int)cur_time)/333333.3435, (int)dataX, (int)dataY, (int)dataZ);

        usleep(2434); // for 400 kHz

        sw0_state = XGpio_DiscreteRead(&XGpio_ap, SW0_GPIO);
        if((sw0_state & 1) == 0){
            do {
                sw0_state = XGpio_DiscreteRead(&XGpio_ap, SW0_GPIO);
                XGpio_DiscreteWrite(&XGpio_ap, POW_CONTROL_GPIO, sw0_state);
                usleep(500000); // 500 ms Wait
            }while((sw0_state & 1) == 0);
            XGpio_DiscreteWrite(&XGpio_ap, POW_CONTROL_GPIO, 1);
            initialize_code();
        }
    }
}

  1. 2021年06月01日 04:27 |
  2. FPGAを使用したシステム
  3. | トラックバック:0
  4. | コメント:0