先行キャリ加算器の設計
加算器の性能向上にはキャリ信号の先行計算が有効です。キャリ・ルックアヘッド加算器(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