【Verilog数字系统设计(夏宇闻)4-----Verilog语法的基本概念2】

Verilog数字系统设计(夏宇闻)3-----Verilog语法的基本概念2

Verilog 模块的基本概念

下面先介绍几个简单的Verilog HDL程序,从中了解Verilog模块的特性。
例1 如图所示的二选一多路选择器的Verilog HDL程序如下:

module muxtwo (out, a,b,sl);
		input a,b,sl;
		output out;
		reg out;
				always @ (sl or a or b)
						if(! sl) out = a;
						else out = b;
endmodule

从例1中很容易理解模块muxtwo的作用。它是一个如图所示的二选一多路器,输出out与输入a一致,还是与输入b一致,由sl的电平决定。当控制信号sl为非(低电平0)时,输出out与输入a相同,否则与b相同。always @ (sl or a or b)表示只要sl 或a 或b,其中若有一个变化时就执行下面的语句。人们并不关心它的电路结构,关心的是如何从逻辑功能上来描述它。Verilog的语法支持这种逻辑行为的描述。
在这里插入图片描述
为了实现这个电路的逻辑功能,也能用布尔表达式来描述,Verilog语言中,可以用“~”、“&”、“|”操作符分别表示:求反、相与和相或运算操作。所以例1的muxtwo模块实现的逻辑功能也能用例2形式的Verilog代码来表示。
例2 如图所示的带有与非门的二选一多路选择器的Verilog HDL程序如下:

module muxtwo (out, a,b,sl);
		input a,b,sl;  //输入信号名
		output out;  //输出信号名
		wire nsl, sela, selb;  //定义内部连接线
		assign nsl =~ sl;  //求反
		assign sela = a&nsl; //按位与运算
		assign selb = b&.sl;
		assign out = sela | selb;  //按位或运算
endmodule

在这里插入图片描述
上面例子中实现的逻辑功能是非常易理解的,它从本质上就是一个逻辑表示式,表达的是一个二选一多路选择器,如例3所示
例3 如图所示的多路选择器的Verilog HDL程序如下:

module muxtwo (out, a,b,sl);
		input a,b,sl;  //输入信号名
		output out;  //输出信号名
		not				u1(nsl,sl);
		annd	#1	u2(sela,a,nsl);
		and		#1	u3(selb,b,sl);
		or			#1 	u4(out,sela,selb);
endmodule

在这里插入图片描述

从图中很容易理解模块muxtwo的作用。它也是一个二选一多路器,输出out与输入a一致,还是与输入b一致,由sl的电平决定。当控制信号sl为非(!)(低电平0),输出out与输入a相同,否则与b相同。模块的描述用基本的与门、或门和非门的互联来描述。在程序模块中出现的and、or和not都是Verilog语言的保留字,由Verilog语言的原语(primitive)规定了它们的接口顺序和用法,分别表示与门、或门和非门,其中元件的输出口都规定在第一个端口,#1和#2分别表示门输入到输出的延迟为1和2个单位时间;模块程序中的u1、u2、u3、u4与逻辑图中的逻辑元件对应,表示逻辑元件的实例名称。模块表示的是电路结构,跟程序右面的电路逻辑图表示完全一致的。Verilog的语法也支持这种基于逻辑单元互联结构的描述。
如果在编写Verilog模块时,不但符合语法,还符合一些基本规则,就可以通过计算机上运行的工具把例1通过例2的中间形式自动转换为例3形式的模块,这个过程叫做综合。我们知道例3模块很容易与某种工艺的基本元件逐一对应起来,再通过布局布线工具自动地转变为某种具体工艺的电路布线结构。在第一部分里除了讲解基本语法外,主要讲解符合何种风格的Verilog模块是可以综合的;何种风格的模块是不可以综合的;不可综合的Verilog模块有些什么作用等。
下面再看几个简单的模块,目的是初步了解Verilog语法最重要的几个基本概念:并行性、层次结构性,并了解测试平台(testbench).
例4 通过连续赋值语句描述一个3位加法器的Verilog HDL程序如下:

module adder( count, sum, a, b,cin);
		input[2:0] a,b;
		input cin;
		output count;
		output[2:0] sum;
		assign {count,sum} = a+b+cin;
endmodule

这个例子通过连续赋值语句描述了一个名为adder的3位加法器。它可以根据两个3比特数a、b和进位(cin)计算出和(sum)及向上进位(count)。从例子中可以看出整个Verilog HDL程序是位于module和endmodule声明语句之间的。
例5 通过连续赋值语句描述一个比较器的Verilog HDL程序如下:

module compare(equal,a,b);
		output equal;   //声明输出信号equal
		input[1:0] a,b;   //声明输入信号a,b
		assign equal = (a==b) ? 1:0;
		/*如果a,b两个输入信号相等,输出为1;否则为0*/
endmodule

此程序通过连续赋值语句描述了一个名为compare的比较器。对2比特数a、b进行比较,如a与b相等则输出equal为高电平,否则为低电平。在这个程序中,/*……*/和//……表示注释部分。注释只是为了方便程序员理解程序,对编译是不起作用的。
例6 如图所示的三态门选择器的Verilog HDL程序如下:

module trist2(out,in,enable);
		output out;
		input in,enable;
		bufif1 mybuf(out,in,enable);
endmodule

在这里插入图片描述

该程序描述了一个名为trist2的三态驱动器。程序通过调用一个在Verilog语言提供的原语(primitive)库中现存的三态驱动器元件bufif1来实现其逻辑功能。在trist2模块中所用到的三态驱动器元件bufif1的具体名字叫做mybuf,这种引用现成元件或模块的方法叫做实例化或实例引用,这表示电路构造的一种常用的语法现象。
例7 采用二个模块的三态门选择器的Verilog HDL程序如下:

`module trist1(sout,sin,ena);
		output sout;
		input sin,ena;
		mytri tri_inst(.out(sout),.in(sin),.enable(ena));
		//引用由mytri模块定义的实例元件tri_inst
endmodule
module mytri(out,in,enable);
		output out;
		input in,enable;
		assign out=enable ? in:'bz;
endmodule

该程序通过另一种方法描述了一个三态门。在这个例子中存在着两个模块:模块trist1引用由模块mytri定义的实例部件tri_inst,模块trist1是上层模块;模块mytri则被称为子模块。在实例部件tri_inst中,带“.”表示被引用模块的端口,名称必须与被引用模块mytri的端口定义一致,小括号中表示在本模块中与之连接的路线。
上面这些例子都是可以综合的,通过综合工具可以自动转换为由与门、或门和非门组成的加法器、比较器和三态门等组合逻辑。在数字电路基础中已经学习过怎样用组合逻辑来实现1位或2位整数的加法和比较,而带超前进位链的多位整数加法器和多位比较器的逻辑图相当复杂,很难即时辨明。但这些也是已经成熟的电路结构,对千计算机支持的EDA工具来 说这只是一个映射的过程,系统设计人员就不必过于关心它们逻辑构成的细节,而把主要精力集中在系统结构的考虑上,从而大大提高了设计效率。

Verilog用于模块的测试

Verilog还可以用来描述变化的测试信号。描述测试信号的变化和测试过程的模块也叫做测试平台(testbench或testfixture),它可以对上面介绍的电路模块(无论是行为的或结构的)进行动态的全面测试。通过观测被测试模块的输出信号是否符合要求,可以调试和验证逻辑系统的设计和结构正确与否,并发现问题及时修改。图2.5为Verilog时用于模块测试的原理图。
在这里插入图片描述
下面来看一个Verilog的测试模块,它可以对[例1]和[例2]和[例3]的多路器模块进行逐步深入的全面测试。
例8 对[例1]~[例3]多路器模块的Verilog HDL程序如下:

`include"muxtwo.v"
		module t;
			reg ain,bin,select;
			reg clock;
			wire outw;
			initial      //把寄存器变量初始化为一确定值
			begin
				ain =0;
				bin  =0;
				select = 0;
				clock = 0;
			end
			always #50 clock =~clock;  //产生一个不断重复地周期为100个地时钟信号clock
			always @ (posedge clock)
				begin   //{$random}为系统任务,会产生一个随机数
					#1 ain = {$ random} %2;  //产生随机地位信号流ain 和bin, %2为模2运算
					#3 bin = {$ random} %2; //分别延迟1和3个时间单位后产生随机地位信号流ain 和 bin
				end
				always #1000	select = ! select;  //产生周期为10000个单位时间的选通信号变化
				//···················
				muxtwo m(.out(outw), .a(ain), .b(bin), .sl(select));
				/*实例引用多路器,并加入测试信号流,以观察模块的输出out。其中,muxtwo是已经定义的(行为的或结构的)模块,m表示在本测试模块中有一个名为m的muxtwo的模块,其四个端口分别为:
				.out(), .a(), .b(), .sl(),
				"."表示端口;后面紧跟端口名,其名称必须与muxtwo模块定义的端口名一致;小括号内的信号名为与该端口连接的信号线名,可以用别的名,但必须在本模块中定义,说明其类型。*/
endmodule

其中 muxtwo 可以是行为模块,也可以是布尔逻辑表达式或门级结构模块。 模块 t 可以 对 muxtwo模块进行逐步深入的完整测试。 这种测试可以在功能(即行为)级上进行,也可以在逻辑网表(逻辑布尔表达式)和门级结构级上进行。 它的分别称为前(RTL)仿真、逻辑网表仿真和门级仿真。 如果门级结构模块与具体的工艺技术对应起来,并加上布局布线引入的延迟模型 ,此时进行的仿真称为布线后仿真,这种仿真与实际电路情况非常接近。 可以通过运行 仿真器 ,并观察输人/输出波形图来分析设计的电路模块的运行是否正确。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周猿猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值