`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/10/17 19:35:00
// Design Name:
// Module Name: adder
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module adder(
input ia, // 1位二进制加数
input ib, // 1位二进制加数
input cin, // 低位来的进位信号
output cout, // 向高位的进位信号
output sum // 1位和数
);
assign cout = (ia&ib) | (ia&cin) | (ib&cin); // 当三个输入其中两个为1时,产生进位
assign sum = ia^ib^cin; // 和数等于三个输入异或的值
endmodule
仿真文件:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/10/17 19:40:57
// Design Name:
// Module Name: test
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module adder_test();
reg a,b,cin; // 定义程序的输入为reg型
wire cout,s; // 因为要对cout和s进行assign赋值,所以定义为wire型
adder add(a, b, cin, cout, s); // 实例化adder模块
initial begin // 给输入赋初值
a = 1;
b = 1;
cin = 1;
#100 // 使赋值持续100ns
a = 1;
b = 0;
cin = 1;
#100 // 使赋值持续100ns
a = 1;
b = 0;
cin = 0;
end
endmodule
接下来直接点击 Run Simulation 进行行为仿真,得到下图结果:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/10/17 19:35:00
// Design Name:
// Module Name: adder
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module adder_4(
input [3:0] a, // 4位无符号数
input [3:0] b, // 4位无符号数
input cin, // 最低位传来的进位信号
output [3:0] s, // 四位和的补码形式
output cf // 进位标志
);
wire [3:0] co;
assign co[0] = (a[0]&b[0]) | (a[0]&cin) | (b[0]&cin);
assign s[0] = a[0]^b[0]^cin;
assign co[1] = (a[1]&b[1]) | (a[1]&co[0]) | (b[1]&co[0]);
assign s[1] = a[1]^b[1]^co[0];
assign co[2] = (a[2]&b[2]) | (a[2]&co[1]) | (b[2]&co[1]);
assign s[2] = a[2]^b[2]^co[1];
assign co[3] = (a[3]&b[3]) | (a[3]&co[2]) | (b[3]&co[2]);
assign s[3] = a[3]^b[3]^co[2];
assign cf=co[3];
endmodule
仿真文件:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/10/17 19:40:57
// Design Name:
// Module Name: test
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module adder_4_test();
reg [3:0] a;
reg [3:0] b;
reg cin; // 定义程序的输入为reg型
wire cf;
wire [3:0] s; // 因为要对cf和s进行assign赋值,所以定义为wire型
adder_4 adder4(a, b, cin, s, cf); // 实例化adder模块
initial begin // 给输入赋初值
a = 4'b0001;
b = 4'b0011;
cin = 1;
#100 // 使赋值持续100ns
a = 4'b1000;
b = 4'b1010;
cin = 0;
#100 // 使赋值持续100ns
a = 4'b0011;
b = 4'b0110;
cin = 0;
#100
a = 4'b0111;
b = 4'b0000;
cin = 1;
end
endmodule
同样按照第一个的操作跑行为仿真。
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/10/17 19:35:00
// Design Name:
// Module Name: adder
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module adder_4_s(
input [3:0] a, // 4位有符号数补码
input [3:0] b, // 4位有符号数补码
input cin, // 最低位传来的进位信号
output [3:0] s, // 四位和的补码形式
output overflow // 溢出标志
);
wire [3:0] p;
wire [3:0]g;
wire [3:0]c;
assign p=a^b; //生成
assign g=a&b; //传递
//进位链
assign c[0]=cin;
assign c[1]=g[0]|(p[0]&c[0]);
assign c[2]=g[1]|(p[1]&c[1]);
assign c[3]=g[2]|(p[2]&c[2]);//和
assign s=p^c;
//符号位
assign a_sign=a[3];
assign b_sign=b[3];
assign s_sign=s[3];
//溢出检测:输入符号位相同而输出的符号位不同
assign overflow=(a_sign & b_sign & ~s_sign)|(~a_sign & ~b_sign & s_sign);endmodule
仿真文件:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/10/17 19:40:57
// Design Name:
// Module Name: test
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module adder_4_s_test();
reg [3:0] a;
reg [3:0] b;
reg cin; // 定义程序的输入为reg型
wire overflow;
wire [3:0] s; // 因为要对overflow和s进行assign赋值,所以定义为wire型
adder_4_s adder4(a, b, cin, s, overflow); // 实例化adder模块
initial begin // 给输入赋初值
a = 4'b0001;
b = 4'b0011;
cin = 1;
#100 // 使赋值持续100ns
a = 4'b1000;
b = 4'b1010;
cin = 0;
#100 // 使赋值持续100ns
a = 4'b0011;
b = 4'b0110;
cin = 0;
#100
a = 4'b0111;
b = 4'b0000;
cin = 1;
end
endmodule
同样步骤进行行为模拟:
可以在下图的右上角小齿轮处跟换数字的表示方法:
4. 在四位有符号串行加法器的基础上,增加减法的功能。
增加 operator 输入对加减法的功能进行选择。因为wire类型数据的限制,代码的判断只能使用三目运算符或者case选择。注意加减法器在实现减法功能时其实是将b取补码,也就是~b+1.
代码文件:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/10/17 19:35:00
// Design Name:
// Module Name: adder
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module full_add_sub4(
input [3:0] a,
input [3:0] b,
input cin,
input operator,
output overflow,
output [3:0]result
);
wire [3:0]bb;
assign bb=operator?~b+1:b;wire [3:0] p;
wire [3:0]g;
wire [3:0]c;
assign p=a^bb; //生成
assign g=a&bb; //传递
//进位链
assign c[0]=cin;
assign c[1]=g[0]|(p[0]&c[0]);
assign c[2]=g[1]|(p[1]&c[1]);
assign c[3]=g[2]|(p[2]&c[2]);//和
assign result=p^c;
//符号位
assign a_sign=a[3];
assign b_sign=bb[3];
assign s_sign=result[3];
//溢出检测:输入符号位相同而输出的符号位不同
assign overflow=operator?(a_sign & ~b_sign & ~s_sign)|(~a_sign & b_sign & s_sign):(a_sign & b_sign & ~s_sign)|(~a_sign & ~b_sign & s_sign);
endmodule
仿真文件:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/10/17 19:40:57
// Design Name:
// Module Name: test
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module add_sub_test();
reg [3:0] a;
reg [3:0] b;
reg cin; // 定义程序的输入为reg型
reg op;
wire overflow;
wire [3:0] result; // 因为要对overflow和s进行assign赋值,所以定义为wire型
add_sub add_sub1(a, b, cin, op, result, overflow); // 实例化adder模块
initial begin // 给输入赋初值
a = 4'b0001;
b = 4'b0011;
op = 0;
cin = 1;
#100 // 使赋值持续100ns
a = 4'b1000;
b = 4'b1010;
op = 0;
cin = 0;
#100 // 使赋值持续100ns
a = 4'b0111;
b = 4'b1000;
op = 0;
cin = 1;
#100
a = 4'b0001;
b = 4'b0011;
op = 1;
cin = 0;
#100 // 使赋值持续100ns
a = 4'b1000;
b = 4'b1010;
op = 1;
cin = 0;
#100 // 使赋值持续100ns
a = 4'b0111;
b = 4'b1000;
op = 1;
cin = 0;
end
endmodule
输出结果显示: