TD4 互換機の製作

概要

某所にて CPU の創りかた で設計する TD4 という 4-bit CPU の話が出たので勢いで作ってしまいました。


動作中の TD4 互換機(クリックで拡大表示)

標準ロジック IC が容易に手に入る今のうちにひとつやっておこうと思いました。

トップページへ戻る


目次

  1. 仕様
  2. アプローチ
  3. 74HC283 の置き換え
  4. 74HC154 の置き換え
  5. 74HC10 の置き換え
  6. その他
  7. デモ動画
  8. TD4 シミュレータ
  9. [May 24 2009] PROJECT TD4R - TD4 をリレースイッチで実現する
  10. [May 24 2009] TD4R: 4-bit インクリメンタ
  11. [Jun.06 2009] TD4R: 4-bit アダー
  12. [Jun.07 2009] TD4R: 4-bit レジスタ
  13. [Jun.07 2009] TD4R: プログラムカウンタ
  14. [Sep.03 2009] TD4R: 命令デコーダ
  15. [Sep.04 2009] TD4R: マルチプレクサ (Nov.02 2009 修正)
  16. [Sep.13 2009] TD4R: ROM アドレスデコーダ
  17. [Sep.27 2009] TD4R: ROM データバス出力回路
  18. [Oct.11 2009] TD4R: TD4R 組み立て ー その1
  19. [Nov.02 2009] TD4R: 4-bit インクリメンタ+セレクタ
  20. [Jan.12 2010] TD4R: TD4R 組み立て ー その2
  21. [Jun.19 2010] TD4R: TD4R デモ動画
  22. [Nov.15 2010] PROJECT TD4V - TD4 を CPLD/FPGA で実現する
  23. 謝辞・関連リンク

仕様

目次へ戻る / トップページへ戻る


アプローチ

IC を触りだした当初にワケもわからずに買った IC を極力使うようにして作りました。 当時 74LS139 を大量に買っていたようですが、その理由は永遠の謎...

74ALS08 なんていうのもありました(なぜ ALS)。74LS32 もありましたが、 これは Z80 の /MEMREQ, /IOREQ, /RD, /WR あたりに使う予定だったんだと思います。

話が逸れましたが、そんなわけで、持っていない IC は持っている IC で置き換えました:

置き換えたら IC の数が 21 個になってしまいました(オリジナルは13個)。

持っている IC の都合で "74HC" シリーズの IC と "74LS" シリーズの IC が混在していますが、 クロック信号の生成に使用している 74HC14 以外はデジタルな使いかたをしていますので、 問題はないと思います。(後日注: 74LS --> 74HC に接続する場合はプルアップ抵抗を付けないと規格上レベルの互換性が確保できません)

ただしクロック信号の生成部分だけは IC をアナログっぽい使いかたをするため、 "74HC" シリーズを使うのが無難だと思います。実際、ここに 74LS14 を使ったところクロック 信号が生成されませんでした。(後日注: 74LS シリーズでクロック信号を生成する場合は抵抗値の再設計が必要と考えます)

あと、"74LS" シリーズの IC は正しく動作する電源電圧の範囲が 4.75[V] 〜 5.25[V] と "74HC" シリーズよりもかなり狭いため、電源には定電圧電源が必要です。

目次へ戻る / トップページへ戻る


74HC283 の置き換え

74HC283 は 4-bit full adder です。キャリー(繰り上がり)信号の入出力が 付いているアダーをフルアダー、付いていないものをハーフアダーと呼ぶようです。 74HC283 はキャリーの入出力がついているので、フルアダーなわけです。

ちなみに1ビットのフルアダーはこれです。


1ビット・フルアダー

これを4つ数珠つなぎにすると、4ビットフルアダーになります。


1ビット・フルアダーを数珠つなぎにして4ビットフルアダーを構成する

ただし、この方式では、直列接続のため、上のブロックの出力の方が下のブロックの出力よりも遅くなってしまいます。 これを回避するために、74HC283 は内部でもっと複雑な回路を組んで、出力信号の遅延時間が一定範囲内に 収まるように設計してあります。

しかし、今回は動作周波数がたかだか 10[Hz] のため、遅延が大きくても問題ないです。 数珠つなぎ方式の信号の最大遅延時間は大きめに見積もっても 500[ns] を超えないと思われます。 仮に 1[us] としても 1[MHz] で動作可能です。なので、10[Hz] はまだ相当余裕があります。 よって、これで行くことにしました。

目次へ戻る / トップページへ戻る


74HC154 の置き換え

74HC154 は 74LS138 2 個で置き換えます。


74HC154 を 74LS138 2 個で置き換える

74HC154 は 4 ビットのバイナリ値を 16 ビットにデコードします。

出力の上にバーが付いていたり、IC の 入力や出力のところに ○ が付いている信号は 「負論理」といい、L が「有効」とか「アクティブ」な状態を示します。今回使う 74HC154 も 出力が負論理になっているので、選択されたビットは L レベルを出力するようになっています。

74HC154 の入力を 3 ビットにしたのが 74HC138 です。3 ビットで表現できる L/H の組合せは 8 通りなので、出力は 8 ビットです。これを 2 つ使って 16 ビット のデコーダを構成することも可能です。今回、私は 74HC154 を持っておらず、 代わりに 74LS138 を 2 個持っていたので、この方法でいきます。

目次へ戻る / トップページへ戻る


74HC10 の置き換え

74HC10 は 3 入力の NAND ゲートが 3 個入った IC ですが、 回路図を見ると、本当に 3 入力全部使っているのは 1 つだけです。 よって、2 入力の NAND ゲートが 4 個入った 74LS00 で置き換えることができそうです。

3 入力 (A,B,C 入力) の NAND ゲートを 2 入力の NAND ゲートで置き換える場合、まず A と B を NAND して、 その結果を C と NAND します。これでいいかと思ってしまいますが、NAND の出力は負論理なので、C と NAND する前に A と B の NAND 結果を反転する必要があります。うおっ、インバータがもうない!?と焦りましたが、 たまたまクロック生成の 74HC14 が 1 ゲートだけ未使用でした(すばらしいです>著者)。 というわけでこれを利用して無事 3 入力 NAND IC を 2 入力 NAND IC に置き換えることができます。


74HC10 を 74LS00 と 74HC14 の空きインバータで置き換える


74HC540 を 74LS139x4 で置き換え

これは、いくらなんでもやりすぎなので省略します。敢えてここで 74LS139 を使ったのは、 単純に 74LS139 を消費したかったからです。そうしないと今後使う機会がもうないと思ったので(実はまだ余っている)...

目次へ戻る / トップページへ戻る


その他

パスコンと抵抗の大部分は基板のハンダ面にチップ部品を取り付けています。 配線は径が 0.26[mm] の UEW で行いましたが、もう少し太くても良いと思いました。


TD4 互換機のハンダ面(クリックで拡大表示)

目次へ戻る / トップページへ戻る


デモ動画

画質が超悪いですが、4ビット・ナイトライダー動作中の動画を置いておきます。 本当は 9 バイトで作れますが、アドレス表示 LED を全パターン点灯させるためにわざと 16 バイトのプログラムにして動かしています。ちなみに出力 LED はボード左側にあるやつです。 ボード下側にあるアドレスとデータの LED の MSB と LSB が通常とは逆になっていますが、 まーいいか。

デモ動画

目次へ戻る / トップページへ戻る


TD4 シミュレータ (Oct.12 2009 追加)

TD4 シミュレータを C++ で記述してみました。 ここをクリックするとダウンロードできます(tar.gz 形式)。 linux + g++ で開発したので改行が LF のみとなっています。Windows の Notepad では改行が正しく認識されません。LF 改行に対応しているエディタ(秀丸等)で開いてください。 make すると td4(.exe) が作成されます。プログラムを実行するとラーメンタイマーを実行し、 1命令ごとの PC, レジスタ A, レジスタ B, IO, キャリーフラグの値を出力します。

シミュレータの出力をここに置いておきます。 1クロックの結果を1行で出力しています。もちろんプログラムを改造して、 上記レジスタ以外の値を表示することも可能です。 実際にハードウェアを製作する場合のデバッグにも使えるかもしれません。

一応個々のモジュールのクラスを作成し、TD4 クラスがそれらを保持・使用する構成にしています。 main() 関数で TD4 の初期化とクロックの操作を行い、出力を取り出しています。 TD4 に限らず、あらゆるハードウェアの動作をこんな感じで書いたらどうかなーと思いつつ 作成しましたが、回路の規模が大きくなるとこのレベルで記述するのは結構つらくなると思います。

目次へ戻る / トップページへ戻る


[May 24 2009] PROJECT TD4R - TD4 をリレースイッチで実現する

TD4 完成めでたしめでたし...で終わりにしようと思っていました。 ところが、ある日ふとリレースイッチで TD4 を製作したらどんな感じだろうか と思い立ってしまい、気になって仕方がなくなったので製作に踏み切りました。

たかだか標準ロジック IC 10 個程度の回路でも、これをリレーで実現しようとすれば、 かなりの数が必要でしょう。TD4 の場合、200 個あってもまだ足りないと思います。 というわけで、とりあえず秋月電子で 12V の小型リレー (Y14H-1C-12DS) を 200 個購入しました(14,000円)。 もう後戻りはできません。失敗して泣き寝入りするか、無事完成させることができるか? 実はリレースイッチというものを使うのは今回が初めてです。

リレーを 200 個くらい使ってロジック回路を動かすと多分「ジャララーッ」 とか「ガチガチガチッ」とか「バリバリバリッ」 とかいうものすごい音を出しながら壮絶な動作をするに違いないです。) ただ単にその光景をこの目で見たくて製作しています。

完成した暁には、動画がちゃんときれいに録れるデジカメでも買って、 リレーが 200 個動作する様を鮮明に記録しようと思います。 んで誰かにあげよう。(いらんて言われそう)

目次へ戻る / トップページへ戻る


[May 24 2009] TD4R: 4-bit インクリメンタ

TD4 の機能の中でも比較的簡単そうなのがインクリメンタです。 4 ビットの入力値を +1 して出力する回路です。 これは、74HC161 の内部回路の一部になります。TD4 で使われている 4 個の 74HC161 の中で、 プログラムカウンタをインクリメント(+1)するために、1 個だけこの機能が使われています。 残りの 3 個はインクリメント機能は使用せず、単純に 4-bit レジスタとして使っています。 なのでインクリメンタは一つだけ作れば OK です。


リレーを用いた 4-bit インクリメンタの回路図(クリックで拡大表示)

各ビット出力の式はかなりテキトーにひねり出したので、式を変形すれば さらにリレーの数を減らせるかもしれません。でもまー 16 個でもそこそこ妥当なところでしょう。

これ自体は単なる組み合わせ回路なので、論理さえ正しければ動作するでしょう。 というわけで早速製作してみました。


実際に製作したリレー式 4-bit インクリメンタ

写真左側の LED が入力、右側の LED が出力を表示しています。 入力に 0101 (= 5) を入力したところ、出力に 0110 (= 6) が出力されています。 カチッという音がいい感じです。 他の値も試したところ、ちゃんと +1 された値が出力に出てきました。 期待どおりに動いているようです。

目次へ戻る / トップページへ戻る


[Jun.06 2009] TD4R: 4-bit アダー

インクリメンタができたっぽいので次は 4-bit アダーを作ってみました。 これは 74HC283 に相当する機能を実現します。その名の通り 4 ビット同士の足し算をする回路です。 リレーを 28 個使用しています。


リレーを用いた 4-bit アダーの回路図(クリックで拡大表示)

回路の構成は、今回は最下位ビットはキャリー入力を使用しないためハーフアダーとし、 上位3ビットはフルアダーとして、全4ビットをカスケード接続しています。 この構成は標準ロジック IC で製作した TD4 互換機と同じです。 今回はこれをリレー化しただけです。

これも単なる組み合わせ回路ですし、論理が正しいことは TD4 互換機ですでに実証されているので、 配線を間違えずに製作すれば動作するでしょう。というわけで製作してみました。


実際に製作したリレー式 4-bit アダー

写真左側の LED が入力 A と B、右側の LED が加算結果を表示しています。 入力に 1010 + 1010 (= 10 + 10) を入力したところ、出力に 10100 (= 20) が出力されています。 回路の構成意図としては、加算結果 4 ビットと、繰り上がり信号 1 ビットの合計 5 ビットです。 なので、この意図通りの解釈としては、演算結果は 4 で、キャリー信号が出力されているので演算結果が 16 以上になったことがわかります。よって 16+4 で 20 とわかります。まー細かいことはこれくらいに しておいて、とりあえず期待どおりに動いているようです。

目次へ戻る / トップページへ戻る


[Jun.07 2009] TD4R: 4-bit レジスタ

組合せ回路ができると、次に作りたくなるのがレジスタです。インクリメンタとレジスタを接続すれば バイナリカウンタが作れます。これにロード機能を追加すれば、ようやくプログラムカウンタが完成します。

1ビットレジスタの回路図です。


リレーを用いた 1-bit レジスタの回路図(クリックで拡大表示)

サクっと書いていますが、↑の基本回路にたどり着くまでにかなりの試行錯誤を要しました。 「これなら動く」と自信満々に作って大失敗...というのを4〜5回繰り返し、かなり精神的ダメージを受けました。 この基本回路にしても、検討の上では RSig4 のリレーがなくても動作するはずなのですが、 実際にはこれがないと確実に動作しませんでした。

RSig0 〜 RSig7 の8個のリレーで制御信号を作成しています。これらはロジックを構成しているというよりは、 信号を遅延させています。これによって、だいたい回路図下のような波形を作ります。 「マスター・スレーブ方式」というやつを使っていて、クロックが 'H' のときはマスター側 (RM00とRM01)が ロードし、クロックが 'L' のときはスレーブ側 (RS0) がロードします。

こうすることの目的は、マスター側がロードしている間、スレーブが値を保持するようにすることです。 TD4 の回路図を見るとわかりますが、レジスタの出力は組み合わせ回路を経て、またレジスタの入力に戻ってきます。 なので、たとえばマスターだけで動作させようとすると、マスターのロード中に出力 Q の値が変わってしまうので、 これが組み合わせ回路に伝わり、最終的にマスターの入力値が変化してしまいます。これでは取り込む値が確定しません。 よってレジスタに値をロードしている間は、誰かが前のレジスタの値を保持しておく必要があります。 その役目を果たすのがスレーブです。

上記のねらい通りにうまく動作させるためには、いくつかの条件があります。

  1. マスター側がロードを開始(MLOAD=H)する前にスレーブ側が値を保持(SHOLD=H)する
  2. マスター側がロードを完了(MLOAD=L)する前に、マスター側の値を保持(MHOLD=H)する
  3. マスター側がロードを完了(MLOAD=L)した後に、スレーブ側がロード(SHOLD=L)する
この条件を満たす上でいちばんキツいのがスレーブの値保持信号 (SHOLD) です。この信号は マスターの MLOAD および MHOLD がロードになるよりも先に値保持モードに入り、 かつ MLOAD および MHOLD がロードを完了した後まで値を保持し続けなければなりません。 上記条件1および2は MLOAD および MHOLD 側に遅延を入れることによって実現します。 条件3は MLOAD 信号をさらに遅延させることによって作り出しています(RSig7)。

1ビットのわりにはリレーをたくさん使っていますが、今回作り出した MLOAD, MHOLD, SHOLD 信号においては、 他のビットに使いまわすことができるので、これ以降は1ビット追加するごとにリレーを3個追加するだけで OK です。 4ビットにする場合、使用するリレーの数は 8+3*4 = 20 個になります。あとは /LOAD 信号用に 1個、RESET (マスターとスレーブ)用に 2 個使うので合計 23 個です。


リレーを用いた 4-bit レジスタの回路図(クリックで拡大表示)

RESET は標準ロジック版では負論理ですが、リレー式では正論理にしています(消費電力が少し減るため)。


実際に製作したリレー式 4-bit レジスタ

目次へ戻る / トップページへ戻る


[Jun.07 2009] TD4R: プログラムカウンタ

レジスタができたので、インクリメンタと接続してプログラムカウンタを構成してみました。


リレーで実現した TD4 のプログラムカウンタ

3階建てです。最上階がインクリメンタ、2階はインクリメンタの出力とロード値を切替えるセレクタ、 1階がレジスタです。プログラムカウンタに使用するレジスタは、常にインクリメンタの出力またはロード値 をロードするため、/LOAD 信号入力用のリレーを1個省略しています。ちなみに2階の「ロード値」は ジャンプ命令で使用します。これで 74HC161 相当の機能を実現できたことになります。

写真ではレジスタが 0101 の値を保持しています。 これがインクリメンタの入力になるので、インクリメンタの入力(最上階左側のLED)は 0101 で、 出力は +1 された 0110 になっています。2階のセレクタは、インクリメンタの出力を選択しているので、 0110 が表示されています。これがレジスタの入力になるため、次のクロックではレジスタに 0110 が 取り込まれることになります。

左横にあるのはテストパネルです。クロックの PUSH SW を押していくとガチガチガチっと 次のステップに行きます。

目次へ戻る / トップページへ戻る


[Sep.03 2009] TD4R: 命令デコーダ

プログラムカウンタの完成で一段落して、さて次はどこに手を出そうかと少し考えましたが、 特にどこから作った方が良いということもなさそうだったので、命令デコーダを作ってみました。 レジスタが完成してしまったので、あとはひたすら組合せ回路を作っていくだけです。


リレーを用いた TD4 命令デコーダの回路図(クリックで拡大表示)

単純に AND とか OR とか NOT を組み合わせただけの回路です。 命令デコーダの入力は ROM からのデータ D4-D7 とキャリーフラグ(CF)です。 半導体版 TD4 では、CF の反転信号を命令デコーダに入力しています。リレー版 TD4 のレジスタは 74HC74 のような反転出力を持っていないので、命令デコーダ側で論理を反転しています。

これもあまり深く考えるところは無いので、サクっと作ってしまいました(その割には更新が遅いですが)。


実際にリレーで製作した TD4 の命令デコーダ

製作は比較的簡単ですが、回路図と動作の確認は少し面倒です。 D4-D7, CF の 5 ビットの入力の全ての組合せに対する出力を全てチェックした方が良さそうです。 今回は簡単なプログラムを作成して全 32 通りの 入力に対する出力を計算し、製作した回路と比較してチェックしました。以下に入力の組合せと出力を示します。

 CF D7 D6 D5 D4 | REGSEL_A REGSEL_B /LDA /LDB /LDIO /LDPC
================+=========================================
  0  0  0  0  0 |    0        0       0    1    1     1
  0  0  0  0  1 |    1        0       0    1    1     1
  0  0  0  1  0 |    0        1       0    1    1     1
  0  0  0  1  1 |    1        1       0    1    1     1
  0  0  1  0  0 |    0        0       1    0    1     1
  0  0  1  0  1 |    1        0       1    0    1     1
  0  0  1  1  0 |    0        1       1    0    1     1
  0  0  1  1  1 |    1        1       1    0    1     1
  0  1  0  0  0 |    1        0       1    1    0     1
  0  1  0  0  1 |    1        0       1    1    0     1
  0  1  0  1  0 |    1        1       1    1    0     1
  0  1  0  1  1 |    1        1       1    1    0     1
  0  1  1  0  0 |    1        0       1    1    1     0
  0  1  1  0  1 |    1        0       1    1    1     0
  0  1  1  1  0 |    1        1       1    1    1     0
  0  1  1  1  1 |    1        1       1    1    1     0
  1  0  0  0  0 |    0        0       0    1    1     1
  1  0  0  0  1 |    1        0       0    1    1     1
  1  0  0  1  0 |    0        1       0    1    1     1
  1  0  0  1  1 |    1        1       0    1    1     1
  1  0  1  0  0 |    0        0       1    0    1     1
  1  0  1  0  1 |    1        0       1    0    1     1
  1  0  1  1  0 |    0        1       1    0    1     1
  1  0  1  1  1 |    1        1       1    0    1     1
  1  1  0  0  0 |    1        0       1    1    0     1
  1  1  0  0  1 |    1        0       1    1    0     1
  1  1  0  1  0 |    1        1       1    1    0     1
  1  1  0  1  1 |    1        1       1    1    0     1
  1  1  1  0  0 |    1        0       1    1    1     1
  1  1  1  0  1 |    1        0       1    1    1     0
  1  1  1  1  0 |    1        1       1    1    1     1
  1  1  1  1  1 |    1        1       1    1    1     0
================+=========================================

実際に確認してみたところ、配線が2本足りてませんでした。 まー全パターン確認したので、命令デコーダはこれで完成とみていいでしょう。

目次へ戻る / トップページへ戻る


[Sep.04 2009] TD4R: マルチプレクサ

レジスタとアダーが完成しているので、その間をつなぐ回路を製作したいと思います。 レジスタ出力や I/O 入力から 1 系統を選択し、そのデータをアダーへ入力する回路。 これはセレクタとかマルチプレクサなどと呼ばれます。半導体版 TD4 では 74HC153 を 2 個使用して、REG_A, REG_B, I/O (各 4 ビット、合計 12 ビット) から 1 種類 (4 ビット)を選択して、これをアダーへ入力しています。【2009/11/02 追記】 マルチプレクサの入力は 4 種類で、最後の一種類は「ゼロ」です。ジャンプ命令実行時に ジャンプ先アドレスをアダーで「ゼロ+アドレス」演算を行ってプログラムカウンタに ロードする際に使用します。

74HC153 は、4 ビットの入力から 1 ビットを選択する回路が 2 回路入っています。 2 回路同時に使用すると、8 ビットの入力から 2 ビットを選択する回路になります。 74HC153 を 2 個使うと、最大 16 ビットの入力から 4 ビットを選択する回路を作る ことができます。半導体版 TD4 は、この 16 ビットの入力から 4 ビットを選択する回路を 構成して、12 ビット入力から 4 ビットを選択する機能を実現しています(入力 1 種類は未使用)。 【2009/11/02 追記】入力 1 種類は未使用ではなく「ゼロ」として使用します(前段落参照)。

これを今回はリレーを使用して実現する必要があるわけですが、よく考えると、今回使っている リレーは、2 つの入力から 1 つを選択する回路そのものです。よって、これを何段か 組み合わせれば 4 つの入力から 1 つを選択する回路が作成できそうです。 そして考え出した回路がこれです。


リレーを用いた 4-TO-1 マルチプレクサの回路図

これで 74HC153 の中の 1/2 回路に相当しますから、これを 4 個作れば 74HC153 2 個相当になります。 実用上は「4-TO-1」(4 ビットから 1 ビット選択)ではなくて「3-TO-1」が 4 つあれば十分なんですが、 「2-TO-1」 のマルチプレクサであるリレーを 2 段構成にすると「4-TO-1」になってしまいます。 なので、半導体版 TD4 と同様、16 ビットの入力の中から 4 ビットを選択する回路構成で、 12 ビット入力から 4 ビットを選択する機能を実現します。【2009/11/02 追記】12 ビット入力ではなく 16 ビットの入力全部使ってました。 1 種類は未使用ではなく「ゼロ」として使用します(最初の段落参照)。


実際に製作したリレー式マルチプレクサ

実際に製作しました。1 回路あたりリレーを 3 個使うので、4 回路だとリレーを 12 個使います。 リレーの数は少ないですが、なにしろ 4 ビットの配線が入力に 3 セット(【2009/11/02 追記】1 セットは ゼロなのでリレー式では NC)、出力に 1 セットあるので、裏の半田面はやや配線が多めになっています。 3種類から1種類を選ぶ機能をもつ基板なのに、入力側の LED (基板左側)が 2 種類分しかないのがわかると思いますが、 これは単なるミスです。でもまー LED 表示は出力側(基板右側)さえあれば間に合うので、入力側は REG_A と REG_B を 表示させることにしました。

あと LED をたくさん使っていますが、実は今回使用しているリレーは高感度タイプで、ON したときの 消費電流は 13[mA] 程度です。一方 LED は 12[V] の電源電圧に対して 1k[Ohm] の抵抗を介して ON するので、10[mA] 程度です(LED の順方向電圧を 2[V] で計算)。意外と LED の消費電流が大きいのです。 なので上のミスは実に 12[V]x10x4[mA] = 480[mW] も低消費電力化に貢献しているのです(常時点灯しているわけではありませんが)。

目次へ戻る / トップページへ戻る


[Sep.13 2009] TD4R: ROM アドレスデコーダ

レジスタ、アダー、その間を接続するロジックができたので、そろそろ ROM を作ることを考えようと思います。 まずは ROM アドレスデコーダを作ります。ROM のアドレスは 4 ビットで、アドレスあたり 1 バイト の ROM を配置しますので、最大 16 バイトになります。この 4 ビットのアドレスを 16 本の enable 信号に分解するのが今回製作する ROM アドレスデコーダです。この enable 信号によって、ROM は その中の特定のバイトがアクセスされたことを知るわけです。

半導体版 TD4 の 74HC154 のところで少し説明しましたが、要するに下表の ADDRESS の入力 (4 ビット) に対して、Y0 〜 Y15 の出力(16 ビット)が得られれば良いです。なお 74HC154 の出力は下の表と 1 と 0 が逆ですが、リレー版では 1 を出力した方が都合が良いのため論理を逆にしています。

  ADDRESS  | Y15 Y14 Y13 Y12 Y11 Y10 Y9  Y8  Y7  Y6  Y5  Y4  Y3  Y2  Y1  Y0
===========+=================================================================
      0    |  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   1
      1    |  0   0   0   0   0   0   0   0   0   0   0   0   0   0   1   0
      2    |  0   0   0   0   0   0   0   0   0   0   0   0   0   1   0   0
      3    |  0   0   0   0   0   0   0   0   0   0   0   0   1   0   0   0
      4    |  0   0   0   0   0   0   0   0   0   0   0   1   0   0   0   0
      5    |  0   0   0   0   0   0   0   0   0   0   1   0   0   0   0   0
      6    |  0   0   0   0   0   0   0   0   0   1   0   0   0   0   0   0
      7    |  0   0   0   0   0   0   0   0   1   0   0   0   0   0   0   0
      8    |  0   0   0   0   0   0   0   1   0   0   0   0   0   0   0   0
      9    |  0   0   0   0   0   0   1   0   0   0   0   0   0   0   0   0
      A    |  0   0   0   0   0   1   0   0   0   0   0   0   0   0   0   0
      B    |  0   0   0   0   1   0   0   0   0   0   0   0   0   0   0   0
      C    |  0   0   0   1   0   0   0   0   0   0   0   0   0   0   0   0
      D    |  0   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0
      E    |  0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0
      F    |  1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
-----------+-----------------------------------------------------------------

このデコーダ回路も、内部的には1を出力するビットをどれにするかというセレクタなので、 リレーを使用すると意外とシンプルに構成できます。


リレーを用いた TD4 ROM アドレスデコーダの回路図

今回も DIP SW で ROM を構成します(これについては某所で「ヒューズを使ってくれ」等いろいろ要望をいただきましたが...)。 今回使用している基板サイズでは、16 バイト分の DIP SW が 1 枚の基板に全部実装できないので、 2 枚の基板に分けるために、アドレスデコーダも Y0 〜 Y7 と Y8 〜 Y15 に分けています。 Y0 〜 Y7 の回路と Y8 〜 Y15 の回路の違いは、A3 のリレーの出力を normally closed 側から 取り出しているか、normally open 側から取り出しているかだけです。

実際にリレーを基板に配置して製作するために、リレーの配置を考慮した版です。 回路自体は読みにくくなりますが、これをみながら配線すると比較的楽です。 実際に製作する回路は、それぞれの出力に1個リレーを追加して、1の出力を前の回路から ではなく、このリレーに接続した電源から出力するようにしています。こうすることで、 前段のリレーの接点をいくつか通過して多少劣化した信号を出力にそのまま出さない ようにしています。


リレーを用いた TD4 ROM アドレスデコーダの回路図 (Y0 〜 Y7 出力回路)

実際に製作しました。


実際に製作したリレー式 ROM アドレスデコーダ

LED は右から順に Y0 〜 Y7 を表示します。 テストでアドレスを 3 にしたときの出力を表示しています。 このとき、Y3 が 1 になるので、右から 4 番目の LED が点灯しています。 正しく動作しているようです。

目次へ戻る / トップページへ戻る


[Sep.27 2009] TD4R: ROM データバス出力回路

ちょっと変なタイトルですが、今回製作するのは、アドレスで指定された ROM の1バイトをデータバスに出力する回路です。 半導体版 TD4 ではダイオードを使用して、これに相当する機能を実現していましたが、今回は半導体のかわりにリレーを 使うという趣旨で製作しているので、ダイオードは使用しないことにしました(ここはかなり葛藤しましたが)。

検討した限りでは、やはりダイオード1個をリレー1個で置き換えることになります。 ROM はたった 16 バイトしかありませんが、されど 16 バイト、これは 16 x 8 = 128 ビットです。 よってダイオードは 128 個必要でしたが、今回はこれを全部リレーに置き換えるので、ROM のデータバス出力回路だけで 128 個のリレーが必要になります。今回使用しているリレーは比較的小型のものですが、それでも小信号用 ダイオードに比べるとかなり大きいので、ダイオードを使う場合に比べるとかなり大がかりな回路になります。

ROM を除いた本体部分を構成するのに必要なリレーは 200 個もあれば十分と思われますが、 ROM だけで 128 個となると、全体の 1/3 強のリレーが ROM だけのために使われることになります。 これはなかなか痛いです。200 個買ったリレーの半分以上が ROM だけのために消費される ことになろうとは...。

まーそうは言ってもダイオードは使用しないと決めたので(実は心が揺れてダイオード 128 個購入して しまいましたが)、覚悟を決めてリレーで作ります。...そう心に決めたわけですが、やはりリレーを 128 個使う回路というのはそれなりにボリュームがあるわけです。そこで、製作は 4 バイト分ずつ、 つまり1つの基板にリレーを 32 個ずつ実装し、この基板を4枚製作することにしました。

4 バイト分の ROM データバス出力回路の回路図を次に示します(DIP SW も含む)。


リレーを用いた TD4 ROM データバス出力回路(クリックで拡大表示)

リレーの上にあるスイッチが DIP SW です。Y0 〜 Y3 は、前回製作した ROM アドレスデコーダの出力です。 4 ビットのアドレスによって Y0 〜 Y3 のどれかが H になり、DIP SW に電圧が供給されます。ここで DIP SW が ON だと、すぐ下のリレーに電圧がかかるので、リレーは ON になります。逆に DIP SW が OFF だとリレーは OFF になります。たとえば Y0 が H で、他が L のとき(つまりアドレスがゼロのとき)は、Y0 に接続された DIP SW だけに電圧がかかるため、このときに出力され得るのは Y0 → DIP SW に接続された 8 個のリレーだけで、 他のリレーはすべて OFF になります。ずらっとリレーが並んでいますが、ある時点において指定されるアドレスはつねに 1 個所だけなので、同時に ON になるリレーの数は最大で 8 個です。たくさんあるのに稼働率は低いのです...

実際に製作してみました。実装の都合上 DIP SW 基板と ROM データバス出力回路を 2 枚の基板に 分けています。


実際に製作した ROM DIP SW 基板


実際に製作したリレー式 ROM データバス出力回路

リレー基板はずらっとリレーが並んでいるだけです。毎回写真を載せていますが、 どの基板も基本的にはリレーが並んでいるだけなので、毎回見て楽しいのかどうかはよくわかりません。 ただ今回は 32 個のリレーを 1 枚の基板に実装する必要があったため、やむを得ずリレーの向きを 変えています。あとリレーの配置ですが、すき間なくずらっと並べてしまうと、不良があった場合や 壊れた場合にそのリレーを交換のために取り外すのが難しくなるため、4 個のブロックごとにすき間を 確保しています。

ROM データバス出力回路は、上の回路図と写真のものでやっと 4 バイト分です。16 バイトの ROM を得るためには、これを 4 枚製作する必要があります。命令の動作確認は 4 バイトもあれば可能だと 思いますが、TD4 の最終目標はなんといっても「ラーメンタイマー」を動かすことです。 そしてこのプログラムのサイズは 16 バイトです。よって、やはり 4 枚製作する必要があります。

これで ROM まわりがだいたいできたので、これまでに製作した基板を組み立ててみました。


リレー式 TD4 "ROM TOWER I" − 上から ROM DIP SW + ROM データバス出力回路 +
ROM アドレスデコーダ + 命令デコーダ + レジスタ(クリックで拡大表示)

このようにタワーを形成します。今後さらに ROM データバス出力回路基板を 1 枚追加するので、 さらに高層化します。スペースの都合で ROM データバス出力回路には LED が実装されていません。 よって目視で動作を確認することができません。ためしに動かしてみたところ、DIP SW の ON/OFF で カチカチッとリレーが切り替わっているので多分動いているでしょう。

ここまでやって動かせずに終了というのは、もうそろそろ考えられないです。 こうなったら意地でも動かすしか!昨日リレーを追加で 100 個注文しました。

目次へ戻る / トップページへ戻る


[Oct.11 2009] TD4R: TD4R 組み立て ー その1

これまでで、TD4 本体に必要なモジュールは一通り製作しましたので、 実際に組み立てて動作するかどうかを確認してみようと思います。 というわけで、組み立ててみました。


実際に仮組みしたリレー式 TD4 (クリックで拡大表示)

なかなか見応えが出てきましたね。 中央が前回で組み立てた「ROM TOWER I」です(上から ROM DIP SW、ROM データバス出力回路、 ROM アドレスデコーダ、命令デコーダ、レジスタ B)。その右の塔が「プログラムカウンタ」 (上から順にインクリメンタ、ロード値セレクタ、PC値保持レジスタ)、左の塔が「アキュムレータ」 (上から順にアダー、マルチプレクサ、レジスタ A)です。I/O レジスタはまだ取り付けていません。 プログラムカウンタの上に ROM 8 バイト分を増築予定です。これが完了すれば「ROM TOWER II」が完成します。

きちんと動作するでしょうか? 実際に MOV B, imm をいくつか実行させてみました(ちょっと写真がピンボケしてしまいましたが...)。


実際に仮組みしたリレー式 TD4 で MOV B, imm を実行している様子(クリックで拡大表示)

クロック発生回路をまだ製作していないので、手動でのクロック供給になりますが、レジスタ B(中央最下部)に きちんと値がロードされています。この命令を現在使用可能な ROM 4 バイトにプログラミングし、連続して実行 させてみます。この一連の動作でプログラムカウンタ → ROM アドレスデコーダ → ROM DIP SW → ROM データバス出力回路 → 命令デコーダ → アダー → レジスタ B の動作確認ができます。期待通りに レジスタ B に値がロードされれば 少なくともこの命令に関しては正しく動作していることになります。実際に imm 値を 1010, 0101, 1001, 0110 としてガチガチと手動でクロックを入力してみたところ、レジスタ B にこれらの値が順にロードされることが確認できました。 どうやら正しく命令を実行できているようです。ここまで実行できれば、配線ミスや想定外の事故がない限り 完成させることができそうです。電源の容量がかなり心配でしたが、とりあえず MOV B, imm に関しては 12V 1Aの ごく普通のスイッチング AC アダプタで問題なく動作させることができました。この様子だと多分 12V 2A の電源で 全ての回路を問題なく動かすことができそうです。

ここまで組み立ててみて、「プログラムカウンタ」の上に ROM 回路を増築すると、左の ROM TOWER I よりも 一段高くなってしまうことに気がつきました(いきあたりばったり設計なので...)。これではちょっと見栄えが よくないので、「プログラムカウンタ」のインクリメンタとロード値セレクタを1枚の基板に作りなおすことにしました。 まーちょっとしたリワークになりますが、これまでに製作してきた規模に比べれば大したことはないです。

今回の動作確認で、だいたい完成の目処が立ったと思います。 あとは残り 12 バイト分の ROM 回路と、I/O 部分を完成させて、 最後に一番面白そうな(派手な音を出すと予想される)クロック発生回路を作るだけです。 あー、あとリセット回路も残ってますね。

ちなみに写真左上に写っている LED は別のプロジェクトの産物です(mp3プレーヤ)。関係ないですが 写ってしまっていたので一応...。

目次へ戻る / トップページへ戻る


[Nov.02 2009] TD4R: 4-bit インクリメンタ+セレクタ

前回の仮組みを行った際にプログラムカウンタのインクリメンタとロード値セレクタを1枚の基板に 作り直すということを書きました。そう言いつつ実際に作り直すのはいちばん最後かなーと思っていたのですが、 なんとなくやる気になったので、先に作り直してしまいました。

プログラムカウンタの機能は、値のロード・保持機能をもつ普通のレジスタに、 インクリメンタを追加したものと考えることができます。通常は+1を繰り返して行きますが、 分岐命令を実行したときは、分岐先のアドレス値をロードする必要があります。 よってプログラムカウンタのレジスタ部に値をロードするソースはインクリメンタの 出力とロード値の 2 つになります。この 2 つは同時に使用しない(ジャンプと+1は同時に起こらない)ので、 場合によってインクリメンタの出力をレジスタにロードするか、ロード値をレジスタにロードするかを 選択する必要があります。この選択に使える信号は何でしょうか?

まーここまで読まれてきた方は既にお分かりかと思いますが、命令デコーダが作り出す /LDPC 信号がそれです。 ジャンプ命令実行時や条件分岐が成立した場合に /LDPC は L になります。このときはプログラムカウンタの 入力データはインクリメンタの出力ではなく、ロード値が選択されていなければなりません。逆に /LDPC が H のときはインクリメンタの出力がプログラムカウンタの入力に選択されていなければなりません。

というわけで考えたのが次の回路です。まーこれは前から作ってあったんですが、 これまでセレクタの部分を掲載していなかったので、ここでまとめて掲載しておきます。


作り直した 4-bit インクリメンタ+セレクタ(クリックで拡大表示)

インクリメンタの出力が Y0〜Y3、プログラムカウンタのロード値は S0〜S3 です。 TD4 ではこのロード値 S0〜S3 はアダーの出力です。データの経路は ROM → ROMデータバス → アダー → レジスタロード用データバス → ロード値セレクタ → レジスタ となります。プログラムカウンタのロード値が アダーを経由しているのが不自然に感じられるかもしれません。TD4 のジャンプ命令に関しては ROM からの データがそのままプログラムカウンタへ流れますので、アダーを経由させなくても目的の機能は実現可能です。 しかし実際には他のレジスタのロードと同じデータバスをを利用してプログラムカウンタへ値をロードしています。 この利点としては、既に他のレジスタに値をロードするために用意されているデータバスを利用できる点が挙げられます (TD4 はそもそも回路の規模が小さいのでその利点はあまり感じられませんが)。また、TD4 は相対ジャンプ命令を持って いませんが、仮に相対ジャンプを実現する場合はアダーを経由させ、相対ジャンプのときはアダーで PC と相対値を加算 するようにし、絶対ジャンプのときはアダーにゼロと絶対値を加算するように構成する方法が考えられます。 この様に考えるとジャンプ先のアドレスがアダーを経由してプログラムカウンタにロードされる経路は不自然ではないでしょう。 コンピュータの回路では NOP などの何もしない命令が実は「変化が起きない演算をする」命令として設計されていることが よくあります。

と、ここまで書いて気がつきましたが、マルチプレクサの 1 入力は未使用ではなく、「ゼロ入力」としてジャンプ命令で 使っていましたね。TD4 はアダーを経て絶対アドレスをプログラムカウンタにロードするので、このときにアダーのもう一方の 入力がゼロでないと不要な値が絶対アドレスに加算されてしまって、ジャンプ先が不正になってしまいます。 →マルチプレクサの記述を訂正しました。

プログラムカウンタは、TD4 の場合、1 クロックごとに +1 されるか、値がロードされるかのどちらかを 必ず実行しますので、リレー式 TD4 プログラムカウンタのレジスタ部はクロックごとに値をロードします。 本来 /LDPC 信号は、プログラムカウンタに値をロードする意味で L になる信号ですが、これをわざわざ 教えてもらわなくても、クロックごとに値をロードしているので、実際には上に書いたように、 /LDPC 信号はインクリメンタの値とロード値を切替えるのに使用しているだけです。

あと 1 クロックごとに必ず値をロードするレジスタが 1 つあります。それはキャリーフラグです。 これは 1 ビットのレジスタで、半導体版 TD4 では 74HC74 で実現されています。リレー式 TD4 では、 プログラムカウンタの基板に別個でレジスタを 1 ビット用意して、これをキャリーフラグとしています。 1 クロックごとに値をロードするレジスタということで、ロードのタイミングが同じなのでここに追加しています (1 ビットのためにマスターとスレーブのタイミングを別に作るのは無駄に思えたので)。


実際に製作したリレー式インクリメンタ+セレクタ(上段)

文章力がないため話が長くなってしまいましたが、写真上段が実際に製作したインクリメンタ+セレクタ基板です。 下段はレジスタ部になります。下段の左に一つ離れた LED がありますが、これがキャリーフラグの LED です。 この 2 段の基板でプログラムカウンタとして機能します。これで、もともと 3 段で構成していたプログラムカウンタを 2 段構成にすることができました。

目次へ戻る / トップページへ戻る


[Jan.12 2010] TD4R: TD4R 組み立て ー その2

ROM を 16 バイトすべて製作したのでまた組み立てました。 これで 95% くらい完成していると思います。机が汚くてすみません。


実際に組み立てたリレー式 TD4 (クリックで拡大表示)

クロック生成部も製作したので、電源を入れるとジャラジャラとかガチャガチャという感じの音を立てて動きます。 うーん、これだ。これですよ(笑)。なかなか壮観です。半導体版の10倍くらいの見応え...特に リレー式は聴き応えがあります。まぁ製作費も半導体版の10倍くらいかかっていますが。

ROM の DIP スイッチにアクセス LED を追加しました。1クロックごとにどの DIP スイッチに アクセスしているかが目視で確認できるので、プログラムが実行されている様子がわかりやすいです。

右端の上段全面にタクトスイッチとトグルスイッチを実装し、クロックを自動/手動切り替え できるようにしました。

自動クロックはリレーを24個ドミノのように接続して生成しています。 最初のリレー出力を NC (Normally-Closed)側から取り出し、2 段目以降はすべて NO (Normally-Open) 側を次のリレーの入力に接続していきます。電源 ON 時は最初のリレーが H になるので、ジャララーっと 最後のリレーまで順に H になっていきます。最後のリレー出力を最初のリレーの入力にフィードバックすれば、 最後のリレーが H になったときに、最初のリレーが ON するので NC 側は L になります。すると今度は 最後のリレーまで順番に L になっていきます。すると最初のリレーが OFF するので、最初の状態に戻ります。 これが繰り返されて H と L が交互に出力されます。見た感じから、だいたい 5[Hz] 〜 6[Hz] の クロックが出力されていると思います。

残すところはパワーオンリセット回路と、入出力ポートの接続です。I/O はまだ配線できていないので I/Oから読み出してもゼロになり、I/O出力命令を実行しても電圧がI/Oに出てきません。

見た目で前回から大きく変わったのは ROM の部分です。配線が多く結構時間がかかりました。 しかし、ここまで来るのに本当に苦労したのは実は ROM ではなく、レジスタでした。

いつの頃からか、プログラムカウンタの動作が不安定になりました。はじめは電源の容量が 足りないのだと思っていましたが、レジスタ+インクリメンタだけの構成でもかなり頻繁に 誤動作します。

改めてレジスタ回路を見直すと、設計がかなり怪しいです。これでよく動いているな、という感じです。 実際に製作される方は多分いないと思いますが、その場合レジスタはご自分で設計し直した方が 良いと思います。

とりあえずプログラムカウンタがかなりの頻度で誤動作するので、回路を修正する必要があった わけですが、リレーを追加するスペースはもうありませんでした。そこで、実験しながらなんとか動くように 配線を変更しました(苦肉の策)。レジスタさえきちんと動けば全部できたも同然と思っていましたが、 ここへ来てレジスタの不具合というのはかなりダメージが大きいです(4つもあるし)。レジスタが まともに動かないと話になりません。

まぁしかしなんとかそれも動くようになりました。実際はまだ若干誤動作することがありますが、 許容範囲としました。

あと少しで完成です。思ったより時間がかかってしまいました。 完成したら動画を撮ろうと思います。当初はちょっといいデジカメでも買おうかと思っていましたが、 やはり画質というよりは、音をしっかり録音したいです。今回製作したリレー式 TD4 は 横長に作ったので、左側と右側で違う音がするのが聴いていてわかります。その辺をちゃんと 再生動画でも再現したいと思います。

とりあえず、コンデンサマイクを2個買ってきてオペアンプで信号を増幅して PC に入力し、ステレオ録音をやってみようと思います。満足の行く音質になるかなー?

目次へ戻る / トップページへ戻る


[Jun.19 2010] TD4R: TD4R デモ動画

更新が遅くなり、すみませんでした。 デジカメを買ったのでデモ動画を撮ってみました。 サーバーの容量がないためファイルサイズをオリジナルの 1/30 未満にエンコードせざるを得ず、画質はかなり劣化していますが、 それでも以前のデモ動画よりは見れるようになったと思います。

→[Nov.15 2010] ニコニコ動画に上げました

電源投入時にアドレスが 0 番地とならずに 1 番地になっていますが、 これは電源投入時にプログラムカウンタをリセットしていないためです(手抜き)。 0 で起動しないのはプログラムカウンタだけなので、ここだけにでもリセット回路を つけようと思いつつ、ついに放置したまま半年が経過してしまったので、 もういいやと思ってそのまま動画にしてしまいました。(苦)

動作させているのはほぼラーメンタイマーそのものです。 オリジナルのプログラムは最終番地で jmp 15 を実行し続けますが、 デモでは jmp 0 として、処理を最初に戻しています。

というわけで、PROJECT TD4R はこの辺で完了としたいと思います。 まー時間をかけて作りましたが、特に思い入れはないですね。(苦) 欲しい方はメールください。現状のモノを着払いで送りますので。。。
→[Oct.02 2010] とある方にあげました。

PROJECT TD4R − 完 −

目次へ戻る / トップページへ戻る


[Nov.15 2010] PROJECT TD4V - TD4 を CPLD/FPGA で実現する

最後に TD4 を CPLD/FPGA でも実現しておこうと思います。 というわけでとりあえず Verilog で記述してみました。 ここをクリックするとダウンロードできます(tar.gz 形式)。 linux で開発したので改行が LF のみとなっています。Windows の Notepad では改行が正しく認識されません。LF 改行に対応しているエディタ(秀丸等)で開いてください。

ラーメンタイマーをシミュレートした結果を以下に示します(経過時間はテキトウです)。


TD4 を HDL で記述してシミュレートしてみた(クリックで別ウィンドウ表示)

どうやら動いているようですね。試しに MOV B, Imm を実行したところ、これも正しく動作していました。

この規模なら CPLD に十分入りそうです。気が向いたときに CPLD または FPGA 上で実行してみようと思います。


[Jan.29 2011]

CPLD で動くことを確認しました。CPLD は XC9572PC44-15 を使用しました。TD4 自体は XC9536 に余裕で入りますが、クロックに 3.58MHz を使用しているため、動作を遅くする必要がありました。 そのために 20 ビットのカウンタを使って分周したところ、XC9536 に入らなくなってしまいました。 ISE の Timing Report によると、80[MHz] 超えでも動作するらしいです。


CPLD に TD4 を実装しラーメンタイマーの動作を確認した

無事確認できました。というわけでめでたしめでたし・・・。

PROJECT TD4V − 完 −

目次へ戻る / トップページへ戻る


謝辞・関連リンク


(C) Ki 2009, 2011

inserted by FC2 system