FC2カウンター FPGAの部屋

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

FPGAの部屋

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

Vivado 2017.1 の新機能4(AXI Verification IPのサンプル・デザイン2)

Vivado 2017.1 の新機能3(AXI Verification IPのサンプル・デザイン1)”の続き。

前回は、AXI Verification IPをIPI にAdd IP してサンプル・デザインを呼び出した。今回は、サンプル・デザインをシミュレーションしてみよう。

最初に、Source ウインドウを示す。
10 個のシミュレーション用テストベンチが並んでいる。
そのうちのaxi_vip_0_exdes_adv_mst_active__pt_passive__slv_comb がアクティブになっている。
Vivado_2017-1_37_170423.png

axi_vip_0_exdes_adv_mst_active__pt_passive__slv_comb の図を”AXI Verification IP v1.0 LogiCORE IP Product Guide Vivado Design Suite PG267 April 5, 2017”の”Figure 6-2: Advanced Simulation Sets”から引用する。
Vivado_2017-1_44_170425.png
上の図を見ると、Pass-Through VIP はPassive でトランザクションを通すモードになっていると思う。

Flow Navigator のSIMULATION -> Run Simulation をクリックして、Run Behavioral Simulation を選択した。
論理シミュレーションがスタートした。
Vivado_2017-1_38_170423.png

最初に波形ウインドウに入っていたのは、clk と reset だけだったので、Divider を挟みながら、各VIP モジュールの信号を入れていった。そして、run all を行った。
axi_vip_mst の全体波形を示す。
Vivado_2017-1_39_170425.png

axi_vip_passthroug の全体波形を示す。
Vivado_2017-1_40_170425.png
Vivado_2017-1_41_170425.png

axi_vip_slv の全体波形を示す。
Vivado_2017-1_42_170425.png

axi_vip_mst のアドレス転送部分を拡大してみよう。
Vivado_2017-1_43_170425.png

まずは、Write トランザクションから、最初のWrite トランザクションのパラメータを示す。
awaddr = 0, awlen = 0d, awsize = 0, awburst = 0, awlock = 0, awcache = e, awport = 4, awregion = 0, awqos = 1
awlen のバースト長 14、awsize は1バイトずつの転送、awburst はアドレス固定、awlock はノーマル・アクセス、awcache はWrite-through Read and Write-allocate、awport は Instruction access, Secure access, Unprivileged acces だった。

次のWrite トランザクションを示す。
awaddr = 0, awlen = 0, awsize = 2, awburst = 1, awlock = 0, awcache = 0, awport = 0, awregion = 0, awqos = 0
awlen のバースト長 1、awsize は4バイトずつの転送、awburst はアドレスをインクリメント、awlock はノーマル・アクセス、awcache はDevice Non-bufferable、awport は Data access, Secure access, Unprivileged acces だった。

最初のRead トランザクションを示す。
araddr = fffffffe, arlen = 0f, arsize = 1, arburst = 2, arlock = 0, arcache = f, arport = 1, arregion = c, arqos = b
arlen のバースト長 16、arsize は2 バイトずつの転送、arburst はアドレスをキャッシュに使われるようにwrap around、arlock はノーマル・アクセス、arcache はWrite-back Read and Write-allocate、arport は Data access, Non-Secure access, Unprivileged acces だった。

次の Read トランザクションを示す。
araddr = 00000000, arlen = 0, arsize = 2, arburst = 1, arlock = 0, arcache = 0, arport = 0, arregion = 0, arqos = 0
arlen のバースト長 1、arsize は4バイトずつの転送、arburst はアドレスをインクリメント、arlock はノーマル・アクセス、arcache はDevice Non-bufferable、arport は Data access, Secure access, Unprivileged acces だった。

最初の Read トランザクションは 0xfffffffe から 16バーストなので、4 K バイト境界を越してしまう。よって、AXI のプロトコル違反なんじゃないか?と思う。ランダムで生成されているようなのだが、ランダムの数に制約は付けられないのかな?
ランダムに発生させた数に自分で制約を与えれば良いのだとは思うが。。。
  1. 2017年04月25日 06:08 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:0

「ニューラルネットワークと深層学習」をやってみる1(CHAPTER 1 ニューラルネットワークを用いた手書き文字認識)

とっても良い資料の「ニューラルネットワークと深層学習」をやってみよう。

そのうちの、「CHAPTER 1 CHAPTER 1 ニューラルネットワークを用いた手書き文字認識」をやってみる。
内容はWeb サイトをよく見てもらうとよくわかると思う。
更にGitHub にPython 2系のコードが置いてあって実際に試してみることができる。
試した環境はVirtualBox 5.1.20 上にインストールしたUbuntu 16.04 となっている。Python のバージョンは2.7.6 だった。

まずは、

git clone https://github.com/mnielsen/neural-networks-and-deep-learning.git

でGitHub からクローンした。
neural-networks-and-deep-learning ディレクトリが作成されて、中に data, fig, src ディレクトリがあった。
DLNN_1_170424.png

data ディレクトリには、mnist.pkl.gz たぶん手書き文字のデータが入っていた。
fig には、文字の画像やグラフが入っている。
DLNN_2_170424.png

src にはPython のソース・ファイルが入っている。
DLNN_3_170424.png

Python を動かすには src ディレクトリで動作させるが、危ないかな?ということで、DLNN_example ディレクトリを新規作成して、neural-networks-and-deep-learning ディレクトリの中身をコピー&ペーストした。
DLNN_4_170424.png

~/DNN/DLNN_example/src ディレクトリに行って、

python

とタイプしてPython をインタプリタモードで起動した。
次のコマンドを入力した

training_data, validation_data, test_data = \
mnist_loader.load_data_wrapper()
import network
net.SGD(training_data, 30, 10, 3.0, test_data=test_data)


DLNN_5_170424.png

学習が始まり、30回で終了した。
DLNN_6_170424.png
Epoch 28 で 86.27 % なので、書いてあるよりも性能が悪い。

次に、隠れニューロンを 30 から 100 に変更した。
net = network.Network([784, 100, 10])
net.SGD(training_data, 30, 10, 3.0, test_data=test_data)


DLNN_7_170424.png
DLNN_8_170424.png
Epoch 28 で 96.37 % だった。こっちは書いてあるのに近い。

学習率η=0.001 に変更した。

net = network.Network([784, 100, 10])
net.SGD(training_data, 30, 10, 0.001, test_data=test_data)


DLNN_9_170424.png
DLNN_10_170424.png
やはり学習が進まない。

学習率η=0.01 に変更した。

net = network.Network([784, 100, 10])
net.SGD(training_data, 30, 10, 0.01, test_data=test_data)


DLNN_11_170424.png
DLNN_12_170424.png
学習率η=0.001 ほどではないがやはり学習が遅い。

学習率η=100 にしてみた。

net = network.Network([784, 100, 10])
net.SGD(training_data, 30, 10, 100, test_data=test_data)


DLNN_13_170424.png
DLNN_14_170424.png
ほとんど学習できていない感じだ。

全てのコマンドと表示を貼っておく。

ono@ono-VirtualBox:~/DNN$ cd DLNN_example/
ono@ono-VirtualBox:~/DNN/DLNN_example$ ls
README.md  data  fig  requirements.txt  src
ono@ono-VirtualBox:~/DNN/DLNN_example$ cd src
ono@ono-VirtualBox:~/DNN/DLNN_example/src$ python
Python 2.7.6 (default, Oct 26 2016, 20:30:19) 
[GCC 4.8.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mnist_loader
>>> import network
>>> net = network.Network([784, 30, 10])
>>> net.SGD(training_data, 30, 10, 3.0, test_data=test_data)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'training_data' is not defined
>>> 
>>> q
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'q' is not defined
>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exit
>>> 
ono@ono-VirtualBox:~/DNN/DLNN_example/src$ python
Python 2.7.6 (default, Oct 26 2016, 20:30:19) 
[GCC 4.8.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mnist_loader
>>> training_data, validation_data, test_data = \
... mnist_loader.load_data_wrapper()
>>> import network
>>> net = network.Network([784, 30, 10])
>>> net.SGD(training_data, 30, 10, 3.0, test_data=test_data)
Epoch 0: 7500 / 10000
Epoch 1: 8497 / 10000
Epoch 2: 8557 / 10000
Epoch 3: 8609 / 10000
Epoch 4: 8605 / 10000
Epoch 5: 8638 / 10000
Epoch 6: 8635 / 10000
Epoch 7: 8631 / 10000
Epoch 8: 8662 / 10000
Epoch 9: 8654 / 10000
Epoch 10: 8657 / 10000
Epoch 11: 8672 / 10000
Epoch 12: 8682 / 10000
Epoch 13: 8691 / 10000
Epoch 14: 8702 / 10000
Epoch 15: 8681 / 10000
Epoch 16: 8691 / 10000
Epoch 17: 8696 / 10000
Epoch 18: 8672 / 10000
Epoch 19: 8704 / 10000
Epoch 20: 8695 / 10000
Epoch 21: 8715 / 10000
Epoch 22: 8711 / 10000
Epoch 23: 8718 / 10000
Epoch 24: 8710 / 10000
Epoch 25: 8726 / 10000
Epoch 26: 8686 / 10000
Epoch 27: 8693 / 10000
Epoch 28: 8727 / 10000
Epoch 29: 8703 / 10000
>>> net = network.Network([784, 100, 10])
>>> net.SGD(training_data, 30, 10, 3.0, test_data=test_data)
Epoch 0: 8352 / 10000
Epoch 1: 8510 / 10000
Epoch 2: 8550 / 10000
Epoch 3: 8613 / 10000
Epoch 4: 8629 / 10000
Epoch 5: 8659 / 10000
Epoch 6: 8689 / 10000
Epoch 7: 8695 / 10000
Epoch 8: 8705 / 10000
Epoch 9: 8742 / 10000
Epoch 10: 9498 / 10000
Epoch 11: 9561 / 10000
Epoch 12: 9588 / 10000
Epoch 13: 9569 / 10000
Epoch 14: 9600 / 10000
Epoch 15: 9595 / 10000
Epoch 16: 9617 / 10000
Epoch 17: 9610 / 10000
Epoch 18: 9619 / 10000
Epoch 19: 9625 / 10000
Epoch 20: 9626 / 10000
Epoch 21: 9626 / 10000
Epoch 22: 9630 / 10000
Epoch 23: 9641 / 10000
Epoch 24: 9634 / 10000
Epoch 25: 9629 / 10000
Epoch 26: 9649 / 10000
Epoch 27: 9628 / 10000
Epoch 28: 9637 / 10000
Epoch 29: 9629 / 10000
>>> net = network.Network([784, 100, 10])
>>> net.SGD(training_data, 30, 10, 0.001, test_data=test_data)
Epoch 0: 1172 / 10000
Epoch 1: 1116 / 10000
Epoch 2: 1022 / 10000
Epoch 3: 1201 / 10000
Epoch 4: 1693 / 10000
Epoch 5: 1810 / 10000
Epoch 6: 1906 / 10000
Epoch 7: 1973 / 10000
Epoch 8: 2024 / 10000
Epoch 9: 2089 / 10000
Epoch 10: 2158 / 10000
Epoch 11: 2206 / 10000
Epoch 12: 2255 / 10000
Epoch 13: 2291 / 10000
Epoch 14: 2341 / 10000
Epoch 15: 2378 / 10000
Epoch 16: 2411 / 10000
Epoch 17: 2455 / 10000
Epoch 18: 2479 / 10000
Epoch 19: 2526 / 10000
Epoch 20: 2555 / 10000
Epoch 21: 2598 / 10000
Epoch 22: 2640 / 10000
Epoch 23: 2682 / 10000
Epoch 24: 2718 / 10000
Epoch 25: 2751 / 10000
Epoch 26: 2777 / 10000
Epoch 27: 2809 / 10000
Epoch 28: 2845 / 10000
Epoch 29: 2878 / 10000
>>> net = network.Network([784, 100, 10])
>>> net.SGD(training_data, 30, 10, 0.01, test_data=test_data)
Epoch 0: 1515 / 10000
Epoch 1: 1890 / 10000
Epoch 2: 2038 / 10000
Epoch 3: 2185 / 10000
Epoch 4: 2339 / 10000
Epoch 5: 2506 / 10000
Epoch 6: 2684 / 10000
Epoch 7: 2852 / 10000
Epoch 8: 2981 / 10000
Epoch 9: 3123 / 10000
Epoch 10: 3253 / 10000
Epoch 11: 3422 / 10000
Epoch 12: 3560 / 10000
Epoch 13: 3640 / 10000
Epoch 14: 3721 / 10000
Epoch 15: 3770 / 10000
Epoch 16: 3834 / 10000
Epoch 17: 3899 / 10000
Epoch 18: 3967 / 10000
Epoch 19: 4052 / 10000
Epoch 20: 4134 / 10000
Epoch 21: 4216 / 10000
Epoch 22: 4316 / 10000
Epoch 23: 4412 / 10000
Epoch 24: 4513 / 10000
Epoch 25: 4591 / 10000
Epoch 26: 4686 / 10000
Epoch 27: 4763 / 10000
Epoch 28: 4868 / 10000
Epoch 29: 4977 / 10000
>>> net = network.Network([784, 100, 10])
>>> net.SGD(training_data, 30, 10, 100, test_data=test_data)
Epoch 0: 894 / 10000
Epoch 1: 894 / 10000
Epoch 2: 894 / 10000
Epoch 3: 894 / 10000
Epoch 4: 894 / 10000
Epoch 5: 894 / 10000
Epoch 6: 894 / 10000
Epoch 7: 894 / 10000
Epoch 8: 894 / 10000
Epoch 9: 893 / 10000
Epoch 10: 893 / 10000
Epoch 11: 893 / 10000
Epoch 12: 893 / 10000
Epoch 13: 893 / 10000
Epoch 14: 893 / 10000
Epoch 15: 893 / 10000
Epoch 16: 893 / 10000
Epoch 17: 893 / 10000
Epoch 18: 893 / 10000
Epoch 19: 893 / 10000
Epoch 20: 892 / 10000
Epoch 21: 892 / 10000
Epoch 22: 892 / 10000
Epoch 23: 1262 / 10000
Epoch 24: 1262 / 10000
Epoch 25: 1262 / 10000
Epoch 26: 1262 / 10000
Epoch 27: 1262 / 10000
Epoch 28: 1262 / 10000
Epoch 29: 1262 / 10000
>>> 


  1. 2017年04月24日 21:32 |
  2. DLNN
  3. | トラックバック:0
  4. | コメント:0

Vivado 2017.1 の新機能3(AXI Verification IPのサンプル・デザイン1)

Vivado 2017.1 の新機能2(AXI Verification IPの概要)”の続き。

前回は、AXI Verification IP の概要を調べた。今回は、AXI Verification IP のサンプル・デザインをやってみよう。

なお、AXI Verification IPの記事を tethys_seesaa さんにお願いして書いて頂いた。検証のプロだけに、要点がまとまった良い記事だと思うので、ご紹介したい。”XilinxのAXI Verification IPを試す。

AXI Verification IPのサンプル・デザインには、10 個のシミュレーション・セット・テストベンチがあって、シミュレーション用のファイルが 3 個ある。 generic_tb.sv と マスタ・スティミュラス、スレーブ・スティミュラスだ。
generic_tb.sv はマスタ側をエラーチェックする機能がある。マスタ・スティミュラスは、AXI Master VIPとAXI pass-through VIP で生成されて、スレーブ・スティミュラスはAXI Slave VIPでマスタへの応答として生成されるようだ。

それでは、AXI Verification IPのサンプル・デザインを始めよう。
まずは、”Digilent社のボード・ファイルのインストール”を参考にして、Vivado 2017.1 に Digilent 社のボード・ファイルをインストールする。
Vivado 2017.1 で ZYBO 用のプロジェクトを作成する。
次に、AXI_VIP_test という名前のブロック・デザインを生成した。
Vivado_2017-1_30_170423.png

Diagram ウインドウで + ボタンをクリックして、IP を追加する。
Vivado_2017-1_31_170423.png

Search のテキスト・ボックスに”AXI Veri”と入力して、AXI Verification IPを選択する。
Vivado_2017-1_32_170423.png

axi_vip_0 がインスタンスされた。
セーブ・ボタンでセーブする。(セーブしないと、Open IP Examples Design... が出てこない)
Vivado_2017-1_33_170423.png

左のDegign ウインドウの axi_vip_0 を右クリックし、右クリックメニューからOpen IP Examples Design... を選択する。
Vivado_2017-1_34_170423.png

Open IP Example Design ダイアログが表示された。
デフォルトで、OK ボタンをクリックする。
Vivado_2017-1_35_170423.png

axi_vip_0_ex プロジェクトが生成されて、開いた。
Vivado_2017-1_36_170423.png
  1. 2017年04月24日 06:13 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:2

Vivado 2017.1 の新機能2(AXI Verification IPの概要)

Vivado 2017.1 の新機能1(概要)”の続き。

前回は、Vivado 2017.1 の新機能の概要を書いた。今回は、AXI Verification IPの概要を調査しよう。

AXI Verification IP v1.0 LogiCORE IP Product Guide Vivado Design Suite PG267 April 5, 2017”を参照させて頂くことにする。
”AR# 68234 AXI Verification IP - AXI VIP のリリース ノートおよび既知の問題”も参考にしよう。

AXI Verification IP v1.0 LogiCORE IP Product Guide Vivado Design Suite PG267 April 5, 2017”によると、AXI Verification IP には、3つのモードがある。

AXI Master VIP
AXI Slave VIP
AXI Pass-Through VIP


つまり、AXI Master になるか、AXI Slave になるか、AXI Master とAXI Slave の間に入るか?の違いのようだ。
AXI VIP はSystemVerilog で書かれているそうだ。Vivado のSystemVerilog サポートも進んできて、だいぶ良くなったのだろう?
UVMと同様の名前付けと構造を使用しているようだ。
AXI VIP は2つの部分で構成されている。

other traditional IP (modules in the static/physical world)
dynamic world


つまり、HDLで書かれた従来のIP があってダイナミック?なソフトウェアがあって、AXI VIP は、仮想インターフェース(virtual interface)でその2つの橋渡しをするようだ。

AXI Master VIP
AXI Master VIPは3つのパートからできている。

• User environment
• Master agent
• AXI master VIP


ソフトウェアの世界には、マスター・エージェントがあって、それには4つのクラス・メンバがあるそうだ。

• Master write driver
• Master read driver
• Monitor
• Virtual interface


AXI Verification IP v1.0 LogiCORE IP Product Guide Vivado Design Suite PG267 April 5, 2017”の29ページの”Figure 4-4: AXI VIP Master Test Bench”を引用する。
Vivado_2017-1_27_170423.png
この図を見ると一目瞭然だ。

ユーザー環境(User Environment)がWrite トランザクションを定義して、マスタ・エージェントのマスタ・ライト・ドライバが create_transaction を行う。
ユーザー環境はデータ入力かランダム入力?トランザクションを決めて、データを出力して、マスタ・エージェントに送る。
マスタ・エージェントでは、send でAXI VIP 経由で検証対象のAXI System に送られるようだ。
AXI Verification IP v1.0 LogiCORE IP Product Guide Vivado Design Suite PG267 April 5, 2017”の30ページの”Figure 4-5: Write Transaction Flow”を引用する。
Vivado_2017-1_28_170423.png

AXI Slave VIP
AXI slave VIP は3つのパートからできている。

• User environment
• Slave agent without a memory model
• AXI slave VIP


やはり、AXI Master VIPと同様にマスタ・エージェントの代わりにスレーブ・エージェントがあって、メモリモデル無しのスレーブ・エージェントには4つのクラス・メンバがある。

• Slave write driver
• Slave read driver
• Monitor
• Virtual interface


”Figure 4-6: AXI VIP Slave Test Bench ”は、構造的には、”Figure 4-5: Write Transaction Flow”と同じ。

Writeする場合は、ユーザー環境は、トランザクション・タイプの変数を宣言してから、スレーブWrite ドライバが get_wr_reactive をコールしてWrite トランザクションが来るまで待っている。
Write トランザクションが来たら、ユーザー環境が用意されたデータでもランダムデータでも応答を用意する。それをスレーブWrite ドライバが仮想インターフェース越しに、AXI VIP に送る。
AXI VIP は応答をAXI System に物理的な信号線で伝える。

Simple SRAM Memory Model
AXI Slave VIP はSystemVerilog の配列を使ったシンプルなメモリ・モデルがある。
Write トランザクションでは、メモリのデータをWrite して、Read トランザクションでは、メモリからデータをRead することができる。
この機能は、ランタイム・スレーブ・モードで、AXI Slave VIPとAXI Pass-through VIP に実装されているそうだ。
メモリ・モデルには、backdoor_memory_write と backdoor_memory_read があって、それぞれ Write または Read するバックドアAPI とのこと。
やはり、メモリ・モデルが無いとAXI Slave を処理するのは厳しい気がするので、これがあって良かった。
AXI Verification IP v1.0 LogiCORE IP Product Guide Vivado Design Suite PG267 April 5, 2017”の32ページのFigure 4-8: Memory Model”を引用する。
Vivado_2017-1_29_170423.png
なお、readmemh はサポートされていないそうだ。あと、reset してもメモリ内容には影響が無いそうだ。

AXI Slave Simple Memory VIP
AXI Slave Simple Memory VIP はAXI Slave VIP にメモリ・モデルが入っているもので、こっちのほうが使いやすいと思う。
私だったら、これを使用すると思う。
  1. 2017年04月23日 07:00 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:0

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

Vivado 2016.2 とVivado 2016.3 の間にはアップグレードの壁がある。
Vivado 2016.4 から Vivado 2017.1 へは簡単にアップグレードできるかどうかを確かめてみた。それにVivado 2017.1 ではルック&フィールが違っているので、確かめてみた。

Vivado 2016.4 からVivado 2017.1 にアップグレードするプロジェクトは”Vivado HLS で生成した AXI4 Master DMA IP を使用したカメラ画像表示システム”を使用する。

それでは、Vivado 2017.1 を立ち上がるところから行ってみよう。立ち上げたら、Open Project > をクリックする。
Vivado_2017-1_01_170421.png

予め cam_disp_axis_171 フォルダにプロジェクトをコピーしておいたので、そのフォルダの cam_disp_axis.xpr を選択してOKボタンをクリックした。
Vivado_2017-1_2_170421.png

Older Project Version ダイアログが表示された。Automatically upgrade to the current version のラジオボタンが選択されていることを確認して、OK ボタンをクリックする。
Vivado_2017-1_3_170421.png

Critical Warning が表示されている。Project Upgraded ダイアログも表示された。Report IP Status ボタンをクリックする。
Vivado_2017-1_4_170421.png

IP Status の Upgrade Selected ボタンをクリックする。
Vivado_2017-1_5_170421.png

Upgrade IP ダイアログが表示された。OK ボタンをクリックする。
Vivado_2017-1_6_170421.png

Upgrade IP ダイアログが表示された。IP Upgrade Completed だった。OK ボタンをクリックする。
Vivado_2017-1_7_170421.png

Genrerate Output Products ダイアログが表示された。Generate ボタンをクリックする。
Vivado_2017-1_8_170421.png

Critical Warning を示す。
board value is unset. ということだった。digilent のIP なので、とりあえず放置する。
Vivado_2017-1_9_170421.png

アップグレードが終了した。
Vivado_2017-1_10_170421.png

ブロックデザインを示す。
Vivado_2017-1_26_170422.png

Vivado 2017.1 では、ブロックデザインを表示すると、標準でIP Catalog が表示されているようだ。
Vivado_2017-1_11_170421.png

Address Editor を示す。
Vivado_2017-1_12_170421.png

Flow Navigator のGenerate Bitstream をクリックしてビットストリームの生成を行った。なお、上のアイコンにGenerate Bitstream があるので、これをクリックしても良いと思う。

Synthesis is Out-of-date ダイアログが表示された。Yes ボタンをクリックする。
Vivado_2017-1_13_170421.png

Launch Runs ダイアログが表示された。OK ボタンをクリックする。
Vivado_2017-1_14_170421.png

ビットストリームの生成が終了した。Bitstream Generation Completed ダイアログが表示された。Cancel ボタンをクリックする。
Vivado_2017-1_15_170421.png

Project Summary ボタンをクリックすると、Project Summary が表示される。
Vivado_2017-1_16_170421.png

左にVivado 2017.1 のProject Summary を示す。右にVivado 2016.4 のProject Summary を示す。Vivado 2017.1 のほうが少しリソース使用量が増えている。
Vivado_2017-1_17_170421.pngVivado_2017-1_18_170421.png

File メニューから Export -> Export Hardware... を選択した。
Vivado_2017-1_19_170421.png

Export Hardware ダイアログが表示された。Include bitstream にチェックを入れて、OK ボタンをクリックする。
Vivado_2017-1_20_170421.png

Vivado 2016.4 からのアップグレードなので、Module Already Exported ダイアログが表示された。Yes ボタンをクリックする。
Vivado_2017-1_21_170421.png

File メニューから Launch SDK を選択した。Launch SDK ダイアログが表示された。OK ボタンをクリックする。
Vivado_2017-1_22_170421.png

SDK が立ち上がり、Older Workspace Versin ダイアログが表示された。OK ボタンをクリックする。
Vivado_2017-1_23_170421.png

cam_disp_axis_wrapper_hw_platform_1 が新規作成された。
Vivado_2017-1_24_170421.png

cam_disp_axis_wrapper_hw_platform_1 プロジェクト以外のプロジェクトをすべて消去した。
cam_disp_hls プロジェクトを新規作成し、ソースコードをドラック&ドロップするとビルドが行われた。
ZYBO を接続して、Program FPGA を行い、cam_disp_hls.elf を起動すると、正常に画像が表示された。
Vivado_2017-1_25_170421.png

Vivado 2016.4 から Vivado 2017.1 へのアップグレードは問題ないようだ。
  1. 2017年04月22日 07:52 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:0

Vivado 2017.1 の新機能1(概要)

昨日、Vivado 2017.1 が出た。早速、インストールしてみたのだが、GUI が新しくなっていた。Windows と Linux のルック・アンド・フィールを統一してあるそうだ。
Vivado_2017-1_01_170421.png

Vivado_2017-1_02_170421.png

Vivado Design Suite ユーザー ガイド リリース ノート 、 インス トール およびライセンス UG973 (v2017.1) 2017 年 4 月 5 日”を見るとたくさんの機能が新しくなったようだ。
気になる機能を、”Vivado Design Suite ユーザー ガイド リリース ノート 、 インス トール およびライセンス UG973 (v2017.1) 2017 年 4 月 5 日”から引用する。

・Vivado IP インテグーター
 ・ AXI 設計アシ ス タ ン ス:
  ° AXI Interconnect (古い) または AXI SmartConnect (新しい) か ら選択可能。
  ° 設計アシ ス タ ン スによ る自動化を AXI4-Stream インターフェイス、 CLK、 リ セ ッ ト に拡張。


IPI での自動配線で、AXI Interconnect と AXI SmartConnect を選択可能なのか?やってみたい。
コメントをIPI 上に書けて、HDL ソースにも含められるそうだ。今までもコメントは書けたので、HDL に含められるのが新しい?

シ ミ ュレーション フ ローおよび検証 IP では、検証IP として、AXI Verification IP と Zynq-7000 VIP が導入されたそうだ。
AXI Verification IPは検証だけで、BFMの機能は無いのだろうか? Zynq-7000 VIPも興味深い。
AXI Verification IP に関しては、”サンプル デザインおよびテスト ベンチを IP インテグレーターで提供”とのことなので、すぐにやってみたい。
Vivado Design Suite ユーザー ガイド リリース ノート 、 インス トール およびライセンス UG973 (v2017.1) 2017 年 4 月 5 日”の 8 ページから引用する。

• 検証 IP
 ° AXI Verification IP を導入
  - SystemVerilog ベース、 ラ イセンス不要
  - AXI3、 AXI4、 および AXI4-Lite をサポー ト 。
  - すべてのプ ロ ト コル データ幅およびア ド レ ス幅、 転送タ イプ、 応答をサポー ト
  - AXI プロ ト コル チェ ッ カーを完全にサポー ト
  - 統合 ARM ラ イセンスのプロ ト コル アサーシ ョ ン
  - パス スルー モー ド で合成を イネーブル (ワ イヤに合成)
  - シ ミ ュレーシ ョ ン メ ッ セージを設定可能
  - サンプル デザイ ンおよびテス ト ベンチを IP イ ンテグ レーターで提供
 ° Zynq-7000 VIP を導入 (上記の AXI VIP に基づ く )
  - ラ イセン ス不要、 SystemVerilog ベース
  - PS Configuration ウ ィ ザー ド の出力フ ァ イル と し て提供
  - 既存の Zynq-7000 BFM 用 API と下位互換性あ り


もしかして、AXI Verification IP はライセンス不要と書いてないので、ライセンスが必要なのか?その場合は試してみることができないな。。。 失礼しました。ライセンス不要と書いてありました。

Vivado デバックで、IPI でのデバックでランタイムのAXIトランザクションの表示をサポートするそうだ。波形のトランザクション行を表示するということで、Vivado アナライザでトランザクション行を表示してくれるのだろうか?楽しみだ。
Vivado Design Suite ユーザー ガイド リリース ノート 、 インス トール およびライセンス UG973 (v2017.1) 2017 年 4 月 5 日”の 10 ページから引用する。

Vivado デバッグ
• IP イ ンテグレーターでのシステム デバ ッ グで ラ ン タ イ ムの AXI ト ラ ンザ ク シ ョ ンの表示をサポー ト 。
 ° 波形に ト ラ ンザ ク シ ョ ン行を表示。
 ° IP イ ンテグ レーターか ら ビ ッ ト ス ト リ ーム生成のフ ローを改善。
  - IP イ ンテグ レーターの設計アシ ス タ ン ス を向上。
  - 合成後に [Debug] ウィンドウで System ILA を表示。


皆さん。。。

System Edition および Design Edition でパーシャル リコンフィ ギュ レーシ ョン (PR) ラ イセン ス を追加コ ス ト な しで提供。

だそうです。やった~。。。これで私もパーシャル リコンフィ ギュ レーシ ョン 試せる。Xilinxさん太っ腹。。。
残念ながら、WebPACK では、ライセンス料が値下げされていはいるが、PR のライセンス料が発生するようだ。

IP としてHDMI のIPが追加されて、MIPI IP の 7 シリーズのサポートが追加されたそうです。

その他、数え切れない程の追加があるようです。でも、こんなにアップデートが多いとバグが心配ですね。気を付けて使ったほうがよさそうです。。。

Vivado HLS のアップデートですが、Vivado System Edition 製品としてアップデートが書いてあるんですが、これは前に System Edition にしかVivado HLS が入っていなかった頃の名残なんでしょうか? System Edition だけVivado HLS を更新して、他のエディションのVivado HLS を更新しないということはあり得ないと思うんですが。。。
math.h ライブラリがアップデートされて、DATAFLOWプラグマで範囲が可変のループをサポートしたそうです。
これに期待しているのですが、C/RTL協調シミュレーションで、ユーザーアシスタンス機能をイネーブルにしたそうです。どのように使いやすくなっているか?楽しみです。

  1. 2017年04月21日 05:05 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:0

”FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(PYNQ-Z1対応)”を使用してカメラの画像を表示

「”FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(PYNQ-Z1対応)”を試してみる9(入れ替え2)」では、FASTX コーナー検出、ラプラシアンフィルタ、アンシャープ・マスクキング・フィルタの回路を使用して、カメラ画像を表示することができなかった。これは、PS から出力される fclk の出力周波数が設定されていないのが原因ではないか?というご指摘を ikwzm さんから頂いた。
そこで、「ikwzm さんの構築したPYNQ ボード用DebianでのPS出力クロックfclkの設定方法」で、デバイスツリー・オーバーレイを使用した。fclk の設定のやり方を学習したので、実際にFASTX コーナー検出、ラプラシアンフィルタ、アンシャープ・マスクキング・フィルタの回路に適用して試してみよう。

まずは、「”FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(PYNQ-Z1対応)”を試してみる7(shellスクリプト)」で作成した devtov スクリプトを変更した。
PYNQ_Linux_ikwzm_107_170419.png

#!/bin/sh
# device tree overlay command (devtov)
# Be sure to run it as superuser
# $1 is device tree name

mkdir /config/device-tree/overlays/$1
cp $1.dtbo /config/device-tree/overlays/$1/dtbo
echo 1 > /config/device-tree/overlays/$1/status

sleep 0.1
chmod 666 /dev/uio*
ls -l /dev/uio*

if test -e /dev/udmabuf*; then
    chmod 666 /dev/udmabuf*
    ls -l /dev/udmabuf*
fi

if test -e /dev/fclk0; then
    chmod 666 /dev/fclk*
    ls -l /dev/fclk*
fi


次に、「ikwzm さんの構築したPYNQ ボード用DebianでのPS出力クロックfclkの設定方法」を参考に fclk のエントリを追加したデバイスツリー・オーバーレイの pynq_fastx_fclk.dts を作成した。
PYNQ_Linux_ikwzm_108_170419.png

/dts-v1/;
/ {
    fragment@0 {
        target-path = "/amba";
        __overlay__ {
            #address-cells = <0x1>;
            #size-cells = <0x1>;
            axi_iic_0@41600000 {
                compatible = "generic-uio";
                reg = <0x41600000 0x10000>;
                #interrupts = <0x0 0x1d 0x4>;
            };
            axi_vdma_0@43000000 {
                compatible = "generic-uio";
                reg = <0x43000000 0x10000>;
                #interrupts = <0x0 0x1d 0x4>;
            };
            axis_switch_0@43C10000 {
                compatible = "generic-uio";
                reg = <0x43C10000 0x10000>;
                #interrupts = <0x0 0x1d 0x4>;
            };
            axis_switch_1@43C20000 {
                compatible = "generic-uio";
                reg = <0x43C20000 0x10000>;
                #interrupts = <0x0 0x1d 0x4>;
            };
            bitmap_disp_cntrler_axi_master_0@43C00000 {
                compatible = "generic-uio";
                reg = <0x43C00000 0x10000>;
                #interrupts = <0x0 0x1d 0x4>;
            };
            fastx_corner_det_0@43C30000 {
                compatible = "generic-uio";
                reg = <0x43C30000 0x10000>;
                #interrupts = <0x0 0x1d 0x4>;
            };
            lap_filter_axis_0@43C50000 {
                compatible = "generic-uio";
                reg = <0x43C50000 0x10000>;
                #interrupts = <0x0 0x1d 0x4>;
            };
            mt9d111_inf_axis_0@43C40000 {
                compatible = "generic-uio";
                reg = <0x43C40000 0x10000>;
                #interrupts = <0x0 0x1d 0x4>;
            };
            unsharp_mask_axis_0@43C60000 {
                compatible = "generic-uio";
                reg = <0x43C60000 0x10000>;
                #interrupts = <0x0 0x1d 0x4>;
            };
            udmabuf4 {
                compatible = "ikwzm,udmabuf-0.10.a";
                minor-number = <4>;
                size = <0x00600000>;
            };
            fclk0 {
                compatible  = "ikwzm,fclkcfg-0.10.a";
                clocks      = <1 15>;
            };
            fclk1 {
                compatible  = "ikwzm,fclkcfg-0.10.a";
                clocks      = <1 16>;
            };
            fclk2 {
                compatible  = "ikwzm,fclkcfg-0.10.a";
                clocks      = <1 17>;
            };
        };
    };
};


dtc -I dts -O dtb -o pynq_fastx_fclk.dtbo pynq_fastx_fclk.dts
で dts をコンパイルして、pynq_fastx_fclk.dtbo を生成した。
PYNQ_Linux_ikwzm_109_170419.png

スーパーユーザーになって、
./devtov pynq_fastx_fclk
で、デバイスツリー・オーバーレイをロードした。uio, udmabuf, fclk のデバイスツリー・オーバーレイがロードされた。
PYNQ_Linux_ikwzm_110_170419.png

/sys/class/fclkcfg/fclk0 ディレクトリに移動して fclk0 のステータスを見た。
100 MHz に設定されていた。 enable = 1 なので、すでに出力されている。
cd /sys/class/fclkcfg/fclk0
cat rate
cat round_rate
cat enable

PYNQ_Linux_ikwzm_111_170419.png

/sys/class/fclkcfg/fclk1 ディレクトリに移動して fclk1 のステータスを見た。
rate を 25 MHz に設定した。
cd ../fclk1
cat rate
cat round_rate
cat enable
su
echo 25000000 > round_rate
cat round_rate
echo 25000000 > rate
cat rate
exit

PYNQ_Linux_ikwzm_112_170419.png

/sys/class/fclkcfg/fclk2 ディレクトリに移動して fclk2 のステータスを見た。
rate を 72 MHz に設定したが、round_rate の結果をみると、71.428572 MHz だった。
cd ../fclk2
cat rate
cat round_rate
cat enable
su
echo 72000000 > round_rate
cat round_rate
echo 72000000 > rate
cat rate
exit

PYNQ_Linux_ikwzm_113_170419.png

~/device_tree_overlay/ ディレクトリに戻って、pynq_fastx_wrapper.bit をPYNQ ボードにコンフィギュレーションした。
cd ~/device_tree_overlay/
ls
su
./fpgamag pynq_fastx_wrapper.bit
exit


”FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(PYNQ-Z1対応)”を試してみる9(入れ替え2)」の cam_disp.c の表示が出ないように書き換えて、コンパイルを行った。
cam_disp を起動した。
gcc -o cam_disp cam_disp.c
./cam_disp

PYNQ_Linux_ikwzm_114_170419.png

すると、カメラ画像を表示することができました。(部屋が散らかっていて、お見苦しい点をお詫びいたします)
PYNQ_Linux_ikwzm_115_170419.jpg

最後に、修正した cam_disp.c を貼っておきます。

// cam_disp.c
// 2017/04/08 by marsee
//

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/mman.h>
#include <fcntl.h>

#define NUMBER_OF_WRITE_FRAMES  3 // Note: If not at least 3 or more, the image is not displayed in succession.

#define HORIZONTAL_PIXELS   800
#define VERTICAL_LINES      600
#define PIXEL_NUM_OF_BYTES  4
#define ALL_DISP_ADDRESS    (HORIZONTAL_PIXELS*VERTICAL_LINES*PIXEL_NUM_OF_BYTES)

#define FASTX_THRESHOLD     20

void cam_i2c_init(volatile unsigned *mt9d111_i2c_axi_lites) {
    mt9d111_i2c_axi_lites[64] = 0x2// reset tx fifo ,address is 0x100, i2c_control_reg
    mt9d111_i2c_axi_lites[64] = 0x1// enable i2c
}

void cam_i2x_write_sync(void) {
    // unsigned c;

    // c = *cam_i2c_rx_fifo;
    // while ((c & 0x84) != 0x80)
        // c = *cam_i2c_rx_fifo; // No Bus Busy and TX_FIFO_Empty = 1
    usleep(1000);
}

void cam_i2c_write(volatile unsigned *mt9d111_i2c_axi_lites, unsigned int device_addr, unsigned int write_addr, unsigned int write_data){
    mt9d111_i2c_axi_lites[66] = 0x100 | (device_addr & 0xfe);   // Slave IIC Write Address, address is 0x108, i2c_tx_fifo
    mt9d111_i2c_axi_lites[66] = write_addr;
    mt9d111_i2c_axi_lites[66] = (write_data >> 8)|0xff;         // first data
    mt9d111_i2c_axi_lites[66] = 0x200 | (write_data & 0xff);        // second data
    cam_i2x_write_sync();
}

int main()
{
    int fd0, fd1, fd2, fd3, fd4, fd5, fd6, fd7, fd8;
    int fd_udmabuf, fd_paddr;
    volatile unsigned int *axi_iic_0, *axi_vdma_0, *axis_switch_0, *axis_switch_1;
    volatile unsigned int *bitmap_disp_cntrler_axim_0, *fastx_corner_det_0;
    volatile unsigned int *mt9d111_inf_axis_0;
    volatile unsigned int *frame_buffer;
    unsigned char  attr[1024];
    unsigned long  phys_addr;

    // axi_iic_0 (uio0)
    fd0 = open("/dev/uio0", O_RDWR); // axi_iic_0
    if (fd0 < 1){
        fprintf(stderr, "/dev/uio0 (axi_iic_0) open errorn");
        exit(-1);
    }
    axi_iic_0 = (volatile unsigned int *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd0, 0);
    if (axi_iic_0 == MAP_FAILED){
        fprintf(stderr, "axi_iic_0 mmap errorn");
        exit(-1);
    }
    
    // axi_vdma_0 (uio1)
    fd1 = open("/dev/uio1", O_RDWR); // axi_vdma_0
    if (fd1 < 1){
        fprintf(stderr, "/dev/uio1 (axi_vdma_0) open errorn");
        exit(-1);
    }
    axi_vdma_0 = (volatile unsigned int *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd1, 0);
    if (axi_vdma_0 == MAP_FAILED){
        fprintf(stderr, "axi_vdma_0 mmap errorn");
        exit(-1);
    }

    // axis_switch_0 (uio2)
    fd2 = open("/dev/uio2", O_RDWR); // axis_switch_0
    if (fd2 < 1){
        fprintf(stderr, "/dev/uio2 (axis_switch_0) open errorn");
        exit(-1);
    }
    axis_switch_0 = (volatile unsigned int *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd2, 0);
    if (axis_switch_0 == MAP_FAILED){
        fprintf(stderr, "axis_switch_0 mmap errorn");
        exit(-1);
    }
    
    // axis_switch_1 (uio3)
    fd3 = open("/dev/uio3", O_RDWR); // axis_switch_1
    if (fd3 < 1){
        fprintf(stderr, "/dev/uio3 (axis_switch_1) open errorn");
        exit(-1);
    }
    axis_switch_1 = (volatile unsigned int *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd3, 0);
    if (axis_switch_1 == MAP_FAILED){
        fprintf(stderr, "axis_switch_1 mmap errorn");
        exit(-1);
    }
    
    // bitmap_disp_cntrler_axim_0 (uio4)
    fd4 = open("/dev/uio4", O_RDWR); // bitmap_disp_cntrler_axim_0
    if (fd4 < 1){
        fprintf(stderr, "/dev/uio4 (bitmap_disp_cntrler_axim_0) open errorn");
        exit(-1);
    }
    bitmap_disp_cntrler_axim_0 = (volatile unsigned int *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd4, 0);
    if (bitmap_disp_cntrler_axim_0 == MAP_FAILED){
        fprintf(stderr, "bitmap_disp_cntrler_axim_0 mmap errorn");
        exit(-1);
    }
    
    // mt9d111_inf_axis_0 (uio7)
    fd7 = open("/dev/uio7", O_RDWR); // mt9d111_inf_axis_0
    if (fd7 < 1){
        fprintf(stderr, "/dev/uio7 (mt9d111_inf_axis_0) open errorn");
        exit(-1);
    }
    mt9d111_inf_axis_0 = (volatile unsigned int *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd7, 0);
    if (mt9d111_inf_axis_0 == MAP_FAILED){
        fprintf(stderr, "mt9d111_inf_axis_0 mmap errorn");
        exit(-1);
    }
    
    // udmabuf4
    fd_udmabuf = open("/dev/udmabuf4", O_RDWR | O_SYNC); // frame_buffer, The chache is disabled. 
    if (fd_udmabuf == -1){
        fprintf(stderr, "/dev/udmabuf4 open errorn");
        exit(-1);
    }
    frame_buffer = (volatile unsigned int *)mmap(NULL, (ALL_DISP_ADDRESS*3), PROT_READ|PROT_WRITE, MAP_SHARED, fd_udmabuf, 0);
    if (frame_buffer == MAP_FAILED){
        fprintf(stderr, "frame_buffer mmap errorn");
        exit(-1);
    }

    // phys_addr of udmabuf4
    fd_paddr = open("/sys/devices/soc0/amba/amba:udmabuf4/udmabuf/udmabuf4/phys_addr", O_RDONLY);
    if (fd_paddr == -1){
        fprintf(stderr, "/sys/devices/soc0/amba/amba:udmabuf4/udmabuf/udmabuf4/phys_addr open errorn");
        exit(-1);
    }
    read(fd_paddr, attr, 1024);
    sscanf(attr, "%lx", &phys_addr);  
    close(fd_paddr);
    printf("phys_addr = %x\n", (unsigned int)phys_addr);
    
    // axis_switch_1, 1to2 ,Select M00_AXIS
    // Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
    axis_switch_1[16] = 0x0// 0x40 = 0
    axis_switch_1[17] = 0x80000000// 0x44 = 0x80000000, disable
    axis_switch_1[18] = 0x80000000// 0x48 = 0x80000000, disable
    axis_switch_1[19] = 0x80000000// 0x4C = 0x80000000, disable
    axis_switch_1[0] = 0x2// Comit registers
    
    // axis_switch_0, 2to1, Select S00_AXIS
    // Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
    axis_switch_0[16] = 0x0// 0x40 = 0;
    axis_switch_0[0] = 0x2// Comit registers

    // AXI VDMA Initialization sequence (axi_vdma_0)
    axi_vdma_0[12] = 0x4// S2MM_VDMACR (S2MM VDMA Control Register  Offset 30h) is 0x4 
    while ((axi_vdma_0[12] & 0x4) == 0x4) ; // Reset is progress
    axi_vdma_0[12] = 0x4// S2MM_VDMACR (S2MM VDMA Control Register  Offset 30h) is 0x4 
    while ((axi_vdma_0[12] & 0x4) == 0x4) ; // Reset is progress
    axi_vdma_0[18] = NUMBER_OF_WRITE_FRAMES; // S2MM_FRMSTORE (0x48) register
    axi_vdma_0[12] = 0x00010002// S2MM_VDMACR(IRQFrameCount = 0x1, Circular_Park = 1)
    axi_vdma_0[41] = HORIZONTAL_PIXELS*PIXEL_NUM_OF_BYTES; // S2MM Horizontal Size Register(S2MM_HSIZE)0xc80 = 3200dec = 800 x 4
    axi_vdma_0[42] = HORIZONTAL_PIXELS*PIXEL_NUM_OF_BYTES; // S2MM Frame Delay and Stride Register(S2MM_FRMDLY_STRIDE)0xc80 = 3200dec = 800 x 4
    axi_vdma_0[43] = (unsigned)phys_addr; // S2MM Start Address (1 to 16) Start Address 1
    axi_vdma_0[44] = (unsigned)phys_addr; // S2MM Start Address (1 to 16) Start Address 2
    axi_vdma_0[45] = (unsigned)phys_addr; // S2MM Start Address (1 to 16) Start Address 3
    axi_vdma_0[12] = 0x00010003// S2MM_VDMACR(IRQFrameCount = 0x1, Circular_Park = 1, Run/stop = 1)
    while((axi_vdma_0[13] & 0x1) == 0x1) ; // Halt? (S2MM_VDMASR 0x34)
    axi_vdma_0[40] = VERTICAL_LINES; // S2MM Vertical Size (S2MM_VSIZE  Offset 0xA0) 0x258 = 600dec

    // CMOS Camera initialize, MT9D111
    cam_i2c_init(axi_iic_0);
    
    cam_i2c_write(axi_iic_0, 0xba, 0xf00x1);        // Changed regster map to IFP page 1
    cam_i2c_write(axi_iic_0, 0xba, 0x970x20);    // RGB Mode, RGB565

    mt9d111_inf_axis_0[1] = 0;
    mt9d111_inf_axis_0[0] = (unsigned int)phys_addr;

    bitmap_disp_cntrler_axim_0[0] = (unsigned int)phys_addr;
        
    munmap((void *)axi_iic_0, 0x10000);
    munmap((void *)axi_vdma_0, 0x10000);
    munmap((void *)axis_switch_0, 0x10000);
    munmap((void *)axis_switch_1, 0x10000);
    munmap((void *)bitmap_disp_cntrler_axim_0, 0x10000);
    munmap((void *)mt9d111_inf_axis_0, 0x10000);
    munmap((void *)frame_buffer, (ALL_DISP_ADDRESS*3));
    
    close(fd0);
    close(fd1);
    close(fd2);
    close(fd3);
    close(fd4);
    close(fd7);
    close(fd_udmabuf);
}

  1. 2017年04月19日 04:55 |
  2. PYNQ
  3. | トラックバック:0
  4. | コメント:0
»