Help us understand the problem. What is going on with this article?

第7回PYNQのHDMI出力overlayを作る

はじめに

base overlayでもHDMIスルーやキャプチャはできたのですが、ちょっと物足りない。せっかくなのでなにか画面を出力する回路を作りたい。小林優著「FPGAプログラミング大全 Xilinx編」を頼りにして、VGAのテスト信号をHDMIに出力するoverlayをつくってみました。

第1回 Setup PYNQ-Z1
第2回 はじめてのJupyter
第3回 pythonとPYNQ PL資源へのアクセス
第4回 PYNQ OVERLAY
第5回 PYNQのOverlayを作ってみた
第6回 カスタムIPを作ってPYNQ overlayに組み込む
第7回 PYNQのHDMI出力overlayを作る
番外編 python ジャンプスタート

方針

道具立て

とりあえず、小林さんの書籍を基にして640x480のVGAのテスト信号を作成する回路をつくり、Digilentさんからvivado用ライブラリとして提供されている「RGB信号をHDMIに出力するrgb2DVI IPコア」を使うことにします。

構成

(phase 1)テスト信号の出力を目指す
とりあえず、ZynqのPSから制御はいらないのですが、あとあと信号を変えたり、フォーマットを変えたりしたくなるので、AXI GPIOで接続する周辺IPとします。
(phase 2)PYNQから自由に作画できるVRAMをつくる
小林さんの本のとおり。

テスト信号作成回路をつくる

プロジェクトをつくる

  1. Zynq (ZC7020)の新規プロジェクトをつくる。
  2. Settingから開発言語を VHDL にかえる

回路をつくる

小林さんの書籍の「2-3 PC用ディスプレイにパターンを表示」を参考ににして回路を作り、シミュレーションで動作を確認します。

  1. 信号フォーマットを確認する。VGA信号のピクセルクロックは25MHzで有効画素640x480ピクセル、同期ふくめると800x525ピクセル相当の信号。
  2. クロックジェネレータ回路(pckgen)を作成
  3. 同期信号とピクセル座標を作成する回路(syncgen)を作成
  4. ピクセル座標に対応する信号を作成する回路(pattern)を作成
  5. テストベンチ回路を作成
  6. チェック

細かな内容は、書籍を参照していただくとして、VHDLで書く時のポイント、書籍とちょっと変えたところなど以下に示します。

pclgen (VGAクロックの作成)

書籍では、クロックジェネレータは150MHzから25MHzのピクセルクロックを作るのですが、クロックイングウィザードをつかうのではなく、直接プリミティブにパラメータを入れてインスタンス化しています。
将来VGA以外のサイズに変更すると、周波数が変わってくるので、分周比などのパラメータはGenericで指定する形が良いかと。

syncgen (同期信号の作成)

verilogからVHDLの変更に対応するため

  • 信号フォーマットのパラメータはpackageファイルにまとめる。
  • 型変換は自動ではないので、変換を多段階に分解し、各段階に応じた信号を定義する。

pattern

課題のgraduationも同様。

  • 書籍のクロックは125MHzだが、AXIクロック100MHzに対応するため、pclgenでパラメタライズした値をGenericポートに追加する
  • vga2DVIでは、pixcel clock、EN(有効画面)が必要なのでこれらの信号を出力ポートに追加
  • 注意点はCLKとPCK(ピクセルクロック)を間違えないようにすること。
  • ピクセル座標をもとにピクセルデータを計算するのだが、ラッチするため1クロック遅延が発生する

overlayをつくる

プロジェクトをつくる

  1. Zynq (ZC7020)の新規プロジェクトをつくる。
  2. Settingから開発言語をVHDLにかえる
  3. ブロックデザインを作る

カスタムIP作成

  1. メニューバーのTools->Create and Package IP...を選択するとwizardが出てくる
  2. Create a new AXI4 peripheralを選択
  3. (中略)
  4. Edit IPを選択してFinish -->カスタムIPのプロジェクトができる
  5. 既に作成した信号作成のファイルを追加する。
  6. RGB信号、同期信号、EN、ピクセルクロックのポートを追加して配線する

rgb2dvi IPの修正と接続

配布されているIPをそのまま結線するとMMCMの実装エラーがでました。VCOの周波数が低すぎるとのこと。marseeさんのFPGAの部屋 AXI VDMAのMM2Sを使用してビデオ出力6(インプリメントしたがエラー)を参考にして解決しました。

  • エラーはピクセルクロックからピクセルクロックとその5倍のクロックを作成する(ClockGen.vhd)のMMCMで起こっている。
  • ピクセルクロック(25MHz)が低すぎてVCOの下限周波数を下回る。
  • MMCMのフィードバック係数の値(分周比)を大きくする修正を加えることで、VCOの周波数を高くする。
  • VCOの周波数はrgb2dviの設定メニューで変更することができるのだが、配布されたパッケージでは分周比は5(=1x5)もしくは10(=2x5)にしか設定できない。そこで、以下のようにIPコアを修正し25(=5x5)を選択できるようにする。

(IPコアの修正)
1. rgb2dviを右クリックしてIP packagerで開く
2. Customization Parameters をクリックし
3. kClkRange の Value Validation List に 25MHz (5)を追加する。この項を選択すると、(5)を5倍した値(5 x 5 =25)が分周比となるので、25MHzx25=625MHzがVCOの周波数になる。
4. Re-packageし、IP packagerを終了する

(IPコア修正をプロジェクトに反映)
1. Reportメニューから[Report IP Status]を選び
2. 下段のペインのIP Status タグを選び
3. rgb2dviを選択し [Upgrade Selected]ボタンをクリック

(rgb2dviへの接続)
R,G,Bの信号をcatで結合し、24bitの信号pDataをつくる。ここで、MSBからR,B,Gの順序で結合すること。
pData<-R_DATA&B_DATA&G_DATA
参考 rgb2dviのドキュメント
参考2 tom01hさんの雑多な趣味の記録帳

(bitファイルを作成しPYNQ-Z1にコピー)
(略)

テスト

HDMI TXとディスプレーを接続しておき、Jupyter notebook にて新たに作成したbitファイルを読み込めば、信号が出力される。

VRAM化

VRAMのメモリアドレスをちゃんと確保してやらないといけません。
第3回 pythonとPYNQ PL資源へのアクセスを参考にしてCMAメモリを確保します。

バッファ取得関数の定義
import numpy as np
import pynq

def get_pynq_buffer(shape, dtype):
    return pynq.Xlnk().cma_array(shape, dtype)
uint16の480x640配列バッファを確保
buffer = get_pynq_buffer(shape=(480,640), dtype=np.uint16)
GPIO_0でbufferの物理アドレスを送る例
from pynq import MMIO
mmio=MMIO(int(PL.ip_dict["axi_gpio_0"]['phys_addr']),4,True)
mmio.write(0, buffer.physical_address)

あとは、buffer(y,x)にピクセルデータをかくだけ。

まとめ

しつもんなどあれば、更新します。

こちらも参考になりそうです。@iwatake2222 さんの記事ZYBO (Zynq) でHDMI出力をする

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away