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 で 開いた。
重みやソースコード、テストベンチ・ファイルは firmware ディレクトリにある。
このプロジェクトは Ultra96V2 ボード用だった。
C シミュレーションを行った。
C コードの合成を行ったが、エラーになってしまった。
エラー内容を示す。
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
エラーの回避方法は無いのだろうか?
2021年06月30日 05:05 |
Vitis HLS
| トラックバック:0
| コメント:0
”
”(目標)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 入力をプロジェクトに入れている。
Part は Ultra96V2 用に xczu3eg-sbva484-1-e に設定した。
C シミュレーションを行った。結果を示す。
”
(目標)Vivado HLSで1クロック毎に結果を出力できるNNを作る3(Vivado HLS) ”の結果と同じだった。
C コードの合成を行った。
C Synthesis ダイアログがデフォルトで OK ボタンをクリックした。
何と合成が終了した。
凄いぞ Vitis HLS 2021.1 。。。 結果を示す。
レイテンシは 842 クロックだった。
DSP は 803 個、 FF は 146850 個、LUT は 177705 個使用している。リソース使用量が多すぎると思うが、ともかくコンパイルできたのは嬉しい。。。
変換された Verilog HDL のファイルを示す。
Function Call Graph を示す。
次に NUM_ITERATIONS を 100 から 2 に変更して、C/RTL 協調シミュレーションを行う。
C/RTL 協調シミュレーションが終了した。結果を示す。
Avg Latency は 848 クロック、 Max Latency は 858 クロック、 Min Latency は 838 クロックだった。
Export RTL を行って成功した。
IP 化できた。
Run Implementation を行った。
現在、進行中。
2021年06月29日 04:40 |
Vitis HLS
| トラックバック:0
| コメント: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ファイルを生成した。
今回は、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 フォルダを作成する。
Workspace に vitis_work フォルダを指定した。
Launch ボタンをクリックする。
Vitis IDE が起動した。
Create Application Project をクリックして、プラットフォームとアプリケーション・プロジェクトを作成する。
New Application Project ダイアログが表示された。
Create a new Vivado Project画面が表示される。Next>ボタンをクリックする。
Platform 画面では、Create a new platform hardware (XSA) タブをクリックする。
XSA_file の Browse... ボタンをクリックして、DMA_pow2_test プロジェクトの DMA_pow2_test_wrapper.xsa を選択する。
Next>ボタンをクリックする。
Application Project Details 画面。
Application Project Name に DMA_pow2_test と入力する。
Next>ボタンをクリックする。
Domain 画面。
デフォルトのままとする。
Next>ボタンをクリックする。
Templates 画面。
Empty Application(C) をクリックする。
Finish ボタンをクリックする。
DMA_pow2_test_wrapper プラットフォームと DMA_pow2_test アプリケーション・プロジェクトが作成された。
”
WSL2 上で動作する Vitis 2020.2 で ZYBO Z7-10 をコンフィグレーションして、アプリケーション・ソフトウェアを走らせる ”から、test_dma.c を DMA_pow2_test_system -> DMA_pow2_test -> src フォルダにコピーした。
トンカチマークをクリックして、ビルドを行ったところ、成功してビルドできて、elf ファイルが生成された。
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) を選択する。
Trea Term に正しく結果が表示された。
2021年06月28日 04:21 |
Vitis
| トラックバック:0
| コメント:0
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 で作成した。
Flow Navigator で IP Catalog をクリックして、IP Catalog のウインドウを表示させた。
IP Catalog のウインドウ内で右クリックし右クリックメニューから Add Repository... をクリックする。
Repositories ダイアログで、”
Vitis HLS 2021.1 を使ってみる(DMA_pow2) ”のフォルダの solution1/impl/ip フォルダを選択する。
Add Repository ダイアログが表示された。
IP Catalog に Dma_pow2 IP が追加された。これで、DMA pow2 IP を使えるようになった。
Flow Navigator で Create Block Design をクリックして、ブロックデザインを作成する。
Create Block Design ダイアログが表示された。
Design name に DMA_pow2_test と入力した。
ZYNQ7 Processing System と DMA_pow2 IP を Add IP してブロックデザインを作成した。
processing_system7_0 の設定画面を示す。
S_AXI_HP0 インターフェースを活かした。
FCLK_CLK0 を 100 MHz に設定した。
HDL Wrapper ファイルを生成した。
Flow Navigator から Generate Bitstream をクリックして、論理合成、インプリメンテーション、ビットストリームの生成を行った。
エラーなしで成功した。
Project Summary を示す。
XSAファイルを生成する。
File メニューから Export -> Export Hardware... を選択する。
Export Hardware Platform ダイアログが表示された。
Output 画面で、Include bitstream ラジオボタンをクリックした。
Files はデフォルトのまま、Next>ボタンをクリックする。
Exporting Hardware Platform 画面で、Finish ボタンをクリックした。
DMA_pow2_test_wrapper.xsa ファイルが生成された。
2021年06月27日 04:23 |
Vitis
| トラックバック:0
| コメント:0
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 になったようだ。
ソース・ファイルの 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 に使用する。
ZYBO Z7-10 に使用するので、General の config_interface の m_axi_addr64 のチェックは外した。つまり AXI4 Master のアドレスは 32 ビットとした。
C シミュレーションを行う。
Flow Navigator の Run CSimulation をクリックしても、C シミュレーションが走る。
C シミュレーションの結果を示す。この辺りは前のバージョンと変わらない。
Flow Navigator で C SYNTHESIS の Run C Synthesis をクリックする。
C コードの合成時にもダイアログが表示されるようになった。
C コードの合成が終了した。
C コードの合成結果を示す。
Performance & Resource Estimates の VITIS_LOOP_12_1 を見ると、PIPELINE 指示子が書いてないのに、Interval が 1 になっていて、パイプラインされているのが分かる。
Open Function Call Graph → Synthesis を選択する。
Function Call Graph が表示された。
簡単なコードなので、良く分からない?もっと複雑なコードをやってみた方が良さそうだ。
C/RTL協調シミュレーションを行った。
C/RTL Co-simulation Dialog で Dump Trace を all に変更した。このダイアログは 2020.2 から変更点が無さそう?
C/RTL協調シミュレーションの結果を示す。
レイテンシは 35 クロックだった。
Open Function Call Graph → Cosimulation を見た。
こちらも複雑なモデルで見た方が良さそうだ。
Export RTL を行った。
Export RTL のダイアログを示す。そのまま OK ボタンをクリックした。
Export RTL が終了した。
次に Flow Navigator から Run Implementation をクリックする。
Run Implementation ダイアログが表示された。
RTL Synthesis のラジオボタンがクリックされていた。
RTL Synthesis, Place & Route ラジオボタンに変更して、OKボタンをクリックした。
結果を示す。
solution1 -> impl の export.zip に IP が圧縮されている。
2021年06月26日 13:12 |
Vitis HLS
| トラックバック:0
| コメント:0
”
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 を追加した。
論理合成、インプリメンテーション、ビットストリームの生成を行って、成功した。
Project Summary を示す。
Vitis 2020.2 で Assistant ウインドウのDMA_pow2_test_system -> DMA_pow2_test -> Debug を右クリックし、右クリックメニューから Debug -> Debugger_DMA_pow2_test-Default (前回作成した Debug Configuration)を選択した。
Vitis がデバックモードになって、最初の C コードで停止している。
最初にデバックモードで起動するのは、クロックが出力されないからだ。クロックは PS から PL に供給されているので、最初のブート・ソフトウェアが走らないとクロックが PL に供給されない。
Vivado で PROGRAM AND DEBUG -> Open Hardware Manager -> Open Target をクリックして出てきたメニューの内の Resent Target -> 192.168.3.32.Xilinx_tcf/Digilent/... を選択する。
すると、ILA デフォルト・ダッシュボードが表示されて、波形を見ることができる。
ILA デフォルト・ダッシュボードをフローとして、トリガボタンをクリックし、トリガ待ちにした。
なお、トリガ条件は DMA_pow2_0_m_axi_gmem : ARVALID の立ち上がりとした。
Vitis に戻って Resume ボタンをクリックして、アプリケーション・ソフトウェアを走らせる。
アプリケーション・ソフトウェアが走って、ILA デフォルト・ダッシュボードに波形が表示された。
真ん中を拡大した。
AXI4 インターフェースの Read で 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 を Read した。
AXI4 インターフェースの Write で Read した値を 2 乗した数を Write しているのが分かる。
最後に Tera Term の画面を示す。
2021年06月25日 04:31 |
WSL2
| トラックバック:0
| コメント:0
”
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 プロジェクトを示す。
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 コードの合成結果を示す。
Export RTL 結果を示す。
WSL2 上の Vivado 2020.2 で DMA_pow2_test プロジェクトを作成した。
下の図は、論理合成、インプリメンテーション、ビットストリームの生成が終了した状態だ。
DMA_pow2_test ブロックデザインを示す。
Address Map を示す。
Project Summary を示す。
ハードウェアをエクスポートして、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 アプリケーション・プロジェクトのビルドを行って成功した。
Assistant ウインドウで、DMA_pow2_test_system -> DMA_pow2_test -> Debug を右クリックし、Run -> Run Configuration... を選択する。
Run Configuration ダイアログが開いた。
Single Application Debug を右クリックし、右クリックメニューから New Configuration を選択する。
Dubugger_DMA_pow2_test-Default コンフィグレーションが生成された。
Connection の New ボタンをクリックする。
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 を起動した。
Target Connection Details ダイアログで、Target Name と Host に IP アドレスを入れて、Advanced ボタンをクリックすると Zybo Z7 が出ているので大丈夫そうだ。
OKボタンをクリックする。
クリック後にまた、パケット届いていないというダイアログが出るが無視して良いようだ。
Tera Term を立ち上げて、ZYBO Z7-10のシリアルポートに接続する。
Run Configuration ダイアログで、Apply ボタンをクリックし、Run ボタンをクリックした。
Tera Term に演算の結果が表示された。成功だ。
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; }
しかし、パケットが届いていないというダイアログが出ているのに、パケットが届いているとはどういう訳だろう。。。
人騒がせなバグだ。だいぶ時間をロスしてしまった。。。
2021年06月24日 05:14 |
WSL2
| トラックバック:0
| コメント:0
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 ボタンをクリックすると、利用可能なボードが出てくるようだ。
Refresh ボタンをクリックすると、Refresh Catalog が出てきてカタログをダウンロードしている。
ZYBO Z7-20 や ZYBO Z7-10 などが出てきた。
Status の Install ボタンをクリックすると、ボード・ファイルがインストールされるようだ。
ボード・ファイルがインストールされた。
これで ZYBO Z7-10 のボード・ファイルが反映される。
2021年06月23日 20:28 |
Vivado
| トラックバック:0
| コメント:0
Vivado ML 2021.1 が出ています。
Vivado の新機能 です。
特に、”DFX の BDC”の”IP インテグレーターでリリースされた DFX 用のブロック デザイン コンテナー (BDC)”、”ブロック デザインの中にブロック デザインを配置して、DFX デザインを作成/処理する”をやってみたいです。
Vivado ML を見ると、
Vivado ML のスタンダード版は無償でダウンロード可能です。
ということなので、従来の WebPACK が Vivado ML のスタンダード版になったようです。
さて、早速、ウエブインストーラーをダウンロードしてインストールを始めました。
Xilinx Unified 2021.1 Installer の Welcome 画面です。
Select Install Type 画面です。
ここでは登録した E-mail アドレスとパスワードを入れます。
Select Product to Install 画面。
Vitis を選びました。
Vitis Unified Software Platform 画面。
Vivado ML のスタンダード版でサポートされているデバイスを選びました。
Accept License Agreements 画面。
全てのライセンス条件にチェックを入れました。
Select Destination Directory 画面。
インストール・フォルダを設定しました。
Installation Summary 画面。
Install ボタンをクリックしました。
インストールがスタートして、ダウンロードしています。
まだダウンロード中です。インストール終了して使ってみるのが楽しみですね。。。
インストール中に WinPcap がインストールされます。
インストールが終了しました。
Vivado 2021.1 を起動しました。これは Windows 10 版です。
2021年06月23日 04:32 |
Vivado
| トラックバック:0
| コメント:0
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 プロジェクトを作成した。
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 PROGRAM AND DEBUG -> Open Hardware Manager -> Open Target -> open New Target... を選択した。
Open New Hardware Target ダイアログが表示された。
Hardware Server Settings 画面で Remote server を選択して、Host name に IP アドレスを入れる。
Windows 10 でもう 1 つ PowerShell を立ち上げて、
ipconfig /all で IP アドレスを確認した。
確認した IP アドレスを Host name に入れた。
しかし、これで接続できなかった。
Windows 10 のファイヤー・ウォールではじかれていると思って、”
Windows10で特定のポートを開放する ”を参考にして、 3121 番 TCP 受信ポートを開けた。
すると、Windows 10 の hw_server に接続できた。
Open Hardware Target Summary 画面が表示された。Finish ボタンをクリックした。
Program device をクリックした。
Program device ダイアログが表示された。
Bitstream file に LED_test.bit が表示されている。
Program ボタンをクリックして、コンフィギュレーションを行った。
コンフィギュレーションができて、SW0 を ON/OFF すると LD0 が点灯・消灯した。
2021年06月22日 20:49 |
WSL2
| トラックバック:0
| コメント:0
”
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 がダウンロードできた。
balenaEtchar を立ち上げて Avnet-u96v2_sbc-Vitis-AI-1-3-2021-02-23.zip を読み込んで、 16 GB の MicroSD カードにイメージを書き込む。
イメージ書き込みが終了した。
sudo resize2fs -f /dev/sdf2 を実行したが、またダメだったようだ。
MicroSD カードを Ultra96-V2 に挿して電源ON すると、PetaLinux が立ち上がった。
ID: root, PASSWORD: root でログインできた。
Ultra96-V2 の USB ポートに PLANEX GU-1000T (USB - LAN 変換)が接続されている。そのため、IP アドレスを取得できている。
ifconfig の結果を示す。
ネットワークが接続されているので、ターミナルから
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 ファイルにまとめた。
#!/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 を実行した。
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 Ultra96-V2 の DisplayPort に接続した Display に車の認識の画像が表示された。(動画です)
gtkterm の表示画像を示す。
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 ポーズの検出画像が表示された。(動画です)
gtkterm の表示画像を示す。
2021年06月21日 04:57 |
Vitis-AI
| トラックバック:0
| コメント:0
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 をダウンロードした。
work ディレクトリに解凍した。
sd_card.img が今回 MicroSD カードに書くイメージだ。
balenaEtchar を起動して、 sd_card.img とマウントした MicroSD カードを指定して、書き込む。
書き込み中。
書き込み終了。
lsblk でみると MicroSD カードは sdf にマウントされているようだ。
sudo resize2fs -f /dev/sdf2 を実行して、リサイズしてみたがダメなようだった。
MicroSD カードを Ultra96-V2 に入れて、電源ON した。
PetaLinux が起動して gtkterm にメッセージが出た。
ID: root , Password: root でログインできた。
”
Updating PMIC on Ultra96-V2 through the 2020.1 BSP! ”に従ってコマンドを入れていく。
cd pmic-prog/ cd pmic-configs/ ls cd .. ./pmic_prog detect 6 Device 0x13 programming ./pmic_prog program 6 0x13 -i ./pmic-configs/U96V2_5401_0x13_191030.txt Device 0x14 programming ./pmic_prog program 6 0x14 -i ./pmic-configs/U96V2_5401_0x14_191030.txt Programming Verification ./pmic_prog read-registers 6 0x13 -o 0x13.txt -i ./pmic-configs/U96V2_5401_0x13_191030.txt ./pmic_prog read-registers 6 0x14 -o 0x14.txt -i ./pmic-configs/U96V2_5401_0x14_191030.txt これで、 Ultra96-V2 の PMIC の電流制限を変更できたはず。。。
2021年06月20日 04:36 |
Ultra96
| トラックバック:0
| コメント:0
”
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 ボタンをクリックして、アプリケーション・ソフトウェアを実行した。
Gtkterm にメニューが表示された。
カメラ画像がディスプレイに表示された。カメラをぶら下げているので、画像が上下反対になっている。
Gtkterm で設定を変えようと思うが、うまく入らない。というか、Enter キーを押さないと、getchar() でキー入力を取り込んでくれないが、キー入力を取得できるのは最後の Enter キーだけの 0x0D になってしまっているようだ。
そこで、 getchar() を inbyte() に変更して、ビルドした。
こうすると楽に設定が変更できるようになった。
Vivado 2020.2 での ZYBO Z7-20 + Pcam5C でのカメラ画像のディスプレイ出力に成功した。良かった。。。
2021年06月19日 03:17 |
ZYBO Z7
| トラックバック:0
| コメント:0
”
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-pcam-5c-2019.1 (後で、Zybo-Z7-20-pcam-5c-2020.2 に改名する)ディレクトリの下に vitis_work ディレクトリを作成した。
vitis_work ディレクトリの中に入って”開く”ボタンをクリックした。
Zybo-Z7-20-pcam-5c-2019.1/vitis_work が Workspace に指定されたので、 Launch ボタンをクリックする。
Vitis IDE が立ち上がった。
Create Application Project をクリックする。
New Application Project ダイアログが表示された。 Next > ボタンをクリックする。
Platform 画面が表示された。
Create a new platform hardware (XSA) タブをクリックする。
Browse... ボタンをクリックして、XSA ファイルを指定する。
system_wrapper.xsa ファイルを選択する。
XSA File に system_wrapper.xsa ファイルが表示された状態で、Next > ボタンをクリックする。
Application Project Details 画面が表示された。
Application Project name に pcam_vdma_hdmi と入力した。
Next > ボタンをクリックする。
Domain 画面はそのまま、Next > ボタンをクリックする。
Templates 画面では、Empty Applicaiton (C++) を選択した。
Finish ボタンをクリックした。
system_wrapper プラットフォームと pcam_vdma_hdmi_system アプリケーション・プロジェクトが作成された。
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 ボタンをクリックした。
pcam_vdma_hdmi_system/pcam_vdma_hdmi/src に main.cc がインポートされた。
後は、pcam_vdma_hdmi_system/pcam_vdma_hdmi/src ディレクトリに Zybo-Z7-20-pcam-5c-2019.1/sdk_appsrc/pcam_vdma_hdmi ディレクトリ の hdmi 、 ov5640 、 platform ディレクトリをファイルマネージャーでコピーした。
すると、 Vitis IDE に hdmi 、 ov5640 、 platform ディレクトリが入った。
トンカチ・ボタンをクリックして、ビルドした。
ビルドが成功した。
Linux だとビルドが成功するようだ。
なお、事前にWindows 版の Vitis 2020.2 ではビルドが通らないかもと思っていた。
それは、”
Windows 10 版の Vitis HLS 2020.2 で作成した AXI4Lite インターフェースの IP を使用した回路は Vitis 2020.2 でプラットフォームがビルドできない ”を経験していたからだ。ぜひ、Vitis 2021.1 では治っていて欲しいと思う。
2021年06月18日 04:55 |
ZYBO Z7
| トラックバック:0
| コメント:0
”
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 ダイアログが表示された。
Output 画面では、 Include bitstream のラジオボタンをクリックする。
Files 画面はデフォルトのままとする。
Exproting Hardware Platform 画面。Finish ボタンをクリックする。
XSA ファイルが生成された。
2021年06月17日 05:21 |
ZYBO Z7
| トラックバック:0
| コメント:0
”
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 ディレクトリを展開した。
Vivado 2020.2 を起動して Zybo-Z7-20-pcam-5c-2019.1/vivado_proj ディレクトリの Zybo-Z7-20-pcam_5c.xpr を開く。
Older Project Version ダイアログが表示された。
Automatically upgrade to the current version のラジオボタンがクリックされているので、そのまま OK ボタンをクリックした。
Project Upgraded ダイアログが表示された。
Report IP Status ボタンをクリックした。
Vivado 2020.2 の Zybo-Z7-20-pcam_5c プロジェクトが開かれた。
IP Status が表示されている。
Upgrade Selected ボタンをクリックした。
Upgrade IP ダイアログが表示された。
OK ボタンをクリックした。
IP の Upgrade が成功した。
続いて、Generate Output Products ダイアログが表示された。
Generate ボタンをクリックした。
Critical Messages が表示された。
Generate Output Products が完了した。
ブロックデザインを示す。
Address Map を示す。
論理合成、インプリメンテーション、ビットストリームの生成を行った。
タイミング・エラーがでている。
Open Implementation Design をクリックして、Timing を表示させた。
タイミング・エラーは dpy_hs_clock_p で発生していた。
これは以前解析した Zybo-Z7-20-pcam-5c プロジェクトのタイミング・エラーと同じだ。
”
ZYBO Z7-20でPcam 5Cを使用する4(タイミングエラーの検討) ”を参照のこと。
よって、タイミング・エラーは無視することにする。
2021年06月16日 04:37 |
ZYBO Z7
| トラックバック:0
| コメント:0
”
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 multi_axim が動作しているのが確認できた。
axi_slave_bfm の Write に Wait が入っているのは、 axi_slave_bfm.v のパラメータで”WRITE_RANDOM_WAIT = 1”に設定されていて Write 時にランダムな Wait が入るように設定されているからだ。
2021年06月15日 04:47 |
シミュレーション
| トラックバック:0
| コメント:0
”
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 を作成した。
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 を示す。
-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 で .v を .cpp に変換し、コンパイルする。
verilator -f multi_axim.cmd cd obj_dir make -j -f Vmulti_axim_top_wrapper.mk Vmulti_axim_top_wrapper Vmulti_axim_top_wrapper を実行する。
./Vmulti_axim_top_wrapper simx.vcd ファイルが生成された。
GTKWave を実行する。
gtkwave simx.vcd multi_axim_top_wrapper の信号を表示した。
AXI4 Lite の Write アクセスと Read アクセスが表示されている。
multi_axim_top_wrapper/multi_axim_top_i/axi_slave_bfm_0 の信号を検索したが、 ram_array の信号がなかった。
RAM は無いのかな?
2021年06月14日 04:49 |
シミュレーション
| トラックバック:0
| コメント:0
”
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/ のファイルをディレクトリごとコピーした。
axi_slave_bfm.v と sync_fifo.v は IP にしてあるのだが、Verilog HDL ファイルのみ使用する。
Vivado 2020.2 の multi_axim_pj プロジェクトを作成して、
multi_axim/solution1/syn/verilog/ のファイルと axi_slave_BFM.v と sync_fifo.v を登録した。
multi_axim_top ブロックデザインを作成し、 multi_axim.v と axi_slave_BFM.v をドラック&ドロップした。すると RTL IP になる。
multi_axim_0 と axi_slave_bfm_0 が生成された。
2 個の RTL IP を配線した。今回は、AXI Interconnect は使用していない。
そして multi_axim_top ブロックデザインに HDL ラッパーファイルを作成した。
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 を示す。
multi_axim_top_axi_slave_bfm_0_0 がモジュール名なので、これを axi_slave_bfm に書き換えた。
multi_axim も同様に書き換えて、セーブした。
今回の multi_axim_pj は axi_slave_bfm.v と multi_axim.v の接続だけに使っているので、問題ない。
2021年06月13日 05:51 |
シミュレーション
| トラックバック:0
| コメント:0
”
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;”に変更した。
最後に RAM を初期化するコードを追加した。
initial begin for(i=0; i<SLAVE_ADDR_NUMBER-1; i=i+1) ram_array[i] = i; end
(2021/06/15:修正 integer i; の宣言がすでにされていたので、削除した) multi_axim.v と axi_slave_BFM.v を接続するのは、Vivado の IPI で接続しようと思う。IPI で接続して、出力された Verilog HDL ファイルを加工して使用する。
今まで述べてきたファイルと、C++ のテストベンチ・ファイル(multi_axim_top_wrapper_sc.cpp)を使用して Verilator でシミュレーションしてみよう。
2021年06月12日 04:57 |
シミュレーション
| トラックバック:0
| コメント:0
”
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 シミュレーションの出力結果を貼っておく。
(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 で見た結果を示す。
2021年06月11日 05:17 |
シミュレーション
| トラックバック:0
| コメント:0
”
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 cd verilator export SYSTEMC_INCLUDE=/usr/local/systemc/2.3.3/include autoconf ./configure --prefix=/usr/local/verilator/v4.202 make -j2 sudo make install Verilator のインストールは成功した。
/usr/local ディレクトリに systemc と verilator のディレクトリが生成されている。
Verilator の make_hello_sc サンプルを実行してみよう。
verilator/examples/make_hello_sc ディレクトリに移動した。
make を実行した。
make 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!
が表示された。
.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
を追加した。
2021年06月10日 04:36 |
シミュレーション
| トラックバック:0
| コメント:0
FPGAの部屋のまとめサイト を更新しました。
PICマイコン を追加して、2021 年 6 月 9 日までの記事を更新しました。
2021年06月09日 04:36 |
その他のFPGAの話題
| トラックバック:0
| コメント:0
親父の葬式が終わって一息ついたので、”
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 ディレクトリが解凍できた。
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++ ../configure gmake gmake check gmake install gmake check で examples をコンパイルしてあるので、systemc-2.3.3/objdir/examples/sysc/simple_bus ディレクトリの example を動かしてみよう。
test が実行ファイルのようだ。
./test 動作しているようだ。
2021年06月08日 04:46 |
シミュレーション
| トラックバック:0
| コメント:0
”
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 があるのは無視して欲しい)
Verlator/ex2 ディレクトリで下のコマンドを実行した。
verilator --cc --trace -Wno-lint dice_top.v --exe dice_top_tb.cpp 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() 文がエラーになるので、コメントアウトした。
cd obj_dir/ make -j -f Vdice_top.mk Vdice_top Vdice_top 実行形式ファイルができた。
./Vdice_top を実行すると simx.vcd が作成された。
gtkwave を実行した。
gtkwave simx.vcd いろいろと設定を行った結果のタイミングチャートを示す。
2021年06月04日 19:53 |
シミュレーション
| トラックバック:0
| コメント:0
昨日、親父が亡くなりました。
ここ5年位は透析していたのですが、40日前から誤嚥性肺炎で病院に入院していました。
昨日、病院からお昼頃呼び出しがあり、今、心臓マッサージ中だと言うことでした。
13時10頃、私が病院に駆けつけると心電図波形はフラットでした。医者が死亡確認をしてくれました。
88歳で親父が永眠しました。
今度の日曜日にお葬式ですが、コロナ禍でもあり、家族葬でこじんまりとやりたいと思います。
今週はブログ書けないかも知れませんが、よろしくお願いいたします。
2021年06月03日 05:00 |
日記
| トラックバック:0
| コメント:0
”
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/ make した。
make -j -f Vdice_state_machine.mk Vdice_state_machine printf 文の top->v__DOT__current_state の部分でエラーが出ている。
テストベンチ・ファイル dsm_test.cpp を編集する。
printf 分全体をコメントアウトした。
ex1 ディレクトリに戻って、もう一度コンパイルした。
obj_dir ディレクトリに行った。
make すると今度は成功した。
実行ファイル Vdice_state_machine ができている。
Vdice_state_machine を実行した。
./Vdice_state_machine 実行後に simx.vcd ができていた。
gtkwave を立ち上げて simx.vcd を確認した。
gtkwave simx.vcd gtkwave の GUI が立ち上がった。
左下のウインドウで、すべての信号を選択して、Append ボタンをクリックすると波形が表示された。
なお、最初の DICE_STATE は最初は数字を表示していたが、DICE_STATE を右クリックし、右クリックメニューから Data Format -> ASCII を選択すると文字で表示された。
2021年06月03日 04:49 |
シミュレーション
| トラックバック:0
| コメント:0
”
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 Vdice_state_machine 実行ファイルが生成されている。
実行ファイルを実行した。
./Vdice_state_machine 成功だ。
実行結果を貼っておく。
(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
2021年06月02日 04:06 |
シミュレーション
| トラックバック:0
| コメント:0
”
AXI4-Lite インターフェースの I2C Master Core を使用して 3 軸加速度度センサーの値を収集する3 ”の続き。
ストロベリーリナックスさんの”
LTC4331 絶縁型I2C延長モジュール(2個セット) ”のスレーブ側に付けるストロベリーリナックスさんの”
ADXL355 超低ノイズ3軸加速度センサモジュール ”は同じ値をずっと出力して、リセットが効かないことがある。そこで、
秋月電子の低飽和型レギュレーター 3.3V500mA NJM2884U1-33 を使用して、スレーブ側の電源を GPIO で ON/OFF できるようにした。
下図にそのブロック図を示す。
ZYBO Z7-20 の Vivado 2020.2 プロジェクトの acc_sensor_pow_202 を示す。
ブロックデザインを示す。
ZYBO Z7-20 のスライドスイッチの SW0 で NJM2884U1-33 の CONTROL 端子を制御する。
Address Map を示す。
制約ファイルを示す。
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 を示す。
ハードウェアをエクスポートして、Vitis を立ち上げた。
Vitis でプラットフォームとアプリケーション・プロジェクトを作成し、アプリケーション・ソフトウェアを作成して、ZYBO Z7-20 で確かめてみたところ、SW0 を ON した 0.5 秒後に 3軸加速度センサーの計測がスタートした。SW0 を OFF すると 3軸加速度センサーの計測が止まった。何度やっても ON/OFF することができた。成功だ。
実際の実験の様子を示す。ピンクの丸で囲った部分が NJM2884U1-33 だ。
アプリケーション・ソフトウェア 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(); } } }
2021年06月01日 04:27 |
FPGAを使用したシステム
| トラックバック:0
| コメント:0