ALU(Arithmetic Logic Unit,算术逻辑单元),是CPU执行单元中最主要的组成部分。
1 主要功能
算术运算:执行加法、减法、乘法和除法等算术运算。
逻辑运算:执行与、或、非、异或等逻辑运算。
移位运算:执行逻辑左移、逻辑右移、算术右移等移位运算。
比较运算:执行大小比较等比较运算。
超标量CPU中的加法器、减法器、乘法器、除法器和移位器在硬件实现中,依赖于组合逻辑和时序逻辑的设计。加法器通过基本的半加器和全加器实现,减法器利用二进制补码和加法实现,移位器则通过简单的位操作实现,乘法器可以采用Booth算法或阵列乘法器,除法器则通过顺序减法和移位实现。通过这些基础电路的优化和组合,超标量CPU能够高效执行复杂的算术操作。
2 加法器(Adder)
加法器是用于执行二进制加法的基本电路。常见的加法器包括半加器、全加器和多位加法器(如行波进位加法器、先行进位加法器)。
1)半加器(Half Adder)
半加器用于两个单比特的加法:输入两个单比特 `A` 和 `B`,输出和 `Sum` 和进位 `Carry`
逻辑实现。
module HalfAdder(input A, B, output Sum, Carry);
assign Sum = A ^ B; // 异或运算
assign Carry = A & B; // 与运算
endmodule
2)全加器(Full Adder)
全加器用于两个单比特和前一位进位的加法:输入两个单比特 `A` 和 `B`,前一位进位 `Cin`,输出和 `Sum` 和进位 `Cout`。
逻辑实现
module FullAdder(input A, B, Cin, output Sum, Cout);
assign Sum = A ^ B ^ Cin; // 异或运算
assign Cout = (A & B) | (Cin & (A ^ B)); // 与或运算
endmodule
3)多位加法器(Ripple Carry Adder)
行波进位加法器是由多个全加器级联而成:输入两个多比特二进制数 `A` 和 `B`,输出和 `Sum` 和进位 `Cout`
逻辑实现
module RippleCarryAdder #(parameter WIDTH = 8)(input [WIDTH-1:0] A, B, output [WIDTH-1:0] Sum, output Cout);
wire [WIDTH:0] Carry; // 进位链
assign Carry[0] = 0;
genvar i;
generate
for (i = 0; i < WIDTH; i = i + 1) begin: add_bit
FullAdder FA (.A(A[i]), .B(B[i]), .Cin(Carry[i]), .Sum(Sum[i]), .Cout(Carry[i+1]));
end
endgenerate
assign Cout = Carry[WIDTH];
endmodule
3 减法器(Subtractor)
减法可以通过加法实现,使用二进制补码进行减法操作,即:`A - B` 可以表示为 `A + (~B + 1)`。
4位减法器逻辑实现
module Subtractor #(parameter WIDTH = 4)(input [WIDTH-1:0] A, B, output [WIDTH-1:0] Diff);
wire [WIDTH-1:0] B_complement;
assign B_complement = ~B + 1; // 计算B的补码
RippleCarryAdder #(WIDTH) RCA (.A(A), .B(B_complement), .Sum(Diff), .Cout());
endmodule
4 乘法器(Multiplier)
乘法器用于执行二进制乘法,现代乘法器通常由部分积生成器(Partial Product Generator)、部分积压缩器(Partial Product Compressor)和最终加法器(Final Adder)构成。
工作原理
乘法运算单元是处理器中的关键组件之一,基本原理是将被乘数(Multiplicand)和乘数(Multiplier)分解成若干部分积(Partial Products),然后将这些部分积进行累加得到最终的乘积。乘法运算单元可以采用不同类型的乘法器,如布尔乘法器、串行乘法器、并行乘法器等,具体选择取决于性能和面积的要求。
主要组件
3.1)部分积生成器
部分积生成器的任务是根据乘数的每一位生成对应的部分积。每一个部分积是被乘数与乘数某一位的乘积。
例如,对于 4 位乘数和被乘数:
- 乘数 `B`:\( B_3B_2B_1B_0 \)
- 被乘数 `A`:\( A_3A_2A_1A_0 \)
生成的部分积为:
- 第 0 位:`P_0 = B_0 * A`
- 第 1 位:`P_1 = B_1 * A << 1`
- 第 2 位:`P_2 = B_2 * A << 2`
- 第 3 位:`P_3 = B_3 * A << 3`
Booth 算法
Booth 算法进行乘法操作可以有效减少部分积生成的位数,从而减少计算量,其基本思想是利用乘数的位模式,将部分积中连续的1和0序列合并为一个更大的值或更小的值,以减少需要执行的加法和移位操作。
1)Booth 编码:对乘数进行 Booth 编码,将每两位乘数转换为一个 Booth 编码值,可以是0、1或-1。
2)循环运算:从最低位开始,对每两位乘数进行 Booth 编码并执行相应的加法和移位操作,生成部分积的一部分。
3)部分积累加:每次循环产生的部分积通过累加器累加,最终得到完整的部分积。
实现示例
输入:被乘数A = 1010 (十进制:10)
乘数B = 0110 (十进制:6)
Booth 编码:0101 (十进制:5)
1100 (十进制:-4)
循环运算:
1)A 的最低位为 0,保持部分积不变。
2)A 的第二低位为 1,部分积左移一位并加上 B。
部分积:00000000
+ 0110
--------
00000110
3)A 的第三低位为 1,部分积左移一位并加上 B。
部分积:00000110
+ 0110
--------
00010000 (此时部分积的低4位即为结果)
部分积 P = 0001 0000 (十进制:16)
基于Booth算法的乘法器逻辑实现
module BoothMultiplier #(parameter WIDTH = 4)(input [WIDTH-1:0] A, B, output [2*WIDTH-1:0] Product);
reg [2*WIDTH-1:0] P;
reg [WIDTH-1:0] Q;
reg Q_1;
integer i;
always @(A or B) begin
P = 0;
Q = B;
Q_1 = 0;
for (i = 0; i < WIDTH; i = i + 1) begin
case ({Q[0], Q_1})
2'b01: P = P + (A << i);
2'b10: P = P - (A << i);
default: ;
endcase
Q_1 = Q[0];
Q = Q >> 1;
end
end
assign Product = P;
endmodule
3.2)部分积压缩器
部分积压缩器用于减少部分积的层数,将得到的部分积需要按权值错位相加,以得到最终的乘积结果。这个过程通常通过树型结构的加法器实现,可以采用Wallace树、Dadda树等,需要确保加法过程中的进位被正确传递。
Wallace 树压缩
Wallace树是一种常见的部分积压缩器,利用全加器和半加器将部分积逐层压缩。
逻辑实现
module WallaceTree(input [3:0] A, input [3:0] B, output [7:0] Product);
wire [15:0] partial_products;
// 生成部分积
assign partial_products[3:0] = A & {4{B[0]}};
assign partial_products[7:4] = A & {4{B[1]}};
assign partial_products[11:8] = A & {4{B[2]}};
assign partial_products[15:12] = A & {4{B[3]}};
// 声明中间结果
wire [7:0] sum1, sum2, sum3, carry1, carry2, carry3;
// 第一级压缩
assign sum1 = {partial_products[3:1], 1'b0} + partial_products[7:4];
assign carry1 = {4'b0, partial_products[11:8]} + {4'b0, partial_products[15:12]};
// 第二级压缩
assign sum2 = {carry1[3:1], 1'b0} + sum1[7:4];
assign carry2 = carry1[7:4] + sum1[3:0];
// 最后一级压缩
assign sum3 = sum2 + carry2;
assign carry3 = {carry2[3:1], 1'b0};
// 最终加法
assign Product = sum3 + carry3;
endmodule
3.3)最终加法器(Final Adder)
最终加法器用于将压缩后的部分积进行累加,得到最终的乘积,常见的加法可以参照第一章节内容,包括行波进位加法器和先行进位加法器。
结果输出,将最终的乘积结果存储在结果寄存器中,以便后续的使用或传输。
逻辑实现
module FinalAdder(input [7:0] sum, input [7:0] carry, output [7:0] Product);
assign Product = sum + carry;
endmodule
4位乘法器实现示例
module Multiplier4Bit(input [3:0] A, B, output [7:0] Product);
wire [3:0] P0, P1, P2, P3;
// 部分积生成
assign P0 = B[0] ? A : 4'b0000;
assign P1 = B[1] ? (A << 1) : 4'b0000;
assign P2 = B[2] ? (A << 2) : 4'b0000;
assign P3 = B[3] ? (A << 3) : 4'b0000;
// 部分积压缩(Wallace Tree)
wire [7:0] sum1, sum2, sum3, carry1, carry2, carry3;
assign {carry1, sum1} = {4'b0, P0} + {2'b0, P1, 2'b0};
assign {carry2, sum2} = {4'b0, P2, 4'b0} + {4'b0, P3};
assign {carry3, sum3} = sum1 + carry1;
// 最终加法
assign Product = sum3 + carry2;
endmodule
5 除法器(Divider)
除法器用于执行二进制除法。常见的方法包括恢复余数法和非恢复余数法。
恢复余数法:通过顺序减法和移位实现:
逻辑实现
module RestoringDivider #(parameter WIDTH = 4)(input [WIDTH-1:0] Dividend, Divisor, output [WIDTH-1:0] Quotient, Remainder);
reg [2*WIDTH-1:0] A, Q, M;
integer i;
always @(Dividend or Divisor) begin
A = 0;
Q = Dividend;
M = Divisor << WIDTH;
for (i = 0; i < WIDTH; i = i + 1) begin
A = (A << 1) | Q[WIDTH-1];
Q = Q << 1;
A = A - M;
if (A[2*WIDTH-1]) begin
Q[0] = 0;
A = A + M;
end else begin
Q[0] = 1;
end
end
end
assign Quotient = Q[WIDTH-1:0];
assign Remainder = A[WIDTH-1:0];
endmodule
6 移位器(Shifter)
移位器用于执行二进制数的移位操作(左移和右移),可以是逻辑移位、算术移位或循环移位。
逻辑移位器:逻辑左移和右移逻辑实现
module LogicalShifter #(parameter WIDTH = 8)(input [WIDTH-1:0] A, input [2:0] Shift, output [WIDTH-1:0] Result);
assign Result = (Shift[2]) ? {8'b0, A[WIDTH-1:8]} :
(Shift[1]) ? {4'b0, A[WIDTH-1:4]} :
(Shift[0]) ? {2'b0, A[WIDTH-1:2]} :
A;
Endmodule