Make/Day

毎日なにか作ります

6日目 ~Nandで書く加算器~

7/17日更新
補足記事もあるのでぜひ参考にしてください❕
in-reality.hatenablog.com


こんにちは!今日も更新していきます!

今回は加算を行う回路、加算器をハードウェア記述言語(HDL)で実装していきます。
前回と異なり、この記事ではVerilog HDLを使用して書いていきます。

まず、下の桁からの繰り上がりを考えない1bit加算器(半加算器という)について考えます。a,bが入力、Sをa+bの和、Cを桁上がりの出力すると、下の表のような真理値表で表すことができます。

半加算器の真理値表

これを、Nandゲートと、前回紹介したNotゲートで記述すると以下のようなコードになります。

module HalfAdder (
    input a, b,
    output sum, carry
);
    wire w1, w2, w3;
    
    assign w1 = ~(a & b);
    assign w2 = ~(a & w1);
    assign w3 = ~(w1 & b);
    assign sum = ~(w2 & w3);
    Not U1(w1, carry);
endmodule

半加算器は上位の加算器に繰り上がりの信号を渡すことはできますが、そもそも下位からのbitを受け取ることができません。そこで、この桁上がり信号Cinを受け取ることのできる加算器を考えると、下の真理値表のようになります。

全加算器の真理値表

また、桁上がりのbitのことをキャリービットと言います。表では、自身から出るキャリービットをCout、入力される方をCinとしています。

これを、先ほどと同様にHDLに書き表すと、

module FullAdder (
    input a, b, c,
    output sum, carry
);
    wire w1, w2, w3, w4, w5, w6, w7;

    assign w1 = ~(a & b);
    assign w2 = ~(a & w1);
    assign w3 = ~(w1 & b);
    assign w4 = ~(w2 & w3);
    assign w5 = ~(w4 & c);
    assign w6 = ~(w4 & w5);
    assign w7 = ~(w5 & c);
    assign sum = ~(w6 & w7);
    assign carry = ~(w1 & w5);
endmodule

となります。

これで、デジタル回路で足し算ができるようになりました。ここから、参考書籍に沿ってさらに複雑なことができるハードウェアへ進化させていきます。

参考書籍