1.问题重述:
试用查找真值表的方式实现真值表中的加法器,写出Verilog HDL代码。
2.问题分析:
本题要求是通过查找真值表的方式实现全加器,即三个输入,两个输出的加法器,要实现查找真值表,有两种方法,分别为case分支语句和UDP。
1)Case分支语句是对输入信号整合为一个分支判断信号,通过case跳转到所选条目下进行输出,即对应了真值表中每三个不同输入对应两个输出的行为,case是可以综合生成电路的,有时可以对应多路选择器。
2)而UDP是用户自定义元件(User Defined Primitive)的缩写,是用户自己定义实现逻辑元件的功能,相当于用户自己创建的与仿真元件对应的原语库。这种情况下,是不可以进行综合的,但利用UDP进行仿真,可以大大节省仿真处理时间。
下面将分别对这两种方法进行代码实现。
3.用 case分支语句实现的代码:
.v文件
`timescale 1ns / 1ps
//
// Company:
// Engineer: jeffery
//
// Create Date: 2022/03/18 11:39:55
//
module case1(Cin,ain,bin,sum,Cout);
input [0:0] Cin,ain,bin;
output reg [0:0] sum,Cout; //将在always过程语句中对其进行赋值,定义为reg类型
always@ (*) //表示过程内所有的信号发生变化时都会被检测并触发always语句
begin
case ({Cin,ain,bin})//case这里的括号不能忘记 !!!
3'b000:{sum,Cout}=2'b00;
3'b001:{sum,Cout}=2'b10;
3'b010:{sum,Cout}=2'b10;
3'b011:{sum,Cout}=2'b01;
3'b100:{sum,Cout}=2'b10;
3'b101:{sum,Cout}=2'b01;
3'b110:{sum,Cout}=2'b01;
3'b111:{sum,Cout}=2'b11;
default:{sum,Cout}=2'b00;
//default最好写上!避免不必要的错误
endcase
end
endmodule
tb文件:
`timescale 1ns / 1ps
module tb(sum,Cout);
reg [0:0] Cin,ain,bin; //由于下面要在过程语句进行赋值,必须为reg
output wire [0:0] sum,Cout;
initial //生成测试信号
begin
Cin=0;ain=0;bin=0;
#2 Cin=0;ain=0;bin=0;
#2 Cin=0;ain=0;bin=1;
#2 Cin=0;ain=1;bin=0;
#2 Cin=0;ain=1;bin=1;
#2 Cin=1;ain=0;bin=0;
#2 Cin=1;ain=0;bin=1;
#2 Cin=1;ain=1;bin=0;
#2 Cin=1;ain=1;bin=1;
end
case1 my_case(Cin,ain,bin,sum,Cout);//按顺序写端口或者老老实实用.Cin(Cin)
endmodule
4.用UDP实现的代码:
.v文件:
`timescale 1ns / 1ps
//
// Company:
// Engineer: jeffery
//
// Create Date: 2022/03/18 12:50:47
//
primitive addr_sum(sum,Cin,ain,bin);//由于UDP的输出只能有一个,所以这里要分两个UDP描述真值表
output sum;
input ain,bin,Cin;
table
//Cin ain bin : sum
0 0 0 : 0;
0 0 1 : 1;
0 1 0 : 1;
0 1 1 : 0;
1 0 0 : 1;
1 0 1 : 0;
1 1 0 : 0;
1 1 1 : 1;
endtable
endprimitive
primitive addr_cout(Cout,Cin,ain,bin);
output Cout;
input ain,bin,Cin;
table
//Cin ain bin : Cout
0 0 0 : 0;
0 0 1 : 0;
0 1 0 : 0;
0 1 1 : 1;
1 0 0 : 0;
1 0 1 : 1;
1 1 0 : 1;
1 1 1 : 1;
endtable
endprimitive
module UDP_test(Cout,Cin,sum,ain,bin);
output Cout,sum;
input Cin,ain,bin;
addr_sum(sum,Cin,ain,bin);
addr_cout(Cout,Cin,ain,bin);
endmodule
tb文件:
`timescale 1ns / 1ps
module tb(sum,Cout);
reg [0:0] Cin,ain,bin; //由于下面要在过程语句进行赋值,必须为reg
output wire [0:0] sum,Cout;
initial //生成测试信号
begin
Cin=0;ain=0;bin=0;
#2 Cin=0;ain=0;bin=0;
#2 Cin=0;ain=0;bin=1;
#2 Cin=0;ain=1;bin=0;
#2 Cin=0;ain=1;bin=1;
#2 Cin=1;ain=0;bin=0;
#2 Cin=1;ain=0;bin=1;
#2 Cin=1;ain=1;bin=0;
#2 Cin=1;ain=1;bin=1;
end
UDP_test my_UDP(.Cout(Cout),.Cin(Cin),.sum(sum),.ain(ain),.bin(bin));//用.Cin(Cin)
endmodule
5.实验结果:
由上面的结果可知,两种方法的真值表查找方法所获得的结果是一样的,均完成了全加器的功能。