高速加算器とALUの設計と実装

先行キャリ加算器の設計

加算器の性能向上にはキャリ信号の先行計算が有効です。キャリ・ルックアヘッド加算器(Carry Lookahead Adder)は、生成信号(Gi)と伝播信号(Pi)を用いて高速な加算を実現します。

キャリ先行原理

各ビット位置iにおける生成信号と伝播信号は以下のように定義されます:

Gi = Ai & Bi
Pi = Ai ^ Bi

キャリ信号は再帰的に表現できます:

C1 = G0 | (P0 & C0)
C2 = G1 | (P1 & G0) | (P1 & P0 & C0)
C3 = G2 | (P2 & G1) | (P2 & P1 & G0) | (P2 & P1 & P0 & C0)

4ビットCLAの実装

module cla_4bit(
    input [3:0] op1, op2,
    input carry_in,
    output [3:0] sum_out,
    output carry_out
);
    wire [3:0] gen, prop;
    wire [4:0] carry_chain;
    
    assign gen = op1 & op2;
    assign prop = op1 ^ op2;
    
    assign carry_chain[0] = carry_in;
    assign carry_chain[1] = gen[0] | (prop[0] & carry_chain[0]);
    assign carry_chain[2] = gen[1] | (prop[1] & gen[0]) | (prop[1] & prop[0] & carry_chain[0]);
    assign carry_chain[3] = gen[2] | (prop[2] & gen[1]) | (prop[2] & prop[1] & gen[0]) | 
                           (prop[2] & prop[1] & prop[0] & carry_chain[0]);
    assign carry_chain[4] = gen[3] | (prop[3] & gen[2]) | (prop[3] & prop[2] & gen[1]) | 
                           (prop[3] & prop[2] & prop[1] & gen[0]) | 
                           (prop[3] & prop[2] & prop[1] & prop[0] & carry_chain[0]);
    
    assign sum_out = prop ^ carry_chain[3:0];
    assign carry_out = carry_chain[4];
endmodule

算術論理演算装置(ALU)の設計

多機能ALUのVerilog実装

module alu_core #(
    parameter BIT_WIDTH = 32
)(
    input [BIT_WIDTH-1:0] operand_a,
    input [BIT_WIDTH-1:0] operand_b,
    input operation_sel,
    output [BIT_WIDTH-1:0] result_val,
    output carry_flag,
    output overflow_flag,
    output zero_flag,
    output sign_flag
);

    wire [BIT_WIDTH-1:0] modified_b;
    wire initial_carry;
    wire [BIT_WIDTH:0] extended_sum;
    
    assign modified_b = operation_sel ? ~operand_b : operand_b;
    assign initial_carry = operation_sel ? 1'b1 : 1'b0;
    
    assign extended_sum = {1'b0, operand_a} + {1'b0, modified_b} + {{BIT_WIDTH{1'b0}}, initial_carry};
    
    assign result_val = extended_sum[BIT_WIDTH-1:0];
    assign carry_flag = extended_sum[BIT_WIDTH];
    
    assign overflow_flag = (operand_a[BIT_WIDTH-1] == modified_b[BIT_WIDTH-1]) && 
                          (result_val[BIT_WIDTH-1] != operand_a[BIT_WIDTH-1]);
    
    assign zero_flag = (result_val == {BIT_WIDTH{1'b0}});
    assign sign_flag = result_val[BIT_WIDTH-1];
    
endmodule

テストベンチ

module test_alu;
    reg [31:0] val_a, val_b;
    reg op_mode;
    wire [31:0] res;
    wire carry, overflow, zero, sign;
    
    alu_core uut (
        .operand_a(val_a),
        .operand_b(val_b),
        .operation_sel(op_mode),
        .result_val(res),
        .carry_flag(carry),
        .overflow_flag(overflow),
        .zero_flag(zero),
        .sign_flag(sign)
    );
    
    initial begin
        op_mode = 0;
        val_a = 32'h0000000F; val_b = 32'h00000001; #10;
        val_a = 32'h7FFFFFFF; val_b = 32'h00000001; #10;
        
        op_mode = 1;
        val_a = 32'h0000000F; val_b = 32'h00000001; #10;
        val_a = 32'h80000000; val_b = 32'h00000001; #10;
        
        val_a = 32'h00000000; val_b = 32'h00000000; #10;
        val_a = 32'hFFFFFFFF; val_b = 32'h00000001; op_mode=0; #10;
        
        $finish;
    end
endmodule

加算器タイプ比較

加算器タイプ遅延特性リソース使用量適用場面
リップルキャリ加算器O(n)低速・低消費電力設計
キャリ先行加算器O(log n)高速演算
キャリ選択加算器O(√n)中速要求

4ビット符号付き加減算器の実装

module signed_adder_4bit(
    input [3:0] input_a,
    input [3:0] input_b,
    input subtract_en,
    output [3:0] output_result,
    output carry_out,
    output overflow_out,
    output zero_out,
    output sign_out
);
    
    wire [3:0] operand_b_modified;
    wire carry_input;
    wire [4:0] sum_extended;
    
    assign operand_b_modified = subtract_en ? ~input_b : input_b;
    assign carry_input = subtract_en ? 1'b1 : 1'b0;
    
    assign sum_extended = {1'b0, input_a} + {1'b0, operand_b_modified} + {4'b0, carry_input};
    
    assign output_result = sum_extended[3:0];
    assign carry_out = sum_extended[4];
    
    assign overflow_out = (input_a[3] == operand_b_modified[3]) && 
                        (output_result[3] != input_a[3]);
    
    assign zero_out = (output_result == 4'b0000);
    assign sign_out = output_result[3];
endmodule

タグ: Verilog FPGA 加算器 ALU デジタル回路設計

8月6日 11:24 投稿