Demo」が提供されています。外部からのHDMI信号をZynqが受信しDDRメモリに格納ということを行っています。本記事では、デモサンプル内のアプリケーションプロジェクトを参考に、(b)の「外部からのHDMI信号をZynqが受信しDDRメモリに格納」するアプリケーションを作成し、Zyboに実装しました。以前の記事から、外部から受信した動画像の映像信号をZynqで受信し、それを外部に出力するHDMI入出力デモサンプルを試しています。-本記事では、Zynqが外部からのHDMI信号を受信しDDRメモリに格納した後、DDRメモリを読み出しVGA信号を送信するDigilent社のデモサンプルの解説を行い、デモサンプルをもとにZynq内部のハードウェア構成を作成しています。phys-higashi.com2021.04.30統合ソフトウェア開発環境「Vitis」上で、アプリケーションプロジェクトの作成方法について3回の記事に分けて説明しており、これが最後の記事となります。Zynqが外部からのHDMI信号を受信しDDRメモリに格納した後、DDRメモリを読み出しVGA信号を送信するアプリケーションの解説を行っています。HDMI信号をZynqが受信する際の割り込みの設定方法について紹介・解説しました。phys-higashi.com2021.05.23前回の記事で解説した割り込みハンドラの構成に従って、引き続き受信系のアプリケーションプロジェクトを作成します。本記事では外部からのHDMI信号を受信しDDRメモリに格納して、それをVGA信号として出力するソースコードの作成と動作確認までを行うこととしました。実際に筆者が組んだソースコードを紹介します。workspace内の[src]フォルダのファイル構成は次のようにしています。Demo」からダウンロードしたSDKファイルを参考に作成しました。前回の記事で紹介した、video_inout.cに受信系の関数を追加しました。追加した箇所を中心に説明いたします。VBAマクロ)vga_modes.h:Digilent社からダウンロードしたファイルをそのまま活用dynclkフォルダ:Digilent社からダウンロードしたファイルをそのまま活用dynclk.cdynclk.h作成したvideo_inout.cとvideo_inout.hについてソースコードは、以下の通りです。長くなりましたので、[+]マークをクリックしてトグルボックスを開いてご確認いただければと思います。XST_SUCCESS;}ソースコードの解説では、受信系(ビデオ側)を動作させるためのアプリケーションvideo_inout_receiveradd.cとvideo_inout_receiveradd.hの解説をしていきます。インスタンスの宣言と初期化アプリケーションで定義するインスタンスの構成図は次の図の通りです。アプリケーション上で、各デバイスに対応したインスタンスを定義しました。IPコア(ディスプレイ側)のインスタンスをヘッダファイル内で宣言し、main関数内で初期化しました。汎用割り込みコントローラ)のインスタンスを追加でヘッダファイル内で宣言しています。汎用割り込みコントローラ)のみ、初期化と設定を実行します。IPコア(ビデオ側)の初期化と設定はまだ行いません。IPコア(ビデオ側)はHDMI信号を受信してから動作を開始するため、HDMI受信時のクロック動作を確立してから発生するGPIOからの割り込み要求を受けたときに初期化・設定することにしています。IPコアの設定を行います。前回の記事でHDMI動作について解説したときに用いた図を改めて掲載します。IPコアにはチャネルを2つ設けます。Detect)チャネルとして外部に出力します。チャネル2はTMDSチャネルにおけるクロック信号に基づいてクロック動作を確立したときにアサートされる信号をトリガーに、割り込み要求を発生させます。この動作原理に基づいて、GPIOインスタンスを以下の通り、設定しています。XST_SUCCESS;}まず、R.1.1でGPIOの入出力設定について、チャネル1を出力に、チャネル2を入力に設定します。0)によりHPDチャネルをLow状態に設定しておき、HDMIの接続を切断しておきます。次に、R.1.2でGPIOのチャネル2の割り込みをイネーブルします。次に、割り込みハンドラ表を設定します。割り込みに関係するAPIの使用方法や概念の解説を、以下の記事にまとめているので、こちらの記事もご覧いただけると嬉しいです。【LED点滅編(4)】タイマー割り込みを行うAPIについて解説Zynqのプロセッサ上で割り込みをかける方法について解説します。SDKでのAPIの使用方法についてまとめました。phys-higashi.com2021.05.04前回の記事で、割り込みハンドラの構成について整理しました。最終的な結論は、以下の図のようになります。IPコア(ビデオ側)はHDMI信号を受信してから動作を開始するため、GPIOからの割り込み要求を受けたときに初期化・設定することにします。GpioIsr」上で行います。ユーザー定義関数interrput_controller()では、この分岐の計画に基づいて、割り込みベクターテーブルとGICインスタンスへの割り込みハンドラの登録を行いました。例外処理で、割り込みが発生したときにGICインスタンスの割り込みハンドラ表に分岐するようにしています。次に、R.2.1-1でGICインスタンスを初期化します。その後、R.2.1-2で、GICインスタンスへ2つの割り込みハンドラを登録しています。このとき、for文を使って、まとめて割り込みハンドラを登録しています。構造体ivt_tは、割り込みハンドラテーブルにおける1行分をひとかたまりにした変数と考えれば、わかりやすいと思います。「id」、「割り込みハンドラの関数ポインタ(Handler)」、「割り込みハンドラに送る引数(CallBackRef)」、「優先順位(priority)」、「トリガータイプ(trigType)」をまとめています。この構造体ivt_tを配列化して、割り込みハンドラテーブルを仮想的に構成するわけです。この自作で構築した仮想的な割り込みハンドラテーブルを、for文を使って機械的にGICの割り込みハンドラテーブルに写しています。ひがし構造体ivt_tを利用した、割り込みハンドラ表の定義は、Digilent社のデモサンプルを用いました。この構造体はわかりやすいですね。GpioIsrでは、HDMI信号を受信しクロック動作が確立したときに実行する、割り込みハンドラGpioIsrの処理を解説します。IP(ビデオ側)の初期化と設定です。}}R.3.2でGPIOのチャネル2を読み出し、確かにHDMI動作がロックされていることを確認できれば、R.3.3で受信側VTCのインスタンスを初期化します。初期化が完了したら、R.3.4で受信側VTCを設定する関数VTC_receive_setting()を実行します。XST_SUCCESS;}この関数のポイントは2つあります。関数XVtc_SetCallBack()を用いて、割り込みハンドラにVtcIsrを登録しています。VTCにおけるタイミング信号の検出が完了し、ロック状態になったときにはこの割り込みハンドラが実行されるようになりました。次に、関数XVtc_IntrEnableを用いて、VTCの割り込みをイネーブルしました。VTCがロック状態になったときに割り込み発生するように、XVTC_IXR_LO_MASKで制限をしています。このようにして、HDMI信号を確かに受信できてから、VTC(ビデオ側)の設定を開始するようにしています。VTC(ビデオ側)が設定されてから、タイミング検出が完了するまでは、待機状態になります。ひがし前回説明した状態遷移図において、「VTC検出待機中」という状態になります。VtcIsrVTC(ビデオ側)がタイミング信号を検出したときの、割り込み処理を解説しましょう。このとき、割り込みハンドラVtcIsrが実行されます。IPコアの受信側の設定を行います。}}GPIO同様に、VTCの状態を確認し、確かにロック状態にあれば、VDMAの設定を開始します。R.4.1でVTCで検出したタイミング信号を読み出し、それをR.4.2でVDMAの受信側の設定に反映させます。VDMAの受信側設定は、関数VDMA_receive_settingを用います。XST_SUCCESS;}基本的には、送信側VDMAの設定と同じように、映像のサイズや書き込むフレームのポインタを設定し、XAxiVdma_StartWriteFrameを用いてフレームへの書き込みを開始します。ひがしプログラムの説明は以上です。受信側は、割り込みが関係するため、かなり複雑ですね。実装ダウンロードや作成した一連のファイルをworkspaceのsrcフォルダに移動させたらビルドし、実装まで行いました。実装までの手順の詳細を改めて[+]マーク以下に記載しておきます。実装方法の詳細1プロジェクトのビルドエクスプローラ内のプラットフォームプロジェクト(hdmi_out_system_wrapper)を選択し、右クリックします。Project]を選択すると、ビルドが始まります。次に、エクスプローラ内のシステムプロジェクト(hdmi_out_application_system)を選択し、右クリックします。Project]を選択すると、ビルドが始まります。2コンフィグレーション回路基板をホストPCにつなぎます。つないで電源を入れたら、PC側からFPGAへのbitstreamファイルの書き込み(コンフィグレーション)とアプリケーションソフトウェアのDDRへの書き込みを実行します。Hardware]を選択すると、コンフィグレーションとソフトウェアの書き込みが実施されます。※今回の記事ではCOMポートの接続は不要です。実装したZybo基板の動作を確認しました。いくつか気になる点はありますが、なんとかHDMI信号をVGA信号に変換してディスプレイに表示することができました。気になるところは、主に以下の3つ。表示にノイズが含まれる(最後のExplorerのシーケンスバーがわかりやすく、本来灰色のシーケンスバーが赤色のモザイク状になっています)今後、これらは直していければと思います。ひがしなんとか画像処理を試す準備が整いました!今後は気になる点などを修正しつつ、Zynq上での画像処理に挑戦していきたいと思います。最後までご覧いただきありがとうございました。CPUで動作するLED点滅アプリケーションの作成を通じて、アプリケーションプロジェクトで使用されるインスタンスという概念とGPIOを制御するドライバAPI関数の使用方法について解説しました。-プログラムの作成と実行-本記事では、VitisとVivadoを用いてZybo経由で外部ディスプレイに画像を出力するアプリケーションを作成します。CPUで動作するHDMI出力プログラムを読み込み、Zybo上で動作を確認しました。カスタムIPの内部構成について解説ハードウェア言語で作成したRTLモジュールにIPパッケージャーを使用してAXI4-Liteインタフェースを追加する方法を解説しています。カスタムIPのどこを変更すればよいか、図解しながらIPの内部構成とカスタマイズ方法を解説しています。Vitis【HDMI出力編(3)】静止画をZynqからHDMI出力するVitisアプリケーション本記事では、Vitisを用いてZybo経由で外部ディスプレイに画像を出力するアプリケーションを作成します。アプリケーションでは、ドライバ関数によりIPコアの設定を行った後、読み出すフレームバッファに直接静止画を書き込んでいます。2021.1をインストールしました。インストールにあたり、いくつか詰まったところもあったので、その解決方法を記事にまとめています。企業のエンジニアとして働きつつ、FPGAを使ったデジタル回路の設計に興味を持ち、休日に勉強をしています。コメントをキャンセルメールアドレスが公開されることはありません。※サイト次回のコメントで使用するためブラウザーに自分の名前、メールアドレス、サイトを保存する。上に表示された文字を入力してください。@phys_higashiFPGAを使ったデジタル回路の設計に興味を持ち、休日に勉強をしています。初学者の目線から、詰まりやすいポイントとそれを解決した方法について、記事にまとめています。初学者ゆえの間違い等あるとは思いますが、お気づきの際はお問い合わせをいただけますと幸いです。@phys_higashiFPGAを使ったデジタル回路の設計に興味を持ち、休日に勉強をしています。初学者の目線から、詰まりやすいポイントとそれを解決した方法について、記事にまとめています。初学者ゆえの間違い等あるとは思いますが、お気づきの際はお問い合わせをいただけますと幸いです。-掛け算IPをZyboに実装-2021.04.182022.02.13Rustupをインストールするときに発生したエラーの回避方法2021.08.102021.11.07。