在Verilog语言中,使用门级建模设计一个由1位全加器组成的4位全加器

4位全加器的门级建模

Verilog语言的层级

在Verilog硬件描述语言中,我们可以分许多层次对电路进行描述,每一层都有自己的特点。层次分为开关级、门级、数据流级、行为级。我们不能说必须使用哪一种层级来描述某 一个指定的电路,只要在合适的“需求”下,都可以使用。
记住!Verilog只是用于描述电路的一种语言,其中最困难的是电路的结构、功能等问题。可以这样说,就好比自己在写一篇作文,Verilog语言只是让你的作文没有一些低级语法错误;自己电路的理解则是获取高分的亮点。

目标

这次先使用门级建模描述一个4位全加器,主要是认识一个模块的简单组成和其测试代码的编写。所以在这篇文章中会认识到什么是门级建模、模块和测试代码的编写。

门级建模

门级建模是在已知门级电路图的条件下,使用基本门级元器件把电路描述出来。这句话简单直接说明门级建模的应用前提,就是已知电路的门级原理图。

设计过程

设计思路:采用自上而下的设计思想。若设计一个4位全加 器,先设计一个1位全加器。之后,把4个一位全加器级联起 来。这样便设计好一个四位全加器。

1位全加器门级描述过程

1位全加器的设计思路就是“翻译”电路图。电路图如下:
一位全加器电路图

代码

Verilog代码的编写要有两部分:设计代码和测试代码,门级建模中设计代码编写是最简单的,只需要会认电路图中的门是什么,再掌握Verilog编码规则就可以轻松的编写代码。有关测试代码的编写先简单说明一下,测试就是验证设计代码是否满足“预期的结果”。

1位全加器门级描述代码

module	add_1_m	(a,b,cin,cout,sum);
input	a,b;
input	cin;
output	cout;
output	sum;
wire	[2:0]	w;
and
	a1(w[0],a,cin),
	a2(w[1],a,b),
	a3(w[2],b,cin);
xor	a4(sum,a,b,cin);
or	a5(cout,w[0],w[1],w[2]);
endmodule

1位全加器测试代码

module	add_1_m_tb;
reg	a,b;
reg	cin;
wire	cout1;
wire	sum1;
add_1_m		u1 (a,b,cin,cout1,sum1);

initial
begin
#00	a=0;b=0;cin=0;
#10	a=0;b=1;
#10	a=1;b=0;
#10	a=1;b=1;
#00	a=0;b=0;cin=1;
#10	a=0;b=1;
#10	a=1;b=0;
#10	a=1;b=1;
end
initial
begin
  $monitor($realtime,"\ta=%d\tb=%d\tcin=%d\t\t\tcout1=%d\tsum1=%d\t",a,b,cin,cout1,sum1);
end
endmodule

有关测试代码的说明基本上没有什么可说的,结果可以看波形也可以直接看transcript里面的结果。如下图:
transcript中显示的结果

4位全加器门级描述代码

//use add_1_m connect to add_4
module add_4_m (a,b,cin,cout,sum);
input	[3:0]	a,b;
input		cin;
output		cout;
output	[3:0]	sum;
wire	[3:1]	c;
add_1_m	u1	(a[0],b[0],cin,c[1],sum[0]);
add_1_m	u2	(a[1],b[1],c[1],c[2],sum[1]);
add_1_m	u3	(a[2],b[2],c[2],c[3],sum[2]);
add_1_m	u4	(a[3],b[3],c[3],cout,sum[3]);
endmodule

4位全加器测试代码

module add_4_tb;
reg	[3:0]	a,b;
reg		cin;
wire		cout1;
wire	[3:0]	sum1;
add_4_m t1 (a,b,cin,cout1,sum1);
integer seed1,seed2,seed3;
initial
begin
	seed1=1;seed2=2;seed3=3;
	a=0;b=0;cin=0;
	repeat(10)
		begin
		#10	a=($random(seed1)/16);b=($random(seed2)/16);cin=($random(seed3)/2);
		end
	#10	$stop;
end

initial	$monitor($realtime,"\ta=%d\tb=%d\tcin=%d\t\t\tcout1=%d\tsum1=%d",a[3:0],b[3:0],cin,cout1,sum1[3:0]);
endmodule

这个测试代码的编写分格和上一个测试代码的风格有所不同,这两种的区别是什么?以后再说!这两个代码我测试过,没有什么问题的。
运行结果见下图:
4位全加器的运行结果

总结

这篇文章提供了门级建模的基本方法——翻译电路(仅仅是门级电路)。我以后会使用门级建模设计一个32的超前进位加法器。至于测试模块的编写习惯或者是经验,我会在随后的文章中写一下有用的干货。本篇文章为出入Verilog的新手提供一个简单入门案例。

预告

其实我本来是想先把门级、数据流级和行为级这三种描述电路的方法都试一下。但是,最后我改变主意了,我先完成有关加法器的一些简单的设计。所以下一个文章就是使用数据流级+模块调用设计一个32位的全加器。

感想

这是我第一次在CSDN上上传自己写的代码,我会一直写下去,总结自己的学习内容、经验。如果有什么问题,请指出。若有幸有大佬光临,希望提出指导性意见。感谢大家!

猜你喜欢

转载自blog.csdn.net/yixiaoyaobd/article/details/107677063