演習B ★★☆ 中級 所要:20–30分

8ビット減算器

2の補数の仕組みを使って、加算器を応用した減算器を Verilog で設計しよう。

📚 概念説明:2の補数による減算

コンピュータの減算は「加算器を使って実現されます。 減算 A − B は、A + (−B) として計算できます。 2進数で −B を表すには 2の補数(ビット反転 + 1)を使います。

2の補数の計算例(8ビット)

B = 0000_0011(= 3)
~B = 1111_1100(ビット反転)
−B = ~B + 1 = 1111_1101(= -3 の2の補数表現)
A − B = A + (~B) + 1 ← Cin に 1 を渡すだけ!

減算器の構成

  • 加算器の B 入力を ~B(全ビット反転)に
  • 加算器の Cin を 1 に固定
  • これだけで A − B を計算できる!

ボロー(Borrow)とは

A < B の場合、結果が負になり ボロー = 1 になります。8ビット符号なし整数では ~cout がボローに相当します。

A B diff = A−B borrow 備考
10370正常
0000ゼロ
3102491アンダーフロー
25512540正常

📝 課題

モジュール名:subtractor8

入力:a [7:0]b [7:0]

出力:diff [7:0](差)、borrow(アンダーフロー時 1)

💻 Verilog テンプレート

Design(右パネル)
// ================================
// 8ビット減算器モジュール
// A - B = A + (~B) + 1
// ================================
module subtractor8 (
    input  [7:0] a,
    input  [7:0] b,
    output [7:0] diff,
    output       borrow
);

    wire [8:0] result;

    // ~b はビット反転(B の1の補数)
    // +1 は Cin=1 で実現 → 2の補数 = ~b + 1
    assign result = {1'b0, a} + {1'b0, ~b} + 9'd1;

    assign diff   = result[7:0];
    assign borrow = ~result[8]; // キャリーが出なかった = ボロー

endmodule
Testbench(左パネル)
module tb_subtractor8;
    reg  [7:0] a, b;
    wire [7:0] diff;
    wire       borrow;

    subtractor8 uut (.a(a), .b(b), .diff(diff), .borrow(borrow));

    initial begin
        $dumpfile("dump.vcd");
        $dumpvars(0, tb_subtractor8);
        $monitor("a=%0d b=%0d | diff=%0d borrow=%0d", a, b, diff, borrow);

        a = 8'd10;  b = 8'd3;   #10; // 正常:7
        a = 8'd0;   b = 8'd0;   #10; // ゼロ:0
        a = 8'd3;   b = 8'd10;  #10; // アンダーフロー:borrow=1
        a = 8'd255; b = 8'd1;   #10; // 254
        a = 8'd100; b = 8'd100; #10; // ゼロ:0

        $display("--- テスト完了 ---");
        $finish;
    end
endmodule

▶ EDA Playground で開く

上のテンプレートを貼り付けてシミュレーションしてみましょう。

🚀 EDA Playground を開く →

※ ログインに Gmail が必要です。 使い方ガイドを見る

🤔 考えてみよう

  1. a=5, b=200 のとき diff と borrow の値を計算して、シミュレーション結果と合っているか確認しよう。
  2. 加算器(演習A)と減算器のモジュールを比べると、何が違いますか?共通点は何ですか?
  3. Verilog で assign diff = a - b; と書くだけでも動作します。なぜでしょうか?手動で2の補数を使う意義は何でしょうか?
  4. 加減算を 1つのモジュールで処理するには、どのような設計にしますか?(ヒント:演習Cで登場します)
← 演習A:加算器 次:演習C 8ビット ALU →