全加器输入和输出的逻辑关系,一般使用卡诺图的方式来获取。
以下内容中关于sum的表达式的推导可能和网上其它方法不太一样,cout的逻辑关系依然使用卡诺图来得到。
单bit全加:
SUM的逻辑表达式推导
输入:a, b, cin
输出:sum, cout
step1. 列出真值表
a | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 |
---|---|---|---|---|---|---|---|---|
b | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
cin | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
sum | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 |
cout | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 |
step2. 先不考虑cin的影响
当cin = 0, 即不考虑cin时:sum_0 = a + b
两个加数与和有以下关系
a | 0 | 1 | 0 | 1 |
---|---|---|---|---|
b | 0 | 0 | 1 | 1 |
sum_0 | 0 | 1 | 1 | 0 |
此时可以很容易看出,输出与输入的逻辑关系为异或:
sum_0 = a ^ b;
step3. 考虑cin的影响
当cin =1, 把cin的影响代进来:sum = a + b + cin = sum_0 + cin;
因为我们已经得到了两个加数与和的关系了,这里等于再做一次两个数的加法而已,把sum_0和cin分别当成两个加数,则使用step2的结论可以得到
sum = sum_0 ^ cin = a ^ b ^ cin;
Cout的逻辑表达式推导
通过Cout卡诺图可以得到,其逻辑表达式为:
Cout = ab + aCin + bCin;
多bit全加:
前一位的Cout做为后一位的Cin,即:
Cin [0] = Cin输入;
Cin [i] = Cout[i-1]; (i > 0)
Verilog转换
通过以上推导,我们已经有了这么几个公式
sum = sum_0 ^ cin = a ^ b ^ cin;
Cout = ab + aCin + bCin;
Cin [i] = Cout[i-1]; (i > 0)
接下来就是将以上公式转换为Verilog语言,这里要注意的是上面的式子是逻辑函数表达式,大家可以去查一下逻辑函数表达式的意思:逻辑函数表达式中: ab = a&b, a+b = a | b,千万不可当成数学表达式那样,直接用 * 和 +来转换。我就是犯了这个错误,导致表达式推导出来了,但转成verilog后怎么仿真都不对。
直接来看多bit的全加:
对bit[0]先单独处理:
sum[0] = a[0] ^ b[0] ^ cin;
cout[0] = a[0] && b[0] || ((a[0] || b[0]) && cin);
然后是其余bit位的处理,使用for循环:
for (i = 1; i <255; i=i+1) begin
sum[i] = a[i] ^ b[i]^cout[i-1];
cout[i] = a[i] && b[i] || ((a[i] || b[i]) && cout[i-1]);
end
完整代码如下
module top_module(
input [99:0] a, b,
input cin,
output [99:0] cout,
output [99:0] sum );
integer i;
always @(*) begin
sum[0] = a[0] ^ b[0] ^ cin;
cout[0] = a[0] && b[0] || ((a[0] || b[0]) && cin);
for (i = 1; i <255; i=i+1) begin
sum[i] = a[i] ^ b[i]^cout[i-1];
cout[i] = a[i] && b[i] || ((a[i] || b[i]) && cout[i-1]);
end
end
endmodule