※このサイト内の情報は一切保証されません。参考にする際はすべて自己責任となります。

目次

1. 概要
2. パーツ
3. XGAタイミング
4. 回路(同期信号部)
5. 回路(VRAM部)
6. 製作
7. 実験
8. あとがき
9. 参考にさせていただいたサイト・情報

1. 概要

「ロジックICで作るVGA信号生成回路」「ロジックICで作るVGA信号生成回路用のVRAM回路」では、VGA(640x480@60Hz)に準拠したアドレス・同期信号およびVRAM内容を表示する回路を制作しました。
1色・垂直4pxパックドピクセル方式、256x192の解像度でしたが、640x480の画面の右端・下端が使えていない、VRAMのアクセスタイム遅延を考慮していないなど、手抜き妥協した部分もかなりありました。
今回は、同じ256x192の解像度でも、4等分でぴったりのXGA(1024x768@60Hz)として、水平2pxパックドピクセル方式、8色カラーの信号生成回路(簡易CRTC)およびVRAM回路を一体で制作しました。

2. パーツ

今回は「同期信号部」「VRAM部」「バックプレーンボード」の3つに分けて製作して、合体させる方法をとりました。
以前の製作の時よりも、部品の輸入のハードルが下がり、DIPパッケージのICが使いやすくなったので、すべてDIP品を使用しています。

3. XGAタイミング

XGAは、VGAと同じく、色信号は0V-0.7Vのアナログ信号、同期信号が0V-5VのTTLレベルデジタル信号(負論理)です。
XGA(Extended Graphics Array)のタイミングの規格は次のように定められています。

表1 XGAの周波数対応
画素周波数65MHz
水平同期周波数48.36 kHz
垂直同期周波数60Hz


水平同期信号・垂直同期信号とフロントポーチ・バックポーチの説明は、VGAのときと全く同じです。
タイミングは次のようになっています。


(図1 XGAの表示エリアと総エリア)
(図では垂直同期、垂直フロント・バックポーチの期間に水平同期が無いように見えますが、この期間も実際には水平同期信号は出力されています。)

同様に、生成される信号は次の通りとなります。

表2 XGAの信号の期間
水平同期信号48.36kHz2.092us(136pixels相当の時間)だけL
垂直同期信号60Hz124.1us(6lines=8064pixels相当の時間)だけL
水平ブランク信号----4.923us(水平同期含む)
垂直ブランク信号----785.7us(垂直同期含む)

4. 回路(同期信号部)


(図2 同期信号部 回路図)

今回も、256x192を表示期間とするため、4分の1の発振器を使用します。
65MHz / 4=16.25MHzですが、やはりぴったりの素子はないので、16.0000MHzのものを使用しています。250kHz分は誤差です。
発振器がTTLレベルの出力のため、74HCT04で受けて5VのCMOSレベルに変換しています。
上記の図1に示したピクセルやラインをぴったり4分の1にすると、端数が出たり、回路上、デコードが難しくなったりするので、大幅に簡略化しています。

対応表を示します。

表3 XGA規格と本回路での周波数対応
信号名本来のpixel/line本回路でのpixel/line1/4(vpx/vln)
水平フロントポーチ24px48px12vpx
水平同期信号136px128px64vpx
水平バックポーチ160px112px28vpx
垂直フロントポーチ3lines8lines2vln
垂直同期信号6lines8lines2vln
垂直バックポーチ29lines24lines6vln

したがって、水平同期周波数は16000/(1312/4)=48.78kHz、垂直同期周波数は48.78/808=60.37Hzとなる計算です。
以降は、4分の1した仮想ピクセル(vpx)・仮想ライン(vln)で説明していきます。

同期カウンタ74HC(AC)161の初期値同期ロード・キャリーアウトを組み合わせて、各信号を生成していきます。
カウンタは担当する信号で5つの部分に分かれています。

HFp部では水平フロントポーチを生成します。あらかじめ3をロードすることで、12をカウントしています。
15に達した時点で、キャリーアウトの反転信号でカウントを停止すると同時に、HDIV・HSYNC部にバトンタッチします。

HDIV部は、12-15のカウントを反復することで、クロックを4分周しています。
水平同期・水平バックポーチは仮想ピクセルでも4の倍数になっているため、カウントを簡略化するために、さらに4分周して、HSYNC部をピクセルクロック(16.0000MHz)の4回に1回だけカウントアップするようにしています。
HDIV部は、HSYNC部がカウント可能(HFp部が停止中(HFpのキャリーアウトがH)、かつ、HSYNC部がカウント完了していない(HSYNC部のキャリーアウトがL))であるときに動作します。

HSYNC部では、仮想ピクセルをさらに4分の1にしたものでカウントしています。
水平同期は64vpxなので8カウント、水平バックポーチは28vpxなので7カウントします。合計15カウントでちょうど74HC(AC)161のキャリーアウトまでのカウントになります。
(というよりも、合計15カウントになるように簡略化したというのが正直なところです。)
こうすることで、HSYNC部のQDとHFpのキャリーアウトの負論理AND(=NOR)を取るだけで水平同期信号(~HSYNC)が生成できます。
残りの7カウントの間はQDがHになるためHSYNCは非アクティブになり、キャリーアウトが出るまでは水平ブランク期間となるため、キャリーアウト自体が負論理の水平ブランク信号(~HBLANK)となります。

この負論理水平ブランク期間をHVIS部のカウンタのイネーブルとすることで、256vpxの水平ピクセルアドレスをカウントします。
256vpxをカウントしきったら、キャリーアウトの反転を、HFp部とHSYNC部のロードに入れることで、次のクロックから、HFp部に戻ります。

ここまでが水平方向の信号生成です。
一部は高速な74AC161(CD74AC161)を使用しています。これは、16MHz=62.5nsの速さの場合、ゲートICを介した際の伝播遅延が、74HC161では仕様を超過し、正常に動作しなかったため(特にキャリーアウトを反転してカウントをロックする動作)です。日立製のHD74HC161やTI製のSN74HC161Nでは何故か動きましたが...(^^;
CD74AC161とSN74HC161Nでは、もちろん後者のほうが安いので、動いていればそれでもいいと言えばいいのですが、なんとなく気持ち悪いので思い切ってCD74AC161に置き換えました。
~HSYNCと~HBLANKが74HC74を通過している理由はVRAM部の項目で後述します。

VDIV部では、HSYNC信号を4分周します。4linesが1vlnになるためです。

VLINE部では、192vlnの垂直ラインのカウントと、垂直ブランク信号(VBLANK)・垂直同期信号(VSYNC)の生成を一手に行います。
0-191までは垂直ラインをカウントし、192以降、すなわち、上位2ビットがHになる期間は垂直ブランク期間であるため、そのANDが~VBLANKになります。
上記の表から192-193vlnが垂直フロントポーチ、194-195vlnが垂直同期のラインになるため、下位4ビットのうちLSBを除いた3ビットを、~VBLANKでイネーブルされた74HC138でデコードすることで、74HC138の~Y1を垂直同期信号(~VSYNC)としています。
202vlnまでカウントしたら、次はまた表示期間に戻るため、202=192+10、10=5*2であることから、74HC138の~Y5で0をロードさせています。

ここまでが垂直方向の信号生成です。

映像出力コネクタは、VRAM部がなくても同期信号の検証ができるように、同期信号部に載せています。
色信号の電圧は、VGAと同様に、インピーダンス75Ωで0.7Vp-pが規定されているため、470Ωの抵抗を挟んで出力しています。

5. 回路(VRAM部)


(図3 VRAM部 回路図)

VRAM部は、水平パックドピクセル方式にするために、アクセスタイム遅延を考慮する必要があり、SRAMの後段が入り組んでいます。
回路図左側の74HC161および74HC157はVGAのときと同じで、垂直ブランク期間(SRAM書き込み可能期間)と、表示期間で、SRAMのアドレスを切り替えています。
3ステートバッファ(74HC245)を使用して、書き込み可能時以外にはデータバスにデータが外部から流れ込まないようにしています。これも、74HC244と74HC245の違いだけで、VGAのときと同じです。
書き込みは垂直ブランク期間だけできるように、~WRは~VSYNCとの負論理ANDを取っています。
なお、~VSYNCをわざわざ2段反転させているのは、ファンアウトが多いためのバッファ用です。

SRAMの出力は、そのままマルチプレクサ(74HC157)に入れるのではなく、間に、D-FF(74HC574)を介しています。
この回路では、85nsのSRAMを使用しています。そのままでは、ピクセルクロックの16MHz=62.5nsに間に合いません。
今回は、1vpxを4bit(ニブル)で表す(ただし、MSBは不使用で、IMG_Xは将来の拡張用)こととして、2vpxを1バイトに割り当てることで、実質的にVRAMへのアクセスを125ns毎としています。
しかし、アドレスの切り替え時には、やはりデータの出力まで85nsかかるため、2vpx出力後、さらに次のvpxを表示しようとすると、次のvpxの62.5ns間は不定データが出てきてしまいます。
この不定データが表示されないようにするため、アドレスの切り替えに同期して、D-FFで受けることで、不定データがマルチプレクサ(74HC157)に入らないようにしています。
TC55257DPL-85Lに限らず、62256系のSRAMのデータシートを見ると、アドレス切り替え直後は、切り替え前のデータが一定期間出力されています(TC55257DPL-85Lであれば最低10ns)。
そのため、アドレスの切り替えを74HC574のクロックとして入力すれば、1つ前のアドレスのデータが74HC574の出力として安定して出力されます。
PA0反転の伝播遅延もありますが、それよりもアドレス変換の74HC157の伝播遅延の方が大きいため、74HC574にクロックが入る際には1つ前のアドレスのデータのままです。
この段階で、前述のとおり、1アドレスあたり2vpxなので、2vpxの遅延が発生します。
したがって、水平ブランク期間も2vpx遅延させる必要があります。同期信号部の回路で~HBLANKを74HC74で2クロック遅延させて、~dHBLANK(delayed HBLANK)を生成しているのはこのためです。

同時に、ニブル切り替えに使用しているPA0も、74HC157の後段の74HC574(後述)で2vpx遅延させています。
PA0は水平ブランク期間では固定されているため、遅延させないとライン末尾の254vpxと255vpxのニブルの切り替えができなくなるためです。

2vpx遅延した安定データを74HC157(U12)に入れ、水平アドレスのLSB(遅延PA0)で上下のニブルを切り替えることで、ニブルで表現される1vpxを出力しています。
この部分は、何も考えずにPA0を~A/Bに入れたところ、リトルエンディアンになりました。
また、74HC157の~G端子は、Hにすることで、出力を全てLにすることができるため、~Gに負論理のブランク信号(~dHBLANKと~VBLANKの負論理OR)を入れることで、ブランク処理をしています。

PA0がHからLになると同時に、前段の74HC574(U11)も1つ前のアドレスのデータに更新されますが、74HC574の伝播遅延が20nsあるため、PA0がLになった瞬間に、74HC157(U12)に入力されているデータは、一瞬だけ、2つ前のアドレスの内容を示すことになります。
20nsは、XGAの実ピクセルクロック(65MHz=15.4ns)に十分なため、1pxのゴミデータが画像上に表示されてしまいます。

(図4 ゴミデータが1px分出力されている)

これを解決するため、74HC157の出力も、ピクセルクロックに同期して、D-FF(74HC574)で受けています。これにより、ニブル切り替え直前のデータを安定して出力することができるようになります。
4bitしか使用していないため、前述のPA0の2vpx遅延も残りのbitで行っています。
ただし、この時点で画像データは同期回路部の出力するアドレスに対して、さらに1vpxの遅延が生じ、累積3vpxが遅延しています。
ブランク処理は前段で行われているため、ブランク期間も同時に1vpx遅延しますが、~HSYNCはここまでの遅延の累積を反映させなければなりません。
そのため、74HC74を重ねて3クロック遅延させたものを~dHSYNC(delayed HSYNC)としています。

なお、~VSYNCは3vpx程度の遅延であれば、フロントポーチ・バックポーチ内で吸収されるため、そのままでも問題ありません。
アクセスタイムと伝播遅延を図示したタイミングチャートは次の通りです。

(図5 アクセスタイムと伝播遅延のD-FFでの同期タイミングチャート(実線はクロックと出力の対応、破線は入力と出力の対応 灰色は不定データ))

6. 製作

製作には秋月電子のスルーホールユニバーサル基板を使用しました。
片面基板でもいいのですが、ランド剥がれの起きにくさや、配線をスルーホールの中に差し込んで半田付けできて便利です。
そのかわり、若干熱容量が大きくなるので、ハンダゴテを当てる時間が変わります。

今回も例によって過密実装のため、電源ラインを0.6mm径のスズメッキ線で配線し、ICソケットの中にパスコンを埋めて半田付けします。いまだに表面実装コンデンサは用意していません(^^;

(図6 パスコン埋め)

コンパクトに収めるため今回はワイヤラッピングは使用せず、配線は0.26mm径(AWG30)のETFE線とUEWを直接半田付けして製作しました。
特に、未使用ピン処理部分にUEWを使用しています。回路変更で使用するようになった際にUEWならランドの根元で切断するだけで使用できるようになります
コンパクトにしたいならSOPやTSSOPをPCBに実装を、というツッコミはなしで(_ _;

それでも、1枚の基板に、同期信号部とVRAM部を納めるのは難しいため、2枚に分けています。

(図7 同期信号ボード 左:表面 過密実装 右:裏面 盛りソバ)


(図8 VRAMボード 左:表面 さらに過密実装 右:裏面 超・盛りソバ)

その2枚を接続するために、バックプレーンボードも製作しました。
といっても、単純に、電源ラインの配線と、40ピンのピンソケットの各ピンを0.2mmのUEWで数珠つなぎにしただけです。
UEWをピンソケットの足に巻き付けてから、370℃-420℃程度のハンダゴテのコテ先に少しだけ半田を盛ってから熱して、UEWの被覆が溶けた瞬間に、一瞬で半田を供給して、ハンダゴテを離すことで半田付けできます。
コテ先温度が高いので、当てる時間が少しでも長いと、すぐにフラックスが飛んで、ブリッジやツノだらけになります。なりました(_ _;

(図9 バックプレーンボード 左:表面 ピンソケットだけ 右:裏面 電源以外はUEW配線)

ピンヘッダ・ピンソケットは2x20ピンなので、40ピンリボンケーブルでも相互接続はできますが、バックプレーンボードを使用すると、外部からのデータをピンソケットにジャンパワイヤで乗せることができ、ブレッドボード上のマイクロコントローラからの実験が容易になります。

向きを合わせて差し込んで完成です。各ピンソケットは等価です。

(図10 統合後)

7. 実験

ディスプレイとミニD-Sub15ピンコネクタで接続し、5V電源を供給します。
ディスプレイは5年前と同じI-O DATAのEX-LD2071TBのままです。

(図11 左:ランダムパターン 右:ほぼ計算通りの値)
ディスプレイにはランダムなカラーパターンが出ています。SRAMのデータ内容は不定なので、電源投入の度に変わります。
ブレもなく表示されていて、74HC157および74HC245による垂直ブランク期間のデータ切り替えも想定通りです。

実は、最初はまったく信号が出ていませんでした。発振器を低い周波数のものに取り替えてから、ロジックアナライザを使用して検証したところ、想定通りの動作をしていたため、前述の74HC161とゲートICの伝播遅延による問題と判明しました。74AC161に換装後は安定しました。

次に、外部ホストからSRAMの書き換えを行ってみます。今回は、Arduinoの他に、高速なSTM32F411CEU6(100MHz)、いわゆる「Blackpill」も使用してみました。
実は、STM32F411CEU6は、VGAのときにも、「Bad Apple!! PV【影絵】」のシングルVRAMでの15fpsの再生実験に使用していました。

SRAM書き換えの結果はこれです。

幸いにして一発で動作しました。
画像表示も実験してみました。

きれいにblobcatが表示されました。

調子に乗って、シングルVRAMで「Bad Apple!! PV【影絵】」に挑戦してみました。
今回は、1画面あたりのデータ量が24KBに倍増している上、VBLANK期間がVGAよりも短いため、画面書き換えに使える時間がわずかで、256x192のままではとても動画になりません。
そのため、192x96まで縮小することで、10fpsでなんとか再生できるようになりました。
ところで、STM32は3.3V系で、入力は5Vトレラントではありますが、なぜ出力3.3Vなのに5V系の本回路と直接通信できるのでしょうか...?(^^;
レベルシフタを挟むとかえって不安定になる...

8. あとがき

今回はとにかく伝播遅延に悩まされました。回路を組んで、実験して動かず、ロジックアナライザに繋いだり、回路を修正したりを繰り返しています。
SRAMのアクセスタイムや74HC157の切り替えによる遅延に対して、タイミングチャートを何度も書き直して、D-FFでの同期設計をかなり意識しました。
そのかわり、汎用性は高くなり、アクセスタイムが100nsのSRAMまで対応できるようにはなりました。
出力も、4bitを1vpxとしたことで、データ量は多くなりましたが、出力の抵抗を変更することで、グレースケール16階調も可能です。

XGA・カラー対応にしたことで、フルサイズで256x192の解像度を表示できるようになりましたが、前述の通り、データ量が倍増した上、垂直ブランク期間が短くなったことで、動画にはかなり厳しい仕様になりました。
やはりダブルVRAM仕様にしなくては...

5年前はDIPのICが入手しづらくなりましたが、メーカーさえこだわらなければ、DigikeyやFarnellなどで輸入しやすくなったため、かえって今回はDIPでの製作が捗りました。
しかし、実は、過密実装が仇となり、同期信号ボードでは、74HCT04, 74HC00, 74HC02のパッケージをヤスリで削り落としています。
14ピンPDIPは、16ピンPDIPと外形サイズが同じであることを忘れて、密着してICソケットを配置したため、実装の段階で干渉することに気づいたためです。
その後に着手したVRAMボードではちゃんと間隔を開けています(^^;

それにしても、このプロジェクト、5年ごとに動き出すな...

9. 参考にさせていただいたサイト・情報


上へ
戻る