首页 理论教育Verilog硬件描述语言的特点和规范

Verilog硬件描述语言的特点和规范

【摘要】:Verilog语言博大精深,本节提取Verilog语言精华做详细介绍,主要从以下几个方面入手:Verilog语言基本结构、其门级描述与行为级描述,搭建组合逻辑与时序逻辑,以及如何使用状态机,从基础框架到骨髓血液,整个硬件描述语言塑造成型。图5.3 Verilog基本结构1.Verilog基本结构Verilog模块在工程中以.v的文件形式存在,在每个.v文件中都定义了一个功能模块,其基本结构如图5.3所示。

Verilog语言博大精深,本节提取Verilog语言精华做详细介绍,主要从以下几个方面入手:Verilog语言基本结构、其门级描述与行为级描述,搭建组合逻辑与时序逻辑,以及如何使用状态机,从基础框架到骨髓血液,整个硬件描述语言塑造成型。

978-7-111-55094-5-Chapter05-3.jpg

图5.3 Verilog基本结构

1.Verilog基本结构

Verilog模块在工程中以.v的文件形式存在,在每个.v文件中都定义了一个功能模块(module),其基本结构如图5.3所示。

图5.3中,第一行语句module用来声明一个模块,它与endmodule配套使用,endmodule在代码最后一行,表示代码的结束,module声明后面跟着模块的名称,名称后面跟着端口列表,在端口列表中需要列出该模块的输入输出端口名,在接下来的端口定义中对端口的位宽进行说明,在数据类型说明中需要用reg和wire型声明output型端口,reg和wire类似于C语言中用int之类去定义数据类型,reg型指数据类型为寄存器型,wire型指数据类型为线型,紧接着就是模块功能的描述,这部分由组合电路和时序电路共同组成,在输入信号的激励下,经过组合电路和时序电路的处理将信号输出,完成一个基本模块的编写。

当模块的上一层调用这个模块的时候,需要将该模块例化,生成该模块的调用实例,将该模块端口与其他各模块端口一一对应,例化的方法如图5.4所示。

978-7-111-55094-5-Chapter05-4.jpg

图5.4 模块例化

其中,调用的模块名称是module_A,引用该模块时将其命名为module_A_inst,即module_A_inst是模块module_A的实例引用名。

2.门级描述与行为级描述

门级描述和行为级描述都是用在图5.3中“功能描述”的那部分,都是完成功能描述的方式。所谓门级描述,就是利用门器件完成功能描述,如:与门(and),或门(or),非门(not),异或门(nor)等,它们都可以在代码中直接引用,如图5.5所示。

978-7-111-55094-5-Chapter05-5.jpg

图5.5 门级描述示例

其中,a1和a2为与门“and”的实例化名称,此句表示将输入datain1和da-tain2相与输出到out1,将datain3和datain4相与输出到out2。如上所述,图5.5中通过改变实例化名称(a1、a2、…)将与门“and”多次例化,实现与门模块的重复利用。

所谓行为级描述,就是用Verilog自身的语言去实现功能,没有现成的门器件,取而代之的是always块、if语句、case语句等,if、case等比较好理解,与C语言功能一样,always块是Verilog语言所独有的、并且大面积使用的表达方式,如图5.6所示。

第一句表示当时钟信号clk的上升沿或者复位信号rst的上升沿出现时,触发always块下面的语句执行,第二句表示当信号A、B、C中至少有一个发生变化时,触发always块执行其下面的语句,第三句表示当always块下面的语句中用到的所有条件信号,比如if语句中的条件,case语句中的条件等,至少有一个发生变化时,触发always块。上面只是行为级描述的一个简单例子,所有用自身语言实现的描述都可以统称为行为级描述。在行为级描述中,有的语句是可以综合的,也就是说能用工具翻译成门级网表,这些语句又称为RTL级描述,在我们的设计中,最终目的都是将设计变成电路,所以都必须是可综合的,因此都要使用RTL级描述,除了部分只用于仿真的代码,不用考虑其可综合性,关于可综合,会在后面做详细介绍。

在电路规模较小的情况下,可以用门级描述去实现,此时电路门数少,直接用门级描述使得电路结构清晰,便于综合。然而,随着功能的强大,电路复杂度的提高,很难用简单的门级结构去分析和描述其功能,容易造成错误,这时用行为级描述就简单易懂,用语句去实现,而不是自己去搭电路,把搭电路的工作留给后续的综合工具,而我们只需要了解语法,并组织起来,所以,行为级描述比门级描述对于机器来说抽象层次更高,对于人来说更通俗易懂,可以显著地提高设计效率

978-7-111-55094-5-Chapter05-6.jpg

图5.6 always块

3.组合逻辑与时序逻辑

前面已经多次提到组合逻辑与时序逻辑,它们是数字电路设计的血肉。它们最大的区别就是时钟,组合逻辑中只有逻辑和符号运算,没有时钟的控制,而时序逻辑都是在时钟的控制下进行逻辑和符号运算,因此,当组合逻辑遇上时序逻辑,组合逻辑在电路中容易出现竞争冒险现象,信号产生毛刺,埋下不稳定的地雷。它们的关系如图5.7所示。

978-7-111-55094-5-Chapter05-7.jpg

图5.7 组合逻辑与时序逻辑关系

组合逻辑通常使用assign语句和always块实现,如图5.8所示。

图5.8中,变量c的类型为wire型,在assign语句中被赋值的变量必须定义为wire型,c相对于a、b没有延迟,当a、b发生变化时,c即刻跟随a或者b发生变化,上述语句也可以通过always块实现,如图5.9所示。

978-7-111-55094-5-Chapter05-8.jpg

图5.8 assign语句实现组合逻辑

978-7-111-55094-5-Chapter05-9.jpg

图5.9 always语句实现组合逻辑

图5.8与图5.9表达的意思相同,它们都是组合逻辑的表现形式,c的输出与时钟没有关系,不管是在时钟的上升沿或下降沿或中间某个位置,只要a、b或sel中至少一个发生变化,c就会在同一时间跟随a或者b发生变化。时序逻辑也是通过always语句来实现,但其过程却截然不同,如图5.10所示。

978-7-111-55094-5-Chapter05-10.jpg

图5.10 时序逻辑

图5.10中,当时钟的上升沿(posedge clk)或者复位信号的上升沿(posedge rst)到来时才执行always块里面的代码,这就意味着c的输出与时钟沿是同步的,它是在每个时钟沿去判断sel,并根据sel选择输出a或者b,所以c会比a或者b的变化要晚一个时钟周期,由于c要受时钟沿的控制,所以在后续将代码映射成电路的过程中(即综合),可以通过控制时钟来达到控制c的目的,起到保证c能正确输出的作用,而不会采到亚稳态值,组合逻辑就无法控制,所以时序逻辑比组合逻辑的可控性更强。在数字电路设计中,对于异步时钟的输入信号都会做同步处理,即用本地时钟做握手,可以通过寄存器打两拍,也可以通过存储介质隔离一下,以保证模块采集到的输入信号是正确的;模块输出时也采用时序逻辑输出,保证输出的信号跟时钟同步,便于做管理和约束,关于约束在后续章节中会有详细介绍,这里不再赘述。

虽说组合逻辑容易产生毛刺,电路不稳定,但在实际的电路设计中,很难用时序逻辑完全取代组合逻辑,需要二者相互配合,将组合逻辑有效的穿插在时序逻辑间,通过约束时钟达到管理时序逻辑,携带管理组合逻辑的目的,这样能够合理地提高数字电路设计效率,实现电路设计的功能。两者相辅相成,缺一不可。

4.状态机

如果说时序逻辑和组合逻辑是数字电路设计的血肉,那么状态机就是数字电路设计的灵魂。所谓,灵魂和血肉,总有一个在路上。在数字电路设计中,总会用到它们,不离不弃,难舍难分。状态机,就是一个有多种状态的机器,根据自己的节奏,有条不紊地运转,在每个状态完成一件或几件事情,这个完成的事情就是我们需要的输出,这个控制节奏的砝码就是我们得到的输入。状态机的优势在于能大大提高数字电路的稳定性和可靠性

状态机的设计,首先要提取状态机的要素,即需要几个状态,各个状态之间的联系;其次是状态编码,就是给每个状态一个编号,最好用独热码,有利于综合工具进行优化,否则在综合时,综合工具可能自动将其转换为独热码;最后就是状态机的功能,就是每个状态需要干的事情,举个例子来说明状态机,比如交通灯控制,将其划分为如下几个状态,如图5.11所示。

978-7-111-55094-5-Chapter05-11.jpg

图5.11 状态机示例

起初交通灯是熄灭的(idle),当早上6点交通灯开始工作,此时进入绿灯亮状态(S0),绿灯亮60s,进入黄灯亮状态(S1),黄灯亮30s,进入红灯亮状态(S2),红灯亮60s,再次进入绿灯亮状态(S0),当晚上10点,无论这时是绿灯亮(S0)、黄灯亮(S1)还是红灯亮(S2),交通灯都要关闭,回到灯熄灭状态(idle)。代码如例5.1所示。

例5.1 交通灯状态转移代码

978-7-111-55094-5-Chapter05-12.jpg

978-7-111-55094-5-Chapter05-13.jpg

978-7-111-55094-5-Chapter05-14.jpg

978-7-111-55094-5-Chapter05-15.jpg

978-7-111-55094-5-Chapter05-16.jpg

例5.1中采用经典三段式状态机描述交通灯的控制过程,第一个always块由组合逻辑描述状态转移过程,第二个always块由时序逻辑描述各个状态下信号的输出情况,状态跳转没有时钟延迟,当输入条件变化,状态即刻变化,输出信号在各个状态下用时钟输出,保证输出信号的可约束性和稳定性,两者相互结合,大大地保证了电路的可靠性和实效性。所以,笔者认为在数字电路设计中状态机的描述使得代码逻辑更清晰,结构更合理,状态更稳定,是值得推荐的描述方式。