HDMIの安定入力のために「フィルタ」を追加
HDMIの出力が安定してできるようになったので、今度はHDMIの入力を安定にしたいと考えました。
今の安定性の問題は、画面の上方に4ラインくらいのごみラインが出て、画面が上下に揺れることです。
dvi2rgbでHDMIの信号をデコードし、その中にある垂直同期信号的な信号(vsync)や、水平同期信号的な信号(hsync)、それとvdeを取り出して、内蔵ロジアナで見てみることにしました。
まず、VSYNCが来る際の挙動です。
HSYNCとVSYNCが同時に立ち上がっていますね。HSYNCの立ち上がりの次でhcount=0にクリアして、HSYNCの長さを測ってみたら44クロックでした。
どうやら、HDMIではHSYNCやVSYNCは8b/10b変換して、c0,c1,c2,c3という符号として送られてきています。これらの符号がいつ送られてくるかはソース機器によるのかもしれません。(余談ですが、HDMIの8b/10bはPCI ExpressやSATAの8b/10bとは違うコード体系なんじゃないかなと思います)
このようにして、水平のカウント数や垂直のライン数を数えて、VDEがHになる期間を調べました。
HやVの数を図にしてみます。
HDMIの1920×1080pでは、ブランキング期間を含めると2200×1125のタイミングで送られてきていました。2200×1125×60fps = 148.5MHzなので計算も合います。
さて、入力が安定しない機器では、VSYNCが来てから2回目のHSYNCが立ち上がるVCOUNT=1のときにvdeがバタバタ動いているのがわかります。
VCOUNT=2のときにも、vdeはバタバタ動いています。
HDMIの機器によっては上記のVDEがライン1~4くらいの間にバタバタしながらやってくるので、AXI Video DMAなどのカウンタが誤動作してしまいます。それがノイズや信号の減衰によるものなのか、規格的にそうなのかはわかりません。たぶん、FPGAに到達したときのTMDS波形の質が悪いからなんじゃないかなと思います。
そこで、VCOUNTが31以下ならVDEがHになっても強制的にLにするというチート的な回路を入れてみたところ、画面の揺れはぴたりと収まりました。
process(pixclk) begin
if(pixclk'event and pixclk='1') then
hsync_o <= hsync_i;
vsync_o <= vsync_i;
data_o <= data_i;
if(disable_filter_i = '1') then
vde_filter <= vde_i;
else
if(vcount >= 32) and (vcount < 1121) then
vde_filter <= vde_i;
else
vde_filter <= '0';
end if;
end if;
vde_filter_d <= vde_filter;
end if;
end process;
こんなんでいいのかという疑問はありますが、画像が劇的に安定したのでした。
| 固定リンク
コメント