目次
半加算器とは
以下を参考にしました。
https://ja.wikipedia.org/wiki/%E5%8A%A0%E7%AE%97%E5%99%A8
http://www.ctleec.sakura.ne.jp/2024/01/28/13-%e5%8d%8a%e5%8a%a0%e7%ae%97%e5%99%a8%e3%80%81%e5%85%a8%e5%8a%a0%e7%ae%97%e5%99%a8/
要はaとbを1ビットの2進数として足し算をするだけです。
桁上げと言うと難しく聞こえますが、1+1=2(2進数では10)となり、桁が足りなくなるから1つ位を上げているだけです。
cは桁上げ、sは足し算の結果です。
真理値表
| a | b | c | s | 10進数 |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 | 1 |
| 1 | 0 | 0 | 1 | 1 |
| 1 | 1 | 1 | 0 | 2 |
半加算器には幾つか実現方法がありますが、ANDとXORを使う簡単な方を採用します
真理値表を見ると、cはaとbのAND、sはaとbのXORとなっていることが分かります。
$$
S = A \oplus B
$$
$$
C = A \cdot B
$$
LEDで動作を可視化
今までNANDを並べて検証してきましたが、この辺りからNANDが多くなり過ぎて、並べるのが困難になってきます。
既に前の記事でNANDを並べることで全ての論理素子を構成できることを証明しているので、ここからは既成の素子を使います。
既存の素子を使いますが以下のようにNANDを用いて構成した場合と同等です。
/opt/simulide-110sr0/simulide hadder.sim1
hadder.sim1
<circuit version="1.1.0-SR0" rev="1917" stepSize="1000000" stepsPS="1000000" NLsteps="100000" reaStep="1000000" animate="0" >
<item itemtype="Xor Gate" CircId="Xor Gate-1" mainComp="false" Show_id="false" Show_Val="false" Pos="-116,-100" rotation="0" hflip="1" vflip="1" label="Xor Gate-1" idLabPos="-16,-24" labelrot="0" valLabPos="-16,20" valLabRot="0" Input_High_V="2.5 V" Input_Low_V="2.5 V" Input_Imped="1000 MΩ" Invert_Inputs="false" Out_High_V="5 V" Out_Low_V="0 V" Out_Imped="40 Ω" initHigh="false" Inverted="false" Open_Collector="false" Tpd_ps="10 ns" Tr_ps="3 ns" Tf_ps="4 ns" />
<item itemtype="And Gate" CircId="And Gate-2" mainComp="false" Show_id="false" Show_Val="false" Pos="-116,-60" rotation="0" hflip="1" vflip="1" label="And Gate-2" idLabPos="-16,-24" labelrot="0" valLabPos="-16,20" valLabRot="0" Input_High_V="2.5 V" Input_Low_V="2.5 V" Input_Imped="1000 MΩ" Num_Inputs="2" Invert_Inputs="false" Out_High_V="5 V" Out_Low_V="0 V" Out_Imped="40 Ω" initHigh="false" Inverted="false" Open_Collector="false" Tpd_ps="10 ns" Tr_ps="3 ns" Tf_ps="4 ns" />
<item itemtype="Fixed Voltage" CircId="Fixed Voltage-3" mainComp="false" Show_id="false" Show_Val="false" Pos="-224,-104" rotation="0" hflip="1" vflip="1" label="Fixed Voltage-3" idLabPos="-64,-24" labelrot="0" valLabPos="-16,8" valLabRot="0" Voltage="5 V" Out="false" />
<item itemtype="Fixed Voltage" CircId="Fixed Voltage-4" mainComp="false" Show_id="false" Show_Val="false" Pos="-224,-80" rotation="0" hflip="1" vflip="1" label="Fixed Voltage-4" idLabPos="-64,-24" labelrot="0" valLabPos="-16,8" valLabRot="0" Voltage="5 V" Out="false" />
<item itemtype="Resistor" CircId="Resistor-7" mainComp="false" ShowProp="Resistance" Show_id="false" Show_Val="true" Pos="-184,-144" rotation="0" hflip="1" vflip="1" label="Resistor-7" idLabPos="-16,-24" labelrot="0" valLabPos="-16,6" valLabRot="0" Resistance="70 Ω" />
<item itemtype="Led" CircId="Led-8" mainComp="false" Show_id="false" Show_Val="false" Pos="-144,-144" rotation="0" hflip="1" vflip="1" label="Led-8" idLabPos="-16,-24" labelrot="0" valLabPos="-16,20" valLabRot="0" Color="Yellow" Grounded="false" Threshold="2.4 V" MaxCurrent="30 mA" Resistance="0.6 Ω" />
<item itemtype="Ground" CircId="Ground-9" mainComp="false" Show_id="false" Show_Val="false" Pos="-120,-124" rotation="0" hflip="1" vflip="1" label="Ground-9" idLabPos="-16,8" labelrot="0" valLabPos="-16,20" valLabRot="0" />
<item itemtype="Resistor" CircId="Resistor-11" mainComp="false" ShowProp="Resistance" Show_id="false" Show_Val="true" Pos="-184,-28" rotation="0" hflip="1" vflip="1" label="Resistor-11" idLabPos="-16,-24" labelrot="0" valLabPos="-16,6" valLabRot="0" Resistance="70 Ω" />
<item itemtype="Ground" CircId="Ground-12" mainComp="false" Show_id="false" Show_Val="false" Pos="-120,-8" rotation="0" hflip="1" vflip="1" label="Ground-12" idLabPos="-16,8" labelrot="0" valLabPos="-16,20" valLabRot="0" />
<item itemtype="Led" CircId="Led-13" mainComp="false" Show_id="false" Show_Val="false" Pos="-144,-28" rotation="0" hflip="1" vflip="1" label="Led-13" idLabPos="-16,-24" labelrot="0" valLabPos="-16,20" valLabRot="0" Color="Yellow" Grounded="false" Threshold="2.4 V" MaxCurrent="30 mA" Resistance="0.6 Ω" />
<item itemtype="Resistor" CircId="Resistor-22" mainComp="false" ShowProp="Resistance" Show_id="false" Show_Val="true" Pos="-68,-100" rotation="0" hflip="1" vflip="1" label="Resistor-22" idLabPos="-16,-24" labelrot="0" valLabPos="-16,6" valLabRot="0" Resistance="50 Ω" />
<item itemtype="Ground" CircId="Ground-23" mainComp="false" Show_id="false" Show_Val="false" Pos="-4,-80" rotation="0" hflip="1" vflip="1" label="Ground-23" idLabPos="-16,8" labelrot="0" valLabPos="-16,20" valLabRot="0" />
<item itemtype="Led" CircId="Led-24" mainComp="false" Show_id="false" Show_Val="false" Pos="-28,-100" rotation="0" hflip="1" vflip="1" label="Led-24" idLabPos="-16,-24" labelrot="0" valLabPos="-16,20" valLabRot="0" Color="Yellow" Grounded="false" Threshold="2.4 V" MaxCurrent="30 mA" Resistance="0.6 Ω" />
<item itemtype="Resistor" CircId="Resistor-25" mainComp="false" ShowProp="Resistance" Show_id="false" Show_Val="true" Pos="-68,-60" rotation="0" hflip="1" vflip="1" label="Resistor-25" idLabPos="-16,-24" labelrot="0" valLabPos="-16,6" valLabRot="0" Resistance="50 Ω" />
<item itemtype="Ground" CircId="Ground-26" mainComp="false" Show_id="false" Show_Val="false" Pos="-4,-40" rotation="0" hflip="1" vflip="1" label="Ground-26" idLabPos="-16,8" labelrot="0" valLabPos="-16,20" valLabRot="0" />
<item itemtype="Led" CircId="Led-27" mainComp="false" Show_id="false" Show_Val="false" Pos="-28,-60" rotation="0" hflip="1" vflip="1" label="Led-27" idLabPos="-16,-24" labelrot="0" valLabPos="-16,20" valLabRot="0" Color="Yellow" Grounded="false" Threshold="2.4 V" MaxCurrent="30 mA" Resistance="0.6 Ω" />
<item itemtype="Node" CircId="Node-5" mainComp="false" Pos="-156,-80" />
<item itemtype="Node" CircId="Node-6" mainComp="false" Pos="-148,-104" />
<item itemtype="Node" CircId="Node-20" mainComp="false" Pos="-200,-104" />
<item itemtype="Node" CircId="Node-21" mainComp="false" Pos="-200,-80" />
<item itemtype="Connector" uid="Connector-3" startpinid="Node-5-1" endpinid="And Gate-2-in1" pointList="-156,-80,-156,-56,-132,-56" />
<item itemtype="Connector" uid="Connector-5" startpinid="Node-5-2" endpinid="Xor Gate-1-in1" pointList="-156,-80,-132,-80,-132,-96" />
<item itemtype="Connector" uid="Connector-6" startpinid="Node-6-1" endpinid="And Gate-2-in0" pointList="-148,-104,-148,-64,-132,-64" />
<item itemtype="Connector" uid="Connector-8" startpinid="Node-6-2" endpinid="Xor Gate-1-in0" pointList="-148,-104,-132,-104" />
<item itemtype="Connector" uid="Connector-9" startpinid="Led-8-rPin" endpinid="Ground-9-Gnd" pointList="-128,-144,-120,-144,-120,-140" />
<item itemtype="Connector" uid="Connector-10" startpinid="Resistor-7-rPin" endpinid="Led-8-lPin" pointList="-168,-144,-160,-144" />
<item itemtype="Connector" uid="Connector-14" startpinid="Resistor-11-rPin" endpinid="Led-13-lPin" pointList="-168,-28,-160,-28" />
<item itemtype="Connector" uid="Connector-15" startpinid="Led-13-rPin" endpinid="Ground-12-Gnd" pointList="-128,-28,-120,-28,-120,-24" />
<item itemtype="Connector" uid="Connector-40" startpinid="Resistor-7-lPin" endpinid="Node-20-1" pointList="-200,-144,-200,-104" />
<item itemtype="Connector" uid="Connector-41" startpinid="Fixed Voltage-3-outnod" endpinid="Node-20-0" pointList="-208,-104,-200,-104" />
<item itemtype="Connector" uid="Connector-42" startpinid="Node-20-2" endpinid="Node-6-0" pointList="-200,-104,-148,-104" />
<item itemtype="Connector" uid="Connector-43" startpinid="Resistor-11-lPin" endpinid="Node-21-1" pointList="-200,-28,-200,-80" />
<item itemtype="Connector" uid="Connector-44" startpinid="Fixed Voltage-4-outnod" endpinid="Node-21-0" pointList="-208,-80,-200,-80" />
<item itemtype="Connector" uid="Connector-45" startpinid="Node-21-2" endpinid="Node-5-0" pointList="-200,-80,-156,-80" />
<item itemtype="Connector" uid="Connector-46" startpinid="Resistor-22-rPin" endpinid="Led-24-lPin" pointList="-52,-100,-44,-100" />
<item itemtype="Connector" uid="Connector-47" startpinid="Led-24-rPin" endpinid="Ground-23-Gnd" pointList="-12,-100,-4,-100,-4,-96" />
<item itemtype="Connector" uid="Connector-48" startpinid="Resistor-25-rPin" endpinid="Led-27-lPin" pointList="-52,-60,-44,-60" />
<item itemtype="Connector" uid="Connector-49" startpinid="Led-27-rPin" endpinid="Ground-26-Gnd" pointList="-12,-60,-4,-60,-4,-56" />
<item itemtype="Connector" uid="Connector-50" startpinid="Xor Gate-1-out" endpinid="Resistor-22-lPin" pointList="-100,-100,-84,-100" />
<item itemtype="Connector" uid="Connector-52" startpinid="And Gate-2-out" endpinid="Resistor-25-lPin" pointList="-100,-60,-84,-60" />
</circuit>
分かりづらいですが上の出力がS、下の出力がCです。
- a=0 b=0の時、CS=00で両方点灯せず
- a=0 b=1の時、CS=01で上のみ点灯
- a=1 b=0の時、CS=01で上のみ点灯
- a=1 b=1の時、CS=10で下のみ点灯
Verilogで半加算器を作る
各素子はNANDを組み合わせて作りましたが、毎回NANDを直接使うと増えすぎて読みづらくなる為、ここからはNANDから構成された各論理素子を使って設計します。
直接NANDを呼ばないだけで、各論理素子はNANDで作ったものを使用しています。
コンパイル及び実行
iverilog -o test.out nand_gate_lib.v tb_hadder.v
vvp test.out
ファイル構成
nandcpu/
├── nand_gate_lib.v # NAND構成の論理素子
└── tb_hadder.v # 動作確認用
`timescale 1ns/1ps
// ========================================
// NAND素子の定義(これを最小単位とする)
// ========================================
module nand_gate (
input a,
input b,
output y
);
nand(y,a,b);
endmodule
// ========================================
// NOT素子
// ========================================
module not_gate (
input a, // 入力
output y // 出力
);
nand_gate u_not (
.a(a), // 入力aをNANDのAに繋ぐ
.b(a), // 同じくNANDのBにも繋ぐ
.y(y)
);
endmodule
// ========================================
// AND素子
// ========================================
module and_gate (
input a,
input b,
output y
);
wire n;
nand_gate g1(a, b, n); // 一つ目のNANDの出力を
nand_gate g2(n, n, y); // NOTに繋ぐ(NANDの入力両方に繋ぐ)
endmodule
// ========================================
// OR素子
// ========================================
module or_gate (
input a,
input b,
output y
);
wire not_a;
wire not_b;
nand_gate u_not_a(a, a, not_a); // aを反転(NAND入力2本共a)
nand_gate u_not_b(b, b, not_b); // bを反転(NAND入力2本共b)
nand_gate nand_nota_notb(not_a, not_b, y); // NOT(a)とNOT(b)をNAND→OR
endmodule
// ========================================
// XOR素子
// ========================================
module xor_gate (
input a,
input b,
output y
);
wire n1; // A NAND B
wire n2; // A NAND n1
wire n3; // B NAND n1
nand_gate g1(a, b, n1);
nand_gate g2(a, n1, n2);
nand_gate g3(n1, b, n3);
nand_gate g4(n2, n3, y);
endmodule
// ========================================
// 半加算器 (Half Adder)
// 自分で作ったXORとANDを使用
// ========================================
module half_adder (
input a,
input b,
output sum,
output carry
);
// 和 → XORで計算
xor_gate u_xor (a, b, sum);
// 桁上り → ANDで計算
and_gate u_and (a, b, carry);
endmodule
`timescale 1ns/1ps
module tb_half_adder;
reg a, b;
wire sum;
wire carry;
half_adder uut ( .a(a), .b(b), .sum(sum), .carry(carry)); //半加算器を一個配置
initial begin
$dumpfile("wave.vcd"); // 出力する波形
$dumpvars(0, tb_half_adder); // 全階層の波形を記録
$display("A B | CARRY | SUM");
$monitor("%b %b | %b %b", a, b, carry, sum);
a = 0; b = 0; #10; // 10ns 時間を進める
a = 0; b = 1; #10;
a = 1; b = 0; #10;
a = 1; b = 1; #10;
$finish;
end
endmodule
動作結果
iverilog -o nand.out nand_gate_lib.v tb_hadder.v
vvp nand.out
test@test-fujitsu:~/kaihatsu/nandcpu$ vvp nand.out
VCD info: dumpfile wave.vcd opened for output.
A B | CARRY | SUM
0 0 | 0 0
0 1 | 0 1
1 0 | 0 1
1 1 | 1 0
波形
gtkwave wave.vcd
※AND記事では設計した回路を可視化していますが、何故かORからは回路を生成してもNAND単体の図しか生成されないので原因を調査中です。