1.半加全加的区别
半加器没有进位输入——c_in,只有两个输入
全加器有进位输入c_in,有三个输入
2.一位半加器代码
现在知道了半加器的功能,但是还不知道具体的逻辑表达式,因此还不能得出整个半加器的输入输出关系,下一步需要列出真值表,利用卡诺图得出逻辑表达式。
因为变量不是很多,可以跳过卡诺图直接得出输入输出关系:
c_out = a & b (与)
sum = a ^ b (异或)
所以代码如下:
module half_add_1bit
(
input a,b,
output c_out,sum
);
assign c_out = a & b;
assign sum = a ^ b;
endmodule
测试代码:
`timescale 1 ns/1 ns //时间标尺 时间单位/时间精度
module tb_half_add_1bit();
//输入用reg
reg a;
reg b;
reg clk;
//输出用wire
wire sum;
wire c_out;
//时钟周期,单位为ns
parameter CYCLE = 20;
//生成本地时钟
initial begin
clk = 0;
forever
#(CYCLE/2)
clk=~clk;
end
//信号初始化
initial begin
#1
a = 0;
b = 0;
end
//待测试的模块例化
half_add_1bit u1
(
.a (a),
.b (b),
.c_out (c_out),
.sum (sum)
);
//其他输入信号赋值
always @(posedge clk)begin
a = {$random}%2;
b = {$random}%2;
end
endmodule
仿真结果:
3.一位全加器代码
同理,列出真值表,利用卡诺图得出逻辑表达式:
最后得出:
c_out = cb + ab + ac
sum = a ⊕ b ⊕ c
所以代码如下:
module all_add_1bit
(
input a,b,c_in,
output sum,c_out
);
assign sum = a ^ b ^ c_in;
assign c_out = (c_in & b)|(a & b)|(a & c_in);
endmodule
当然,也可以用一句assign来代替上述的两句assign代码:
assign {c_out,sum} = a + b + c_in;
测试代码:
`timescale 1 ns/1 ns //时间标尺 时间单位/时间精度
module tb_all_add_1bit();
//输入用reg
reg a;
reg b;
reg c_in;
reg clk;
//输出用wire
wire sum;
wire c_out;
//时钟周期,单位为ns
parameter CYCLE = 20;
//生成本地时钟
initial begin
clk = 0;
forever
#(CYCLE/2)
clk=~clk;
end
//信号初始化
initial begin
#1
a = 0;
b = 0;
c_in = 0;
end
//待测试的模块例化
all_add_1bit u1
(
.a (a),
.b (b),
.c_in (c_in),
.c_out (c_out),
.sum (sum)
);
//其他输入信号赋值
always @(posedge clk)begin
a = {$random}%2;
b = {$random}%2;
c_in = {$random}%2;
end
endmodule
仿真结果:
4.多位的加法器
多位的全加器或者半加器只需要在定义信号的时候加上多位的位宽即可。如:
将上述的一位全加器的
input a,b,c_in;
output sum,c_out
改成
input [3:0] a,b;
input c_in;
output [3:0] sum;
output c_out
就能使一位的全加器变成4位([3:0])全加器