目次
1. 概要2. パーツ
3. XGAタイミング
4. 回路(同期信号部)
5. 回路(VRAM部)
6. 製作
7. 実験
8. あとがき
9. 参考にさせていただいたサイト・情報
1. 概要
1色・垂直4pxパックドピクセル方式、256x192の解像度でしたが、640x480の画面の右端・下端が使えていない、VRAMのアクセスタイム遅延を考慮していないなど、
今回は、同じ256x192の解像度でも、4等分でぴったりのXGA(1024x768@60Hz)として、水平2pxパックドピクセル方式、8色カラーの信号生成回路(簡易CRTC)およびVRAM回路を一体で制作しました。
2. パーツ
- ユニバーサル基板(72x95mm) x3
- ICソケット(各種たくさん(もう数えてません^^;))
- ピンヘッダ(たくさん(数えてま(ry)
- 2x20ピンソケット x4
- 0.1uF 積層セラミックコンデンサ x31(パスコン)
- 抵抗 10kΩ x3
- 集合抵抗 10kΩ8素子 x1
- 水晶発振器 16.0000MHz x1
- 74HC00 x2
- 74HC02 x2
- 74HCT04 x1
- 74HC74 x3
- 74HC138 x1
- 74AC161 x4
- 74HC161 x8
- 74HC157 x5
- 74HC245 x1
- 74HC574 x2
- TC55257DPL-85L(256kbits 32KiB SRAM 85ns) x1
- 「ロジックICで作るVGA信号生成回路用のVRAM回路」で使用したミニD-Sub15pin接続治具
以前の製作の時よりも、部品の輸入のハードルが下がり、DIPパッケージのICが使いやすくなったので、すべてDIP品を使用しています。
3. XGAタイミング
XGA(Extended Graphics Array)のタイミングの規格は次のように定められています。
表1 XGAの周波数対応
| 画素周波数 | 65MHz |
| 水平同期周波数 | 48.36 kHz |
| 垂直同期周波数 | 60Hz |
水平同期信号・垂直同期信号とフロントポーチ・バックポーチの説明は、VGAのときと全く同じです。
タイミングは次のようになっています。

(図1 XGAの表示エリアと総エリア)
(図では垂直同期、垂直フロント・バックポーチの期間に水平同期が無いように見えますが、この期間も実際には水平同期信号は出力されています。)
同様に、生成される信号は次の通りとなります。
表2 XGAの信号の期間
| 水平同期信号 | 48.36kHz | 2.092us(136pixels相当の時間)だけL |
| 垂直同期信号 | 60Hz | 124.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/line | 1/4(vpx/vln) |
| 水平フロントポーチ | 24px | 48px | 12vpx |
| 水平同期信号 | 136px | 128px | 64vpx |
| 水平バックポーチ | 160px | 112px | 28vpx |
| 垂直フロントポーチ | 3lines | 8lines | 2vln |
| 垂直同期信号 | 6lines | 8lines | 2vln |
| 垂直バックポーチ | 29lines | 24lines | 6vln |
したがって、水平同期周波数は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. 実験
ディスプレイは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系の本回路と直接通信できるのでしょうか...?(^^;74HCシリーズのロジックICだけで、8色カラー 256x192(XGA互換信号)ビデオコントローラができた! pic.twitter.com/0LpxFnz8rf
— 東雲玲β@Ugo (@Rei_S_Ugo) 2026年8月11日
レベルシフタを挟むとかえって不安定になる...
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. 参考にさせていただいたサイト・情報
- コンピュータを作ろう
- Micro VGA: Cost-effective Microcontroller VGA Interface
- Martin Hinner's homepage
- ELM by ChaN
- Texas Instruments
上へ
戻る