原创 那些年,我们拿下了FPGA-第13章抽象级别的描述

2012-12-21 16:39 4068 19 24 分类: FPGA/CPLD 文集: 那些年,我们拿下了FPGA

 

第13章抽象级别的描述      

前面我们介绍了这么多Verilog的基本语法,最终目的还是要通过这些语句来描述电路,不管你是用if语句还是case语句,不论你是用always还是assign,这些用Verilog描述的电路设计就是该电路的Verilog模型。一个复杂电路的完整Verilog模型是由若干Verilog模块构成的,每个模块又可以由若干子模块构成,而这些模块可以分别用不同抽象级别的Verilog模块来描述,那么,有人肯定会问,到底什么才是不同抽象级别的Verilog模块呢?这一章,我们将一起探讨这个问题。

 

13.1 不同抽象级别概述

我们知道,Verilog是一种用于数字逻辑电路设计的语言,而数字逻辑电路对于我们学电子的人来说并不陌生,也十分形象,它无非是对应着各种逻辑门结构,并用这些简单的逻辑门结构构成五花八门的数字电路,然后实现我们需要的功能。然而,Verilog是一种硬件编程语言,它既是一种结构描述的语言也是一种行为描述的语言,也就是说对于同一功能的物理电路,我们可以用Verilog中提供的数字电路中较为形象的门级结构来描述电路,也可以用更为抽象的一些语句来描述电路,于是乎,我们根据抽象的程度不同,将不同的描述方式进行划分,得到以下几种不同抽象级别的描述方式,其中,从上至下,离真相越来越近,也就是说最形象的是开关级,其次是门级,依次类推,最抽象的是系统级。

系统级(system):用高级语言结构实现设计模块的外部性能的模型;

算法级(algorithm):用高级语言结构实现设计算法的模型;

RTL级(Register Transfer Level):描述数据在寄存器之间流动和如何处理这些数据的模型;

门级(gate-level):描述逻辑门以及逻辑门之间的连接的模型;

开关级(switch-level):描述器件中三极管和存储节点以及它们之间连接的模型。

换言之,不同级别的抽象,也就是说在不同抽象层次上用Verilog语言来描述一个物理电路,若从行为和功能的角度来描述某一电路,则为行为级描述,系统级、算法级和RTL级属于行为级描述方式;若从电路的结构来描述某一电路,则为结构级描述,门级和开关级属于结构级描述方式。在实际应用中,我们要根据需求对每个Verilog模型进行设计,选用不同抽象级别的描述,才能使我们的设计事半功倍,下面我们就来说说这结构级描述和行为级描述。

 

13.2 结构级描述  

所谓结构级描述就是通过调用逻辑元件并描述它们之间连接的方式来建立逻辑电路的Verilog模型,它包含模块实例和基本元件实例,那何谓实例呢?也就是说在使用模块或元件时对其名字根据需要重新定义,并对输入输出端口按需映射,从而将已有模块或元件连接起来构成系统。门级和开关级都属于结构级描述。其设计更为接近实际电路,是电路中各种基本元件的真实写照。

在Verilog中,有26种结构级关键字,包括多输入门、多输出门、三态门、上拉下拉电阻、MOS开关以及双向开关,其中三态门只有在控制端有效时才能传输数据,否则输出高阻态Z,结构级描述的各种关键字如下:

多输入门:and、nand、or、nor、xor、xnor

多输出门:buf、not

三态门:bufif0、bufif1、notif0、notif1

上拉下拉电阻:pullup、pulldown

MOS开关:cmos、nmos、pmos、rcmos、rnmos、rpmos

双向开关:tran、tranif0、tranif1、rtran、rtranif0、rtranif1

其中,多输入门、多输出门、三态门、上拉下拉电阻是门级结构关键字,而MOS开关和双向开关是开关级结构关键字。在本节中,我们主要对门级结构描述进行详细的说明,还是一起来探探究竟吧。

 

13.2.1 门级结构描述及其说明语法   

门级结构描述,就是利用Verilog内置的基本门级元件以及它们之间的连接来构筑逻辑电路的模型,简而言之,即电路是用表示门的术语来描述的。其抽象级别比较低,仅此于开关级,因此用门级结构建模来描述逻辑电路是比较接近实际电路的,就跟老一辈的工程师们用三极管、逻辑芯片等原始元件在面包板上搭电路是一个道理。Verilog提供了一系列逻辑门供大家使用。

在上面提到的各种各样的门元件中,我们常用的门结构为以下几种:

非门:not

与门:and

或门:or

与非门:nand

或非门:nor

异或门:xor

异或非门:xnor

缓冲器:buf

对于多输入门(and、or、nand、nor、xor、xnor),其声明语句的格式如下:

<门级元件名>(<驱动能力><延时>)<门实例名>(<输出>,<输入1>,<输入2>,……,<输入n>)

对于多输出门(not、buf),其声明语句的格式如下:

<门级元件名>(<驱动能力><延时>)<门实例名>(<输出1>,<输出2>,……,<输出n>,<输入>)

其中,表示驱动能力的关键字有:supply(supply drive,电源极驱动)、strong(strong drive,强驱动)、pull(pull drive,上拉级驱动)、large(large capacitor,大容性)、weak(weak drive,弱驱动)、medium(medium capacitor,中级容性)、small(medium capacitor,小容性)、highz(high capacitor,高容性),从前向后其驱动强度依次减小。而<驱动能力>和<延时>在程序中是可有可无的,可根据不同的情况选不同的值或不选,对于这种比较特殊的表示,在仿真中是如何呢?又是否能在我们的电路中有所体现呢?且看下例。

 

and       A1(out1,in1,in2);  //out为输出,in1、in2为输入

and  #20  A2(out2,in1,in2);  //out为输出,in1、in2为输入,输出和输入的延时为20个单位时间

A1对应的逻辑示意图如图所示:

 

1.jpg

仿真结果如图所示:

 

2.jpg

A1和A2都是与门的实例,我们在上面提到过实例的概念,现在有了活生生的例子,大家应该不会觉得抽象了吧。其中,A2输出相对于输入in1和in2有20个时钟周期的延迟,A1输出相对于输入没有延迟,图中输入in1和in2每20个时钟周期变化一次,从图中黄线所圈我们不得而知,A2确实比A1晚20个时钟周期输出。

在仿真中我们验证了延时说明的功能,按道理A2应该比A1输出晚20个时钟周期,那在实际电路中结果又是不是如我们所想的那样呢?我们对上述电路进行综合,生成的电路如下所示:

 

3.0.jpg

其中红线所圈为A1和A2的输出out1和out2,由图中可见,虽然延时(#20)能进行综合,也就是说能生成电路,但是在实际电路中并没有实现延时的元件,所以图中out1和out2是同时输出的,也就是说延时的描述在实际电路中是无效滴。那对于信号驱动能力的描述,其结果又如何呢?我们还是举例说明。

not                  N1(out1, datain);//out1为输出,datain为输入

not  (strong1,weak0)   N2(out2,datain);  //out1为输出,datain为输入,out2输出0时弱驱动,输出1时强驱动

N1对应的逻辑示意图如图所示:

 

3.jpg

仿真结果如图所示:

 

4.jpg

N1和N2是非门的两个实例,结果如上图中红线圈和黄线圈所示,当out2对in2取反得到0时,输出强度为弱驱动,此时输出为虚线0,当out2为1时,输出强度为强驱动,此时输出为实线1。那么在实际电路中是否真的能像我们所描述的那样对信号的强度进行明确的说明呢?这个需要来验证一下。

我们对上面的描述进行综合生成电路,如下图所示,从实际电路来看,虽然我们在程序中能对信号强度进行说明,也能够综合形成电路,但实际电路中的两个非门N1和N2并没有区别,输出信号out1和out2也没有区别的标志,也就是说我们人为规定的信号强度在实际电路中跟延时描述一样也是无效滴。

 

 

5.jpg

上面我们对门元件的使用有了初步的认识,当它们成群结队而来时,也就是当我们需要对同一个基本门级元件进行多次调用,此时,可采用下面的元件实例语句格式:

<门级元件名><实例名1>(端口连接表1),

                            <实例名2>(端口连接表2),

                            ……

                            <实例名n>(端口连接表n);

需要注意的是,在多次调用门元件时,中间每调用完一次用逗号隔开,只有在最后一个门元件调用时用分号结束。现在有了各种门元件的说明方法,可是怎么才能得到门级结构描述的模型呢?好比是我们有了一堆积木,怎么把这些积木凑在一起搭成我们需要的模型。其实,这个也不难,我们且来看看Verilog门级结构描述模块的基本结构。

 

 

6.jpg

具备基本的语法后,我们还是需要通过实际的应用对上面的语法进行消化吸收,下节通过一个二选一的选择器来看看我们到底是如何运用这大大小小的门。

 

13.2.2 用门级结构描述二选一选择器

二选一选择器,顾名思义,就是在控制信号的控制下对两路输入信号选择性输出,在本例中,控制信号为sl,两路输入信号分别为datain_A和datain_B,输出信号为dataout,程序如下所示:

moduleTwoMux(

                                     datain_A,

                            datain_B,

                                     sl,

                                     dataout

    );

 

inputdatain_A,datain_B,sl;

outputdataout;

 

not U1(nsl,sl);

and U2(slA,datain_A,sl);     //sl为1,输出datain_A

and U3(slB,datain_B,nsl);    //sl为0,输出datain_B

or  U4(dataout,slA,slB);

 

endmodule

仿真结果如下图所示:

 

7.jpg

 

在上图中,我们可以看到,当sl为为1时(图中红线所圈),输出信号dataout波形与datain_A一致,当sl为0时(图中黄线所圈),输出信号dataout波形与datain_B一致,通过上面一段小小的门级结构建模,我们就轻松地实现了二选一选择器。

所以,在电路规模较小的情况下,由于包含的门数较少,我们可以逐个引用逻辑门实例,把它们互相连接起来,这时使用门级结构描述进行Verilog建模是合适的,然而,随着我们需求的变化,如果电路的功能比较复杂,其中包含的逻辑门个数很多,这时使用门级结构描述不但繁琐而且容易出错,并且门级结构建模描述的是电路结构,看起来比较复杂,很难分析其所描述的功能,尤其对数字逻辑电路学的不好的人来说,要把各种简单的门拼凑到一起还实现复杂的功能,可能光想想就觉得头大了,在这种情况下,我们就需要从更高的抽象层次入手,选用更高抽象级别的描述,如RTL级(寄存器传输级),这样可以大大提高设计的效率,下面我们还是一起看看这更高抽象级别描述是怎么个抽象法吧。

 

13.3 行为级描述

行为级描述,是从电路的功能出发,采用任何Verilog语法进行描述的方式,像我们前面介绍过的always块儿、initial块儿、if语句、case语句、阻塞赋值语句、非阻塞赋值语句等等都属于行为描述。我们平时编写的代码通常都是在行为级描述这个抽象级别,它大大降低了我们电路设计的复杂度,在实现功能方面,真可谓是手到擒来,小菜一碟。

 

13.3.1 行为级描述及其与RTL级区别

行为级描述关注逻辑电路输入、输出的因果关系,即在何种输入条件下产生何种输出,描述的是一种行为特性,它与结构级描述所不同的是,结构级描述侧重于表示一个电路由哪些基本元件组成,以及这些基本元件的相互连接关系,而行为级描述并不关心电路的内部结构,注重的是整个电路的功能而不是具体实现,它是用一系列高级编程语言编写的过程块儿来建模的,相比结构级描述更为简洁,并且可读性更强。显然,当电路规模较大或时序关系较复杂时,采用行为描述方式进行设计可谓是明智之举。

要进行行为级建模,我们首先要知道其设计模型,如下图所示:

 

8.jpg

对于行为级描述中需要的各种语言及其用法,也就是上图中“逻辑功能定义”部分,我们在前面的章节中已经陆续介绍,这里不再赘述。

在行为级描述中包含系统级、算法级和RTL级(寄存器传输级),然而,RTL级与行为级又有所不同, RTL级是用寄存器这一级别的描述方式来描述电路的数据方式,专门针对寄存器级,而行为级指的是仅仅描述电路的功能而可以采用任何Verilog语法的描述方式,因此,RTL级描述的目标是可综合,也就是说能形成最终的逻辑门级网表,能映射到我们芯片中的逻辑资源上,而行为级描述的目标是实现我们需要的功能而没有可综合的限制,例如,initial块儿、forever语句等都是行为描述方式,但我们知道它们只能用于仿真,并不能通过综合形成电路,也就是说RTL级是行为级中可综合的那部分。

对于我们设计者而言,最终还是需要把设计变成能实现功能的电路,所以在我们实现功能的同时,可综合性是必须考虑的,因此RTL级描述在电路设计中是必不可少的。

 

13.3.2 RTL级描述二选一选择器 

在13.2.2节中我们用门级结构建模的方式实现二选一选择器,那用RTL级描述又如何实现这个二选一选择器呢?且看下例。

module ActiveStructure_mux2(

                                                                                    datain_A,

                                                                                    datain_B,

                                                                                    sl,

                                                                                    dataout

    );

 

inputdatain_A,datain_B;

inputsl;

outputdataout;

 

regdataout;

 

always @(datain_A or datain_B or sl)

begin

         if(sl==1)

                   dataout = datain_A;          //控制信号sl为1,输出datain_A

         else

                    dataout = datain_B;          //控制信号sl为0,输出datain_B

end

 

endmodule

仿真结果如下图所示:

 

9.jpg

上图与13.2.2中仿真结果相同,在sl为为1时(图中红线所圈),输出信号dataout波形与datain_A一致,当sl为0时(图中黄线所圈),输出信号dataout波形与datain_B一致。这也验证了RTL级描述和门级结构描述实现的功能是相同的,只是编程方式不同,真是条条大路通罗马。

然而,前面我们也说到过,门级结构建模是最为接近实际电路的,只是对于实现功能复杂的电路来说,其优势就是小巫见大巫咯,此时RTL级建模就进入了设计者的视线,但是不禁有人会问,RTL级建模是怎么变成我们实际的电路呢?它与实际电路之间又有着怎样的瓜葛呢?“综合工具”就帮大家解决了这个问题。为了将这种较高抽象级别的描述映射到实际电路中,需要将这种较高抽象级别的描述转换为低抽象级别的逻辑门级网表,这一过程就是我们一直提到的“综合”,RTL级描述经过综合工具的综合之后,生成逻辑门网表,也就是我们的电路,我们可以通过RTL级视图来检验我们设计的电路,下图是上例二选一选择器RTL级描述经过综合之后得到的RTL级视图,如图所示:

 

10.jpg

将上图进一步展开,图中lut3元件又由下图构成,如图所示:

 

 

11.jpg

由此图可知,该例中RTL级描述经过综合之后,生成的电路也是由1个非门,2个与门和1个或门构成,与我们13.2.2中门级结构描述的电路相同。所以,综合工具帮我们完成了从功能设计到电路的转换。

尽管如此,我们在设计电路时,还是要想着电路的结构,毕竟Verilog是一种硬件编程语言,虽说RTL级建模给我们带来极大的便利,但程序设计不合理、编写不规范、又或者逻辑结构混乱等等都会使综合之后的电路结构错综复杂甚至漏洞百出,所以电路结构是不容小觑的,只有二者结合,相辅相成,各尽其用,才能充分利用芯片的各种资源,完美的实现我们需要的功能,好比是一场音乐会,只有形形色色的乐器都发挥得淋漓尽致时,才能有那余音绕梁,三日不绝于耳之功效。

PARTNER CONTENT

文章评论5条评论)

登录后参与讨论

用户377235 2014-7-27 04:54

謝謝!受益良多,也解决我不能理解的部分,你好棒,加油!

用户377235 2013-7-21 10:22

期待......

用户961355 2013-4-27 13:47

期待下集,期待更新。

用户420773 2013-3-15 21:51

北航苏阳大神,感谢您的分享,我今天将您博客内容全部看完并做了相应的记录,受益匪浅,不知您什么时候更新呢?或者说是就此结束了吗?可以补充一些开发实例吗?比如串口通信这一块的,最好是用ISE平台的1期待您的快速更新,您真棒!~~我在北科,旅途尽美!

用户377235 2013-1-23 08:16

不错的连载

飞言走笔 2012-10-30 22:55

初学者易犯的错误^_^
相关推荐阅读
用户427466 2017-04-27 10:08
EXATA/Qualnet调试方法
1、exata5.3安装**** exata-5.3-windows-installer-64bit.exe或者exata-5.3-windows-installer-32bit.exe 默认安装路...
用户427466 2015-04-01 10:57
一个工程师说走就走的西藏之旅(九)
今年终于放下了手头的工作 背上背包 来一场说走就走的旅行 在这里让更多的朋友看到 路上的故事 路上的风景 路上的陌生人 川青大环线第九天 (实时状况关注微信) ...
用户427466 2015-03-28 23:50
一个工程师说走就走的西藏之旅(八)
今年终于放下了手头的工作 背上背包 来一场说走就走的旅行 在这里让更多的朋友看到 路上的故事 路上的风景 路上的陌生人 川青大环线第八天 (实时状况关注微信) ...
用户427466 2015-03-24 23:50
一个工程师说走就走的西藏之旅(七)
今年终于放下了手头的工作 背上背包 来一场说走就走的旅行 在这里让更多的朋友看到 路上的故事 路上的风景 路上的陌生人 川青大环线第七天 (实时状况关注微信) ...
用户427466 2015-03-24 23:40
一个工程师说走就走的西藏之旅(六)
今年终于放下了手头的工作 背上背包 来一场说走就走的旅行 在这里让更多的朋友看到 路上的故事 路上的风景 路上的陌生人 川青大环线第六天 (实时状况关注微信) ...
用户427466 2015-03-23 11:25
一个工程师说走就走的西藏之旅(三)
今年终于放下了手头的工作 背上背包 来一场说走就走的旅行 在这里让更多的朋友看到 路上的故事 路上的风景 路上的陌生人 川青大环线第三天 (实时状况关注微信) ...
我要评论
5
19
关闭 站长推荐上一条 /3 下一条