驚いたことに、もう11月だ。
この分だとあと2ヶ月足らずで今年も終わりそうだ・・・って当たり前か。
以前、日曜日に3:30に起床する必要があり土曜の夜に夜更しができなくなったと書いた。 その状況は今も続いていて、というか、今後も数年間は変わらないと思われるが、金曜日の夜は本業の余韻があって思考がFPGAの方に向かないので、やっぱ土曜の夜中にFPGAを弄りたいなぁ−−、どうしたもんか・・・と思案していたのだが、そうだ! 寝なきゃいいじゃん! かぁー、その手があったかー、 ということに気づいた。 用事というのはボランティアみたいなもので、遅くても5:00には終わる。 なので、4週間前から土曜の夜は徹夜して用事が終わってから仮眠するようにしている。 ただ、歳のせいか2〜3日後に疲労が来る。 ところが、先週は何故か翌日から体調が不調で眠くはないのだがずっと水中にいるような感じだった。 早くこのリズムに順応したいものだ。
さて、ZYBOだが、思いつきでzybo_base_systemのHDMI Transmiter部を自作のdvi_encに置き換えてみた。
dvi_encではピクセルクロック部とSerdes用クロック部間のデータのクロック載せ替えを下図のようにpvld_x信号で行っていた。
この信号はdvi_encの外部(普通はクロック生成モジュール)で生成していたのだが、今回はdvi_encに一つラッパーモジュールを被せてそのモジュール内で生成するようにした。
これをVivadoでIP化して、DigilentのHDMI Transmiterと入替えた。
合成してみたところ、Serdes用クロックが配線出来ないというエラーが出た。
HDMI TransmiterのRTLを見たら、hdmi_txのSerdesはハードマクロのOSERDESE2が使用されていた。
クロックは別モジュールのAXI Display Controller (axi_dispctrl)で生成されており、クロックバッファはBUFIOが使われていた。 dvi_encはSerdesの部分もユーザロジックとしてHDLで書いており、I/Oバンク専用のクロックバッファであるBUFIOからのクロックは使えない。 そこで、BUFIOではなくBUFRに変更してみた。
これで合成したところ、合成は出来たが若干のタイミングエラーが出た。
クロックのパルス幅が足りないようだ。
試しに、bitデータを作成して実機動作させてみたが動作しなかった。 zybo_base_systemに付属しているデモソフト (base_demo)では、画面の解像度を幾つか指定できる。
この中の最低解像度を選択した場合は以下のような画像が表示された。
その上の解像度では何も表示されず、LCDディスプレイは信号を受信できていないことを示すランプ点滅状態になってしまった。 クロックバッファをBUFGにしてみても同様だった。 ZynqではSerdesの部分をHDLで作成するのは無理そうである。 そこで、Sedes部をOSERDESE2を使うようにRTLを書き換えてみた。
クロックバッファもBUFIOに戻して、合成したところ成功しタイミングもMetした。
動作も最大解像度の1920x1080@60Hzまで問題なく動作した。
HDLで書いたSerdesとこれの合成結果は以下のようだった。
これに対してOSERDESE2使用版の回路は以下のようになった。
ところで、図の左側にあるdvi_encoderはデータをDVIの規格にしたがってエンコードするモジュールである。規格にしたがってエンコードするので、回路はDigilent版も私のもの似通ったものになるような気がする。そこで、両者のこの部分を回路図表示して見てみた。
DigilentのTMDSEncoder
自作のdvi_encoder
両者を見比べると、似通っている気もするのだが回路規模は若干私のほうが小さいようだ。
この図の肌色の箱はフリップフロップやLUT等のプリミティブセルを表しているのだが、数を数えると私の方が少なかった。 Digilent版はVHDLで記述してあり、私のはVerilogで記述している。その差なのか、あるいは、パイプラインの段数に差があるのかも知れない。