exStickGEでHDMIの転送をしてみた

技術紹介

今回は2台のexStickGE間をUDP経由でHDMIの映像を転送してみました.
exStickGEでHDMI表示をしてみたexStickGEでHDMIの画像を取得してみたの回を
組み合わせたようなものです.
ソースコードはここの「exStickGE_stream_optimized」(送信側)と「exStickGE_stream_recv」(受信側)にアップしてあります.

動かしてみた

exStickGE同士をLANケーブルで接続し,
HDMI出力(PC)をexStickGE_stream_optimizedを書き込んだFPGAのCN3へ,
HDMI入力(モニター)をexStickGE_stream_recvを書き込んだFPGAのCN2へ接続します.

実際の例はこちらです.(解像度1600×900で転送し表示しているディスプレイを撮影)

(c) copyright 2008, Blender Foundation / www.bigbuckbunny.org

実現するに当たり

実現するに当たり, 多少の改良が必要となりました.
改良した点は3つです.

  • 一度に送受信するデータ量を増やした.
  • AXIのオーバラップ転送を追加した.
  • 受信側のフレームバッファをバンク違いにした.
一度に送受信するデータ量を増やした.

データを送信するに当たり, RGBデータだけではなく
UDP等のヘッダー分のオーバヘッドが増えてしまうので
一度に送受信するRGBデータを増やしトータルのパケット数を減らしました.
もともとは1パケット64ピクセル分でしたので
4倍の256ピクセルに変更しました.

AXIのオーバラップ転送

受信側の映像を表示するための読み込みは表示タイミングに
合わせないといけないため遅延は許されません.
メモリから読み込むためのモジュール(axi4m_to_fifo)では
アドレス発行をすべてデータを読み終わってから都度発行していました.
そうするとアドレス発行から実際にデータが読み出されるまでの
遅延が増えてしまうのでアドレス発行を事前に行っておき,
できる限り連続で読み出されるようにしました.

受信側のフレームバッファをバンク違いにした

DRAMメモリにはバンクと呼ばれるまとまりがあります.
一つのバンクでは一度に一箇所にしかアクセスすることができず,
また読み書き前に多少の準備時間が必要になります.
なので, 同じバンク内の別の場所に同時にアクセスされた場合,
どちらかに待ちが発生するもしくは互いにアクセスする(準備時間が多くなる)ことになります.
そこで複数のバンクに対してアクセスさせることで一つのバンクは一箇所集中して
読み書きができるので高速化を図ることができます.
高速化を図る方法としてXilinx社のアプリケーションノートXAPP792に記載されています.

以上の方法で改良を行いました.

実装

ほぼ構成は変わらず, 送信間隔を調整するためのVirtual Input/Outputを追加しました.
1パケット送信後の待ち時間を調整します. 

送信側 

受信側

 

ビルドと動作確認

ソースコードから実際にビルドして動作するまでの確認方法について紹介します.
環境はVivado 2019.1で行いました.

まずはgithub.comからソースコードをクローンしてきます.

弊社のe7UDP/IP IPコアのedifをクローンしたディレクトリ内のedif内にコピーします.
次に「Vivado 2019.1 Tcl Shell」を起動し, クローンしたディレクトリへ移動しプロジェクトの合成を行います.

cd ~/exstickge_samples/exStickGE_stream_optimized
vivado -mode batch -source create_project.tcl
cd ~/exstickge_samples/exStickGE_stream_recv
vivado -mode batch -source create_project.tcl

それぞれのFPGAにbitファイルを書き込みます.

冒頭の接続図通りに接続されていれば表示されます.

初期設定では送信間隔の調整時間が長めに設定されているため,
Hardware ManagerのVIOで調整します.
この値は内部で200MHzのカウンタに対応していて
0x1000でおよそ20[us]の遅延を挿入する形です.
値はおおよそ0x0-300あたりで最高速度になります

最大で10FPS前後で更新されます.

 

コメント

タイトルとURLをコピーしました