2進数の足し算をする回路
加算器は、2進数の足し算をする回路です。CPU の計算は、1桁の足し算を重ねたものです。加算器の仕組みを知ると、その始まりが分かります。
たとえば券売機が、350円と150円を足すときも、中では1桁ずつの足し算が動いています。
このレッスンのゴール
メモ
桁上がりが次の桁へ渡る仕組みを説明できる。
重要な言葉
| ことば | いみ |
|---|---|
| 半加算器 | 2つのビットを足し、和とキャリーを出す回路 |
| 全加算器 | キャリー入力も含め、3つのビットを足す回路 |
| 和 | その桁に残るビット |
| キャリー | 1つ上の桁へ送る、桁上がりのビット |
| 最下位ビット | 一番右の、いちばん小さい桁のビット |
学生が入力するセルは、このプレビューでは空白です。
1ビットの足し算は2つの出力を持つ
1 + 1 は2進数で 10 です。答えが1桁に収まらないので、その桁に残る和の0と、上の桁へ送るキャリーの1に分かれます。
これを回路にしたものが半加算器です。和は XOR、キャリーは AND で作れます。
半加算器の表
| a | b | 足した結果 | キャリー | 和 |
|---|---|---|---|---|
| 0 | 0 | 00 | 0 | 0 |
| 0 | 1 | 01 | 0 | 1 |
| 1 | 0 | 01 | 0 | 1 |
| 1 | 1 | 10 | 1 | 0 |
学生が入力するセルは、このプレビューでは空白です。
半加算器2つでは桁上がりが消える
2ビットの数を足すには、下の桁と上の桁を足します。上の桁には、下の桁のキャリーも足さなければなりません。
半加算器にはキャリーを受け取る入力がありません。2つ並べただけだと、桁上がりが捨てられます。3 + 1 で確かめましょう。
半加算器を並べた回路
// 半加算器を2つ並べて、2ビットの足し算をしてみる。
half_adder low(.a(x[0]), .b(y[0]), .sum(s0), .carry(c0));
half_adder high(.a(x[1]), .b(y[1]), .sum(s1), .carry(c1));
// c0 は、上の桁に渡されていない。
ラボのフォルダに入る
cd ~/hdlここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
テストベンチを書く
printf 'module two_bit_tb;\n reg [1:0] x, y;\n reg [2:0] want;\n wire s0, c0, s1, c1;\n half_adder low(.a(x[0]), .b(y[0]), .sum(s0), .carry(c0));\n half_adder high(.a(x[1]), .b(y[1]), .sum(s1), .carry(c1));\n initial begin\n x = 3; y = 1; want = x + y;\n #1 $display("correct %%0d, circuit %%0d", want, {c1, s1, s0});\n end\nendmodule\n' > /tmp/two_bit_tb.vここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
2つのファイルを準備する
iverilog -o /tmp/two_bit half_adder.v /tmp/two_bit_tb.vここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
3 + 1 を動かす
vvp /tmp/two_bitここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
全加算器はキャリーも足す
正しくは、各桁で3つのビットを足します。足す2つのビットと、下の桁から来たキャリーです。これを全加算器と呼びます。
全加算器の中身は、ラボの課題です。ここでは、3 + 1 を桁ごとに足したときの、キャリーの流れを見ましょう。
3 + 1 を桁ごとに足す
| 桁 | 足すビット | キャリー入力 | 和 | キャリー出力 |
|---|---|---|---|---|
| 0(下) | 1 と 1 | 0 | 0 | 1 |
| 1(上) | 1 と 0 | 1 | 0 | 1 |
| 2(答えの桁) | 0 と 0 | 1 | 1 | 0 |
学生が入力するセルは、このプレビューでは空白です。
よくある間違い
注意
2ビットの数どうしの和は、2ビットに収まると思いがちです。実際は、3 + 3 = 6 で、110 と3ビット要ります。いちばん上の桁から出るキャリーも、答えの1桁です。捨てると、答えが小さくなります。
さらに挑戦: 引き算
課題が通ったら、引き算を考えましょう。2進数では、引く数のビットを反転して1を足すと、負の数になります。
add_bits を使って、5 から 3 を引く手順を紙に書いてみましょう。3ビットで、答えの桁あふれを捨てると、2になります。