Verilog 学习笔记 04 - 加法与减法

1 Bit 全加器

1
2
3
4
module add1 ( input a, input b, input cin,   output sum, output cout );
assign sum = a ^ b ^ cin;
assign cout = (a & b) | (cin & (a ^ b));
endmodule

几种加法器

在使用全加器构建更高位的加法器时,根据运算时间和占用资源的不同,有几种加法器:行波进位加法器、选择进位加法器和超前进位加法器。

行波进位加法器需要等待低位的加法器先完成运算并产生进位值后,高位的加法器才可以开始运算,这样使用的全加器个数等于加法器位数,但是时间复杂度高,为*O(n)*。

选择进位加法器通过并行计算两种进位情况下的结果并选择,时间复杂度适中,为*O(sqrt n)*,但是使用的全加器个数多。

超前进位加法器通过提前计算各位的进位信号来加速加法运算,时间复杂度最低,为*O(log n)*,使用的全加器个数与行波进位加法器一致,但需要额外的进位计算电路。

减法

原码与补码

在计算机中,有符号数通常有三种表现形式:原码、反码与补码,符号的判断则用最高位的 0 和 1 表示,0 为正数,1 为负数。

正数的原码、反码与补码相同;负数的反码是除符号位以外的位按位取反(与 1 异或),补码则是在反码的基础上加 1,比如 -15:

1
2
3
原码: 1000_1111
反码: 1111_0000
补码: 1111_0001

而补码的补码便是原码:

1
2
3
补码: 1111_0001
反码: 1000_1110
原码: 1000_1111

而在要计算减法(与负数的加法),只需要加上对应负数的补码即可,比如 5-3:

1
2
3
4
  0101
+ 1101
------
10010

此时得到的是一个 5 位二进制数,将低 4 位作为 sum 输出,得到 0010 即是 2。

加减法器

加减法器就是在加法器的基础上提供一个输入 sub(对于有符号数,这个输入可以直接取符号位),sub 同时作为低位加法器的进位输入,如果该输入为 1,则将第二个加数取反(或与对应位数的 1 做异或),而且此时相当于给低位加一,即实现了从原码到补码的转换。

1
2
3
4
5
6
7
8
9
10
11
12
module top_module(
input [31:0] a,
input [31:0] b,
input sub,
output [31:0] result
);
wire [31:0] b_n;
wire carry;
assign b_n = b^{32{sub}};
add16 a0(a[15:0],b_n[15:0],sub,result[15:0],carry);
add16 a1(a[31:16],b_n[31:16],carry,result[31:16],);
endmodule