目次
全加算器とは
以下の真理値表が示す通り、A,B及びCinの足し算をする回路です。
例えばA=1,B=1,Cin=1の場合、1+1+1=3で、和の2進数で11となり、真理値表と一致しています。
| A | B | Cin | Sum | Cout |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 1 | 0 |
| 0 | 1 | 0 | 1 | 0 |
| 0 | 1 | 1 | 0 | 1 |
| 1 | 0 | 0 | 1 | 0 |
| 1 | 0 | 1 | 0 | 1 |
| 1 | 1 | 0 | 0 | 1 |
| 1 | 1 | 1 | 1 | 1 |
参考にしたサイト
https://www.elecfans.com/d/2156606.html
https://www.zhihu.com/question/39925519/answer/2693480829
これまでにNANDで積み上げてきた部品は真理値表や論理式、想像等から理解が出来ましたが、全加算器からは直感が働かず理解が難しくなってきました。
既に確立されている回路図のように並べたら動くということだけを実証して進みます。
LEDで動作を可視化
これまで入力側にもLEDをつけて電気が流れていることを証明して来ましたが、部品が増えて収まりきらなくなったので省きます。
電源側にも橙色の電灯がついているのでこれで代用します。白=0、橙=1です。
/opt/simulide-110sr0/simulide fadder.sim1
fadder.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="528,-92" 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="Xor Gate" CircId="Xor Gate-2" mainComp="false" Show_id="false" Show_Val="false" Pos="604,-88" rotation="0" hflip="1" vflip="1" label="Xor 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Ω" 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-3" mainComp="false" Show_id="false" Show_Val="false" Pos="528,-56" rotation="0" hflip="1" vflip="1" label="And Gate-3" 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="And Gate" CircId="And Gate-4" mainComp="false" Show_id="false" Show_Val="false" Pos="616,-56" rotation="0" hflip="1" vflip="1" label="And Gate-4" 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="Or Gate" CircId="Or Gate-5" mainComp="false" Show_id="false" Show_Val="false" Pos="660,-28" rotation="0" hflip="1" vflip="1" label="Or Gate-5" 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" Num_Inputs="2 _Inputs" 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-6" mainComp="false" Show_id="false" Show_Val="false" Pos="456,-96" rotation="0" hflip="1" vflip="1" label="Fixed Voltage-6" idLabPos="-64,-24" labelrot="0" valLabPos="-16,8" valLabRot="0" Voltage="5 V" Out="false" />
<item itemtype="Ground" CircId="Ground-11" mainComp="false" Show_id="false" Show_Val="false" Pos="776,-68" rotation="0" hflip="1" vflip="1" label="Ground-11" idLabPos="-16,8" labelrot="0" valLabPos="-16,20" valLabRot="0" />
<item itemtype="Resistor" CircId="Resistor-12" mainComp="false" ShowProp="Resistance" Show_id="false" Show_Val="true" Pos="712,-88" rotation="0" hflip="1" vflip="1" label="Resistor-12" idLabPos="-16,-24" labelrot="0" valLabPos="-16,6" valLabRot="0" Resistance="50 Ω" />
<item itemtype="Led" CircId="Led-13" mainComp="false" Show_id="false" Show_Val="false" Pos="752,-88" 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="Fixed Voltage" CircId="Fixed Voltage-14" mainComp="false" Show_id="false" Show_Val="false" Pos="456,-76" rotation="0" hflip="1" vflip="1" label="Fixed Voltage-14" idLabPos="-64,-24" labelrot="0" valLabPos="-16,8" valLabRot="0" Voltage="5 V" Out="false" />
<item itemtype="Fixed Voltage" CircId="Fixed Voltage-17" mainComp="false" Show_id="false" Show_Val="false" Pos="456,-36" rotation="0" hflip="1" vflip="1" label="Fixed Voltage-17" idLabPos="-64,-24" labelrot="0" valLabPos="-16,8" valLabRot="0" Voltage="5 V" Out="false" />
<item itemtype="Ground" CircId="Ground-19" mainComp="false" Show_id="false" Show_Val="false" Pos="776,-8" rotation="0" hflip="1" vflip="1" label="Ground-19" idLabPos="-16,8" labelrot="0" valLabPos="-16,20" valLabRot="0" />
<item itemtype="Resistor" CircId="Resistor-20" mainComp="false" ShowProp="Resistance" Show_id="false" Show_Val="true" Pos="712,-28" rotation="0" hflip="1" vflip="1" label="Resistor-20" idLabPos="-16,-24" labelrot="0" valLabPos="-16,6" valLabRot="0" Resistance="50 Ω" />
<item itemtype="Led" CircId="Led-21" mainComp="false" Show_id="false" Show_Val="false" Pos="752,-28" rotation="0" hflip="1" vflip="1" label="Led-21" 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-15" mainComp="false" Pos="504,-96" />
<item itemtype="Node" CircId="Node-16" mainComp="false" Pos="496,-76" />
<item itemtype="Node" CircId="Node-18" mainComp="false" Pos="564,-92" />
<item itemtype="Node" CircId="Node-22" mainComp="false" Pos="588,-52" />
<item itemtype="Connector" uid="Connector-8" startpinid="Resistor-12-rPin" endpinid="Led-13-lPin" pointList="728,-88,736,-88" />
<item itemtype="Connector" uid="Connector-9" startpinid="Led-13-rPin" endpinid="Ground-11-Gnd" pointList="768,-88,776,-88,776,-84" />
<item itemtype="Connector" uid="Connector-11" startpinid="Xor Gate-2-out" endpinid="Resistor-12-lPin" pointList="620,-88,696,-88" />
<item itemtype="Connector" uid="Connector-13" startpinid="Node-15-1" endpinid="And Gate-3-in0" pointList="504,-96,504,-60,512,-60" />
<item itemtype="Connector" uid="Connector-15" startpinid="Node-15-2" endpinid="Xor Gate-1-in0" pointList="504,-96,512,-96" />
<item itemtype="Connector" uid="Connector-16" startpinid="Node-16-1" endpinid="And Gate-3-in1" pointList="496,-76,496,-52,512,-52" />
<item itemtype="Connector" uid="Connector-17" startpinid="Fixed Voltage-14-outnod" endpinid="Node-16-0" pointList="472,-76,496,-76" />
<item itemtype="Connector" uid="Connector-18" startpinid="Node-16-2" endpinid="Xor Gate-1-in1" pointList="496,-76,512,-76,512,-88" />
<item itemtype="Connector" uid="Connector-20" startpinid="And Gate-3-out" endpinid="Or Gate-5-in1" pointList="544,-56,544,-24,644,-24" />
<item itemtype="Connector" uid="Connector-21" startpinid="And Gate-4-in0" endpinid="Node-18-1" pointList="600,-60,564,-60,564,-92" />
<item itemtype="Connector" uid="Connector-22" startpinid="Xor Gate-1-out" endpinid="Node-18-0" pointList="544,-92,564,-92" />
<item itemtype="Connector" uid="Connector-23" startpinid="Node-18-2" endpinid="Xor Gate-2-in0" pointList="564,-92,588,-92" />
<item itemtype="Connector" uid="Connector-24" startpinid="And Gate-4-out" endpinid="Or Gate-5-in0" pointList="632,-56,644,-56,644,-32" />
<item itemtype="Connector" uid="Connector-25" startpinid="Led-21-rPin" endpinid="Ground-19-Gnd" pointList="768,-28,776,-28,776,-24" />
<item itemtype="Connector" uid="Connector-26" startpinid="Resistor-20-rPin" endpinid="Led-21-lPin" pointList="728,-28,736,-28" />
<item itemtype="Connector" uid="Connector-27" startpinid="Or Gate-5-out" endpinid="Resistor-20-lPin" pointList="676,-28,696,-28" />
<item itemtype="Connector" uid="Connector-28" startpinid="And Gate-4-in1" endpinid="Node-22-1" pointList="600,-52,588,-52" />
<item itemtype="Connector" uid="Connector-29" startpinid="Fixed Voltage-17-outnod" endpinid="Node-22-0" pointList="472,-36,588,-36,588,-52" />
<item itemtype="Connector" uid="Connector-30" startpinid="Node-22-2" endpinid="Xor Gate-2-in1" pointList="588,-52,588,-84" />
<item itemtype="Connector" uid="Connector-31" startpinid="Fixed Voltage-6-outnod" endpinid="Node-15-0" pointList="472,-96,504,-96" />
</circuit>
- 000 (0+0+0=0)
- 001 (0+0+1=1)
Verilogで全加算器を作る
simulideには半加算器の部品がなく、XOR,AND,ORの素子を組み立てていました。
Verilogではコード可読性の為、前回作成した半加算器を用いて全加算器を構成します。
粒度が異なりますが、中身は同等です。
筆者もOR回路を使う部分の原理を理解できておらず、回路をそのままコードに落とし込んでいます。
コードが長くなってきたので動作再現用の完全版は折り畳み、全加算器のみ切り抜いて掲載します。
iverilog -o test.out nand_gate_lib.v tb_fadder.v
vvp test.out
// ========================================
// 全加算器 (Full Adder)
// half_adder を2つと or_gate で構成
// 入力: A, B, Cin
// 出力: Sum, Cout
// ========================================
module full_adder (
input A,
input B,
input Cin,
output Sum,
output Cout
);
wire sum1; // 1段目の half_adder の和
wire carry1; // 1段目の half_adder の桁上がり
wire carry2; // 2段目の half_adder の桁上がり
// 1段目: A + B
half_adder ha1 (
.a(A),
.b(B),
.sum(sum1),
.carry(carry1)
);
// 2段目: sum1 + Cin
half_adder ha2 (
.a(sum1),
.b(Cin),
.sum(Sum),
.carry(carry2)
);
// ORの部分
or_gate u_or (
.a(carry1),
.b(carry2),
.y(Cout)
);
endmodule
test@test-fujitsu:~/kaihatsu/nandcpu$ vvp test.out
VCD info: dumpfile wave.vcd opened for output.
A B Cin | Sum | Cout
0 0 0 | 0 | 0
0 0 1 | 1 | 0
0 1 0 | 1 | 0
0 1 1 | 0 | 1
1 0 0 | 1 | 0
1 0 1 | 0 | 1
1 1 0 | 0 | 1
1 1 1 | 1 | 1
- 以下完全版コード
tb_fadder.v
`timescale 1ns/1ps
module tb_full_adder;
reg A, B, Cin;
wire Sum, Cout;
// 全加算器を1個配置
full_adder uut (
.A(A),
.B(B),
.Cin(Cin),
.Sum(Sum),
.Cout(Cout)
);
initial begin
// 波形出力
$dumpfile("wave.vcd");
$dumpvars(0, tb_full_adder);
// 表示
$display("A B Cin | Sum | Cout");
$monitor("%b %b %b | %b | %b", A, B, Cin, Sum, Cout);
// 真理値表の全8通りを順に入力(各10ns)
{A, B, Cin} = 3'b000; #10;
{A, B, Cin} = 3'b001; #10;
{A, B, Cin} = 3'b010; #10;
{A, B, Cin} = 3'b011; #10;
{A, B, Cin} = 3'b100; #10;
{A, B, Cin} = 3'b101; #10;
{A, B, Cin} = 3'b110; #10;
{A, B, Cin} = 3'b111; #10;
$finish;
end
endmodule
nand_gate_lib.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
// ========================================
// 全加算器 (Full Adder)
// half_adder を2つと or_gate で構成
// 入力: A, B, Cin
// 出力: Sum, Cout
// ========================================
module full_adder (
input A,
input B,
input Cin,
output Sum,
output Cout
);
wire sum1; // 1段目の half_adder の和
wire carry1; // 1段目の half_adder の桁上がり
wire carry2; // 2段目の half_adder の桁上がり
// 1段目: A + B
half_adder ha1 (
.a(A),
.b(B),
.sum(sum1),
.carry(carry1)
);
// 2段目: sum1 + Cin
half_adder ha2 (
.a(sum1),
.b(Cin),
.sum(Sum),
.carry(carry2)
);
// ORの部分
or_gate u_or (
.a(carry1),
.b(carry2),
.y(Cout)
);
endmodule
波形を確認
gtkwave wave.vcd