Verilog语法的基本概念

634 阅读7分钟

我正在参加「掘金·启航计划」

写在前面

本篇列举多个例子对Verilog语法的概念进行整体的描述,大家可以直观的通过RTL视图理解代码的运行过程。例1还附带了波形图和仿真后的波形图,帮助大家更好的了解Verilog。

相信大家仔细观察代码后,会发现赋值时所用的符号有所不同。“=”:阻塞赋值,“<=”:非阻塞赋值,这两种赋值符号都有其精妙之处,会在后续更新,带大家详尽了解这两种赋值语句的不同。

笔者才疏学浅,本篇如有缺点和疏漏在所难免,恳请广大读者批评指正。

Verilog模块的基本概念

例1

二选一多路选择器

描述

从RTL视图中很容易理解模块muxtwo的作用,输出out与输入a一致,还是与输入b一致,由sl的电平决定。当控制信号为非(低电平0)时,输出out与输入a相同,否则与b相同。

人们并不关心它的电路结构,关心的是如何从逻辑功能上来描述它。Verilog的语法支持这种逻辑行为的描述。

波形图

20221013091611.png

信号名称信号类型信号描述
a输入信号输入
b输入信号输入
sl输入信号输入选择信号
out输出信号输出

RTL代码

20221013094504.png

RTL视图

20221013092156.png

仿真代码

20221013095143.png

仿真波形图

20221013092736.png

20221013092757.png

例2

二选一多路选择器布尔表达式形式

参考例1,不再进行波形图的绘制和模块的仿真

描述

为了实现例1这个电路的逻辑功能,也能用布尔表达式来描述,Verilog语言中,可以用“~”、“&”、“|”操作符分别表示:求反、相与和相或运算操作。所以例1的二选一多路选择器模块实现的逻辑功能也能用例2的形式来表示。

RTL代码

20221013181250.png

RTL视图

20221013100208.png

例3

二选一多路选择器

描述

例3所描述的也是一个二选一多路选择器,输出out与输入a一致,还是与输入b一致,由sl的电平决定。当控制信号sl为非(!)(低电平0),输出out与输入a相同,否则与b相同。模块的描述用基本的与门、或门和非门的互联来描述。在程序模块中出现的and、or和not都是Verilog语言的保留字,由Verilog语言的原语规定了它们的接口顺序和用法,分别表示与门、或门和非门,其中元件的输出口都规定在第一个端口,#1表示门输入到输出延迟1个时间单位,模块中的u1、u2、u3、u4与逻辑图中的逻辑元件对应,表示逻辑元件的实例名称。模块表示的是电路结构,和下方RTL视图完全一致。Verilog的语法也支持这种基于逻辑单元互联结构的描述。

如果在编写Verilog模块时,不但符合语法,还符合一些基本规则,就可以通过计算机上运行的工具把例1通过例2的中间形式自动转换为例3形式的模块,这个过程叫做综合。我们知道例3模块很容易与某种工艺的基本元件逐一对应起来,再通过布局布线工具自动地转变为某种具体工艺的电路布线结构。在这一部分里除了讲解基本语法外,主要讲解符合何种风格的Verilog模块是可以综合的;何种风格的模块是不可以综合的;不可综合的Verilog模块有些什么作用。

RTL代码

20221013181337.png

RTL视图

20221013103746.png

例4

3位加法器

描述

例4通过连续赋值语句描述了一个名为adder的3位加法器。它可以根据两个3比特数a、b和进位(cim)计算出和(sum)及向上进位(count)。

RTL代码

20221013181428.png

RTL视图

20221013104416.png

例5

2位比较器

描述

例5通过连续赋值语句描述了一个名为compare的比较器。对2比特数a、b进行比较,如a与b相等,则输出equal为高电平,否则为低电平。

RTL代码

20221013105642.png

RTL视图

20221013105703.png

例6

三态门选择器

描述

例6描述了一个名为trist2的三态驱动器。程序通过调用一个在Verilog语言提供的原语库中现存的三态驱动器元件bufif1来实现其逻辑功能。在trist2模块中所用到的三态驱动器元件bufif1的具体名字叫做mubuf,这种引用现成元件或模块的方法叫做实例化或实例引用,这表示电路构造的一种常见的语法现象。

RTL代码

20221013173021.png

RTL视图

20221013173029.png

从RTL视图中可以很清楚地了解到当enable信号为高电平时,out的电平变化等于in的电平变化

例7

三态门选择器

描述

例7通过另一种方法描述了一个三态门。在这个例子中存在着两个模块:模块trist1引用由模块mytri定义的实例部件mytri_inst,模块trist1是上层模块;模块mytri则被称为子模块。在实例部件tri_inst中,带“.”表示被引用模块的端口,名称必须与被引用模块mytri的端口定义一致,小括号中表示在本模块中与之连接的线路。

RTL代码

20221013175444.png

RTL视图

20221013175503.png

绿色框图里面模拟了类似例6中的三态门选择器

20221013175515.png

上面这些例子都是可以综合的,通过综合工具可以自动转换为由与门、或门和非门组成的加法器、比较器和三态门等组合逻辑。在数字电路基础中已经学习过怎样用组合逻辑来实现1位或2位整数的加法和比较,而带超前进位链的多位整数加法器和多位比较器的逻辑图相当复杂,很难即时辨明。但这些也是已经成熟的电路结构,对于计算机支持的EDA工具来说,这只是一个映射的过程,系统设计人员就不比过于关心它们逻辑构成的细节,而把主要精力集中在系统结构的考虑上,从而大大提高了设计效率。

Verilog用于模块的测试

Verilog还可以用来描述变化的测试信号。描述测试信号的变化和测试过程的模块也叫做测试平台(testbench),它可以对上面介绍的电路模块(无论是行为的或结构的)进行动态的全面测试。通过观测被测试模块的输出信号是否符合要求,可以调试和验证逻辑系统的设计和结构正确与否,并发现问题及时修改。

下图为例1的仿真代码(稍作修改),可以看做例1的Verilog测试模块,它可以对例1、例2和例3的多路选择器模块进行逐步深入的全面测试。

20221013185915.png

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