リレーやトランジスタやICで全加算器を作った

リレー・トランジスタ・ICで半加算器や全加算器を作った。リレー回路は4bit全加算器です。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">リレーやトランジスタやICを使って全加算器を作りました。リレーは4bit全加算器です。各リレーの結果が伝搬するまで時間がかかるので、入力してからパタパタと遅延があるのがかわいい(後半)。(2019年に作ったものをqiitaにまとめるので動画upload)<a href="https://t.co/pz6IWqS55y">https://t.co/pz6IWqS55y</a> <a href="https://t.co/ZkEh47XsPS">pic.twitter.com/ZkEh47XsPS</a></p>&mdash; Akira KANAI (@recuraki) <a href="https://twitter.com/recuraki/status/1263094408490086400?ref_src=twsrc%5Etfw">May 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/055c66c9-cb0b-b5c2-2146-280ad0317dd9.png" width=33%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/796af9cc-5cde-78f9-13a1-95bf071fea56.png" width=25%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/eabf904d-7c40-ef3c-c342-3e18f4bd73ca.png" width=33%>


# 加算器の基本
加算器には半加算器(Half Adder)と全加算器(Full Adder)が存在する。半加算器は繰り上がりを入力に持たない加算器でNANDゲートを用いると以下のように示せる。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/69affd47-6051-96b4-d10a-88a87094e7cd.png" width=50%>

次に、全加算器とは、繰り上がりを入力にもつ加算器でり、全加算器は半加算器2つとORゲート1つで表現することができる様子を下図に示す。この図ではORゲートをNANDゲートで実装している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/9f123fce-5c1e-e88c-d043-31331b6fb1bf.png)

# NANDゲートのみで加算された加算器の事前検証
上記の論理回路が正しく全加算器として動作するかを検証する。最も安易な確認として下図のように手で検証を行う。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/ec1aebf5-4d7e-aeb2-20a2-ad184bf153f1.png" width=50%>


ただし、もう少しうまい手として、FPGAなどで用いられる言語Verilogのシミュレータであるiverilog(イカルス・ヴェリログ)を用いる。以下に半加算器のシミュレーションコードと結果を示す。

```Verilog
// 半加算器の検証
module HA( input x, y, output r, c);
  logic r11, r21, r22, r23, r31;
  assign r11 = x ~& y;
  assign r21 = x ~& r11;
  assign r22 = y ~& r11;
  assign c = r11 ~& r11;
  assign r = r21 ~& r22;
endmodule
module test;
  logic a, b, c, s;
  HA adder(.x(a), .y(b), .r(s), .c(c));
  initial begin
    $dumpfile("test.vcd");
    $dumpvars(0, test);
    $display("A B C S");
    $monitor("%b %b %b %b", a, b, c, s);
    a = 0; b = 0; #1;
    a = 0; b = 1; #1;
    a = 1; b = 0; #1;
    a = 1; b = 1; #1;
    $finish;
  end
endmodule
```

```
   iverilog -g2012 -o test  test.v
   vvp test
   VCD info: dumpfile test.vcd opened for output.
   A B C S
   0 0 0 0
   0 1 0 1
   1 0 0 1
   1 1 1 0
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/9b9c8c58-5b98-d1cd-7238-8ef1b907f927.png)

# ICで実装する
上記で(上記は半加算器だが全加算器もシミュレーションし、)ロジックとして正しいことが分かった。この様子を以下に示す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/055c66c9-cb0b-b5c2-2146-280ad0317dd9.png)
図の下がNANDだけに書き下したものだ。 この回路はNANDだけで演算しようとしているが、ORをもうちょっと省力化してもいいかもしれない。 ICとしては秋月電子で購入できる74HC00を使った。これは比較的低額にできる。せいぜい、IC代20円 x 4程度だ。
C,X,Yの入力はVCCを直接入力し、R,Cの出力はLEDを光らせることで表現している。

# トランジスタを使ったNANDの実装
汎用ロジックICで回路が組めたので、半導体のディスクリートで回路を組む。トランジスタ等(FETなど)を使ったNANDの実装はいくつかある。まず、ANDとNOTを端的に組み合わせると以下のような回路が思いつく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/b52b941b-f9dc-a4d3-d06b-957ff9b8a281.png)
Trを用いた教科書的なANDとNOTを組み合わせただけの簡単な回路である。 これは一見して動くように見える。ただ、青い線の場合のように、X=0, Y=0のとしてGNDに落とした場合、期待としてはTrのベースに対する入力は0vとなり、結果、outにVccが印加されてほしいが、ダイオードのVFがあるため、この回路ではTrのベースには0.8V以上がかかり、VF0.6Vくらいだとすると、トランジスタがONしてしまう。 こうなると、コレクタ側からの5Vはすべて接地されてしまい、outに出力が行われない。そこで、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/d16e9c2c-dd4b-60fa-b3a1-5ce838c507c4.png)
のようにTrの手前に(通常はIn側と同じ)ダイオードを入れてやる。これをレベルシフトダイオードと呼ぶ。こうなると、VF分落ちるので、Trはめでたく0Vとなり、OFF状態になって、NANDとして作用する。 実際にブレッドボードに試作した。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/99015e6d-8c7c-883a-856e-92454c352ff4.png" width=50%>


# トランジスタを使った半加算器のシミュレーションと実装
NANDが作成できたため、あらゆる論理回路が実装できる。これらを組み合わせて半加算器を作成する。まず、LTSpiceをつかってシミュレートしてみた結果が以下。使い方に明るくないので、電源を複数種類用意してパルス波形をはくシミュレーションにした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/20157132-6b90-afb0-1f6b-ad58c723ccd0.png)

実際にうまくいきそうなので、ユニバーサル基盤に実装した。家にあったユニバーサル基盤に全加算器を実装できないかなとトライを初めてものすごい詰め込んだらつらいことになってしまった。一応、各ロジックか5x5のピンには収まっている。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/796af9cc-5cde-78f9-13a1-95bf071fea56.png" width=50%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/cb9509ea-aab7-3582-aedf-4a0f1c6398ec.png" width=50%>

# リレーを使った4bit全加算器の実装
リレーはある入力を受け付けると、ONになるスイッチ(a接点)とOFFになるスイッチ(b)が組み合わされている。これらを適切に組み合わせることで、さまざまな論理演算を行うことが可能である。結論からいうと次のようなリレー回路を組めばよい。 +となっているところにはリレーの起動電圧を入れる。 GNDとONはコイル部分の13,14番ピンである。 下側が入力のX, Y, C, 上側が出力のSumとCarryである。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/f16c4a38-a2bd-0616-a1e1-9a451d08896e.png)


## 調達と実装
リレーを実際に利用する際は、ソケットを用いた実装とした。 ラッピングワイヤが使えればそれでもいいが、実際問題、ソケットが現実的だろう。 ただ、このリレーとソケットの組み合わせは恐ろしく高い。新品定価で購入しようとすると、2c接点の組み合わせで1500 + 1000 = 2500円位する。これは現実的でないので、 FA機器 などで安い2MY等が出るのを待ち購入した。 尚、ソケットは基本的にM3のねじでとまる。ただし、若干長さがあるのであまり短いと合わないかも。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/9caa2d32-d058-123a-1a5f-7e8afd69663a.png" width=33%>

この結果、4c接点を含む20強のリレーを手に入れた。 ご覧の通り、リレーの端子はY端子をねじ止めすることになっている。配膳部材としては以下のものを用意した。

- VSF 0.75mm より線(20m)
- ニチフ 1.25Y-3.5 (200個)
- スリーブ(TIC 1.25) (200個)

基本的に電工カッターで向いて、圧着する。の繰り返し。あとはドリルなりM3のねじやナットで詰めていく。基本的に忠実に作っていけばあまり問題はない。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/4c60431f-c1d4-71a2-fb9f-1ca18507dca9.png" width=33%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/06d59f2f-c62e-ff0b-5932-7fce5eafd829.png" width=33%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/447e82e4-6ab8-b6f6-5aa9-810a3a342bea.png" width=33%>

完成したところ。 右上のほうの端子はリレー回路実験用の端子盤。こういうのがあるとトラブルシュートが楽。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/7e0d6ce4-4f33-816f-2ddf-19fa180d36d5.png" width=50%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/eabf904d-7c40-ef3c-c342-3e18f4bd73ca.png" width=50%>


# 参考：リレーの動作(2C接点での実装のシミュレーション)
次に、それぞれの入力状態で、各リレーがどのように動作し、どのように出力されるのかを示す。 オレンジがコイルによって動作した部分、赤は電流が伝搬している旨を示している。

- X=0, y=0, C=0 結果はSum = 0, Carry = 0
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/94a6a732-0e4f-6ea7-821c-2ce154ecbde0.png)

- X=1, y=0, C=0 結果はSum = 1, Carry = 0
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/1b4b7aff-e12c-338f-1cb2-53b87e744ff0.png)

- X=0, y=1, C=0 結果はSum = 1, Carry = 0
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/029b6f75-dcde-7802-ed55-512ec9dda936.png)

- X=1, y=1, C=0 結果はSum = 0, Carry = 1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/4ac08a47-8c88-6e8b-6c07-7dfb7cd38d63.png)

- X=0, y=0, C=1 結果はSum = 1, Carry = 0
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/dc9defdb-53d0-014e-8504-6f0fc11611cc.png)

- X=1, y=0, C=1 結果はSum = 0, Carry = 1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/e36d6b88-cb3e-3771-915f-fc526159f808.png)

- X=0, y=1, C=1 結果はSum = 0, Carry = 1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/600cbd00-078e-450e-58ea-25b4df0d198a.png)


- X=1, y=1, C=1 結果はSum = 1, Carry = 1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/c9d8cf9b-c958-0dca-ff51-e8f26aee2fa1.png)

(以上)