HDMIとかDVIとかいうものを無性に扱ってみたくなって、特電Spartan-6ボードで作ってみることにしました。何も予備知識がない段階でまず読んだのが、FPGAマガジンのVOL1。
しかし、これがさっぱりわからない。
- 結局のところ、どんな信号を出せばいいの?
(9ページの図5は、なんだかすごい絵だけど、2番目の絵の説明がない)
- DVIとHDMIの画像の電気信号は同じなのか?
(CECがないとかあるとかそういうことが知りたいんじゃないんだ)
- XILINX FPGAの端子からHDMIに信号を出していいのか?
- ソースコードはどこにある?ダウンロードできるの?有料?無料?
- CECとかHPDとか、どう配線を処理すればいいの?
(ホットプラグですなんて解説はいらない。Lになったらどうなる!?そういうこと書いてほしい)
- とにかく回路図出せ!回路図!
(変換ICの使い方の回路図なんていらない!)
各筆者がそれぞれいろんなことを書いているけど、肝心な部分は知ることができませんでした。
次に読んだのがInterfaceの2011年9月号。これを読んでようやくわかりました。長嶋毅さんの記事にちゃんと書かれていました。FPGAから直接HDMIに出す回路図もありました。
こうして疑問が解けました。
- DVI-DとHDMIの電気信号は同じ。どちらもTMDSで、タイミングも同じ。おおざっぱに言えば、コネクタのピン配置が違うだけ。
- XILINX FPGAの端子からHDMIに信号を出してよい。直列抵抗もプルアップもプルダウンもいらない。
- HPDは10kΩでGNDに落とせばよい。
ということでした。
そして、ザイリンクスのアプリケーションノートXAPP495に付属のHDMI/DVI出力のコードをダウンロードしてきて、特電Spartan-6ボード用にビルドしてみました。
XAPP495には、dvi_demoとvtc_demoの2つのトップモジュールが入っていますが、使うのはvtc_demoのほうです。dvi_demoはHDMI入力と出力を試すもの(HDMI入力が必要)で、vtc_demoはカラーバーを出力するだけのサンプルです。
XAPP495はATLYSというボード用に作られているので、いくつか書き換えなければなりません。以下のように書き換えました。
① rtl\tx\vtc_demo.vの77行目を
BUFIO2 #(.DIVIDE_BYPASS("FALSE"), .DIVIDE(2))
から
BUFIO2 #(.DIVIDE_BYPASS("FALSE"), .DIVIDE(1))
に書き換える。これはATLYSボードのクロックが100MHzなのに対し、特電ボードのクロックが50MHzだからです。
BUFIO2はDIVIDE2で使ってはいけないというアンサーもあるし、もともとのアプリケーションノートが正しかったのかどうかはわからない
② UCFファイル(vtc_demo.ucf)の該当する部分を以下のように書き換える。
NET "RSTBTN" LOC = "D6" | IOSTANDARD = LVCMOS33;
NET "LED<0>" LOC = "F13" | IOSTANDARD = LVCMOS33;
NET "LED<1>" LOC = "C11" | IOSTANDARD = LVCMOS33;
NET "LED<2>" LOC = "C9" | IOSTANDARD = LVCMOS33;
NET "LED<3>" LOC = "A9" | IOSTANDARD = LVCMOS33;
NET "SYS_CLK" LOC = "D11" | IOSTANDARD = LVCMOS33;
NET "SW<0>" LOC = "U13" | IOSTANDARD = LVCMOS33 | PULLDOWN;
NET "SW<1>" LOC = "U15" | IOSTANDARD = LVCMOS33 | PULLDOWN;
NET "SW<2>" LOC = "U16" | IOSTANDARD = LVCMOS33 | PULLDOWN;
NET "SW<3>" LOC = "R10" | IOSTANDARD = LVCMOS33 | PULLUP;
NET "DEBUG[0]" LOC = "U10" | IOSTANDARD = LVCMOS33;
NET "DEBUG[1]" LOC = "V11" | IOSTANDARD = LVCMOS33;
NET "TMDS(0)" LOC = "N10" | IOSTANDARD = TMDS_33 ; # Blue
NET "TMDSB(0)" LOC = "P11" | IOSTANDARD = TMDS_33 ;
NET "TMDS(1)" LOC = "R8" | IOSTANDARD = TMDS_33 ; # Red
NET "TMDSB(1)" LOC = "T8" | IOSTANDARD = TMDS_33 ;
NET "TMDS(2)" LOC = "T4" | IOSTANDARD = TMDS_33 ; # Green
NET "TMDSB(2)" LOC = "V4" | IOSTANDARD = TMDS_33 ;
NET "TMDS(3)" LOC = "R3" | IOSTANDARD = TMDS_33 ; # Clock
NET "TMDSB(3)" LOC = "T3" | IOSTANDARD = TMDS_33 ;
これでビルドします。
SW3,SW2,SW1,SW0はピンヘッダに出していますが、プルアップ、プルダウン、プルダウン、プルダウンとすることで1000の初期値を与えています。この1000という初期値を与えることで、XAPP495の回路はSXGA(1280×1024)の解像度になります。
特電Spartan-6ボードの左下のところからHDMI信号が出てくるので、これをケーブルにつなぎます。
本当はHDMIのコネクタを使いたかったのですが、あいにく会社においてきてしまったので、HDMIケーブルをぶった切って中から配線を取り出して直接つなぎました。
このケーブルは千石で買った 「YOKO イーサネット対応ハイスピード」と書かれた1mのHDMIケーブルなのですが、おそらくシールドの配線の取り方が間違っていると思われます。TMDSのデータ2のリターンがデータ1の配線のリターンを通るようになっています。MADE IN CHINAだし。
そして、家庭用のテレビのHDMI入力につないでみると・・・
カラーバーが表示されました。ケーブルのピン配置の解析や、クロックの件で、ここまで結構苦労したので、これが出たときには感動しました。
テレビがハイビジョンなのにSXGAで出力しているので、「この信号は推奨していません」と出ています。次は1920×1080に挑戦してみたいです。
さて、本を読んでもわからなくて実際に触ってみてはじめてわかったことは、
- CECはオープンで良い。
- SCLとSDAは、プルアップしておけばよい。実際には使わない。
- 5Vは供給しなくてよい。
- HPDは、LでもHでもオープンでも、何でもよい
ということでした。最初、DDC(SDAやSCL)を使って解像度の情報をやりとりしなければいけないのかと思ったのですが不要でした。テレビは画像データを見て判断しているようです。
結論は、Spartan-6の汎用I/O※が8本(差動4ペア)あれば、外付け部品なしでHDMI出力ができる、ということです。
※Bank0,Bank2に限る。
次はこのデザインをArtix-7に移植してみたいと思います。
最近のコメント