一.一位全加器
1.原理
X | Y | Cin | S | Cout |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 | 0 |
0 | 1 | 0 | 1 | 0 |
0 | 1 | 1 | 0 | 1 |
1 | 0 | 0 | 1 | 0 |
1 | 0 | 1 | 0 | 1 |
1 | 1 | 0 | 0 | 1 |
1 | 1 | 1 | 1 | 1 |
-
公式如下
S = X ^ Y ^ Cin
Cout = ( (X ^ Y) & Cin ) + X & Y = (X & Y) | (X & Cin) | (Y & Cin)
2.代码
- 第一种方法:利用原理中整理的公式
module full_adder (
input x,
input y,
input cin,//低位进位
output s,//本位和
output cout//进位
);
assign s = x ^ y ^ cin;//本位和输出
assign cout = (x & y) | (x & cin) | (y & cin);//高位进位输出
endmodule
- 第二种方法:位拼接法
module full_adder (
input x,
input y,
input cin,//低位进位
output s,//本位和
output cout//进位
);
assign {cout,s} = x + y + cin;
endmodule
二.N位全加器
1.generate语法
2.代码
- 第一种方法:位拼接法
module N_adder #(parameter N = 4)(
input wire [N-1:0] x,
input wire [N-1:0] y,
input wire cin,
output wire cout,
output wire [N-1:0] s
);
assign {cout,s} = x + y + cin;
endmodule
- 第二种方法:generate语句
module N_adder #(parameter N = 4)(
input wire [N-1:0] x,
input wire [N-1:0] y,
input wire cin,
output wire cout,
output wire [N-1:0] s
);
//assign {cout,s} = a + b + cin;
wire [N:0] c;
assign c[0] = cin;
genvar i;
generate
for (i = 0;i < N;i = i + 1) begin:u_generate
full_adder u_full_adder
(
.x (x[i]),
.y (y[i]),
.cin (c[i]),//低位进位
.s (s[i]),//本位和
.cout (c[i+1]) //进位
);
end
endgenerate
assign cout = c[N];
endmodule
3.仿真文件
`timescale 1ns/1ns //单位,精度
module tb_full_adder ();
//激励信号
reg [3:0] tb_x;
reg [3:0] tb_y;
reg tb_cin;
//输出信号
wire [3:0] tb_s;
wire tb_cout;
//模块例化
N_adder u_N_adder(
.x (tb_x),
.y (tb_y),
.cin (tb_cin),//低位进位
.s (tb_s),//本位和
.cout (tb_cout) //进位
);
//过程赋值
initial begin
tb_x = 4'b1010;
tb_y = 4'b0110;
tb_cin = 0;
#10;
tb_x = 4'b1001;
tb_y = 4'b1011;
tb_cin = 0;
#10;
tb_x = 4'b1000;
tb_y = 4'b0011;
tb_cin = 0;
#10;
tb_x = 4'b1010;
tb_y = 4'b0110;
tb_cin = 1;
#10;
tb_x = 4'b1001;
tb_y = 4'b1011;
tb_cin = 1;
#10;
tb_x = 4'b1000;
tb_y = 4'b0011;
tb_cin = 1;
#10;
end
endmodule
4.仿真效果
三.总结
- 全加器也是由半加器进而实现的,不仅可以用verilog代码实现,也可以用模块图实现。N位全加器可以成为一个模板,需要不同位数的全加器只需要修改N值即可,仿真文件的修改需要对应我们修改的N值来定义激励信号和输出信号的位宽。