FC2カウンター FPGAの部屋 2016年12月

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

FPGAの部屋

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

2016年のFPGAの部屋のブログのまとめ(7月~12月)

2016年のFPGAの部屋のブログを振り返ってみた。その2。

7月
PmodHB5 のセンサー・フィードバック処理IP を作ってみた3
Zybotの車輪のセンサー・フィードバックのデータを取得した
AXI4 Slave Bus Functional Model のVerilog HDL版4(今回の修正は、Xilinx社のIP はAxREADY がいつもは 1 になっていることから、AxREADYがいつも 1 になるように変更した。これがデフォルトのモードで、AWREADY_IS_USUALLY_HIGH、ARREADY_IS_USUALLY_HIGH を 0 にすることで、従来のAxREADY がいつもは 0 のモードにすることができる)
AXI4 Slave Bus Functional Model のVHDL版4
Vivado HLS で DMA Write IP を作る(絶対アドレス指定編)(AXI4 Master でフィルタを実装するコードを考えていると、やはり、memcpy() と中のフィルタ処理を重ね合わせられないので、すべてVivado HLS で作ると性能が出しにくい。
そこで、フィルタ部分はAXI4 Stream で作っておいて、DMA 部分は別にAXI4 Master Read - AXI4 Stream のDMA Read とAXI4 Stream - AXI4 Master Write の DMA Write の2つのIP をVivado HLS で作った方が良さそうだ)
Zybot が走った(Ubuntu 上でPWMモジュールIP とモーター・モニタIP を制御するアプリケーション・ソフトウェアを作成して、Zybot を走らせた)
Vivado HLS で DMA Read IP を作る(絶対アドレス指定版)
ガボール・フィルタ (Gabor Filter) による白線検出1
(ガボール・フィルタ (Gabor Filter) を使用して白線を検出してみようと思う)
ガボール・フィルタ (Gabor Filter) による白線検出2(カーネルサイズ 21 のガボール・フィルタで道路の白線を検出してみたが、今回はカーネルサイズ21だとハードウェアが大きいので、カーネルサイズを 9 にしてみた。更に、カーネルのパラメータを取得した)
ガボール・フィルタ (Gabor Filter) による白線検出11(その他の道路写真での検証)(ガボール・フィルタは完成した(パラメータを調整する必要はあると思う)が、まだ1枚の道路の写真しか試していないので、もう少し違った写真で試した)

8月
Gabor FilterをZYBO_0_162_2 へ実装してみた(ガボール・フィルタをZYBO用のプロジェクトに実装した)
Zybot にカメラを搭載して、白線を写してみた
Maker Faire Tokyo 2016 に行ってきました
ビットマップ・ディスプレイ・コントローラをAXI4-Stream対応にする1(構想編)(メラ・コントローラはAXI4-Stream版がすでに作ってあるが、ビットマップ・ディスプレイ・コントローラのAXI4-Stream版がないのでそれを作ることにした)
Gabor FilterをZYBO_0_162_2 へ実装してみた4(ZYBOで確かめた)(ガボール・フィルタをZYBO用のプロジェクトに実装して、白線がどのように表示されるか確かめた)
宝篋山に登ってきました
Vivado HLS でAXI4-Stream Master Model IP を作る
(久しぶり Verilog HDL を使って、AXI4-Stream版ビットマップ・ディスプレイ・コントローラを作っている。ビットマップ・ディスプレイ・コントローラはAXI4-Stream Slave なので、シミュレーションするには AXI4-Stream Master が必要となる。始めは、HDL で AXI4-Stream Master IP を作ろうとしたのだが、考えてみれば、Vivado HLS で、C++ で AXI4-Stream Master IP を作ってもよいのじゃないか?ということで、Vivado HLS 2016.2 を使用して作ってみた)
ビットマップ・ディスプレイ・コントローラをAXI4-Stream対応にする5(IP作成)(AXI4-Stream版ビットマップ・ディスプレイ・コントローラが出来上がったのでIP にした)
スペアリブの煮込みを作りました
MT9D111インターフェース基板2の作製1(KiCadでの設計)(CMOS カメラ MT9D111 のインターフェース基板は以前作成したが、Zybot で使用するのに、ケーブルで伸ばしたいので、バッファを入れた基板を作成することにした。この基板はGNDとVCCのピンを間違っていた。orz)
Zybot のカメラ画像をBMPファイルに変換するアプリケーションを作成した(Zybot の白線の画像や白線検出した結果の画像をBMPファイルに変換するアプリケーションを作成した。これで、白線の画像をGabor Filter で検出するときのパラメータを最適化することができる)
Vivado HLS で生成した AXI4 Master DMA IP を使用したカメラ画像表示システム1(プロジェクト作成)(今まで作ってきた AXI4-Stream版ビットマップ・ディスプレイ・コントローラ IPと AXI4-Stream版カメラ・コントローラ IP、Vivado HLS で作成したAXI4 Master DMA Write IP、Vivado HLS で作成したAXI4 Master DMA Read IP を使って、カメラ表示システムを作ってみることにした)
Zybot のカメラ画像でGabor Filterのパラメータを取得した(Zybot のカメラ画像を取得してBMPファイルに変換するアプリケーション・ソフトウェアを作成した。今回は、このアプリケーションで取得したZybot のカメラ画像からGabor Filterのパラメータを取得した)
Zybot による白線間の自動走行1(Gabor fillter の修正、C ソースコード)

9月
FPGAコンパイルマシンが届きました(新しいパソコン)
リコンフ研に行ってきました
Vivado HLSで作ったDMA Read IP を実機でテスト1(動作しない)(DMA Read IP が今も動いていないので、来年はちゃんと動くようにしたい)
Zybotのカメラによる白線追従走行(Zybot の白線検出、追従走行のアプリケーション・ソフトウェアを作って、白線追従走行させてみました。動画ありますので、見てください。まだ、限定的な状況でしか白線走行できません)
Zybot で Gabor filter を使う際のDMA Write IP(Gabor filter をソフトウェアで 250 ms ごとに切り替えていた。これは、500 ms に1回 Gabor filter の画像が取得できることを表している。この時間を短くしたいということで、AXI VDMA をVivado HLS 2016.2 で作成したDMA Write IP に差し替えようと思う。つまり、ハードウェアで自動的に左右のGabor filter を切り替えて、異なるアドレスのフレームバッファに書き込むことにしよう)
飛行ドローンを買ってみた
Vivado HLS でFIFO を作ってみた1(指示子を入れない場合)

10月
Zybot で Gabor filter を使うためのZYBO_0_5 プロジェクト5(走行テスト)(、ハードウェアで自動的に左右のGabor filter を切り替えて、異なるアドレスのフレームバッファに書き込むことにしたプロジェクトを使用した白線走行の動画がある)
Zybot で隊列走行をさせたい(妄想編)(マーカーをRGBからHSVに変換して色相を見て追従走行する)
Vivado HLS でRGB2HSV IPを作る1(UNROLL指示子による性能向上)
PYNQボード1(PYNQボードが届いた)
PYNQボード用PSの設定方法(Vivado のブロックデザインでPS の設定はどうやるのか?というのが疑問だったので、調べてみた)
PYNQボードのデバイス・ツリー(devicetree)
Vivado HLS 2016.3 での変更点
Vivado 2016.2 のプロジェクトをVivado 2016.3 にアップグレードすると動作しなかった
Vivadoを使用してZYBO_0_163_6フォルダのプロジェクトにRGB2HSV IPを追加4(RGB2HSV)(HSV2RGB変換をARMプロセッサで動作するソフトウェアとして実装して結果を確認し、次にHSV2RGB変換時にS = V = 255 としてH を変換して結果を確認した)
MT9D111をコードを伸ばしてステレオ・カメラにする1(I2Cのプルアップ抵抗)(Zybot にMT9D111 カメラ・モジュールを搭載しているが、インターフェース基板をZYBO に直付けしている。ステレオ・カメラにするためには、延長コードをつけてカメラ・モジュールを 15 cm 程度延ばす必要がある。延長するとI2Cが通らなくなるので、カメラ・モジュールのI2Cのプルアップ抵抗を変更してみたが駄目だった)
MT9D111をコードを伸ばしてステレオ・カメラにする2(SCL, SDAの波形計測)(SCL, SDAの波形をオシロスコープで計測した。測定ポイントはコードを延ばした先のカメラ・インターフェース基板のコネクタ部分だ)
2台の Zybot での隊列走行1(構想編)(今まで作ってきたRGB2HSV変換IP を使って、2台のZybot で隊列走行をさせたいと思う。それではどのようにやるか?を検討していこう)
MT9D111をコードを伸ばしてステレオ・カメラにする3(I2CリピータIO付きカメラ・インターフェース基板)(秋月電子のI2C リピーターIC の PCA9515AD を使ったカメラ・モジュールのインターフェース基板をKiCad で作成した。この基板もGNDとVCC が間違っていた)

11月
Intel SoC FPGA デベロッパー・フォーラム
JACORN2016に参加しました
RAMの初期化ファイルのあるAXI4 Slave BFM(VHDL版)(Xilinx社のIP はAxREADY がいつもは 1 になっていることから、AxREADYがいつも 1 になるように変更した。これがデフォルトのモードで、AWREADY_IS_USUALLY_HIGH、ARREADY_IS_USUALLY_HIGH を 0 にすることで、従来のAxREADY がいつもは 0 のモードにすることができる)
RAMの初期化ファイルのあるAXI4 Slave BFM(Verilog HDL版)
坂東市いわい将門ハーフマラソン(2016)
MT9D111をコードを伸ばしてステレオ・カメラにする6(I2CリピータIO付きカメラ・インターフェース基板が届いた)(GND とVCC が間違っていたので、I2CリピーターIC から煙が出た。慌てて、修正した基板を発注した)
Vivadoを使用してZYBO_0_163_6フォルダのプロジェクトにRGB2HSV IPを追加6(UbuntuでRGB2HSVを試す)(BOOT.bin や devicetree.dtb を作成して、SDカードに書き込み、ZYBOに挿入して電源ONした。Ubuntu が起動して、それ上でカメラの動作を確認できた。今回は、RGB2HSV IP を使うアプリケーション・ソフトウェアを作成して、RGB2HSV変換を行った)
つくばマラソンの10Kmに出場しました
Vivado HLS によるAXI4 マスタ・インターフェースのバースト転送2(Vivado HLS 2015.4 時代からは、Vivado HLS によるAXI4 マスタ・インターフェースのバースト転送が memcpy() 関数を使うだけでなく、ある条件の for 文で AXI4 マスタポートを使用したときにも適用されるようになった。それをテストしてみた)
2台の Zybot での隊列走行3(追従用Zybotの戦略)(隊列走行の前走車のアプリケーションはできた。今回は追従用Zybot の戦略を考える)
SDSoC 2016.2 でラプラシアンフィルタをテスト1(SDSoC を試したのはSDSoC 2015.2 の時だったが、今回、SDSoC 2016.2 でもう一度、確かめてみよう)
2台の Zybot での隊列走行4(追従走行用アプリケーションの作成1)(追従用Zybot の戦略を考えたが、今回はそれに基づいて追従走行用アプリケーション・ソフトウェアを作成し、認識テストを行った)

12月
2台の Zybot での隊列走行5(追従走行を試してみた)(追従走行用アプリケーション・ソフトウェアを作成し、認識テストを行った。今回は、実際に2台の Zybot を使用して追従走行を試してみた。動画あります)
Zybot に超音波距離センサを搭載する1(概要)(「2台の Zybot での隊列走行5(追従走行を試してみた)」で曲がりなりにも 2 台の Zybot で隊列走行ができるようになった。その際に前走車の走り方によっては隊列走行が崩れる時がよくある。そこで、カメラの画角から外れてしまっても、追従車は予測で走れるようにしたいのだが、何か物体があったらぶつかってしまう。そこで、ぶつからないように超音波距離センサをつけたいと思う)
Xilinx 社のマイクロプロセッサまとめ1(PicoBlaze, MicroBlaze MCS)
Zybot に超音波距離センサを搭載する2(Arduino でセンサをテストする)(動作した)
Zybot をステレオカメラにする1(カメラ・インターフェース基板の実装とテスト)(”I2Cリピーター付きカメラ・インターフェース基板2が来ました”で届いた基板に部品を実装してZYBO に延長ケーブルを付けてテストしてみた。テストの結果、問題なく動作した。これでステレオカメラにすることができる。なお並べてZYBOに実装することもできる)
Zybot に超音波距離センサを搭載する3(Vivado HLSでインターフェースIPを作製)
Xilinx 社のマイクロプロセッサまとめ2(MicroBlaze)
Zybot に超音波距離センサを搭載する8(ZYBO_0_162_7 に 2 つのIP を追加2)(Synchronizer を追加して完成した)
Xilinx 社のマイクロプロセッサまとめ3(Zynq)
第2回FPGAスタートアップセミナーに参加しました
Zybot に超音波距離センサを搭載する10(Zybot に取り付けた)(超音波距離センサ・インターフェースIP をLinuxからも使うことができた)
Vivado 2016.2 からVivado 2016.4 へアップグレード
Vivado HLSのビデオ プロセッシング関数を使用したOpenCVのFPGAアクセラレーション
SDSoC のプラットフォームのお勉強1(SDSoC のプラットフォームの生成方法について学ぶことにした)
SDSoC のプラットフォームのお勉強3(ハードウェア・プラットフォームの試作1)(試しにハードウェア・プラットフォームを作成してみる)


1年を振り返ってみると、Vivado HLS を使いまくった1年だった気がする。
来年はSDSoC も自由にプラットフォームを作りれるようになりたい。
Zybot の実装も順調に進めてきた。来年はステレオカメラにしよう。
  1. 2016年12月31日 07:26 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:0

2016年のFPGAの部屋のブログのまとめ(1月~6月)

2016年のFPGAの部屋のブログを振り返ってみた。

1月
Vivado HLS勉強会4(AXI4 Master)を公開しました(今年はVivado HLS の記事をFPGAマガジンにも書かせてもらった)
筑波山神社に歩いて初詣に行ってきました
ZYBO_0_2 と ZYBO_1_XGA_test との接続テスト(ZYBO_0 にDigilent 社の rgb2dvi IP を実装することができた。(ZYBO_0_2))
Vivado HLS勉強会5(AXI4 Stream)を公開しました
ステレオカメラによる距離測定テスト1(構想編)(”ZYBO_0 を変更3(Ubuntu 14.04 LTSのBOOT.binを変更)”でステレオカメラの要素技術は大体クリア出来たので、ステレオカメラを構築していくことを考えてみよう。)
牛久シティマラソンの5kmに参加しました
Digilent社のボード・ファイルのインストール(ボード・ファイルにはお世話になった)
ZYBO_0_2 と ZYBO_1_XGA_test との接続テスト時の画像のバグのデバック2(アプリの変更)(HDMIの出力を入力するときの左端の画像がおかしい問題は解決した)
FreeCADでDIP ICの3Dモデルを作る1(3D CadソフトのFreeCADを勉強してDIP ICパッケージのモデルを作った。実際に3Dプリンタでプリントしてみた)
デバイスドライバ udmabuf を使用する1(@ikwzm さんのLinuxでユーザー空間で動作するプログラムとハードウェアがメモリを共有するためのデバイスドライバ udmabuf を使わせて頂いた。便利に使っている。感謝)
マウスコンピュータのノートパソコン、LB-J321E-SSD2 が来ました(ノートパソコンを購入した)
・ステレオカメラによる距離測定テスト6(ステレオカメラのテスト)(SDKを立ち上げて、ベアメタル・アプリケーションを作製して自分のカメラと、ZYBO_0_2 からHDMI ポート経由で送られてきた画像が表示できるか?を確認した)
LinuxでSDカードをバックアップ、リストア(Linux環境でのSDカードのバックアップ、リストア方法)

2月
MPSoCのお勉強1(概要)
MPSoCのVivado プロジェクトを作ってみよう1(MPSoC のプロジェクトを作製した)
守谷ハーフマラソン(うちの奥さんが5km で世代別優勝した。びっくりしたな。。。)
ZYBO をUbuntu 14.04 LTS にアップグレードした場合のエコーバック(解決方法を教えて頂いた)
ステレオカメラによる距離測定テスト10(左右カメラの視差の測定)(左目カメラ画像に右目カメラ画像の一部を表示するアプリケーションだ。右目カメラ画像の一部を表示するエリアは、左目カメラ画像の輝度を 1/2 にして、そこに輝度を 1/2 にした右目カメラ画像を足し合わせる。デフォルトでは、右目カメラ画像の縦方向真ん中で、横方向左端の 160 ピクセル X 120 行を切り取って、左目カメラ画像に表示する。)
ステレオカメラによる距離測定テスト13(チェッカーボードの撮影結果)(カメラで撮影した画像に思いっきり樽型ひずみが出ていた)
OpenCV 2.4.10 の stereo_calib.cpp をやってみた
MPSoC勉強会で”MPSoCのPLの性能について”という発表をしてきた(サポート用のブログ)
OpenCV 2.4.10 の stereo_match.cpp をやってみた
左目カメラ画像と右目カメラ画像をBMPファイルに変換するアプリケーションを作成した

3月
ZYBO_0_2のビットマップ・ディスプレイ・コントローラのバグフィックス(ZYBO_0_2 のビットマップ・ディスプレイ・コントローラのワードレーンがおかしいようなので修正を行った)
ZYBO_0_2のビットマップ・ディスプレイ・コントローラのバグフィックス2(今回は、右目カメラ画像に出ている黒いドットを消すことができた。原因は、ビットマップ・ディスプレイ・コントローラの出力の display_enable が 1 クロックずれていたことだった)
hls::LineBufferとhls::Windowでラプラシアンフィルタを実装する1(あるところから hls::LineBuffer と hls::Window を教えて頂いたので、それを使ってラプラシアンフィルタを実装した。ありがとうございました)
OpenCV 2.4.10 の stereo_calib.cpp を自分のカメラ画像でやってみた3(いろいろと失敗してきた”OpenCV 2.4.10 の stereo_calib.cpp を自分のカメラ画像でやってみた”ですが、ついにうまく行った。勝因は、チェスボードに黒枠をつけたのと、チェスボードが大きめに画面に写っていたほうが良いみたいだ)
hls::LineBufferとhls::Windowでラプラシアンフィルタを実装する7(2 つの実装を実際に使用する 800 x 600 ピクセルの解像度に変更して、どの位リソースを使うかと、今までは 100 MHz で合成してきたが、どの位の動作周波数で合成できるかを探ってみた)
OpenCV 2.4.10 の stereo_calib.cpp を自分のカメラ画像でやってみた4(stereo_match_cam.cpp の作成)(前回で、”OpenCV 2.4.10 の stereo_calib.cpp を自分のカメラ画像でやってみた”が上手く行った。でも、これは、右目カメラ画像と左目カメラ画像をBMPファイル変換して、そのBMPファイルに対して stereo_match を起動して、disparity を計測した。これだとBMPファイルにする手間があるので、右目カメラ画像と左目カメラ画像をバッファしているフレームバッファから直接、画像を取得して、stereo_match するようにソフトウェアを書き換えた。これを stereo_match_cam.cpp とした)

4月
Vivado HLS 2015.4 で OpenCV を使ってみた2(テストベンチに Mat を使って実装した)
Vivado HLS 2015.4 で OpenCV を使ってみた3(Sobelフィルタを試した1)
Vivado HLS 2015.4 で OpenCV を使ってみた7(FAST Corners Detection 1)
かすみがうらマラソンに出場しました
OpenCV の X軸方向 Sobel フィルタ IP のカメラ表示システム(”Vivado HLS 2016.1 で OpenCV の Sobel フィルタを試してみた”で作った X軸方向 Sobel フィルタの IP をカメラ表示システムに入れて、Sobel フィルタ出力が表示された)
FASTXコーナー検出IPのカメラ表示システム5(Vivado HLS 2016.1でやってみた3)(前回は、hls::Duplicate() で複製された img_1_ の data_stream に hls::FASTX() と hls::Dilate() の最大レイテンシの 7 行と 3 行を足した 10 行分より多い 2 の 13 乗の 8196 個の FIFO バッファを付けるように STREAM ディレクティブを指定した。
今回は、前回作製した FASTX コーナー検出IP を使用して、Vivado 2016.1 で論理合成、インプリメントを行って、SDKでZYBO にコンフィグレーションしアプリケーションを起動して、 FASTX コーナー検出できた)
FASTX コーナー検出の改良3(threshold をソフトウェアで変更可能にする)( threshold を変更できるFASTX コーナー検出IP をカメラ表示システムに組み込んで実際に表示してみた)
AXI VDMAのMM2Sを使用してビデオ出力1(構想編)(これはうまく行かなかったな。どうもAXI VDMA とは相性が良くないようだ)

5月
定期戦に行ってきました
AXI VDMAのMM2Sを使用してビデオ出力7(実機でテスト)(cam_disp_axis.c を AXI VDMA の MM2S を使う仕様に変更して、ZYBO実機でテストしてみたが、何も表示されない。やはり、AXI VDMA とは相性が悪い)
KiCad-4.0.2 と FreeRouter インストール覚書
Vivado HLS を使用した車の白線検出1(初めに)(車の白線検出をハードウェア化してみたいということで、OpenCVを使用して車の白線検出を行い、それをVivado HLS でハードウェア化してみることにした)
Vivado HLS を使用した車の白線検出4(ヒストグラム均一化)(cannyフィルタでエッジ検出した後でHough 変換を行って、直線検出したが、最後の暗い画像では、道路の白線を検出することはできなかった。今回は、canny フィルタの前に equalizeHist() を行うことで、ヒストグラムの均一化したところ、白線検出できるようになった)
Vivado HLS を使用した車の白線検出5(hls::HoughLine2())(前回はヒストグラムの均一化を行ってから、グレー変換、Canny フィルタ、Hough 変換を行うと白線検出をすることができた。今回は、”Vivado HLS を使用した車の白線検出1(初めに)”で使用した”ka367/Lane-Detecting-Using-Hough-Transform”が動作して、C シミュレーションとC コードの合成をすることができた。でも、ロジックが大きすぎてZYBOに入らない。。。)
Vivado HLS を使用した車の白線検出7(Canny フィルタ1)(前回、白線検出ハードウェアはとてもZYBO には入らないということがよく分かった。それでも Canny フィルタだけはハードウェアにしたいということでやってみた)
ZYBO 上のOpenCV で白線検出2(equalizeHist() を使用した場合2)(前回は、equalizeHist() を使用し、Canny フィルタを掛けて、HoughLine 変換で道路の白線検出を行った。しかし、画像を読み込む時点で白黒画像に変換していた。ハードウェアでは、カメラで撮影した画像を白黒変換して、Canny フィルタを掛ける予定なので、白黒画像変換の部分の経過時間も測る必要がある。それでC++ ソースコードを修正した。更に、白黒画像変換+Canny フィルタの経過時間を測定した)
Z-turn Board が届きました
ZYBO 上のOpenCV で白線検出3(Canny フィルタのみの場合)(今回は前回のコードはそのままに、10行目の”#define HIST”をコメントアウトして、equalizeHist() を使用しないで、Canny フィルタのみで白線検出を行うことにする。なお、Canny フィルタのスレッショルドは、試行錯誤して、最適化したつもりだ)

6月
Vivado HLS を使用した車の白線検出10(ラプラシアンフィルタ1)(Cannyフィルタのロジック量が大きいので、ラプラシアンフィルタに変更したら良好な結果を得た)
Z-turn Board のPS設定をサンプル・プロジェクトからコピーする
Zybot の作製1(構想編)(Zybot を作製しようとしている。Zybot はZYBO を搭載した車といっても本物の車のサイズではなくミニカーの部類だ)
Zybot の作製2(組み立て1)(Zybot 組み立てマニュアルを参照して、Zybot を途中まで組み立ててみた。なお、これは、Zybot の仮組でとりあえずモーターを動かして、車を動かすのを目的とする)
Vivado HLS で PWM モジュールIP を作ってみた(Zybot のモーターコントロール用Hブリッジ回路のPmodの Digilent PmodHB5 を制御するPWM モジュールIP をVivado HLS 2016.1 で作ってみた)
Altera SDK for OpenCL勉強会に行ってきた
レジスタ設定用AXI4 Master IPをVivado HLS で作ってみた(PWM モジュールIP をシミュレーションするために、レジスタ設定用AXI4 Master IPをVivado HLS で作ってみた)
PmodHB5 のセンサー・フィードバック処理IP を作ってみた
Vivado HLS 2016.2 で volatile を使用する場合
Zybot の車輪が回転した(モーター・センサポートのSA, SB の波形有り)
舌下免疫療法(スギ花粉症)
KiCad-4.0.2 のフットプリント作成方法

7月~12月編に続く。

今年は中身が濃い気がするな。。。
  1. 2016年12月30日 07:45 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:0

SDSoC のプラットフォームのお勉強5(ハードウェア・プラットフォームのメタデータファイルを作る2)

SDSoC のプラットフォームのお勉強4(ハードウェア・プラットフォームのメタデータファイルを作る1)”の続き。

前回は、Tcl スクリプトを実行して、SDSoC Vivado Tcl API を読み込んで手順を実行し、ハードウェア・プラットフォームのメタデータファイルを作っていく過程の途中でクロックポートを宣言したところで終了した。今回は、最後の ZYBO_0_163_6.hpfm を生成する所まで行ってみよう。


次はAXI ポートの宣言だ。
まずは、PS からのAXI マスタ・ポートのAXI_GP1 ポートを宣言する。そのフォーマットを示す。

sdsoc::pfm_axi_port
 <pfm ハンドル ($pfm)>
 <AXI ポート名 (M_AXI_GP1)>
 <ポートを含むブロックのインスタンス名 (processing_system7_0)>
 <M_AXI_GP or S_AXI_HP or S_AXI_ACP or MIG (M_AXI_GP)>

M_AXI_GP1 と S_AXI_HP0 を宣言する。
sdsoc::pfm_axi_port $pfm M_AXI_GP1 processing_system7_0 M_AXI_GP
sdsoc::pfm_axi_port $pfm S_AXI_HP0 processing_system7_0 S_AXI_HP

SDx_v2016_3_34_161227.png


AXI4-Stream ポートを宣言する。

sdsoc::pfm_axis_port
 <pfm ハンドル ($pfm)>
 <AXI4-Stream ポート名 (m_axis)>
 <ポートを含むブロックのインスタンス名 (mt9d111_inf_axis_0)>
 <Master or Slave [M_AXIS or S_AXIS] (M_AXIS)>

mt9d111_inf_axis_0 つまりカメラ・インターフェースIP のAXI4-Stream ポートを宣言する。
SDx_v2016_3_37_161227.png

sdsoc::pfm_axis_port $pfm m_axis mt9d111_inf_axis_0 M_AXIS
SDx_v2016_3_38_161227.png


割り込みを宣言する。

sdsoc::pfm_irq

 <pfm ハンドル ($pfm)>

 <irqポート名 (In$i)>

 <ポートを含むブロックのインスタンス名 (xlconcat_0)>

サンプル・コードの通りに書いた。
for {set i 0} {$i < 16} {incr i} {
  sdsoc::pfm_irq $pfm In$i xlconcat_0
}

SDx_v2016_3_39_161227.png


IOデバイスを宣言する。Linux でのUIO フレームワークを使用するときは、デバイスを宣言する必要があるようだ。

sdsoc::pfm_iodev
 <pfm ハンドル ($pfm)>
 <I/Oポート名 (s_axi_lite)>
 <UIOを使用するブロックのインスタンス名 (bitmap_disp_cntrler_axi_master_0)>
 <I/Oデバイスタイプ[uio, kio] (uio)>

sdsoc::pfm_iodev $pfm s_axi_lite bitmap_disp_cntrler_axi_master_0 uio
sdsoc::pfm_iodev $pfm s_axi_lite bitmap_disp_cntrler_axi_master_1 uio
sdsoc::pfm_iodev $pfm s_axi_lite mt9d111_inf_axis_0 uio
sdsoc::pfm_iodev $pfm s_axi_AXILiteS PmodHB5_inf_left uio
sdsoc::pfm_iodev $pfm s_axi_AXILiteS1 PmodHB5_inf_left uio
sdsoc::pfm_iodev $pfm s_axi_AXILiteS PmodHB5_inf_right uio
sdsoc::pfm_iodev $pfm s_axi_AXILiteS1 PmodHB5_inf_right uio
sdsoc::pfm_iodev $pfm S_AXI axi_gpio_0 uio

SDx_v2016_3_40_161227.png
SDx_v2016_3_41_161227.png
SDx_v2016_3_42_161227.png


最後に、ハードウェア・プラットフォームのメタデータファイルを書き込む。

sdsoc::generate_hw_pfm
 <pfm ハンドル ($pfm)>

sdsoc::generate_hw_pfm $pfm
SDx_v2016_3_43_161227.png

このTcl コマンドを実行すると、ディレクトリを指定していないので、デフォルトのディレクトリ(C:\Users\Masaaki\AppData\Roaming\Xilinx\Vivado)にZYBO_0_163_6.hpfm が生成された。
SDx_v2016_3_44_161227.png

ZYBO_0_163_6.hpfm の一部を示す。
SDx_v2016_3_45_161227.png

ZYBO_0_163_6.hpfm を貼っておく。

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<!-- ZYBO_0_163_6.hpfm -->
<xd:repository xmlns:xd="http://www.xilinx.com/xd" xd:name="zybo" xd:library="xd" xd:version="1.0" xd:vendor="marsee">
  <xd:component xd:name="zybo" xd:library="xd" xd:version="1.0" xd:vendor="marsee" xd:type="platform" xd:BRAM="60" xd:DSP="80" xd:FF="35200" xd:LUT="17600">
    <xd:platformInfo>
      <xd:deviceInfo xd:name="xc7z010clg400-1" xd:architecture="zynq" xd:device="xc7z010" xd:package="clg400" xd:speedGrade="-1"/>
      <xd:registeredDevices xd:kio="0" xd:uio="8"/>
      <xd:description>Zynq ZYBO camera</xd:description>
      <xd:systemClocks xd:defaultClock="0">
        <xd:clock xd:name="CPU" xd:instanceRef="processing_system7_0" xd:componentRef="processing_system7" xd:frequency="650.000000" xd:period="1.538462" xd:status="reserved"/>
        <xd:clock xd:name="processing_system7_0_FCLK_CLK0" xd:instanceRef="processing_system7_0" xd:componentRef="processing_system7" xd:id="0" xd:frequency="100.000000" xd:period="10.000000" xd:normalizedPeriod="6.500000" xd:status="changeable"/>
        <xd:clock xd:name="processing_system7_0_FCLK_CLK1" xd:instanceRef="processing_system7_0" xd:componentRef="processing_system7" xd:id="1" xd:frequency="40.000000" xd:period="25.000000" xd:normalizedPeriod="16.250000" xd:status="changeable"/>
        <xd:clock xd:name="processing_system7_0_FCLK_CLK2" xd:instanceRef="processing_system7_0" xd:componentRef="processing_system7" xd:id="2" xd:frequency="35.714283" xd:period="28.000002" xd:normalizedPeriod="18.200001" xd:status="changeable"/>
        <xd:clock xd:name="processing_system7_0_FCLK_CLK3" xd:instanceRef="processing_system7_0" xd:componentRef="processing_system7" xd:id="3" xd:frequency="65.000000" xd:period="15.384615" xd:normalizedPeriod="10.000000" xd:status="changeable"/>
      </xd:systemClocks>
    </xd:platformInfo>

    <xd:parameter xd:name="PCW_USE_M_AXI_GP1" xd:instanceRef="processing_system7_0" xd:componentRef="processing_system7" xd:isValid="count($designComponent/xd:connection/xd:busInterface[@xd:instanceRef=$instance and @xd:name='processing_system7_0_M_AXI_GP1'])>0" xd:value="1"/>
    <xd:parameter xd:name="PCW_USE_S_AXI_HP0" xd:instanceRef="processing_system7_0" xd:componentRef="processing_system7" xd:isValid="count($designComponent/xd:connection/xd:busInterface[@xd:instanceRef=$instance and @xd:name='processing_system7_0_S_AXI_HP0'])>0" xd:value="1"/>

    <xd:parameter xd:name="NUM_PORTS" xd:instanceRef="xlconcat_0" xd:componentRef="xlconcat" xd:isValid="'true'" xd:value="number(count($designComponent/xd:connection/xd:port[@xd:instanceRef=$instance and starts-with(@xd:name,'xlconcat_0_In')])+0)"/>

    <xd:busInterface xd:busTypeRef="aximm" xd:name="processing_system7_0_M_AXI_GP1" xd:instanceRef="processing_system7_0" xd:componentRef="processing_system7" xd:mode="master" xd:dataWidth="32" xd:clockRef="processing_system7_0_M_AXI_GP1_ACLK" xd:busInterfaceRef="M_AXI_GP1" xd:memport="M_AXI_GP"/>
    <xd:busInterface xd:busTypeRef="aximm" xd:name="processing_system7_0_S_AXI_HP0" xd:instanceRef="processing_system7_0" xd:componentRef="processing_system7" xd:mode="slave" xd:dataWidth="64" xd:clockRef="processing_system7_0_S_AXI_HP0_ACLK" xd:busInterfaceRef="S_AXI_HP0" xd:memport="S_AXI_HP"/>

    <xd:busInterface xd:name="mt9d111_inf_axis_0_m_axis" xd:instanceRef="mt9d111_inf_axis_0" xd:componentRef="mt9d111_inf_axis" xd:busTypeRef="axis" xd:mode="master" xd:hasTlast="true" xd:busInterfaceRef="m_axis"/>

    <xd:busInterface xd:busTypeRef="interrupt" xd:name="xlconcat_0_In0" xd:instanceRef="xlconcat_0" xd:componentRef="xlconcat" xd:direction="in" xd:irq="61" xd:busInterfaceRef="In0"/>
    <xd:busInterface xd:busTypeRef="interrupt" xd:name="xlconcat_0_In1" xd:instanceRef="xlconcat_0" xd:componentRef="xlconcat" xd:direction="in" xd:irq="62" xd:busInterfaceRef="In1"/>
    <xd:busInterface xd:busTypeRef="interrupt" xd:name="xlconcat_0_In2" xd:instanceRef="xlconcat_0" xd:componentRef="xlconcat" xd:direction="in" xd:irq="63" xd:busInterfaceRef="In2"/>
    <xd:busInterface xd:busTypeRef="interrupt" xd:name="xlconcat_0_In3" xd:instanceRef="xlconcat_0" xd:componentRef="xlconcat" xd:direction="in" xd:irq="64" xd:busInterfaceRef="In3"/>
    <xd:busInterface xd:busTypeRef="interrupt" xd:name="xlconcat_0_In4" xd:instanceRef="xlconcat_0" xd:componentRef="xlconcat" xd:direction="in" xd:irq="65" xd:busInterfaceRef="In4"/>
    <xd:busInterface xd:busTypeRef="interrupt" xd:name="xlconcat_0_In5" xd:instanceRef="xlconcat_0" xd:componentRef="xlconcat" xd:direction="in" xd:irq="66" xd:busInterfaceRef="In5"/>
    <xd:busInterface xd:busTypeRef="interrupt" xd:name="xlconcat_0_In6" xd:instanceRef="xlconcat_0" xd:componentRef="xlconcat" xd:direction="in" xd:irq="67" xd:busInterfaceRef="In6"/>
    <xd:busInterface xd:busTypeRef="interrupt" xd:name="xlconcat_0_In7" xd:instanceRef="xlconcat_0" xd:componentRef="xlconcat" xd:direction="in" xd:irq="68" xd:busInterfaceRef="In7"/>
    <xd:busInterface xd:busTypeRef="interrupt" xd:name="xlconcat_0_In8" xd:instanceRef="xlconcat_0" xd:componentRef="xlconcat" xd:direction="in" xd:irq="84" xd:busInterfaceRef="In8"/>
    <xd:busInterface xd:busTypeRef="interrupt" xd:name="xlconcat_0_In9" xd:instanceRef="xlconcat_0" xd:componentRef="xlconcat" xd:direction="in" xd:irq="85" xd:busInterfaceRef="In9"/>
    <xd:busInterface xd:busTypeRef="interrupt" xd:name="xlconcat_0_In10" xd:instanceRef="xlconcat_0" xd:componentRef="xlconcat" xd:direction="in" xd:irq="86" xd:busInterfaceRef="In10"/>
    <xd:busInterface xd:busTypeRef="interrupt" xd:name="xlconcat_0_In11" xd:instanceRef="xlconcat_0" xd:componentRef="xlconcat" xd:direction="in" xd:irq="87" xd:busInterfaceRef="In11"/>
    <xd:busInterface xd:busTypeRef="interrupt" xd:name="xlconcat_0_In12" xd:instanceRef="xlconcat_0" xd:componentRef="xlconcat" xd:direction="in" xd:irq="88" xd:busInterfaceRef="In12"/>
    <xd:busInterface xd:busTypeRef="interrupt" xd:name="xlconcat_0_In13" xd:instanceRef="xlconcat_0" xd:componentRef="xlconcat" xd:direction="in" xd:irq="89" xd:busInterfaceRef="In13"/>
    <xd:busInterface xd:busTypeRef="interrupt" xd:name="xlconcat_0_In14" xd:instanceRef="xlconcat_0" xd:componentRef="xlconcat" xd:direction="in" xd:irq="90" xd:busInterfaceRef="In14"/>
    <xd:busInterface xd:busTypeRef="interrupt" xd:name="xlconcat_0_In15" xd:instanceRef="xlconcat_0" xd:componentRef="xlconcat" xd:direction="in" xd:irq="91" xd:busInterfaceRef="In15"/>

    <xd:busInterface xd:busTypeRef="clock" xd:name="processing_system7_0_FCLK_CLK0" xd:instanceRef="processing_system7_0" xd:componentRef="processing_system7" xd:mode="master" xd:busInterfaceRef="FCLK_CLK0"/>
    <xd:busInterface xd:busTypeRef="clock" xd:name="processing_system7_0_FCLK_CLK1" xd:instanceRef="processing_system7_0" xd:componentRef="processing_system7" xd:mode="master" xd:busInterfaceRef="FCLK_CLK1"/>
    <xd:busInterface xd:busTypeRef="clock" xd:name="processing_system7_0_FCLK_CLK2" xd:instanceRef="processing_system7_0" xd:componentRef="processing_system7" xd:mode="master" xd:busInterfaceRef="FCLK_CLK2"/>
    <xd:busInterface xd:busTypeRef="clock" xd:name="processing_system7_0_FCLK_CLK3" xd:instanceRef="processing_system7_0" xd:componentRef="processing_system7" xd:mode="master" xd:busInterfaceRef="FCLK_CLK3"/>
    <xd:busInterface xd:busTypeRef="clock" xd:name="processing_system7_0_M_AXI_GP1_ACLK" xd:instanceRef="processing_system7_0" xd:componentRef="processing_system7" xd:mode="slave" xd:busInterfaceRef="M_AXI_GP1_ACLK"/>
    <xd:busInterface xd:busTypeRef="clock" xd:name="processing_system7_0_S_AXI_HP0_ACLK" xd:instanceRef="processing_system7_0" xd:componentRef="processing_system7" xd:mode="slave" xd:busInterfaceRef="S_AXI_HP0_ACLK"/>

    <xd:busInterface xd:busTypeRef="reset" xd:name="rst_processing_system7_0_100M_peripheral_reset" xd:instanceRef="rst_processing_system7_0_100M" xd:componentRef="proc_sys_reset" xd:mode="master" xd:clockRef="processing_system7_0_FCLK_CLK0" xd:busInterfaceRef="peripheral_reset"/>
    <xd:busInterface xd:busTypeRef="reset" xd:name="rst_processing_system7_0_100M_interconnect_aresetn" xd:instanceRef="rst_processing_system7_0_100M" xd:componentRef="proc_sys_reset" xd:mode="master" xd:clockRef="processing_system7_0_FCLK_CLK0" xd:busInterfaceRef="interconnect_aresetn"/>
    <xd:busInterface xd:busTypeRef="reset" xd:name="rst_processing_system7_0_100M_peripheral_aresetn" xd:instanceRef="rst_processing_system7_0_100M" xd:componentRef="proc_sys_reset" xd:mode="master" xd:clockRef="processing_system7_0_FCLK_CLK0" xd:busInterfaceRef="peripheral_aresetn"/>
    <xd:busInterface xd:busTypeRef="reset" xd:name="proc_sys_reset_0_peripheral_reset" xd:instanceRef="proc_sys_reset_0" xd:componentRef="proc_sys_reset" xd:mode="master" xd:clockRef="processing_system7_0_FCLK_CLK1" xd:busInterfaceRef="peripheral_reset"/>
    <xd:busInterface xd:busTypeRef="reset" xd:name="proc_sys_reset_0_interconnect_aresetn" xd:instanceRef="proc_sys_reset_0" xd:componentRef="proc_sys_reset" xd:mode="master" xd:clockRef="processing_system7_0_FCLK_CLK1" xd:busInterfaceRef="interconnect_aresetn"/>
    <xd:busInterface xd:busTypeRef="reset" xd:name="proc_sys_reset_0_peripheral_aresetn" xd:instanceRef="proc_sys_reset_0" xd:componentRef="proc_sys_reset" xd:mode="master" xd:clockRef="processing_system7_0_FCLK_CLK1" xd:busInterfaceRef="peripheral_aresetn"/>
    <xd:busInterface xd:busTypeRef="reset" xd:name="proc_sys_reset_1_peripheral_reset" xd:instanceRef="proc_sys_reset_1" xd:componentRef="proc_sys_reset" xd:mode="master" xd:clockRef="processing_system7_0_FCLK_CLK2" xd:busInterfaceRef="peripheral_reset"/>
    <xd:busInterface xd:busTypeRef="reset" xd:name="proc_sys_reset_1_interconnect_aresetn" xd:instanceRef="proc_sys_reset_1" xd:componentRef="proc_sys_reset" xd:mode="master" xd:clockRef="processing_system7_0_FCLK_CLK2" xd:busInterfaceRef="interconnect_aresetn"/>
    <xd:busInterface xd:busTypeRef="reset" xd:name="proc_sys_reset_1_peripheral_aresetn" xd:instanceRef="proc_sys_reset_1" xd:componentRef="proc_sys_reset" xd:mode="master" xd:clockRef="processing_system7_0_FCLK_CLK2" xd:busInterfaceRef="peripheral_aresetn"/>
    <xd:busInterface xd:busTypeRef="reset" xd:name="proc_sys_reset_2_peripheral_reset" xd:instanceRef="proc_sys_reset_2" xd:componentRef="proc_sys_reset" xd:mode="master" xd:clockRef="processing_system7_0_FCLK_CLK3" xd:busInterfaceRef="peripheral_reset"/>
    <xd:busInterface xd:busTypeRef="reset" xd:name="proc_sys_reset_2_interconnect_aresetn" xd:instanceRef="proc_sys_reset_2" xd:componentRef="proc_sys_reset" xd:mode="master" xd:clockRef="processing_system7_0_FCLK_CLK3" xd:busInterfaceRef="interconnect_aresetn"/>
    <xd:busInterface xd:busTypeRef="reset" xd:name="proc_sys_reset_2_peripheral_aresetn" xd:instanceRef="proc_sys_reset_2" xd:componentRef="proc_sys_reset" xd:mode="master" xd:clockRef="processing_system7_0_FCLK_CLK3" xd:busInterfaceRef="peripheral_aresetn"/>

    <xd:resourceEstimates xd:BRAM="0" xd:DSP="0" xd:FF="0" xd:LUT="0"/>
  </xd:component>
</xd:repository>



今まで、TCLスクリプトを貼っておく。

source -notrace C:/HDL/Xilinx/SDx/2016.3/scripts/vivado/sdsoc_pfm.tcl

set pfm [sdsoc::create_pfm ZYBO_0_163_6.hpfm]
sdsoc::pfm_name $pfm "marsee" "xd" "zybo" "1.0"
sdsoc::pfm_description $pfm "Zynq ZYBO camera"

sdsoc::pfm_clock $pfm FCLK_CLK0 processing_system7_0 0 true rst_processing_system7_0_100M
sdsoc::pfm_clock $pfm FCLK_CLK1 processing_system7_0 1 false proc_sys_reset_0
sdsoc::pfm_clock $pfm FCLK_CLK2 processing_system7_0 2 false proc_sys_reset_1
sdsoc::pfm_clock $pfm FCLK_CLK3 processing_system7_0 3 false proc_sys_reset_2

sdsoc::pfm_axi_port $pfm M_AXI_GP1 processing_system7_0 M_AXI_GP
sdsoc::pfm_axi_port $pfm S_AXI_HP0 processing_system7_0 S_AXI_HP

sdsoc::pfm_axis_port $pfm m_axis mt9d111_inf_axis_0 M_AXIS

for {set i 0} {$i < 16{incr i{
  sdsoc::pfm_irq $pfm In$i xlconcat_0
}

sdsoc::pfm_iodev $pfm s_axi_lite bitmap_disp_cntrler_axi_master_0 uio
sdsoc::pfm_iodev $pfm s_axi_lite bitmap_disp_cntrler_axi_master_1 uio
sdsoc::pfm_iodev $pfm s_axi_lite mt9d111_inf_axis_0 uio
sdsoc::pfm_iodev $pfm s_axi_AXILiteS PmodHB5_inf_left uio
sdsoc::pfm_iodev $pfm s_axi_AXILiteS1 PmodHB5_inf_left uio
sdsoc::pfm_iodev $pfm s_axi_AXILiteS PmodHB5_inf_right uio
sdsoc::pfm_iodev $pfm s_axi_AXILiteS1 PmodHB5_inf_right uio
sdsoc::pfm_iodev $pfm S_AXI axi_gpio_0 uio

sdsoc::generate_hw_pfm $pfm

  1. 2016年12月28日 05:19 |
  2. SDSoC
  3. | トラックバック:0
  4. | コメント:0

SDSoC のプラットフォームのお勉強4(ハードウェア・プラットフォームのメタデータファイルを作る1)

SDSoC のプラットフォームのお勉強3(ハードウェア・プラットフォームの試作1)”の続き。

前回はハードウェア・プラットフォームを作成するためのVivado 2016.3 のプロジェクトを作った。今回は、Tcl スクリプトを実行して、SDSoC Vivado Tcl API を読み込んで手順を実行し、ハードウェア・プラットフォームのメタデータファイルを作っていこう。

最初に”SDSoC Environment Platform Development Guide UG1146 (v2016.3) November 30, 2016” の40ページ”Chapter 6: Hardware Platform Metadata Creation”を参照のこと。
日本語の資料として、”SDSoC 環境プラットフォームおよびライブラリ UG1146 (v2016.2) 2016 年 7 月 13 日”の12ページの”プラットフォーム ハードウェア記述ファイル”を参照する。

41 ページの SDSoC Vivado Tcl Commands 参照
最初に、/scripts/vivado/sdsoc_pfm.tcl をVivado 2016.3 のTcl コンソールで起動して、次の手順を実行する。
1.ハードウェア・プラットフォームの名前を宣言する。
2.プラットフォームの簡単な説明を定義する。
3.プラットフォームのクロックポートを宣言する。
4.AXI バス・インターフェースを宣言する。
5.AXI4-Stream バス・インターフェースを宣言する。
6.プラットフォームの割り込みを宣言する。
7.ハードウェア・プラットフォームのメタデータファイルを書き込む。

SDSoC のプラットフォームのお勉強3(ハードウェア・プラットフォームの試作1)”のVivado 2016.3 プロジェクトでTcl コンソールを開いて、sdsoc_pfm.tcl を実行するために次のコマンドを入力した。
source -notrace C:/HDL/Xilinx/SDx/2016.3/scripts/vivado/sdsoc_pfm.tcl
SDx_v2016_3_27_161226.png

リターンキーを入力するとコマンドが実行された。
SDx_v2016_3_28_161226.png

最初に、ハードウェア・プラットフォームのメタデータファイルの名前を sdsoc::create_pfm コマンドで指定する。この名前は前回の”SDSoC のプラットフォームのお勉強2”の注意点1.に書いたように”Vivado のプロジェクト名はハードウェア・プラットフォームの名前と一致させる必要がある”ということだ。

SDSoC Vivado Tcl API を使用して、ハードウェア・プラットフォームのメタデータファイルを作っていく。

最初に、ハードウェア・プラットフォームのメタデータファイルを生成する。
set pfm [sdsoc::create_pfm ZYBO_0_163_6.hpfm]
SDx_v2016_3_29_161226.png

ベンダーやライブラリ、プラットフォーム名、バージョンを追加する。
sdsoc::pfm_name $pfm "marsee" "xd" "zybo" "1.0"
SDx_v2016_3_30_161226.png

ハードウエアプラットフォームの説明を追加する。
sdsoc::pfm_description $pfm "Zynq ZYBO camera"
SDx_v2016_3_31_161226.png

次にクロックポートを宣言しよう。

クロックポート宣言のコマンドのフォーマットを示す。

sdsoc::pfm_clock
 <pfm ハンドル($pfm)>
 <クロックポート名(FCLK_CLK0)> 
 <PSのインスタンス名(processing_system7_0)>
 <インスタンス番号(0)>
 <デフォルト・クロックかどうか(true or false)>
 <procesor System Reset のインスタンス名(rst_processing_system7_0_100M)>

FCLK_CLK0 はすでにprocesor System Reset がインスタンスされいて、その名前は rst_processing_system7_0_100M だった。
よって、4つのクロックポートを宣言するTCLスクリプトは以下の通りとなる。
sdsoc::pfm_clock $pfm FCLK_CLK0 processing_system7_0 0 true rst_processing_system7_0_100M
sdsoc::pfm_clock $pfm FCLK_CLK1 processing_system7_0 1 false proc_sys_reset_0
sdsoc::pfm_clock $pfm FCLK_CLK2 processing_system7_0 2 false proc_sys_reset_1
sdsoc::pfm_clock $pfm FCLK_CLK3 processing_system7_0 3 false proc_sys_reset_2

SDx_v2016_3_32_161227.png
  1. 2016年12月27日 07:40 |
  2. SDSoC
  3. | トラックバック:0
  4. | コメント:0

「この世界の片隅に」(映画)を見てきました

この世界の片隅に」(映画)を見てきました。
ほのぼのとしたタッチの中にも戦争や原爆の脅威などが描かれていました。良かったです。最初の10分ほど遅れて見られなかったのが残念です。
最初に見始めた時に「日本昔ばなし」と錯覚しました。
  1. 2016年12月26日 20:37 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

SDSoC のプラットフォームのお勉強3(ハードウェア・プラットフォームの試作1)

SDSoC のプラットフォームのお勉強2”の続き。

前回は、ハードウェア・プラットフォームの作り方を見てきた。今回は、試しにハードウェア・プラットフォームを作成するためにVivado 2016.3 のプロジェクトを作った。

今回使用するのは、ZYBO_0 ブロックデザインをコピー&ペーストして、ZYBO_0_platform_163 フォルダとしたものだ。これには、AXI4-Stream出力のカメラ・コントローラからラプラシアンフィルタIP やガボール・フィルタIP、RGB2HSV変換IP などがストリーム・スイッチを介して接続されているが、それをSDSoC で生成してみようと思う。

ZYBO_0_platform_163 フォルダのVivado 2016.3 プロジェクトを示す。
SDx_v2016_3_20_161226.png

ZYBO_0 ブロックデザインを開いて、mt9d111_inf_axis_0 の m_aixs ポートを空けて、その下のラプラシアンフィルタIP やガボール・フィルタIP、RGB2HSV変換IP、ストリーム・スイッチを削除した。
SDx_v2016_3_21_161226.png

PS をダブルクリックして、設定画面を開き、Page Navigator でInterrupts をクリックし、Interrupt Port のFabric Interrupts にチェックを入れた。その下のPL-PS Interrupt Ports の IRQ_F2P[15:0] にチェックを入れた。
SDx_v2016_3_22_161226.png

PS に戻ると、IRQ_F2P[0:0] ポートが増えていた。
Add IP してConcat を追加した。ポートは入力ポートを 1 個に設定した。
SDx_v2016_3_23_161226.png

FCLK_CLK0 にはProcessor System Rest が付いているので、FCLK_CLK1、FCLK_CLK2、FCLK_CLK3 にProcessor System Rest をAdd IP した。
SDx_v2016_3_24_161226.png

S_AXI_HP0 にカメラ側のDMAがつながっていたのを削除した。
SDx_v2016_3_25_161226.png

全体のブロックデザインを示す。
SDx_v2016_3_26_161226.png

ちょっと複雑すぎるかもしれない?
それに、ソフトウェアから起動を指示するカメラ・インターフェースIP やビットマップ・ディスプレイ・コントローラIP などはどうやって起動すれば良いのだろうか?
もう1つ、DMAする場合にLinux 上でのDMA領域の確保はどうするんだろうか?(たぶん、これは自動的にメモリ帯域をマップしてくれるのだろう?)

さて、次からはTcl スクリプトを使用して、.hpfm ファイル(ハードウェア・プラットフォームのメタデータ)を作っていこう。
  1. 2016年12月26日 05:19 |
  2. SDSoC
  3. | トラックバック:0
  4. | コメント:0

「ローグ・ワン/スター・ウォーズ・ストーリー」と「海賊と呼ばれた男」を見てきました

12月23日に「ローグ・ワン/スター・ウォーズ・ストーリー」を見てきました。面白かったです。ダースベイダー懐かしい。最後には…も出てきましたよ。

今日は、奥さんと「海賊と呼ばれた男」を見てきました。岡田准一さんの演技が凄かったですね。見てよかったです。最後のエピソードは原作にはなかったですね。
  1. 2016年12月25日 20:32 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

SDSoC のプラットフォームのお勉強2

SDSoC のプラットフォームのお勉強1”の続き。

前回はプラットフォームの構成ファイルや構成フォルダを見てきた。今回は、ハードウェア・プラットフォームの作り方を見ていこう。

SDSoC Environment Platform Development Guide UG1146 (v2016.3) November 30, 2016” を参照しながら見ていこう。

SDSoC Environment Platform Development Guide UG1146 (v2016.3) November 30, 2016” の18ページのChapter 3 Hardware Platform Creation のHardware Requirements を引用する。
1.Vivado を使用してハードウェア・システムをビルドして検証する。

2.SDSoC Vivado TCL APIs を使用してTcl スクリプトを生成する。

3.Vivado Tcl コンソールでTcl スクリプトを起動するとハードウェア・プラットフォームのメタデータXMLファイル(.hpfm)が生成される。メタデータにはプラットフォームのクロック、AXI と AXI4-Stream バス・インターフェース、割り込みやその他のハードウェア情報が書かれる。

その次に注意点が書かれている。
1.Vivado のプロジェクト名はハードウェア・プラットフォームの名前と一致させる必要があるようだ。

2.使用するIPはVivado に標準で含まれているIP以外はローカルにVivado プロジェクトに置いておく必要がある。外部のIP参照はダメだそうだ。

3.ブロックデザイン内にPS を含めないとだめだそうだ。

4.SDSoC のハードウェア・ポート・インターフェース、つまり、配線しないでIPからむき出しままのIPのポートはAXI、AXI4-Stream、クロック、割り込みのどれかだそうだ。カスタムバスは自動的にSDSoC で使われることはないので、ブロックデザイン内で完結しておく必要があるようだ。

5.PSで少なくとも1つはAXI マスタ・ポート(GPポート)かAXI マスタ・ポートに接続されているAXI Interconnect IPを作る必要があるそうだ。これらは、SDSoC コンパイラでデータ・ムーバ、アクセラレータIPのソフトウェア制御に使用されるそうだ。
でもZYBOのデフォルト・プラットフォームを見てもAXI マスタポートもAXI Interconnect も無いのはなぜなんだろうか?
ZYBOのデフォルト・プラットフォームはPS から4つのクロックを出力していて、それらに接続されている4つのproc_sys_reset とPS のIRQ_F2P に接続されたConcat だけしかない。

6.少なくとも1つのAXI スレーブ・ポート(HPポート)を作っておく必要があるようだ。それは、SDSoC コンパイラでデータ・ムーバやアクセラレータ IP からのDDR のアクセスに使用される。
これもZYBOのデフォルト・プラットフォームにはない。

7.AXIポートをSDSoC環境と内部ロジックで共有する場合は、AXI Interconnect をつけて、SDSoCのためにポートを開けつつ、若い番号のポートをプラットフォームで使う必要があるそうだ。

8.AXI インターフェースはSDSoC環境によって1つのデータ・モーション・クロックに接続されるそうだ。よくわからないがクロックをつないでくれるということかな?
注記で、アクセラレータIPはプラットフォームとは異なるクロックで動作することがあるようだ。

9.AXI4-Streamインターフェースには、TLAST と TKEEP が必要だそうだ。でもsample にあるzybo_axis_io をみてもどちらも定義されていないけど、大丈夫なのだろうか?

10.各クロックには、個別に Processor System Rest IP を付ける必要があるそうだ。これはデフォルト・プラットフォームでも付いている。

11.割り込み入力は、PS のIRQ_F2P にConcat をつけて、ポートをそのままにしておくそうだ。IRQ_F2P は1ビットで 0 にしておくそうだ。

大体、ハードウェア・プラットフォームの作り方が分かったので、適当にVivado プロジェクトを作って、ハードウェアのメタデータを生成してみよう。
  1. 2016年12月25日 06:12 |
  2. SDSoC
  3. | トラックバック:0
  4. | コメント:2

SDSoC のプラットフォームのお勉強1

SDSoC にはプラットフォームというベースとなるハードウェアとソフトウェアの集合がある。例えば、ハードウェアで言うとHDMI を使用するようなハードウェアをアクセラレーションしたいとすると、SDSoC がどう頑張ってもHDMI をサポートするハードウェアを直接出力することはできない。HDMI を扱うベースとなるハードウェアが必要となる。そのベースのプラットフォームを自由に作りたいと思っている。今回は、”SDSoC Environment Platform Development Guide UG1146 (v2016.3) November 30, 2016” を読みながら、SDSoC のプラットフォームについて勉強していくことにする。なお、ブログ記事は”SDSoC Environment Platform Development Guide UG1146 (v2016.3) November 30, 2016”からの引用となる。

なお、SDSoC 2016.3 からだいぶ変更になったようだ。プラットフォームの構造も変更になっている。2016.2 以前とは互換性がないと思われるので注意されたい。

まずは、構成ファイルを示す。
・メタデータファイル
 ・プラットフォーム・トップレベル記述ファイル(Platform top-level description file (.xpfm) )手書きで書くそうだ
 ・プラットフォーム・ハードウェア記述ファイル(Platform hardware description file (.hpfm))Vivado からTCLスクリプトで生成
 ・プラットフォーム・ソフトウェア記述ファイル(Platform software description file (.spfm))手書きで書くそうだ

・Vivado プロジェクト
 ・Vivado プロジェクトファイル
 ・ソース
 ・制約
 ・IPブロック

・ソフトウェア・ファイル
 ・ライブラリ・ヘッダ・ファイル(オプション)
 ・スタティック・ライブラリ(オプション)
 ・共通のブート・ファイル
  ・u-boot.elf, fsbl.elf
  ・bif ファイル(ブートイメージを生成したときに生成される)
  ・readme ファイル
 ・Linux 関連ファイル
  ・u-boot.elf(ブート・ファイルで書いたが)、デバイスツリー、ラムディスク・イメージ(image.ub)
 ・予めビルドされたハードウェア・ファイル(オプション)
  ・ビットストリーム
  ・SDKのエクスポートされたハードウェア・ファイル(hdf ファイル)
  ・予め生成されたポート情報ソフトウェア・ファイル(portinfo.c, portinfo.h)
  ・予め生成されたハードウェア・ソフトウェア・インターフェース・ファイル

プラットフォームのフォルダ構成の図を示すために、”SDSoC Environment Platform Development Guide UG1146 (v2016.3) November 30, 2016”の7ページのFigure 2: Directory Structure for a Typical SDSoC Platform を引用させて頂く。
SDx_v2016_3_8_161223.png
なお、HW Platform File の platform_hpfm は、platform.hpfm の間違いだと思う。

SDSoC Environment Tutorial: Creating a Platform from a Reference Design (UG1236)があるようだが、まだリリースされていない。。。残念。。。

さて、それでは、SDSoC のプラットフォームがどのようなファイル構造になっているのかを見てみよう。

Xilinx\SDx\2016.3\platforms にプラットフォームが並んでいるが、そのうちのzybo を見ていこう。
SDx_v2016_3_9_161223.png

zybo フォルダの中は、hw、sw フォルダとzybo.xpfm ファイルがある。
SDx_v2016_3_10_161223.png

hw フォルダに入ると、vivado フォルダと zybo.hpfm があった。
SDx_v2016_3_11_161223.png

vivado フォルダの下は、zybo.srcs (ソースのフォルダ)と zybo.xpr (Vivadoのプロジェクトファイル)、zybo_pfm.tcl があった。
SDx_v2016_3_12_161223.png

次は、sw フォルダに行ってみよう。
SDx_v2016_3_13_161223.png

aarch32-none、boot、freetos、image、prebuilt_platform、qemu の各フォルダと、zybo.spfm があった。

aarch32-noneフォルダに行くと、lscript.ld があった。
SDx_v2016_3_14_161223.png

boot フォルダ。
SDx_v2016_3_15_161223.png

freertos フォルダ。
SDx_v2016_3_16_161223.png

image フォルダ。
SDx_v2016_3_17_161223.png

prebuild_platform フォルダ。
SDx_v2016_3_18_161223.png

qemu フォルダ。
SDx_v2016_3_19_161223.png
  1. 2016年12月24日 04:33 |
  2. SDSoC
  3. | トラックバック:0
  4. | コメント:0

Vivado HLSのビデオ プロセッシング関数を使用したOpenCVのFPGAアクセラレーション

この記事は”OpenCV Advent Calendar 2016”の23日目の記事として書きます。

1.FPGAのツールについて
FPGAを知らないという方も多いと思うので、ツールについて説明したいと思います。
Xilinx 社のFPGA 用のツールとしてVivado Design Suite - HLx Edition (通称 Vivado) というツールがあります。これでFPGA を開発するわけです。通常はハードウェア記述言語(HDL)という専用の言語を使います。HDL言語の 2 大勢力としてVerilog HDLとVHDL があります。ですが、最近は高位合成ということで、C, C++, Python, Jave などからHDLを合成できるツールが出てきました。そのうちのC, C++ を使ってHDL を合成するツールがVivado にもあります。Vivado HLS です。
なお、Vivado と Vivado HLS は、デバイス限定ではありますが、無料です。だれでも気軽に始められますよ。

2.Vivado HLS(高位合成ツール)
正確に書くとVivado HLS はC, C++ 言語の記述をHDLに変換して、Vivado のIP を作ります。そのIP をVivado にインポートし、Vivado のIP インテグレータのブロックデザイン上にインスタンスして使用します。(CやC++でどこが高位なのかという疑問があると思いますが、ハードウェアはHDLレベルなので、動作を書けるCやC++ でも高位な言語となります)
また、Xilinx 社のFPGAチップとして、Zynq というチップが出ていますが、これはARMプロセッサのCortex-A9 x2 +FPGAが搭載されているチップです。Zynq を使用するとC やC++ でOpenCV でソフトウェアとして書いて実行もできますし、ハードウェアに落としてアクセラレーションすることもできます。ただし、OpenCV のコードはハードウェアに独自のライブラリを使っているため一部書き換えが必要です。

Vivado HLS についての資料は”Vivado Design Suite ユーザー ガイド 高位合成 UG902 (v2016.3) 2016 年 10 月 5 日”をご覧ください。215ページの「ビデオ プロセ ッ シング関数」にOpenCV ライブラリのことが記述されています。
Accelerating OpenCV Applications with Zynq-7000 All Programmable SoC using Vivado HLS Video Libraries XAPP1167 (v3.0) June 24, 2015”に使用例が書いてあります。
もう1つの情報源はXilinx のWiki の”HLS Video Library”です。
Xilinx のCommunity Forum も参考になります。
とにかく情報が少なく、どのような構造になっているのかが、よくわからないのが欠点です。

3.Xilinx社のHLS ビデオライブラリのWikiの内容
Xilinx のWiki の”HLS Video Library”からの引用です。日本語はGoogle翻訳を使用します。
Vivado HLS のHLS ビデオライブラリには、以下に示すライブラリ関数があります。

Video Library Data Structures
HLS Video Libraryには、イメージ、ピクセルなどの基本的なデータ構造を表現するためのテンプレートクラスがいくつか用意されています。これらの名前と使用方法のほとんどは、OpenCVに似ており、FPGAの特殊化と最適化があります。
 hls :: Mat <ROWS、COLS、T>
 hls :: Scalar <N、T>
 hls :: Window <ROWS、COLS、T>
 hls :: LineBuffer <ROWS、COLS、T>

OpenCV interface functions
 IplImage2AXIvideo
 AXIvideo2IplImage
 cvMat2AXIvideo
 AXIvideo2cvMat
 CvMat2AXIvideo
 AXIvideo2CvMat
 IplImage2hlsMat
 hlsMat2IplImage
 cvMat2hlsMat
 hlsMat2cvMat
 CvMat2hlsMat
 hlsMat2CvMat
 CvMat2hlsWindow
 hlsWindow2CvMat

AXI4-Stream I/O Functions
 hls :: AXIvideo2Mat
 hls :: Mat2AXIvideo

Video Processing Functions
 hls::AbsDiff
 hls::AddS
 hls::AddWeighted
 hls::And
 hls::Avg
 hls::AvgSdv
 hls::Cmp
 hls::CmpS
 hls::CornerHarris
 hls::CvtColor
 hls::Dilate
 hls::Duplicate
 hls::EqualizeHist
 hls::Erode
 hls::FASTX
 hls::Filter2D
 hls::GaussianBlur
 hls::Harris
 hls::HoughLines2
 hls::Integral
 hls::InitUndistortRectifyMap
 hls::Max
 hls::MaxS
 hls::Mean
 hls::Merge
 hls::Min
 hls::MinMaxLoc
 hls::MinS
 hls::Mul
 hls::Not
 hls::PaintMask
 hls::Range
 hls::Remap
 hls::Reduce
 hls::Resize
 hls::Set
 hls::Scale
 hls::Sobel
 hls::Split
 hls::SubRS
 hls::SubS
 hls::Sum
 hls::Threshold
 hls::Zero


4.Vivado HLS の操作手順について
これからのXilinx社の高位合成ツールのVivado HLS について簡単に説明します。
Vivado HLSのファイルはテストベンチとソースに分けられます。Vivado HLSのファイル構成や手順を図 1 に示します。
Vivado_HLS_OpenCV_1_161219.png
図 1 Vivado HLSのファイル構成や手順

テストベンチが main() 関数があるところで、main() からハードウェア化する関数を呼び出して使用します。テストベンチとハードウェア関数は別のファイルで、それぞれ、Vivado HLS のTest Benchフォルダ、Sourcesフォルダにから関連付けされています。その様子を図 2 に示します。
Vivado_HLS_OpenCV_2_161219.png
図 2 Vivado HLS 画面

図 2 で、Sourcesフォルダの opencv_ex_ug.cpp がハードウェア化する関数のファイルで、opencv_ex_ug_tb.cpp がテストベンチです。

図 1 に話を戻すと、ハードウェア関数はCコードの合成を行って、HDLに落とされます。次にIP 化を行って、Vivado で使えるようになります。
この辺りは、話せば相当長くなるので、省略します。

つまり何が言いたかったかというと、ソフトウェアでも実装できて、最初にソフトウェアで動作を確認して、そのままハードウェアに落とすことができます。Vivado_HLS のOpenCVライブラリは通常のOpenCVと違うところもあるので、そのままというわけにはいきませんが、ほとんど同じにできます。
ハードウェアにすると、性能が向上するか?という疑問があると思いますが、ハードウェアに適した課題で、しかもハードウェアに合わせてコードを最適化したり、指示子(ディテクティブ、プラグマで書きます)を適切に追加する必要があります。今のところは、FPGAの構造を熟知していないとチューニングは難しいかもしれません?

5.例1 Sobelフィルタ
それでは実際のC コードを見ていきましょう。最初にSobel フィルタのコード例です。

Vivado HLS 2015.4 で OpenCV を使ってみた3(Sobelフィルタを試した1)

ここでは、シミュレーションだけを行っていて、実機では動作させていません。

6.Vivado HLS のC シミュレーションとC/RTL協調シミュレーション
Vivado HLS にはC シミュレーションとC/RTL協調シミュレーションの2つのシミュレーションがあります。C シミュレーションは普通にC ソースコードをコンパイルして実行します。これは普通のVisual Studio とかでやっているのと同じ普通のC の実行です。
もう1つのC/RTL協調シミュレーションは、ハードウェア化する関数をハードウェアとしてHDL に合成した後に動作を確かめるためにRTL シミュレーター(HDLをテストするシミュレーターです)とC のテストベンチを連動させてシミュレーションするものです。この場合に、HDL にしたときのデータの同一性をチェックするためにテストベンチでOpenCVを使用して処理したデータとRTL シミュレーターの出力データを比較しています。今のところテストベンチはそのように記述されています。図 3 にC/RTL協調シミュレーションのブロック図を示します。
Vivado_HLS_OpneCV_3_161220.png
図 3 C/RTL協調シミュレーションのブロック図1

OpenCV では、値が一致しないこともあるので、(近い値になっています)その場合は異常終了しないようにしています。
また、FPGAに落とす場合は、浮動小数点演算のコストが大きく、膨大なリソースを使用するため浮動小数演算を固定小数点演算にする場合が多いです。その場合の誤差を計測するためにもシミュレーションを使用します。その場合のブロック図を図 4 に示します。
Vivado_HLS_OpneCV_4_161220.png
図 4 C/RTL協調シミュレーションのブロック図2

7.例2 FASTXコーナー検出
OpenCV のFAST コーナー検出器のHLS ビデオライブラリ版のFASTX コーナー検出器を確かめてみたのがこの記事です。

FASTX コーナー検出の改良3(threshold をソフトウェアで変更可能にする)

ここでは、800 x 600 ピクセルの画像で、リアルタイムにFASTX コーナー検出を行っています。レポートを見ると、

FASTX コーナー検出IP は 280 MHz まで動作するというレポートが出ているので、HD 解像度の 148.5 MHz も問題なくできると思う。そのようにすればHD解像度で、60 fps のFASTX コーナー検出ができると思う。

という結論になりました。かなりの性能が出ていると思われます。

その他、Vivado HLS の記事は、Vivado HLS をご覧ください。

8.実例 ミニロボットカーによる自動走行例
Vivado HLS のHLS ビデオライブラリを使用したハードウェア+ソフトウェアによる白線追従走行の様子です。カメラを使用した画像解析で白線の間を走っています。


次に同様に、Vivado HLS のHLS ビデオライブラリを使用したハードウェア+ソフトウェアによるマーカーを使用した隊列走行の様子です。



  1. 2016年12月23日 03:30 |
  2. OpenCV
  3. | トラックバック:0
  4. | コメント:0

Zynq 用SDx v2016.3 を使ってみる1

SDSoC 2016.3 が出ているが、名前が変更されて、SDAccel と SDSoC が統合されてSDx になったようだ。Zynq 用のSDx が SDSoC なんだと思う。

さて、SDx v2016.3 を起動してみた。下の図に示す。すでにlap_filter2 プロジェクトはSDx v2016.3 にコンバートされている。
SDx_v2016_3_1_161222.png

lab2 のプロジェクトをSDSoC からSDx にコンパーとしてみよう。SDx v2016.3 にコンバートするには、SDSoC のproject.sdsoc を右クリックし、右クリックメニューからConvert SDSoC Project を選択する。
SDx_v2016_3_2_161222.png

すると、SDx のプロジェクトにコンバートされる。
SDx_v2016_3_3_161222.png

lap_filter2 プロジェクトに戻ってハードウェア化しない状態で、いったんビルドしてみよう。
ビルドできた。あまり変化がないので図は貼らない。

次に、ハードウェア化する関数に、lap_filter_axim() を指定しよう。
SDx v2016.3 では、Add HW Functions... ボタンでハードウェア化する関数を指定する。
SDx_v2016_3_4_161222.png

Add HW Functions ダイアログで、lap_filter_axim() を選択する。
SDx_v2016_3_6_161222.png

これで、トンカチ・ボタンをクリックして、ビルドしてみた。
ビルドが成功した。
SDx_v2016_3_7_161222.png
  1. 2016年12月22日 05:31 |
  2. SDSoC
  3. | トラックバック:0
  4. | コメント:0

Vivado 2016.2 からVivado 2016.4 へアップグレード

昨日、Vivado 2016.4 が出たので、インストールを行った。

Vivado 2016.4 をインストールしたので、超音波距離センサで使っていたZYBO_0_162_7 フォルダのプロジェクトをVivado 2016.2 からVivado 2016.4 にアップグレードしてみることにした。Vivado 2016.2 から Vivado 2016.3 へのアップグレードは失敗しているので慎重に進めた。

まずは、ZYBO_0_162_7 フォルダのプロジェクトをコピー&ペーストして、ZYBO_0_164_7 フォルダと名前を変えた。

プロジェクトファイル xpr ファイルをダブルクリックして起動するとVivado 2016.4 が立ち上がった。

IP のアップグレードを行った。
Vivado_2016_4_ZYBO_0_1_161220.png

このまま、ビットストリームの生成を行った。やはり、リソース使いすぎエラーが出た。Vivado 2016.3 と同じようだ。この辺は直す気がないのかな?
Vivado_2016_4_ZYBO_0_2_161220.png

まずは、ブロックデザインを作り直してみようと思う。ブロックデザインをTCLスクリプトにエクスポートしてから、いったん削除して、TCLスクリプト起動して再度作り直してみよう。

File メニューからExport -> Export Block Design を選択してTCLスクリプトを作成する。
Vivado_2016_4_ZYBO_0_3_161220.png

Export Block Design ダイアログ。
Vivado_2016_4_ZYBO_0_4_161220.png

これでTCLスクリプトがエクスポートしできたので、ZYBO_0_wapper.v とZYBO_0 ブロックデザインを削除しよう。その2つを選択して、右クリックメニューからRemove File form Project... を選択した。
Vivado_2016_4_ZYBO_0_5_161220.png

Remove Sources ダイアログで、Also delete project local files/directories from disk にチェックを入れておくとファイルもディスクから消してくれる。
Vivado_2016_4_ZYBO_0_6_161220.png

さて次にTCLスクリプトを起動してZYBO_0 ブロックデザインを作成する。
Tcl Console を選択して、 cd でプロジェクトのあるフォルダに移動する。
Vivado_2016_4_ZYBO_0_7_161220.png

次に source ZYBO_0.tcl コマンドでZYBO_0 ブロックデザインを再生成する。
Vivado_2016_4_ZYBO_0_8_161220.png

無事にブロックデザインが再生成された。
Vivado_2016_4_ZYBO_0_9_161220.png

Address Editor も前のままだ。
Vivado_2016_4_ZYBO_0_10_161220.png

これでビットストリームの生成を行ったところ、同様のエラーになってしまった。
やはりだめか。。。それじゃ、AXI4-Lite 用のAXI Interconnect を作り直してみよう。

AXI4-Lite 用のAXI Interconnect を削除した。
Vivado_2016_4_ZYBO_0_11_161220.png

Run Connection Automation をクリックして、表示されたダイアログで、All Automation をチェックした。
Vivado_2016_4_ZYBO_0_12_161220.png

AXI4-Lite 用のAXI Interconnect が生成された。
Vivado_2016_4_ZYBO_0_13_161220.png

しかし、Address Editor のアドレスが変わっているので、修正した。最初にアドレスがかち合うと変更できないので、すべて43DX_0000 に変更してから、以前のアドレスに修正した。
Vivado_2016_4_ZYBO_0_14_161220.png

修正後にビットストリームの生成を行った。成功した。
Vivado_2016_4_ZYBO_0_15_161220.png

最初のブロックデザインの再生成が無駄か?というと、そうではない。実は、前に一度Vivado 2016.2 から Vivado 2016.4 へのアップグレードをやっていて、逆の手順でやったのだが、AXI4-Lite 用のAXI Interconnect を消してから再度生成しても、違うエラーが出てしまっていた。それでブロックデザインを消して、再生成したのだった。

ハードウェアをエクスポートして、SDKを立ち上げて、アプリケーション・プロジェクトを作り直した。
Vivado_2016_4_ZYBO_0_16_161220.png

これで、最初はベアメタル・アプリケーションでテストしたが、GDB でRun してもエラーが出てRun できなかった。System Debugge を選択しないとRun ができなかった。

SDK でFSBL を作り、BOOT.bin を作成した。devicetree.dtb はそのままで、Micro SD カードの BOOT.bin だけ入れ替えて、ZYBO に挿入して電源ON した。Ubuntu 上でも超音波距離センサのアプリケーションが起動して正常に距離を測定できた。カメラも表示できたので、完璧だ。
これでVivado 2016.2 からVivado 2016.4 にアップグレードできたようだ。
  1. 2016年12月21日 04:56 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:0

Zybot に超音波距離センサを搭載する10(Zybot に取り付けた)

Zybot に超音波距離センサを搭載する9(IP のUIO番号を確認)”の続き。

前回までで、超音波距離センサ・インターフェースIP の動作が確認できて、Linux のUIO ドライバを使えるように設定した。今回は、Zybot に超音波距離センサを搭載して、Linux 上で動作を確認した。

まずは、超音波距離センサをユニバーサル基板に搭載してピンヘッダを付けた。ピンヘッダからブレッドボード・ジャンパーコード(オス-メス)でZYBO のPmod JB まで接続した。ジャンパーコードの色は変えてある。+3.3V は赤、GND は黒、SIG は青にしてある。
その取り付けや接続の様子を写真で示す。
Ultrasonic_senser_inf_73_161220.jpg

Ultrasonic_senser_inf_74_161220.jpg

これで前回作ったBOOT.bin と devicetree.dtb をMicro SD カードに入れて、ZYBO に挿入して電源をON して、Ubuntu 14.04 を起動した。
Zybot ディレクトリの下にultrasonic_sensor ディレクトリを作って、cam_disp_plat などを入れた。隊列走行の時とは、超音波距離センサのエントリがデバイスツリーに増えただけなので、そのままカメラを表示することができた。
Ultrasonic_senser_inf_71_161219.png

その下に、us_sensor_test ディレクトリを作成した。us_sensor_test.c を作成して、gcc -o us_sensor_test us_sensor_test.c でコンパイルした。us_sensor_test が生成された。
Ultrasonic_senser_inf_72_161219.png

./us_sensor_test でアプリケーションを起動すると、距離を測定することができた。
Ultrasonic_senser_inf_70_161219.png

us_sensor_test.c を示す。

// us_sensor_test.c
// 2016/12/19 by marsee
// 

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

#include "xultrasonic_sensor_inf.h"

void main(){
    int fd16;
    volatile unsigned int *ultrasonic_sensor_inf_0;
    int ret_val;
    float measure;
    
    // ultrasonic_sensor_inf_0 (UIO 16)
    fd16 = open("/dev/uio16", O_RDWR); // ultrasonic_sensor_inf_0 interface AXI4 Lite Slave
    if (fd16 < 1){
        fprintf(stderr, "/dev/uio16 (ultrasonic_sensor_inf_0) open error\n");
        exit(-1);
    }
    ultrasonic_sensor_inf_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd16, 0);
    if (!ultrasonic_sensor_inf_0){
        fprintf(stderr, "ultrasonic_sensor_inf_0 mmap error\n");
        exit(-1);
    }
    
    while(1){
        usleep(200000); // 200 ms
        
        ultrasonic_sensor_inf_0[0] = 0x1// ap_start = 1
        
        while((ultrasonic_sensor_inf_0[0] & 0x2) == 0// wait ap_done
            usleep(500); // 5 us
            
        if(ret_val = (int)ultrasonic_sensor_inf_0[4]) // 0x10 : Data signal of ap_return
            printf("Error: %d\n", ret_val);
        
        measure = (float)ultrasonic_sensor_inf_0[6] * 0.000342 / 2.0// 0x18 : Data signal of count_val
        printf("Distance is %.2f cm\n", measure);
    }
    munmap((void *)ultrasonic_sensor_inf_0, 0x10000);
    close(fd16);
}



これで、超音波距離センサ・インターフェースIP をLinuxからも使うことができた。
  1. 2016年12月20日 04:29 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

第2回FPGAスタートアップセミナーに参加しました

昨日は第2回FPGAスタートアップセミナーに参加しました。
そこでライトニング・トークをさせていただきました。第1回でFPGAの部屋のブログを宣伝していただいたということなので、より詳しい情報をお知らせしたかったためです。
ライトニング・トークのスライド”FPGAの部屋、slide share、xilinxツールのご紹介”をSlideShareで公開しました。
一部、まずい部分は修正させていただきました。後、会場で聞かれた点を加筆しました。
ライトニング・トークは10分の予定が20分近くしゃべらせて頂いたような。。。実際のツール(Vivado と Vivado HLS)もご紹介しました。
懇親会も途中まで参加させて頂いて、楽しい時間を過ごせました。皆さん、そして会場を提供頂いたサイボウズ様、ありがとうございました。とっても素敵な会場でした。
  1. 2016年12月19日 04:36 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:0

Xilinx 社のマイクロプロセッサまとめ3(Zynq)

Xilinx 社のマイクロプロセッサまとめ2(MicroBlaze)”の続きです。

ハードウェア開発、CPUアーキテクチャ Advent Calendar 2016”の18日目の記事として書きます。

前回は、MicroBlaze について書いてみました。今回はXilinx のZynq チップについて書きたいと思います。
まずは、Zynq の資料としては、なんといっても”Zynq-7000 All Programmable SoC テクニカル リファレンス マニュアル UG585 (v1.10) 2015 年 2 月 23 日”です。1780ページもありますが、目を通しておきましょう。。。

前回まではソフトマクロのプロセッサ、つまり、FPGA のロジックセルで構成されるプロセッサでしたが、今回のZynq はARMのCortex A9 x 2 個がハードマクロとして、搭載されているXilinx 社のFPGA チップというか、ARMプロセッサ + おまけのFPGA チップです。
MicroBlaze が最高動作周波数が 200 MHz 程度(7 シリーズ)なのに比べて、ZYBOボードの -1 グレードのCortex A9 でも 650 MHz で動作します。この本のコラムによると10 倍程度の性能差があるということです。私もそう思います。Linuxも実用的なスピードで使用することができます。Zynq 上のUbuntu 14.04 を使っていますが、これで開発もしています。私はARMプロセッサのパワーとそれに連帯するFPGAが便利で、最近はZynqばかり使っています。ソフトウェアで十分でないところは、Vivado HLS(C、C++ 言語ベースの高位合成ツール)を使って、すぐにハードウェアにオフロードして、ソフトウェアと連帯してシステムを構成することが容易にできます。
なお、私が今書いているZynq は7 シリーズのAll Programmable SoC ですが、更に進化して、Cortex A53が2個または4個、Cortex R5が2個搭載されたMPSoC もあります。MPSoCはやっと一般的に買えるようになってきました。私は、まだ持っていませんが。。。

前置きが長くなりましたが、Zynq のブロック図を図 1 に示します。
Zynq_block_zu_161217.png
  図 1 Zynq ブロック図

図 1 で、PSが Cortex-A9 x 2 があるProcessing System です。Cortex-A9 はFPU のNEON、MMU、I-Cache、D-Cache と一緒にApplication Processing Uinit にあります。512 KB の L2 Cache も搭載されいます。その先には、Memory Controllerがあって、ZYBO だと 512MB のDDR3 SDRAMが載っています。
また、PS の左側にはいろいろなI/O Peripheral があって、モジュールを選択することができます。そして、選択されたモジュールの入出力をMIO にアサインします。I/O Peripheral が何を持っているか?は図を見ると一目瞭然ですが、必要とされるI/Oが一通りそろっています。SDカードのインターフェースもあって、ZYBO にもMicro SDカードのコネクタがついています。Micro SDカードに、Linuxのブートイメージを入れておいてLinuxをブートします。
また、Memory Interface としてはSRAM やQ-SPI のインターフェースなどがあります。

PSとFPGA部分のPL(Programmable Logic) とは、AXIバスで接続されています。主にFPGA上のIP の設定レジスタなどを接続するGeneral-Purpose Ports(GPポート)、FPGAからSDRAMなどをアクセスするためのHigh-Performance (HPポート)、キャッシュにアクセスできるACPポートなどがあります。

奥が深いZynq ですが、Vivado でIP を作って、使う例としては私の書いた”Vivado and zybo linux勉強会資料3”をご覧ください。

さて、Vivado 2016.3 のIP インテグレータでPS をインスタンスしてみましょう。
その前に、Zynqを搭載しているボードがどのようなIOの構成になっているかを知らせるための設定ファイルが必要です。それが、ボードファイルです。それが無ければ、自分ですべて設定する必要があります。
ボードファイルはZynqボードだけでなく、普通のFPGAのボードにも対応しています。例えば、Digiletnt社のボードはボードファイルをダウンロードして使用することができます。詳しくは、”Digilent社のボード・ファイルのインストール”をご覧ください。

ZYBOボードのプロジェクトを作成します。
Zynq のPS を使うためにはIPインテグレータのブロックデザインを作る必要があります。Create Block Design をクリックします。
zynq_test_2_161217.png

Design name に適当な名前(ここでは、zynq_test にしました)を入れて、OKボタンをクリックします。
zynq_test_3_161217.png

Diagram ウインドウができます。そこで、Add IP ボタンをクリックします。
zynq_test_4_161217.png

Search に zynq と入れると、ZYNQ7 Processing System が出てくるので、それをダブルクリックします。
zynq_test_5_161217.png

processing_system7_0 が生成されました。Run Block Automation をクリックします。この時点では、ZYBOボードの設定は反映されていません。
zynq_test_6_161217.png

Run Block Automation ダイアログが表示されます。Apply Board Preset にチェックが入っているとボードファイルの設定情報が反映されるようです。(AR# 58425 2013.3 Vivado IP インテグレーター - Processing System 7 (PS7) IP ブロックでプロジェクトのボード設定に基づいてボード設定が自動入力されない(AR# 58425 2013.3 Vivado IP インテグレーター - Processing System 7 (PS7) IP ブロックでプロジェクトのボード設定に基づいてボード設定が自動入力されない
zynq_test_7_161217.png

DDRとFIXED_IO にポートが出て、ボードファイルの設定が反映されて、processing_system7_0 のポートが増えました。
zynq_test_8_161217.png

processing_system7_0 をダブルクリックするとIOなどの設定が見えるので、見てみましょう。
Zynq Block Design ページです。
ここでは、グラフィカルにPS の設定を確認することができます。使うI/O Peripheral にチェックがついているのが分かります。
zynq_test_9_161217.png

PS-PL Configuration では、UARTのボーレートやFPGA とのデータのやり取りに使用するGPポート、HPポート、ACPポートの設定などあります。
zynq_test_10_161217.png

Peripheral I/O Pins では、MIOピンの設定を行います。どのPeripheral を有効にするかを設定します。有効にしたPeripheral はMIOピンを使用します。同じMIOピンを使用するPeripheral は排他的に使用します。
zynq_test_11_161217.png

MIO Configuration はどのPeripheral がどのMIO ピンを使用するのか?をリストで表した表です。
zynq_test_12_161217.png

Clock Configuration はクロックの設定を行います。PL Fabric Clocks がPL つまりFPGA部に回すことができるクロックです。
zynq_test_13_161217.png

DDR Configuration はその名の通り、DDR SDRAMのパラメータを設定します。
zynq_test_14_161217.png

SMC Timing Caluclation です。これはよくわかりませんがメモリの設定でしょうか?
zynq_test_15_161217.png

最後にInterrupts 割り込みの設定です。
zynq_test_16_161217.png

これでPS の設定画面は終わりです。それでは、FPGA 上のIP の AXI GPIO をPS につないでみましょう。こうすると、PL(FPGA)とPS(Cortex-A9 )の接続方法が良くわかると思います。

右クリックし、右クリックメニューからAdd IP を選択し、Search にgpio と入力すると AXI GPIO が示される。それをダブルクリックする。
zynq_test_17_161217.png

axi_gpio_0 がインスタンスされた。Run Block Automation をクリックすると配線される。
zynq_test_18_161217.png

Run Block Automation ダイアログが表示されます。All Automation にチェックを入れて、OK ボタンをクリックします。
zynq_test_19_161217.png

必要なIP がインスタンスされて、配線も自動でされました。
zynq_test_20_161217.png

processing_system7_0 を見ると、M_AXI_GP0 ポートからAXI Interconnect に配線され、そこから axi_gpio_0 にAXIバスが配線されています。このM_AXI_GP0 ポートが図 1 のところで説明したGeneral-Purpose Ports(GPポート)です。
なお、processing_system7_0 以外の箱は、PL(FPGA)にインスタンスされるIP を表します。つまりFPGA部分をVivado のIP インテグレータで作っています。
  1. 2016年12月18日 04:23 |
  2. FPGAのマイクロプロセッサ
  3. | トラックバック:0
  4. | コメント:0

Zybot に超音波距離センサを搭載する9(IP のUIO番号を確認)

Zybot に超音波距離センサを搭載する8(ZYBO_0_162_7 に 2 つのIP を追加2)”の続き。

前回は、超音波距離センサ・インターフェースIP が完成して、SDKからベアメタル・アプリケーションで動作を確認した。今回は、BOOT.bin と devicetree.dtb を作成して、SDカードに書き込み、ZYBO で UIO としての動作を確認する。

まずはSDK でFSBL を作成した。

FSBL のアプリケーション・プロジェクトで、右クリックし、右クリックメニューから Create Boot Image を選択して、BOOT.bin を作成した。
Ultrasonic_senser_inf_64_161217.png

BOOT.bin が作成された。
Ultrasonic_senser_inf_65_161217.png

VirtualBox 上のUbuntu 14.04 で、drivers_ZYBO_0_162_6 を drivers_ZYBO_0_162_7 にコピーして、zynq-zybo.dts に ultrasonic_sensor_inf_0 のエントリを追加した。
Ultrasonic_senser_inf_66_161217.png

dtc -I dts -O dtb -o devicetree.dtb zynq-zybo.dts コマンドで devicetree.dtb が生成された。
Ultrasonic_senser_inf_67_161217.png

BOOT.bin と devicetree.dtb をZYBO_BOOT のMicro SD カードに書き込んで、ZYBO にセットし、電源ON。

/sys/devices/amba.0 に行くと、ultrasonic_sensor_inf_0 のエントリがあった。
Ultrasonic_senser_inf_68_161217.png

ultrasonic_sensor_inf_0 は uio16 だった。
Ultrasonic_senser_inf_69_161217.png
  1. 2016年12月17日 05:42 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

Zybot に超音波距離センサを搭載する8(ZYBO_0_162_7 に 2 つのIP を追加2)

Zybot に超音波距離センサを搭載する7(ZYBO_0_162_7 に 2 つのIP を追加)”の続き。

前回はVivado HLS 2016.3 の Ultrasorinc_sensor_inf IP とussensor_iobuf IP をZYBO_0_162_7 フォルダのプロジェクトのブロックデザインに追加して、論理合成、インプリメント、ビットストリームの生成を行った。
今回は、SDKでアプリケーション・ソフトウェアを作成して、ZYBO でテストを行った。

SDKで、ultrasonic_sensor_inf アプリケーション・プロジェクトを作成して、ultrasonic_sensor.c を作成した。
Ultrasonic_senser_inf_59_161216.png

ultrasonic_sensor.c を示す。

// ultrasonic_sensor.c
// 2016/12/14 by marsee
//

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "xil_io.h"
#include "xparameters.h"

#include "xultrasonic_sensor_inf.h"

int main(){
    XUltrasonic_sensor_inf uss_inf;
    int ret_val;
    float measure;
    
    XUltrasonic_sensor_inf_Initialize(&uss_inf, 0);
    
    while(1){
        usleep(200000); // 200 ms

        XUltrasonic_sensor_inf_Start(&uss_inf);

        while(!XUltrasonic_sensor_inf_IsDone(&uss_inf))
            usleep(500); // 5us

        if(ret_val = (int)XUltrasonic_sensor_inf_Get_return(&uss_inf))
            printf("Error: %d\n", ret_val);

        measure = (float)XUltrasonic_sensor_inf_Get_count_val(&uss_inf) * 0.000342 / 2.0;
        printf("Distance is %.2f cm\n", measure);
    }
}


ultrasonic_sensor.elf の実行結果を示す。
Ultrasonic_senser_inf_58_161215.png

うまく距離が測定できた。

しかし。。。距離は測定できたのだが、たまに動かなくなってしまう。5分くらいで動作しなくなってしまう。動作しなくなったら、再コンフィギュレーションしないと再び動き出さない。
2時間くらい悩んでいたのだが、ふと気が付いた。sensor_in に入って来る超音波距離センサの距離測定パルスは非同期なのに、シンクロナイザが入っていなかった。Vivado HLS で生成されるIP にシンクロナイザを望むべくもないので、自分で作った、Synchronizer を sensor_in に追加することにした。

Synchronizer を追加した階層モジュール usoinc_sensor_inf を示す。
Ultrasonic_senser_inf_60_161216.png

Synchronizer はビット幅 1 、ステージ数 2 に設定されている。
Ultrasonic_senser_inf_61_161216.png

これでもう一度、論理合成、インプリメント、ビットストリームの生成を行った。
レポートを示す。
Ultrasonic_senser_inf_62_161216.png

成功したので、ハードウェアをエクスポートして、SDK を立ち上げた。

ultrasonic_sensor.elf を実行したところ、30分経っても動作は安定していた。やはり、Synchronizer が無かったためメタステーブル状態が発生し、ステートマシンが不正ステートに行ってしまって、回復できなかったのが原因のようだ。
これで、超音波距離センサをZybot に搭載することができる。。。やった~~~。

なお、実験方法はZYBO のPmod の +3.3V を パララックス社の超音波距離センサの+5V に入力している。つまり、データシートの規格から逸脱して使っているが、今のところは問題なく使用できている。SIG はPmod のJB の 7 番ピン Y18 に接続している。
接続してる写真を示す。あとはGNDを接続している。配線だけのシンプルな回路だ。
Ultrasonic_senser_inf_63_161216.jpg
  1. 2016年12月16日 04:46 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

Zybot に超音波距離センサを搭載する7(ZYBO_0_162_7 に 2 つのIP を追加)

Zybot に超音波距離センサを搭載する6(ZYBO_0_162_7 に usonic_sensor_inf IP を追加)”の続き。

(2016/12/16 : 追記)この回路で距離の測定をすることができたのですが、たまに動作を停止してしまいました。原因はsensor_in にシンクロナイザが入っていないことでした。詳しくは、”Zybot に超音波距離センサを搭載する8(ZYBO_0_162_7 に 2 つのIP を追加2)”をご覧ください。

前回はうまく行ったと思ったのだが、SDKで Vivado HLS 2016.3 の Ultrasorinc_sensor_inf IP のドライバがどうしても使えなかった。それで今回は順当にVivado HLS 2016.3 の Ultrasorinc_sensor_inf IPussensor_iobuf IP をZYBO_0_162_7 フォルダのプロジェクトのブロックデザインに追加して、論理合成、インプリメント、ビットストリームの生成を行う。

前回も書いたが、”Vivadoを使用してZYBO_0_163_6フォルダのプロジェクトにRGB2HSV IPを追加5(Ubuntuでの動作)”のZYBO_0_163_6フォルダのプロジェクトをコピー&ペーストして、ZYBO_0_163_7 フォルダとした。

ZYBO_0_163_7 フォルダに ultrasonic_sensor_inf フォルダと ussensor_iobuf フォルダを新規作成した。
Ultrasonic_senser_inf_44_161215.png

IP Catalog に ultrasonic_sensor_inf と ussensor_iobuf を追加した。
Ultrasonic_senser_inf_45_161215.png

ZYBO_0 ブロックデザインで、 ultrasonic_sensor_inf と ussensor_iobuf 、Constant を追加した。配線済みの状態だ。

次に、その3個のIP を選択して、Create Hiearchy... を選択して階層モジュールにした。名前はusoinc_sensor_inf とした。
Ultrasonic_senser_inf_55_161215s.png 

階層モジュール usoinc_sensor_inf の中身を示す。(2016/12/16 : 追記)この回路で距離の測定をすることができたのですが、たまに動作を停止してしまいました。原因はsensor_in にシンクロナイザが入っていないことでした。詳しくは、”Zybot に超音波距離センサを搭載する8(ZYBO_0_162_7 に 2 つのIP を追加2)”をご覧ください。
Ultrasonic_senser_inf_53_161215s.png 

ZYBO_0 ブロックデザインでどのようなIP が使われているかを示す。
Ultrasonic_senser_inf_54_161215s.png 

Address Editor の画面を示す。 ultrasonic_sensor_inf_0 が 0x43CD_0000 にマップされている。
Ultrasonic_senser_inf_48_161215.png

1つポートを追加したので、Create HDLWapper... を実行して再度トップのVerilog HDL コードを更新した。

論理合成を行い、Synthesized Design を開いて、Layout メニューからI/O planning を選択した。
”ZYBO™ FPGA Board Reference Manual”の25 ページの”Table 9. Pmod pinout.”を参考に、まだ使用していないJB の7 番 Y18 に ussensor_inout を割り当てた。
Ultrasonic_senser_inf_41_161213.png

インプリメント、ビットストリームの生成を行った。
Ultrasonic_senser_inf_49_161215.png

レポートを示す。
Ultrasonic_senser_inf_56_161215s.png

ハードウェアをエクスポートして、SDK を立ち上げると、ZYBO_0_wrapper_hw_platform_1 のdrivers フォルダの下に ultrasonic_sensor_inf_v1_0 が入って、ドライバが見えている。

ultrasonic_sensor アプリケーション・プロジェクトを作成して、超音波距離センサから距離を取得して表示する ultrasonic_sensor.c を書いた。ビルドも成功した。
Ultrasonic_senser_inf_57_161215s.png

なお、最初は以前のハードウェア・プラットフォームが残っていると、SDKのハードウェアのインポートがうまく行かないことがあった。そのような場合は、SDK のフォルダ(ZYBO_0_153.sdk)を一旦削除してから、Vivado でハードウェアを再度エクスポートして、SDKを立ち上げるとうまく行った。
  1. 2016年12月15日 04:41 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

Zybot に超音波距離センサを搭載する6(ZYBO_0_162_7 に usonic_sensor_inf IP を追加)

Zybot に超音波距離センサを搭載する5(usonic_sensor_inf IP の作製)”の続き。

(2016/12/15 : 追記) この実装では、Vivado HLS 2016.3 の Ultrasorinc_sensor_inf IP のドライバがどうしてSDK で使えなかった。よって、このIP は使わないことにした。

前回は usonic_sensor_inf IP を作製した。今回は、usonic_sensor_inf IP をZYBO_0_162_7 のブロックデザインに追加して、論理合成、インプリメント、ビットストリームの生成を行う。

Vivadoを使用してZYBO_0_163_6フォルダのプロジェクトにRGB2HSV IPを追加5(Ubuntuでの動作)”のZYBO_0_163_6フォルダのプロジェクトをコピー&ペーストして、ZYBO_0_163_7 フォルダとした。

ZYBO_0_163_7 フォルダに usonic_sensor_inf フォルダを新規作成して、marsee_user_usonic_sensor_inf_1.0.zip の中身をコピー&ペーストした。
Ultrasonic_senser_inf_34_161212.png

IP Catalog に usonic_sensor_inf を追加した。
Ultrasonic_senser_inf_35_161212.png

ZYBO_0 ブロックデザインで、 usonic_sensor_inf を追加した。配線済みの状態だ。
Ultrasonic_senser_inf_36_161212.png

ブロックデザインを示す。大きいので 2 つに分けた。
Ultrasonic_senser_inf_37_161212.png

Ultrasonic_senser_inf_38_161213.png

Address Editor の画面を示す。usonic_sensor_inf_0 が 0x43CD_0000 にマップされている。
Ultrasonic_senser_inf_39_161213.png

1つポートを追加したので、Create HDLWapper... を実行して再度トップのVerilog HDL コードを更新した。

論理合成を行い、Synthesized Design を開いて、Layout メニューからI/O planning を選択した。
ZYBO™ FPGA Board Reference Manual”の25 ページの”Table 9. Pmod pinout.”を参考に、まだ使用していないJB の7 番 Y18 に ussensor_inout を割り当てた。
Ultrasonic_senser_inf_41_161213.png

インプリメント、ビットストリームの生成を行った。
Ultrasonic_senser_inf_40_161213.png

レポートを示す。
Ultrasonic_senser_inf_42_161213.png

ハードウェアをエクスポートして、SDK を立ち上げると、ZYBO_0_wrapper_hw_platform_0 のdrivers フォルダの下に ultrasonic_sensor_inf_v1_0 が入って、ドライバが見えている。これでドライバも使えそうだ。
Ultrasonic_senser_inf_43_161214.png

なお、最初は以前のハードウェア・プラットフォームが残っていると、SDKのハードウェアのインポートがうまく行かないようで、ZYBO_0_wrapper_hw_platform_0 のdrivers フォルダの下に ultrasonic_sensor_inf_v1_0 が見えなかったです。そういう時はSDK のフォルダ(ZYBO_0_153.sdk)を一旦削除してから、Vivado でハードウェアを再度エクスポートして、SDKを立ち上げてください。

(2016/12/15 : 追記) SDKでいろいろとやってみたが Vivado HLS 2016.3 の Ultrasorinc_sensor_inf IP のドライバがどうしてSDK で使えなかった。
  1. 2016年12月14日 04:38 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

Zybot に超音波距離センサを搭載する5(usonic_sensor_inf IP の作製)

Zybot に超音波距離センサを搭載する4(ussensor_iobuf IP の作製)”の続き。

Zybot に超音波距離センサを搭載する4(ussensor_iobuf IP の作製)”で作ったussensor_iobuf IP とVivado HLS で作ったultrasonic_sensor_inf IP を IP として統合したが、IP の名前がおかしくなって、論理合成できなくなり、うまく行かなかった。そこで、Vivado HLS で作ったultrasonic_sensor_inf IP のVerilog HDL コードにトップのVerilog HDL コードを追加して、IOBUF をインスタンスしてIP 化した。

まずは、usonic_sensor_inf プロジェクトをVivado 2016.2 で作成した。
Ultrasonic_senser_inf_24_161212.png

sources フォルダを作成して、ultrasonic_sensor_inf\solution1\impl\ip\hdl\verilog のultrasonic_sensor_inf.v と ultrasonic_sensor_inf_AXILiteS_s_axi.v をコピー&ペーストした。(ultrasonic_sensor_in はVivado HLS でIP 化してある)

更にトップのVerilog HDL ファイル usonic_sensor_inf.v を作成した。(なお下の図はIP 化まで終了しているため余計なファイルが見えている)
Ultrasonic_senser_inf_32_161212.png

usonic_sensor_inf.v を示す。

// usonic_sensor_inf.v
// 2016/12/12 by marsee
//

`default_nettype none

module usonic_sensor_inf #(
    parameter   ap_const_int64_8 = 8,
    parameter   C_S_AXI_AXILITES_DATA_WIDTH = 32,
    parameter   C_S_AXI_AXILITES_ADDR_WIDTH = 5,
    parameter   C_S_AXI_DATA_WIDTH = 32,
    parameter   C_S_AXI_AXILITES_WSTRB_WIDTH = (C_S_AXI_AXILITES_DATA_WIDTH / ap_const_int64_8),
    parameter   C_S_AXI_WSTRB_WIDTH = (C_S_AXI_DATA_WIDTH / ap_const_int64_8)

)(
    input   wire    ap_clk,    // Clock
    input   wire    ap_rst_n,  // Asynchronous reset active low
    inout   wire    ussensor_inout,
    input   wire    s_axi_AXILiteS_AWVALID,
    output  wire    s_axi_AXILiteS_AWREADY,
    input   wire    [C_S_AXI_AXILITES_ADDR_WIDTH - 1 : 0]   s_axi_AXILiteS_AWADDR,
    input   wire    s_axi_AXILiteS_WVALID,
    output  wire    s_axi_AXILiteS_WREADY,
    input   wire    [C_S_AXI_AXILITES_DATA_WIDTH - 1 : 0]   s_axi_AXILiteS_WDATA,
    input   wire    [C_S_AXI_AXILITES_WSTRB_WIDTH - 1 : 0]  s_axi_AXILiteS_WSTRB,
    input   wire    s_axi_AXILiteS_ARVALID,
    output  wire    s_axi_AXILiteS_ARREADY,
    input   wire    [C_S_AXI_AXILITES_ADDR_WIDTH - 1 : 0]   s_axi_AXILiteS_ARADDR,
    output  wire    s_axi_AXILiteS_RVALID,
    input   wire    s_axi_AXILiteS_RREADY,
    output  wire    [C_S_AXI_AXILITES_DATA_WIDTH - 1 : 0]   s_axi_AXILiteS_RDATA,
    output  wire    [1:0]   s_axi_AXILiteS_RRESP,
    output  wire    s_axi_AXILiteS_BVALID,
    input   wire    s_axi_AXILiteS_BREADY,
    output  wire    [1:0]   s_axi_AXILiteS_BRESP,
    output  wire    interrupt
);

    wire    sensor_out_V;
    wire    sensor_out_en_V;
    wire    sensor_in_V_V;
    wire    sensor_in_V_V_ap_vld;
    wire    sensor_in_V_V_ap_ack;

    IOBUF ussensor_iobuf(
        .I(sensor_out_V),
        .IO(ussensor_inout),
        .O(sensor_in_V_V),
        .T(!sensor_out_en_V)
    );

    assign  sensor_in_V_V_ap_vld = 1'b1;

    ultrasonic_sensor_inf ussensor_inf_i (
        .ap_clk                 (ap_clk),
        .ap_rst_n               (ap_rst_n),
        .sensor_out_V           (sensor_out_V),
        .sensor_out_en_V        (sensor_out_en_V),
        .sensor_in_V_V          (sensor_in_V_V),
        .sensor_in_V_V_ap_vld   (sensor_in_V_V_ap_vld),
        .sensor_in_V_V_ap_ack   (sensor_in_V_V_ap_ack),
        .s_axi_AXILiteS_AWVALID (s_axi_AXILiteS_AWVALID),
        .s_axi_AXILiteS_AWREADY (s_axi_AXILiteS_AWREADY),
        .s_axi_AXILiteS_AWADDR  (s_axi_AXILiteS_AWADDR),
        .s_axi_AXILiteS_WVALID  (s_axi_AXILiteS_WVALID),
        .s_axi_AXILiteS_WREADY  (s_axi_AXILiteS_WREADY),
        .s_axi_AXILiteS_WDATA   (s_axi_AXILiteS_WDATA),
        .s_axi_AXILiteS_WSTRB   (s_axi_AXILiteS_WSTRB),
        .s_axi_AXILiteS_ARVALID (s_axi_AXILiteS_ARVALID),
        .s_axi_AXILiteS_ARREADY (s_axi_AXILiteS_ARREADY),
        .s_axi_AXILiteS_ARADDR  (s_axi_AXILiteS_ARADDR),
        .s_axi_AXILiteS_RVALID  (s_axi_AXILiteS_RVALID),
        .s_axi_AXILiteS_RREADY  (s_axi_AXILiteS_RREADY),
        .s_axi_AXILiteS_RDATA   (s_axi_AXILiteS_RDATA),
        .s_axi_AXILiteS_RRESP   (s_axi_AXILiteS_RRESP),
        .s_axi_AXILiteS_BVALID  (s_axi_AXILiteS_BVALID),
        .s_axi_AXILiteS_BREADY  (s_axi_AXILiteS_BREADY),
        .s_axi_AXILiteS_BRESP   (s_axi_AXILiteS_BRESP),
        .interrupt              (interrupt)
   );

endmodule

`default_nettype wire


Tools メニューのCreate and Package IP... を選択してIP 化を行った。

Packaging Steps の Identification で Vendor を marsee に変更した。
Ultrasonic_senser_inf_25_161212.png

File Groups では、ドライバ・ソフトウェアを追加しよう。
File Groups で 右のペインを右クリックし右クリックメニューからAdd File Groups を選択した。
Add File Groups ダイアログで Software Driver を選択してOK ボタンをクリックした。
Ultrasonic_senser_inf_33_161212.png

File Groupes のAdvanced に Software Driver フォルダができた。

次に、Vivado HLS のultrasonic_sensor_inf\solution1\impl\ip\drivers の下のultrasonic_sensor_inf_v1_0 フォルダをこのプロジェクトのSources フォルダの下にコピーした。
Ultrasonic_senser_inf_30_161212.png

File Groupes のAdvanced の Software Driver フォルダを右クリックし、右クリックメニューからAdd Files... を選択した。
Add Files (Software Driver) ダイアログのAdd Directories ボタンをクリックして、Sources フォルダのultrasonic_sensor_inf_v1_0 フォルダを選択した。
これで、ultrasonic_sensor_inf_v1_0 フォルダ下のファイルが追加された。しかし、mdd ファイルだけが追加されていなかったので、もう一度追加した。
Ultrasonic_senser_inf_26_161212.png

Ports and Interface を示す。
Ultrasonic_senser_inf_27_161212.png

Customization GUI を示す。
Ultrasonic_senser_inf_28_161212.png

Review and Package でCreate archive of IP になっていることを確認して、Package IP ボタンをクリックした。
Ultrasonic_senser_inf_29_161212.png

usonic_sensor_inf\Sources\marsee_user_usonic_sensor_inf_1.0.zip にIP がまとめられている。
Ultrasonic_senser_inf_31_161212.png
  1. 2016年12月13日 05:21 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

Zybot に超音波距離センサを搭載する4(ussensor_iobuf IP の作製)

Zybot に超音波距離センサを搭載する3(Vivado HLSでインターフェースIPを作製)”の続き。

前回はVivado HLS で超音波距離センサのIP を作った。Vivado HLS では入出力ポートは作れないので、IOBUF をIP に追加する必要がある。今回は、IOBUF をIP(ussensor_iobuf) として作成した。

最初にVivado 2016.3 でussensor_iobuf プロジェクトを新規作成した。
次に、ussensor_iobuf.v を作成した。IOBUF をインスタンスするだけなのだが、T に入れるsensor_out_en は論理を反転する。
Ultrasonic_senser_inf_18_161211.png

Tools メニューからCreate and Package IP... を選択した。
Package IP タブが開いた。
Package Steps でCustomization GUI をクリックしたところを示す。
Ultrasonic_senser_inf_19_161211.png

Review and Package をクリックした。
ここで、edit packaging settings をクリックした。
Ultrasonic_senser_inf_20_161211.png

Project Settings ダイアログのPackage タブが開く。
Automatic Behavior のAfter Packaging のCreate archive of IP にチェックが入っているかどうか?を確認した。これにチェックを入れるとIP がアーカイブされたZIP ファイルが生成される。
Ultrasonic_senser_inf_21_161211.png

Review and Package に戻ってPackge IP ボタンをクリックしてIP を作成した。

ussensor_iobuf\ussensor_iobuf.srcs\sources_1\new フォルダにmarsee_user_ussensor_iobuf_1.0.zip が生成された。
Ultrasonic_senser_inf_23_161211.png
  1. 2016年12月12日 04:47 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

Xilinx 社のマイクロプロセッサまとめ2(MicroBlaze)

Xilinx 社のマイクロプロセッサまとめ1(PicoBlaze, MicroBlaze MCS)”の続きです。

”ハードウェア開発、CPUアーキテクチャ Advent Calendar 2016”の11日目の記事として書きます。

MicroBlaze
次のXilinx社のマイクロプロセッサはMicroBlaze です。最近はZynq のARM プロセッサばかりでMicroBlaze はあまり使っていませんでした。ですが、MicroBlaze はXilinx社の32ビットのソフトコアのマイクロプロセッサの代表格です。(MicroBlaze プロセッサ リファレン ガイド 2016.1 UG984 (v2016.1) 2016 年 4 月 6 日参照)
いろいろなコンフィギュレーションがあって、性能重視には5段パイプライン、エリア重視には3段パイプラインと使え分けられます。
MicroBlaze の基本機能です。(MicroBlaze プロセッサ リファレン ガイド 2016.1 UG984 (v2016.1) 2016 年 4 月 6 日から引用)

・32 個の 32 ビッ ト 汎用レジス タ
・オペランド 3 つと アドレス指定モード 2 つを含む 32 ビッ ト 命令ワード
・デフォルトでは、32ビットのアドレスバス
・シングル・パイプライン


ブロック図を引用します。(MicroBlaze プロセッサ リファレン ガイド 2016.1 UG984 (v2016.1) 2016 年 4 月 6 日6 ページの図 2‐1 : MicroBlaze コアのブロック図を引用)
Xilinx_Micon_9_161210.png

それでは実際にMicroBlazeを使ったプロジェクトを作ってみましょう。
Vivado 2016.3 を使用して、ZedBoardのボードの定義ファイルを使ってやってみました。
IP Integrator のブロックデザインを作成しました。
ブロックデザイン上でAdd IP をして、 microで検索して、MicroBlaze を選択しました。
Xilinx_Micon_10_161210.png

MicroBlaze のIP がインスタンスされました。
Xilinx_Micon_11_161210.png

MicroBlaze をダブルクリックして設定を見てみよう。
Select implementation optimization は、PERFORMANCE とAREA, FREQUENCY に設定することができる。
Xilinx_Micon_12_161210.png

Xilinx_Micon_14_161210.png

Select Configuration は下の図に示す設定があります。
Xilinx_Micon_13_161210.png

Next > ボタンをクリックするとGeneral 設定画面が表示されます。
ここでは、バレルシフタを使うか?や浮動小数点演算器を使うか?整数掛け算器、整数割り算器、などなどの設定を行うことができます。
Xilinx_Micon_15_161210.png

次がDebug 設定画面です。
デバック・モジュールの設定ができるようです。
Xilinx_Micon_17_161210.png

次がBus の設定画面です。
AXI バスの設定などがあります。ストリームのインターフェースも指定できるようです。
Xilinx_Micon_18_161210.png

これで設定画面を終了させます。
Run Block Automation のリンクをクリックすると、Run Block Automation ダイアログが表示されます。
ここではメモリを 32KB にしてOK ボタンをクリックしました。
Xilinx_Micon_19_161210.png

MicroBlaze の周辺回路がインスタンスされて、配線されました。
Xilinx_Micon_20_161210.png

axi_gpio を Add IP してみましょう。
Xilinx_Micon_21_161210.png

Run Connection Automation をクリックして配線を行いました。
Xilinx_Micon_22_161210.png

アドレスマップです。
Xilinx_Micon_23_161210.png

これでブロックデザインは終了なので、セーブします。
次に、Source ウインドウのブロックデザインを右クリックして、Create HDL Wapper... を選択して、トップのVerilog HDLファイルを生成します。
Xilinx_Micon_24_161210.png

論理合成、インプリメントを行ってから、ハードウェアをエクスポートし、SDKを立ち上げました。
SDK のFile メニューからNew を選択し、Application Project を選択します。
Application Project ダイアログで、Project name をtest にし、Next > ボタンをクリックします。
次のTemplates ダイアログで、Peripheral Tests を選んで、周辺デバイス・テストのサンプルデザインを選択し、Finish ボタンをクリックします。そうすると、test プロジェクトがビルドされます。
Xilinx_Micon_25_161210.png

これを起動すると、MicroBlaze を使うことができると思います。
  1. 2016年12月11日 03:48 |
  2. FPGAのマイクロプロセッサ
  3. | トラックバック:0
  4. | コメント:0

超音波距離センサ・インターフェースIP の番外編

Zybot に超音波距離センサを搭載する3(Vivado HLSでインターフェースIPを作製)”で作製した超音波距離センサ・インターフェースIP を使うことにしたが、もっと違った方法試してみようと思う。
具体的には、トリガパルスもsensor_in から読み込んで、2つ目の距離パルスをカウントする方法を試してみたい。そのためには最初からsensor_in をモニタする必要がある。方法としては、トリガパルスを出す回路とsensor_in からパルス長を計測する回路を並列に動作させたい。そのためにその2つを関数として実装して、トップにDETAFLOW 指示子を付加することにした。

ultrasonic_sensor_inf2.cpp を示す。

// ultrasonic_sensor_inf2.cpp
// 2016/12/05 by marsee
// count_val は超音波距離センサからのパルス長を示す。単位は 10 ns とする
// 2016/12/07 : パララックス社の超音波距離センサはSIGピンがINOUTなので、自分で出力したトリガパルスを自分で受けてしまう。
//              対策としては、sensor_outのパルスを受けてから、センサのパルス長を測定する。
//
// ライセンスは二条項BSDライセンス (2-clause BSD license)とします。
//

#include <stdio.h>
#include <string.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>
#include <ap_utils.h>

#define COUNT_LIMIT    2000000 // clock = 100MHz, 20ms

void gen_trigger_pulse(volatile ap_uint<1> &sensor_out, volatile ap_uint<1> &sensor_out_en);
int mesure_high_width(hls::stream<ap_uint<1> >& sensor_in, int &cnt);
int mesure_high_width2(hls::stream<ap_uint<1> >& sensor_in, int &cnt);

int ultrasonic_sensor_inf(int &count_val, volatile ap_uint<1> &sensor_out,
        volatile ap_uint<1> &sensor_out_en, hls::stream<ap_uint<1> >& sensor_in){
#pragma HLS DATAFLOW
#pragma HLS INTERFACE ap_hs port=sensor_in
#pragma HLS INTERFACE ap_none register port=sensor_out_en
#pragma HLS INTERFACE ap_none register port=sensor_out
#pragma HLS INTERFACE s_axilite port=count_val
#pragma HLS INTERFACE s_axilite port=return

    int cnt;
    int return_val;

    // 5usのトリガパルスを出力
    gen_trigger_pulse(sensor_out, sensor_out_en);

    // 2回パルスを検出(sensor_out, 距離パルス)
    return_val = mesure_high_width2(sensor_in, cnt);
    count_val = cnt;

    return(return_val);
}

void gen_trigger_pulse(volatile ap_uint<1> &sensor_out, volatile ap_uint<1> &sensor_out_en){
    int cnt;

    Loop_1out5us: for(cnt=0; cnt<500; cnt++){ // 5 us のパルスを出力
#pragma HLS PIPELINE II=1
        sensor_out = 1;
        sensor_out_en = 1;
    }
    sensor_out = 1;
    sensor_out_en = 1;
    Loop_wait1us: for(cnt=0; cnt<100; cnt++){ // 1 us の間 senser_out に 0 を保持
#pragma HLS PIPELINE II=1
        sensor_out = 0;
        sensor_out_en = 1;
    }
    sensor_out = 0;
    sensor_out_en = 1;
    Loop_wait1us2: for(cnt=0; cnt<100; cnt++){ // 1 us の間 senser_out_en に 0 を保持
#pragma HLS PIPELINE II=1
        sensor_out = 0;
        sensor_out_en = 0;
    }
    sensor_out = 0;
    sensor_out_en = 0;
}

// mesure_high_widthを2回実行する
int mesure_high_width2(hls::stream<ap_uint<1> >& sensor_in, int &cnt){
    int return_val;

    // sensor_out のパルスを検出
    return_val = mesure_high_width(sensor_in, cnt);
    if(return_val)
        return(return_val);

    // 超音波距離センサのパルスを検出
    return_val = mesure_high_width(sensor_in, cnt);
    if(return_val)
        return(return_val);

    return(0);
}

// sensor_in が 1 の間のパルス幅を検出する
int mesure_high_width(hls::stream<ap_uint<1> >& sensor_in, int &cnt){
    ap_uint<1> sensor_in_node;

    Loop_wait_high: for(cnt=0; cnt<COUNT_LIMIT; cnt++){
#pragma HLS PIPELINE II=1
        sensor_in >> sensor_in_node;
        if((int)sensor_in_node)
            break;
    }
    if(cnt == COUNT_LIMIT)
        return(1); // error, overflow

    Loop_mesure_high: for(cnt=1; cnt<COUNT_LIMIT; cnt++){ // リミットは 20 ms
#pragma HLS PIPELINE II=1
#pragma HLS LOOP_TRIPCOUNT min=11500 max=1850000 avg=20000
        sensor_in >> sensor_in_node;
        if(!(int)sensor_in_node)
            break;
    }

    if (cnt == COUNT_LIMIT)
        return(2); // error, overflow
    else
        return(0); // normal end
}


ultrasonic_sensor_inf2_tb.cpp を示す。

// ultrasonic_sensor_inf_tb.cpp
// 2016/12/06 by marsee
// 2016/12/07 : パララックス社の超音波距離センサはSIGピンがINOUTなので、自分で出力したトリガパルスを自分で受けてしまう。
//              sensor_in にトリガパルスを出力してから、センサが出力するであろうパルスを出力する。
//
// ライセンスは二条項BSDライセンス (2-clause BSD license)とします。
//

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

#define PULSE_WIDTH 20000 // (PULSE_WIDTH/100) us

int ultrasonic_sensor_inf(int &count_val, volatile ap_uint<1> &sensor_out,
        volatile ap_uint<1> &sensor_out_en, hls::stream<ap_uint<1> >& sensor_in);

int main(){
    using namespace std;

    hls::stream<ap_uint<1> > sensor_in;
    int count_val;
    ap_uint<1> sensor_out, sensor_out_en;
    int return_val;

    // パララックス社の超音波距離センサは入出力なので、自分の出力に反応しないか?を検証する
    // 756 us wait
    for(int i=0; i<22; i++){ // 220 ns wait
        sensor_in << (ap_uint<1>)0;
    }
    for(int i=0; i<500; i++){ // 5 us間 1 を入れる
        sensor_in << (ap_uint<1>)1;
    }
    for(int i=0; i<75078; i++){ // 756 us - 5 us - 220 ns
        sensor_in << (ap_uint<1>)0;
    }
    // 測定用に PULSE_WIDTH 間、1 を入れる
    for(int i=0; i<PULSE_WIDTH; i++){ // PULSE_WIDTHの間 sensor_in を 1 にする
        sensor_in << (ap_uint<1>)1;
    }
    for(int i=0; i<20000; i++){ // 1 usの間 sensor_in を 0 にする
        sensor_in << (ap_uint<1>)0;
    }

    return_val = ultrasonic_sensor_inf(count_val, sensor_out, sensor_out_en, sensor_in);

    printf("Pulse width = %f us\n", (float)count_val/100.0);

    if(return_val){
        printf("Error: return_val = %d\n");
        exit(1);
    }

    return(0);
}


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

C/RTL協調シミュレーションを行った。
Ultrasonic_senser_inf_15_161210.png

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

sensor_out と sensor_out_en が「x」になってしまっている。まずい。。。

最初の波形を拡大した。
Ultrasonic_senser_inf_17_161210.png

sensor_out と sensor_out_en の for 文が終わったところで「x」になってしまっているようだ。
距離パルスが不定なので、sensor_out と sensor_out_en の for 文の長さを合わせることはできない。よってこの実装を使用することは無理そうだと思う。
  1. 2016年12月10日 09:08 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

Zybot に超音波距離センサを搭載する3(Vivado HLSでインターフェースIPを作製)

Zybot に超音波距離センサを搭載する2(Arduino でセンサをテストする)”の続き。

追記:パララックス社の超音波距離センサを使うとするとこの超音波距離センサ用インターフェースIP にはバグがあります。
パララックス社の超音波距離センサは、SIG 1ポートのみで、インターフェースIPからのトリガパルスと超音波距離センサからの距離のパルスの両方が入出力されます。よって、sensor_in をHLS ストリームで宣言しているとインターフェースIPが自分で出力したトリガパルスもsensor_in に入ってきてこれを計測してしまいます。
これについては修正版のブログを後で掲載します。
超音波距離センサー HC-SR04 だと、トリガパルスの長さを 10 us に変更する必要がありますが、Trig ピンと Echo ピンに入力と出力が分かれているので、この超音波距離センサ・インターフェースIPを使うことができると思います。

(2016/12/08 : 追記)
最後から2番目のタイミング波形を見るとトリガパルスが出ている間は、sensor_in の ack が 0 になっていて、信号を受け付けないことが示されています。つまり、vld を 1 に固定して、sensor_in に 超音波距離センサのSIG を入れていると、ack が 0 なので、トリガパルスは無視されると思います。つまり、このIP で問題なく動作すると思います。

前回はArduino を使用して秋月電子の「パララックス社超音波距離センサーモジュール」を使ってみた。今回は、「パララックス社超音波距離センサーモジュール」を使うためのインターフェースIP をVivado HLS で作製してみよう。

Vivado HLS 2016.3 で ultrasonic_sensor_inf プロジェクトを新規作成した。ソースファイルとして ultrasonic_sensor_inf.cpp とテストベンチファイルとして、ultrasonic_sensor_inf_tb.cpp を作成した。
Ultrasonic_senser_inf_7_161206.png

ultrasonic_sensor_inf.cpp を示す。クロック周波数は 100 MHz とする。
(2016/12/08 : 追記)Loop_mesure_high ループに入ったときに、すでに1つ sensor_in に 1 が来ていたので、Loop_mesure_high ループの開始を 1 にしました。

// ultrasonic_sensor_inf.cpp
// 2016/12/05 by marsee
// count_val は超音波距離センサからのパルス長を示す。単位は 10 ns とする
// 
// ライセンスは二条項BSDライセンス (2-clause BSD license)とします。
//

#include <stdio.h>
#include <string.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>
#include <ap_utils.h>

#define COUNT_LIMIT    2000000 // clock = 100MHz, 20ms

int ultrasonic_sensor_inf(int &count_val, volatile ap_uint<1> &sensor_out,
        volatile ap_uint<1> &sensor_out_en, hls::stream<ap_uint<1> >& sensor_in){
#pragma HLS INTERFACE ap_hs port=sensor_in
#pragma HLS INTERFACE ap_none register port=sensor_out_en
#pragma HLS INTERFACE ap_none register port=sensor_out
#pragma HLS INTERFACE s_axilite port=count_val
#pragma HLS INTERFACE s_axilite port=return

    int cnt;
    ap_uint<1> sensor_in_node;

    Loop_1out5us: for(cnt=0; cnt<500; cnt++){ // 5 us のパルスを出力
#pragma HLS PIPELINE II=1
        sensor_out = 1;
        sensor_out_en = 1;
    }

    sensor_out = 0;
    Loop_wait1us: for(cnt=0; cnt<100; cnt++){ // 1 us の間 senser_out に 0 を保持
#pragma HLS PIPELINE II=1
        sensor_out = 0;
        sensor_out_en = 1;
    }

    sensor_out_en = 0// sensor_out のバッファをディスエーブル

    Loop_wait_high: for(cnt=0; cnt<COUNT_LIMIT; cnt++){
#pragma HLS PIPELINE II=1
        sensor_in >> sensor_in_node;
        if((int)sensor_in_node)
            break;
    }
    if(cnt == COUNT_LIMIT)
        return(1); // error, overflow

    Loop_mesure_high: for(cnt=1; cnt<COUNT_LIMIT; cnt++){ // リミットは 20 ms
#pragma HLS PIPELINE II=1
#pragma HLS LOOP_TRIPCOUNT min=11500 max=1850000 avg=20000
        sensor_in >> sensor_in_node;
        if(!(int)sensor_in_node)
            break;
    }

    count_val = cnt;
    if (cnt == COUNT_LIMIT)
        return(2); // error, overflow
    else
        return(0); // normal end
}


ultrasonic_sensor_inf_tb.cpp を示す。
(2016/12/08 : 追記) Pulse width を表示するようにしました。

// ultrasonic_sensor_inf_tb.cpp
// 2016/12/06 by marsee
//
// ライセンスは二条項BSDライセンス (2-clause BSD license)とします。
//

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

int ultrasonic_sensor_inf(int &count_val, volatile ap_uint<1> &sensor_out,
        volatile ap_uint<1> &sensor_out_en, hls::stream<ap_uint<1> >& sensor_in);

int main(){
    using namespace std;

    hls::stream<ap_uint<1> > sensor_in;
    int count_val;
    ap_uint<1> sensor_out, sensor_out_en;
    int return_val;

    for(int i=0; i<75600; i++){ // 756 us wait
        sensor_in << (ap_uint<1>)0;
    }
    for(int i=0; i<20000; i++){ // 200 usの間 sensor_in を 1 にする
        sensor_in << (ap_uint<1>)1;
    }
    for(int i=0; i<20000; i++){ // 1 usの間 sensor_in を 0 にする
        sensor_in << (ap_uint<1>)0;
    }

    return_val = ultrasonic_sensor_inf(count_val, sensor_out, sensor_out_en, sensor_in);

    if(return_val){
        printf("Error: return_val = %d\n");
        exit(1);
    }

    printf("Pulse width = %f us\n", (float)count_val/100.0);

    return(0);
}


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

C コードの合成を行った。
Ultrasonic_senser_inf_9_161206.png

C/RTL協調シミュレーションを行った。96242 クロックかかった。
Ultrasonic_senser_inf_10_161206.png

C/RTL協調シミュレーションの波形を示す。
sensor_in_V_V を見ると予定の 200 us に対して 200.01 us の間 1 になっている。
Ultrasonic_senser_inf_11_161207.png

sensor_out_V は5.02 us の間 1 になって、sensor_out_en_V は 6.03 us の間 1 になっていた。これで問題ない。
Ultrasonic_senser_inf_12_161207.png

sensor_out_en_V が 0 になるまで、sensor_in_V_V_ap_ack が 0 になっていて、sensor_in が受け取れない状況になっている。この時に sensor_out にトリガパルスが出ているので、このトリガパルスは無視されるはずだ。

AXI4-Lite Slave のアドレスマップを示す。

//------------------------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 count_val
//        bit 31~0 - count_val[31:0] (Read)
// 0x1c : Control signal of count_val
//        bit 0  - count_val_ap_vld (Read/COR)
//        others - reserved
// (SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake)


アドレスマップによると count_val は 0x18 番地だということがわかる。
もう一度、C/RTL協調シミュレーションの波形の終わりのほうを見てみよう。
Ultrasonic_senser_inf_13_161207.png

0x18 番地が Read され、20000 という値であることがわかる。

次には、IOBUF のIP を作ってVivado のIPI で接続しよう。
  1. 2016年12月08日 23:07 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

Zybot をステレオカメラにする1(カメラ・インターフェース基板の実装とテスト)

”I2Cリピーター付きカメラ・インターフェース基板2が来ました”で届いた基板に部品を実装してZYBO に延長ケーブルを付けてテストしてみた。

”I2Cリピーター付きカメラ・インターフェース基板2が来ました”で届いた基板に部品を実装した。
MSC-009_3_161206.jpg

MSC-009_2_161206.jpg

延長ケーブルを付けてZYBO に接続して、Ubuntu を起動してカメラを表示してみたところ、5回とも成功。。。つまり、I2Cリピーターを付けると延長ケーブルを付けてもI2C が通って、正常にカメラ画像を表示できた。
MSC-009_1_161206.jpg

延長ケーブルは、Digiletnt社の 2x6 Pin Cable で、長さは 15 cm だ。

これで、ZYBO を2台 Zybot に搭載してステレオカメラにすることができる。

だが、今回のカメラ・インターフェース基板は、幅を狭くしたので、ZYBO に直接取り付けでステレオカメラにすることもできる。
MSC-009_4_161206.jpg

MSC-009_5_161206.jpg

ただし、Zybot ではモーター・コントロールにPMOD を 1 つ使用しているので、ZYBO 1台にカメラを2つ取り付けるステレオカメラにすることはできない。。。
  1. 2016年12月07日 04:48 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

Zybot に超音波距離センサを搭載する2(Arduino でセンサをテストする)

Zybot に超音波距離センサを搭載する1(概要)”の続き。

パララックス社超音波距離センサモジュールで距離を計る(2)」のArduino を使ったテストをやってみた。

Arduino UNOの9番ピンから超音波距離センサモジュールのSIG に接続した。超音波距離センサの+5V とGND も接続した。
Ultrasonic_senser_inf_1_1611205.jpg

Ultrasonic_senser_inf_2_1611205.jpg

パララックス社超音波距離センサモジュールで距離を計る(2)」のスケッチを書いて、Arduino UNO にダウンロードして、起動した。
Ultrasonic_senser_inf_6_161205.png

シリアルコンソールに、距離が表示された。距離も大体合っているようだ。
Ultrasonic_senser_inf_5_161205.png

波形を見てみた。まずは、全体の波形を示す。
トリガーを打ってから、リスポンスは、約760 us くらいで出てくるようだ。
Ultrasonic_senser_inf_3_1611205.jpg

トリガーの幅は、8 us くらいだった。
Ultrasonic_senser_inf_4_1611205.jpg

(2016/12/06 : 追記)
パララックス社の超音波距離センサは今まで +5V 電源で使っていました。規格外ですが +3.3V でやってみたところ問題なく動作しました。+3.3V 電源はZYBOのPMOD から供給できるので、+3.3V 電源でやってみることにします。
  1. 2016年12月05日 20:37 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

Xilinx 社のマイクロプロセッサまとめ1(PicoBlaze, MicroBlaze MCS)

ハードウェア開発、CPUアーキテクチャ Advent Calendar 2016”の記事として書きます。
始めはVivado HLS について書こうと思ったのですが、マイクロプロセッサの話題が主というか?ほとんどマイクロプロセッサの話題のようなので、急遽ブログ記事を変更しました。

PicoBlaze
最初に一番小さいマイクロプロセッサから行きましょう。まだあるんだ。。。ということで、「PicoBlaze 8-ビット マイクロコントローラー」です。

デバイス ファミリ サポート: Zynq-7000 Virtex-7 Kintex-7 Artix-7 Spartan-6 Virtex-6 Virtex-5 Virtex-4 Virtex-II Pro Virtex-II Spartan-3AN Spartan-3A Spartan-3

Zynqもサポートされているんですね。。。知らなかった。とってもコンパクトな 8 ビット マイクロプロセッサです。
ブロック図です(UG129 - PicoBlaze 8-bit Embedded Microcontroller User Guide for Spartan-3, Spartan-6, Virtex-5, Virtex-6 and 7 Series FPGAs ( v2.1, 2835 KB ) [PDF] の8 ページの「Figure 1-1: PicoBlaze Embedded Microcontroller Block Diagram」を転載させていただきました)
Xilinx_Micon_1_161203.png

PicoBlaze フォーラムもありますよ。

PicoBlaze資料のページ

PicoBlaze のダウンロードページ

FPGAの部屋のブログのPicoBlazeの記事
スパルタン3EスターターキットのLCD表示回路まとめ」でLCDを表示するためにPicoBlazeを使用しました。
「スパルタン3Eスタータキットのロータリーエンコーダ2
Spratan3E Starter KitのDDR SDRAMコントローラ(プロジェクト)」 DDR SDRAMコントローラのシミュレーションのためにPicoBlaze を使ったんだったかな?

MicroBlaze MCS
MicroBlaze MCS もまだあったとは知らなかった。。。

資料
MicroBlaze Micro Controller System v3.0 LogiCORE IP Product Guide Vivado Design Suite PG116 October 5, 2016


MicroBlaze MCS はパイプライン3段固定のMicroBlaze で 32 ビットのRISC プロセッサです。
MicroBlaze Micro Controller System (MicroBlaze MCS) のブロック図をMicroBlaze Micro Controller System v3.0 LogiCORE IP Product Guide Vivado Design Suite PG116 October 5, 2016
の 5 ページ Figure 1-1: MicroBlaze Micro Controller System から引用します。
Xilinx_Micon_8_161203.png

次に示す IO モジュールがあります。

I/O Bus
Interrupt Controller using fast interrupt mode
UART
Fixed Interval Timers
Programmable Interval Timers
General Purpose Inputs
General Purpose Outputs


MicroBlaze と MicroBlaze MCS の違いは、MicroBlaze がフルスペックなのに対して、MicroBlaze MCS は固定された機能を使えるという違いがあります。(MicroBlaze マイクロ コントローラー システム (MCS)の表を参照ください)
以前はフルスペックのMicroBlaze が有償だったので使っていましたが、MicroBlaze が無償となった今となっては使いどころはあまりないと思われます。
ですが、7 シリーズも対応しているし、Vivado でも使えるようです。

Vivado のIP Integrator でも使えるので、Add IP してやってみましょう。

Vivado 2016.3 を起動して、IP Integrator のブロックデザインを開きます。

Add IP ボタンをクリックしてAdd IP します。Micro で検索するとMicroBlaze MCSが出てきます。これをダブルクリックして、ブロックデザインに入れてみましょう。
Xilinx_Micon_2_161203.png

すると、MicroBlaze MCS がインスタンスされました。まだ、Clk と Reset のみの状態です。
Xilinx_Micon_3_161203.png

MicroBlaze MCS をダブルクリックして設定してみましょう。
Xilinx_Micon_4_161203.png

MCS タブです。
Xilinx_Micon_5_161203.png

UART タブでUART をイネーブルしてみます。
Xilinx_Micon_6_161203.png

OK ボタンをクリックすると、MicroBlaze MCS にUART のポートが追加されているのが分かります。
Xilinx_Micon_7_161203.png

MicroBlaze MCSのソフトウェアを作るには、Eclipse ベースのSDK を使用します。

FPGAの部屋の「MicroBlaze MCS」のページです。
  1. 2016年12月04日 05:39 |
  2. FPGAのマイクロプロセッサ
  3. | トラックバック:0
  4. | コメント:0

SDSoC 2016.2 でラプラシアンフィルタをテスト3

SDSoC 2016.2 でラプラシアンフィルタをテスト2”の続き。

前回、SDSoC 2015.2 と同様に SDSoC 2016.2 でも 800 x 600 ピクセルの画像をラプラシアンフィルタ処理することはできなかった。それで、前回同様に、64 x 48 ピクセルでやってみることにした。

64 x 48 ピクセルの画像を指定した。例によって使用している 'A' の画像にした。
SDSoC_2016_2_25_161203.png

お気づきと思うが、すでにラプラシアンフィルタ処理の実装をビルドしてある。やはり小さいサイズであればビルドできた。

lap_filter2\SDRelease\sd_card フォルダの内容と temp.bmp('A'の画像)を MicroSD カードに書き込んだ。
SDSoC_2016_2_26_161203.png

Micro SD カードをZYBO に挿入してテストしてみた。

ZYBO 上でLinux が起動した。
mnt ディレクトリに移動して ./lap_filter2.elf を実行して、実行時間を見た。
SDSoC_2016_2_27_161203.png

最初の実行では、ハードウェアが 641 us に対して、ソフトウェアが 362 us となって 2 倍近くハードウェアの方が遅かった。しかしその後、ハードウェアのラプラシアンフィルタ処理時間はかなりばらついた。ソフトウェアの実行時間もハードウェアよりはばらつきが少ないがやはりばらついている。

ZYBO の電源をOFF して MicroSD カードを見ると、temp_lap.bmp が増えていた。
SDSoC_2016_2_28_161203.png

temp_lap.bmp を開いてみると、きちんとエッジの画像になっていた。
SDSoC_2016_2_29_161203.png

レポートを見てみよう。
lap_filter2\SDRelease\_sds\reports\data_motion.html を見てみよう。
SDSoC_2016_2_30_161203.png

cam_fb と lap_fb に AXIDMA_SG が使用されている。スキャッター・ギャザーDMA だ。

lap_filter2\SDRelease\_sds\reports\sds.rpt を貼っておく。

(c) Copyright 2012-2016 Xilinx, Inc. All Rights Reserved.
#-----------------------------------------------------------
# Tool version : sds++ 2016.2 SW Build on Jul 15 2016 19:20:29
# Start time : Fri Dec 02 04:17:56 +0900 2016
# Command line : sds++ -o lap_filter2.elf ./src/lap_filter_tb.o ./src/laplacian_filter2.o -dmclkid 1 -sds-pf zybo
# Log file : C:/Users/Masaaki/workspace/lap_filter2/SDRelease/_sds/reports/sds.log
# Journal file : C:/Users/Masaaki/workspace/lap_filter2/SDRelease/_sds/reports/sds.jou
# Report file : C:/Users/Masaaki/workspace/lap_filter2/SDRelease/_sds/reports/sds.rpt
#-----------------------------------------------------------

-------------------
Design Timing Check
-------------------

Partition 0
Vivado Log : C:/Users/Masaaki/workspace/lap_filter2/SDRelease/_sds/p0/ipi/vivado.log
Timing Summary : C:/Users/Masaaki/workspace/lap_filter2/SDRelease/_sds/p0/ipi/zybo.runs/impl_1/zybo_wrapper_timing_summary_routed.rpt

All user specified timing constraints are met.

Timing Summary Report

Timer Settings
--------------

Enable Multi Corner Analysis : Yes
Enable Pessimism Removal : Yes
Pessimism Removal Resolution : Nearest Common Node
Enable Input Delay Default Clock : No
Enable Preset / Clear Arcs : No
Disable Flight Delays : No
Ignore I/O Paths : No
Timing Early Launch at Borrowing Latches : false

Corner Analyze Analyze
Name Max Paths Min Paths
------ --------- ---------
Slow Yes Yes
Fast Yes Yes



check_timing report

Table of Contents
1. checking no_clock
2. checking constant_clock
3. checking pulse_width_clock
4. checking unconstrained_internal_endpoints
5. checking no_input_delay
6. checking no_output_delay
7. checking multiple_clock
8. checking generated_clocks
9. checking loops
10. checking partial_input_delay
11. checking partial_output_delay
12. checking latch_loops

1. checking no_clock
There are 0 register/latch pins with no clock.


2. checking constant_clock
There are 0 register/latch pins with constant_clock.


3. checking pulse_width_clock
There are 0 register/latch pins which need pulse_width check


4. checking unconstrained_internal_endpoints
There are 0 pins that are not constrained for maximum delay.

There are 0 pins that are not constrained for maximum delay due to constant clock.


5. checking no_input_delay
There are 0 input ports with no input delay specified.

There are 0 input ports with no input delay but user has a false path constraint.


6. checking no_output_delay
There are 0 ports with no output delay specified.

There are 0 ports with no output delay but user has a false path constraint

There are 0 ports with no output delay but with a timing clock defined on it or propagating through it


7. checking multiple_clock
There are 0 register/latch pins with multiple clocks.


8. checking generated_clocks
There are 0 generated clocks that are not connected to a clock source.


9. checking loops
There are 0 combinational loops in the design.


10. checking partial_input_delay
There are 0 input ports with partial input delay specified.


11. checking partial_output_delay
There are 0 ports with partial output delay specified.


12. checking latch_loops
There are 0 combinational latch loops in the design through latch input



Design Timing Summary
---------------------

WNS(ns) TNS(ns) TNS Failing Endpoints TNS Total Endpoints WHS(ns) THS(ns) THS Failing Endpoints THS Total Endpoints WPWS(ns) TPWS(ns) TPWS Failing Endpoints TPWS Total Endpoints
------- ------- --------------------- ------------------- ------- ------- --------------------- ------------------- -------- -------- ---------------------- --------------------
2.599 0.000 0 34698 0.036 0.000 0 34698 3.870 0.000 0 12722


All user specified timing constraints are met.


Clock Summary
-------------

Clock Waveform(ns) Period(ns) Frequency(MHz)
----- ------------ ---------- --------------
clk_fpga_0 {0.000 20.000} 40.000 25.000
clk_fpga_1 {0.000 5.000} 10.000 100.000
clk_fpga_2 {0.000 4.000} 8.000 125.000
clk_fpga_3 {0.000 10.000} 20.000 50.000


-------------------
Data Motion Network
-------------------

Data motion network report generated in C:/Users/Masaaki/workspace/lap_filter2/SDRelease/_sds/reports
HTML file : C:/Users/Masaaki/workspace/lap_filter2/SDRelease/_sds/reports/data_motion.html

-------------------
Design Utilization
-------------------

Partition 0
Utilization Summary : C:/Users/Masaaki/workspace/lap_filter2/SDRelease/_sds/p0/ipi/zybo.runs/impl_1/zybo_wrapper_utilization_placed.rpt

Utilization Design Information

Table of Contents
-----------------
1. Slice Logic
1.1 Summary of Registers by Type
2. Slice Logic Distribution
3. Memory
4. DSP
5. IO and GT Specific
6. Clocking
7. Specific Feature
8. Primitives
9. Black Boxes
10. Instantiated Netlists

1. Slice Logic
--------------

+----------------------------+-------+-------+-----------+-------+
| Site Type | Used | Fixed | Available | Util% |
+----------------------------+-------+-------+-----------+-------+
| Slice LUTs | 7513 | 0 | 17600 | 42.69 |
| LUT as Logic | 6799 | 0 | 17600 | 38.63 |
| LUT as Memory | 714 | 0 | 6000 | 11.90 |
| LUT as Distributed RAM | 456 | 0 | | |
| LUT as Shift Register | 258 | 0 | | |
| Slice Registers | 11408 | 0 | 35200 | 32.41 |
| Register as Flip Flop | 11408 | 0 | 35200 | 32.41 |
| Register as Latch | 0 | 0 | 35200 | 0.00 |
| F7 Muxes | 74 | 0 | 8800 | 0.84 |
| F8 Muxes | 1 | 0 | 4400 | 0.02 |
+----------------------------+-------+-------+-----------+-------+


1.1 Summary of Registers by Type
--------------------------------

+-------+--------------+-------------+--------------+
| Total | Clock Enable | Synchronous | Asynchronous |
+-------+--------------+-------------+--------------+
| 0 | _ | - | - |
| 0 | _ | - | Set |
| 0 | _ | - | Reset |
| 0 | _ | Set | - |
| 0 | _ | Reset | - |
| 0 | Yes | - | - |
| 342 | Yes | - | Set |
| 628 | Yes | - | Reset |
| 222 | Yes | Set | - |
| 10216 | Yes | Reset | - |
+-------+--------------+-------------+--------------+


2. Slice Logic Distribution
---------------------------

+------------------------------------------+------+-------+-----------+-------+
| Site Type | Used | Fixed | Available | Util% |
+------------------------------------------+------+-------+-----------+-------+
| Slice | 3398 | 0 | 4400 | 77.23 |
| SLICEL | 2235 | 0 | | |
| SLICEM | 1163 | 0 | | |
| LUT as Logic | 6799 | 0 | 17600 | 38.63 |
| using O5 output only | 1 | | | |
| using O6 output only | 5271 | | | |
| using O5 and O6 | 1527 | | | |
| LUT as Memory | 714 | 0 | 6000 | 11.90 |
| LUT as Distributed RAM | 456 | 0 | | |
| using O5 output only | 0 | | | |
| using O6 output only | 52 | | | |
| using O5 and O6 | 404 | | | |
| LUT as Shift Register | 258 | 0 | | |
| using O5 output only | 0 | | | |
| using O6 output only | 117 | | | |
| using O5 and O6 | 141 | | | |
| LUT Flip Flop Pairs | 3966 | 0 | 17600 | 22.53 |
| fully used LUT-FF pairs | 953 | | | |
| LUT-FF pairs with one unused LUT | 2819 | | | |
| LUT-FF pairs with one unused Flip Flop | 2684 | | | |
| Unique Control Sets | 599 | | | |
+------------------------------------------+------+-------+-----------+-------+
* Note: Review the Control Sets Report for more information regarding control sets.


3. Memory
---------

+-------------------+------+-------+-----------+-------+
| Site Type | Used | Fixed | Available | Util% |
+-------------------+------+-------+-----------+-------+
| Block RAM Tile | 21 | 0 | 60 | 35.00 |
| RAMB36/FIFO* | 18 | 0 | 60 | 30.00 |
| RAMB36E1 only | 18 | | | |
| RAMB18 | 6 | 0 | 120 | 5.00 |
| RAMB18E1 only | 6 | | | |
+-------------------+------+-------+-----------+-------+
* Note: Each Block RAM Tile only has one FIFO logic available and therefore can accommodate only one FIFO36E1 or one FIFO18E1. However, if a FIFO18E1 occupies a Block RAM Tile, that tile can still accommodate a RAMB18E1


4. DSP
------

+----------------+------+-------+-----------+-------+
| Site Type | Used | Fixed | Available | Util% |
+----------------+------+-------+-----------+-------+
| DSPs | 10 | 0 | 80 | 12.50 |
| DSP48E1 only | 10 | | | |
+----------------+------+-------+-----------+-------+


5. IO and GT Specific
---------------------

+-----------------------------+------+-------+-----------+--------+
| Site Type | Used | Fixed | Available | Util% |
+-----------------------------+------+-------+-----------+--------+
| Bonded IOB | 0 | 0 | 100 | 0.00 |
| Bonded IPADs | 0 | 0 | 2 | 0.00 |
| Bonded IOPADs | 130 | 130 | 130 | 100.00 |
| PHY_CONTROL | 0 | 0 | 2 | 0.00 |
| PHASER_REF | 0 | 0 | 2 | 0.00 |
| OUT_FIFO | 0 | 0 | 8 | 0.00 |
| IN_FIFO | 0 | 0 | 8 | 0.00 |
| IDELAYCTRL | 0 | 0 | 2 | 0.00 |
| IBUFDS | 0 | 0 | 96 | 0.00 |
| PHASER_OUT/PHASER_OUT_PHY | 0 | 0 | 8 | 0.00 |
| PHASER_IN/PHASER_IN_PHY | 0 | 0 | 8 | 0.00 |
| IDELAYE2/IDELAYE2_FINEDELAY | 0 | 0 | 100 | 0.00 |
| ILOGIC | 0 | 0 | 100 | 0.00 |
| OLOGIC | 0 | 0 | 100 | 0.00 |
+-----------------------------+------+-------+-----------+--------+


6. Clocking
-----------

+------------+------+-------+-----------+-------+
| Site Type | Used | Fixed | Available | Util% |
+------------+------+-------+-----------+-------+
| BUFGCTRL | 1 | 0 | 32 | 3.13 |
| BUFIO | 0 | 0 | 8 | 0.00 |
| MMCME2_ADV | 0 | 0 | 2 | 0.00 |
| PLLE2_ADV | 0 | 0 | 2 | 0.00 |
| BUFMRCE | 0 | 0 | 4 | 0.00 |
| BUFHCE | 0 | 0 | 48 | 0.00 |
| BUFR | 0 | 0 | 8 | 0.00 |
+------------+------+-------+-----------+-------+


7. Specific Feature
-------------------

+-------------+------+-------+-----------+-------+
| Site Type | Used | Fixed | Available | Util% |
+-------------+------+-------+-----------+-------+
| BSCANE2 | 0 | 0 | 4 | 0.00 |
| CAPTUREE2 | 0 | 0 | 1 | 0.00 |
| DNA_PORT | 0 | 0 | 1 | 0.00 |
| EFUSE_USR | 0 | 0 | 1 | 0.00 |
| FRAME_ECCE2 | 0 | 0 | 1 | 0.00 |
| ICAPE2 | 0 | 0 | 2 | 0.00 |
| STARTUPE2 | 0 | 0 | 1 | 0.00 |
| XADC | 0 | 0 | 1 | 0.00 |
+-------------+------+-------+-----------+-------+


8. Primitives
-------------

+----------+-------+----------------------+
| Ref Name | Used | Functional Category |
+----------+-------+----------------------+
| FDRE | 10216 | Flop & Latch |
| LUT3 | 2303 | LUT |
| LUT6 | 1835 | LUT |
| LUT4 | 1434 | LUT |
| LUT5 | 1219 | LUT |
| LUT2 | 1171 | LUT |
| FDCE | 628 | Flop & Latch |
| RAMD32 | 610 | Distributed Memory |
| LUT1 | 364 | LUT |
| FDPE | 342 | Flop & Latch |
| CARRY4 | 339 | CarryLogic |
| SRL16E | 338 | Distributed Memory |
| FDSE | 222 | Flop & Latch |
| RAMS32 | 202 | Distributed Memory |
| BIBUF | 130 | IO |
| MUXF7 | 74 | MuxFx |
| SRLC32E | 61 | Distributed Memory |
| RAMD64E | 48 | Distributed Memory |
| RAMB36E1 | 18 | Block Memory |
| DSP48E1 | 10 | Block Arithmetic |
| RAMB18E1 | 6 | Block Memory |
| PS7 | 1 | Specialized Resource |
| MUXF8 | 1 | MuxFx |
| BUFG | 1 | Clock |
+----------+-------+----------------------+


9. Black Boxes
--------------

+----------+------+
| Ref Name | Used |
+----------+------+


10. Instantiated Netlists
-------------------------

+-----------------------------+------+
| Ref Name | Used |
+-----------------------------+------+
| zybo_xlconcat_0 | 1 |
| zybo_xbar_1 | 1 |
| zybo_xbar_0 | 1 |
| zybo_s02_regslice_0 | 1 |
| zybo_s02_data_fifo_0 | 1 |
| zybo_s01_regslice_0 | 1 |
| zybo_s01_data_fifo_0 | 1 |
| zybo_s00_regslice_1 | 1 |
| zybo_s00_regslice_0 | 1 |
| zybo_s00_data_fifo_0 | 1 |
| zybo_ps7_0 | 1 |
| zybo_proc_sys_reset_1_0 | 1 |
| zybo_m01_regslice_0 | 1 |
| zybo_m00_regslice_1 | 1 |
| zybo_m00_regslice_0 | 1 |
| zybo_m00_data_fifo_0 | 1 |
| zybo_lap_filter_axim_0_if_0 | 1 |
| zybo_lap_filter_axim_0_0 | 1 |
| zybo_dm_0_0 | 1 |
| zybo_axis_rtr_dm_0_0 | 1 |
| zybo_auto_us_df_0 | 1 |
| zybo_auto_pc_1 | 1 |
| zybo_auto_pc_0 | 1 |
| zybo_acp_axcache_0xE_0 | 1 |
| zybo_acp_axcache_0x2_0 | 1 |
+-----------------------------+------+

  1. 2016年12月03日 05:41 |
  2. SDSoC
  3. | トラックバック:0
  4. | コメント:0

I2Cリピーター付きカメラ・インターフェース基板2が来ました

MT9D111をコードを伸ばしてステレオ・カメラにする6(I2CリピータIO付きカメラ・インターフェース基板が届いた)”で作ったI2Cリピーター付きカメラ・インターフェース基板ですが、VCC と GND のピンを間違うという大失態を演じてしまいました。orz...

というわけで、新しいI2Cリピーター付きカメラ・インターフェース基板2を11月18日に頼んで、今日届きました。レジストの色は同じ値段で選べるようになったので、黄色にしました。
早く届くように配送に DHL を指定したんですが、製造に2週間くらいかかってしまったので、DHLでは4日くらいで届いたのですが、遅くなってしまいました。

来た基板を見たところ、GNDラインが細いと思って盛ってしまったので、下の写真の→のところがVCC と近くなってしまいました。仕方がないので、ショート気味だったら、カッターを使ってクリアランスを確保します。
でもDRCは問題なかったので、必要なクリアランスは確保できているのかもしれません?良く見えないので。。
kiban_161203.jpg

(2016/12/06 : 追記)
高解像度 顕微鏡デジタルマイクロスコープ で見たところパターンは問題ありませんでした。導通試験もOKでした。
Kiban_2_161206.jpg
  1. 2016年12月02日 20:29 |
  2. プリント基板作成
  3. | トラックバック:0
  4. | コメント:0

Zybot に超音波距離センサを搭載する1(概要)

2台の Zybot での隊列走行5(追従走行を試してみた)」で曲がりなりにも 2 台の Zybot で隊列走行ができるようになった。その際に前走車の走り方によっては隊列走行が崩れる時がよくある。そこで、カメラの画角から外れてしまっても、追従車は予測で走れるようにしたいのだが、何か物体があったらぶつかってしまう。そこで、ぶつからないように超音波距離センサをつけたいと思う。
実は、Zybot に取り付けようとして、秋月電子で、「パララックス社超音波距離センサーモジュール」を購入してある。
マニュアルはこちら”PING))) Ultrasonic Distance Sensor (#28015)
実は安い超音波距離センサも買ってある。「超音波距離センサー HC-SR04

検索してみると「超音波レンジファインダー PING)))™ #28015 」という日本語のマニュアルもあるようだ。

使い方はこの記事「パララックス社超音波距離センサモジュールで距離を計る(2)」を見るとよくわかる。

スケッチもあることだし、まずは Arduino でパララックス社超音波距離センサの動作確認をしてみようかな?
  1. 2016年12月02日 04:05 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0
»