赞
踩
下面先介绍几个简单的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还可以用来描述变化的测试信号。描述测试信号的变化和测试过程的模块也叫做测试平台(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)仿真、逻辑网表仿真和门级仿真。 如果门级结构模块与具体的工艺技术对应起来,并加上布局布线引入的延迟模型 ,此时进行的仿真称为布线后仿真,这种仿真与实际电路情况非常接近。 可以通过运行 仿真器 ,并观察输人/输出波形图来分析设计的电路模块的运行是否正确。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。