Verilog——半加器详解

  1. 半加器:用于计算两个一位二进制相加,不考虑低位进位。
    (1) 我们现在假设一下:a和b都是输入信号,cout是输出信号,sum是求和
    (2) 那么它们的真值表可以表示为:
    ~~~~ 加数a 加数b 进位cout 和数sum
    在这里插入图片描述
    根据真值表,可以快速的得到输入输出关系(逻辑结构)是:
    cout = a^b(表示a异或b)也就是(a&(b)+b&(a))
    sum = a&b(表示a与b,也就是and(sum,a,b))
    (3) 下面,我们分结构描述、行为描述和数据流描述来写半加器的源代码
    在此之前,Vivado的安装说明以及使用说明参见微信公众号“空谷小莜蓝”获取
    ① 我们创建的新工程的名字就叫做:half_add,我们首先来看的就是结构描述:我们在Design Sources中创建一个新的仿真文件:half_add1,在Simulation Sources中创建一个新的测试文件:tb_half_add1,准备工作就是这样
    ② 在half_add1中写的仿真源代码是:

    module half_add1
    (
    input a,b,
    output cout,sum
    /开始在模块中声明了输入信号:a,b和输出信号cout和sum/
    );
    //下面开始结构描述,操作关键字(输出,输入1,输入2,…输入n)
    xor(cout,a,b);
    and(sum,a,b);
    //上面的两行分别表示:a和b进行异或运算值传递给cout,a和b进行与运算值传递给sum
    endmodule

③ 测试文件源代码是:
在tb_half_add1中:

module tb_half_add1();
reg Ain,Bin;//定义两个寄存器型的测试信号Ain和Bin
reg clk;//clk是时钟
wire sum1,cout1;//声明2个线网型的信号sum1和cout1
initial 
	begin//#表示时延,开始的时候电流可能有点不稳定,后面Ain和Bin代表信号的初始化
		#1
		Ain = 0;
		Bin = 0;
		clk = 0;
	end
always #5 clk = ~clk;//这个#5也表示时延5个周期,并且always可以用于组合逻辑和时序逻辑,clk = ~clk必须有时延,否则会形成“死锁”,代表时序逻辑,信号在这儿停留5个周期
always @(posedge clk)//这个表示触发条件是:边沿触发
	begin//这个表示产生随机数
		Ain = {$random} % 2;
		Bin = {$random} % 2;
	end
half_add1 u1(Ain,Bin,sum1,cout1);//这个是调用原来的仿真文件,我们这个是顺序对应,所以不需要.a(a)这么写了
endmodule

④ 下面,我们就可以在Vivado中进行仿真测试了
可以得到RTL电路图:
在这里插入图片描述
和仿真波形图:
在这里插入图片描述
(4) 行为描述
创建的仿真文件和测试文件分别是:half_add2和tb_half_add2
① 仿真文件代码是:

module half_add2
(
	input a,b,
	output cout ,sum
);
reg sum ,cout;
always @(a or b)
	begin
		case({a,b})//表示多分支选择
			2'b00:begin//2'b00之类的代表位宽为2的二进制数
				sum = 0;
				cout = 0;
				end
			2'b01:begin
				sum = 1;
				cout = 0;
				end
			2'b10:begin
				sum = 1;
				cout = 0;
				end
			2'b11:begin
				sum = 0;
				cout = 1;
				end
		endcase
	end
endmodule

② 测试文件代码是:

module tb_half_add2();
	reg Ain,Bin;
	reg clk;//时钟
	wire sum2,cout2;
	initial
		begin
			#1
			Ain = 0;
			Bin = 0;
			clk = 0;
		end
	always #5 clk = ~clk;
	always @(posedge clk)
		begin
			Ain = {$random} % 2;
			Bin = {$random} % 2;
		end
		half_add2 hadder2(Ain,Bin,sum2,cout2);
endmodule

仿真波形图是:
在这里插入图片描述
RTL电路图是:
在这里插入图片描述
(5) 数据流描述:
创建的仿真文件和测试文件分别是:half_add3和tb_half_add3
① 仿真文件源代码是:

module half_add3
(
	input a,b,
	output sum,cout
);
assign sum = a^b;
assign cout = a&b;
endmodule

② 测试文件源代码是:

module tb_half_add3();
reg Ain,Bin;
reg clk;
wire sum3,cout3;
initial
	begin
		#1
		Ain = 0;
		Bin = 0;
		clk = 0;
	end
always #5 clk = ~clk;
always @(posedge clk)
	begin
	Ain = {$random}%2;
	Bin = {$random}%2;
	end
half_add3 u3(Ain,Bin,sum,cout);
endmodule
仿真波形图是:

在这里插入图片描述
RTL电路图是:
在这里插入图片描述
然,这个RTL电路图可能不完全相同,但是仿真图结果都是一样的
觉得本文可以的同学可以关注一下微信公众号“空谷小莜蓝”,我相信后期微信公众号会越来越好看的,谢谢~~

posted @ 2019-08-08 21:30  lures  阅读(312)  评论(0)    收藏  举报