VHDL和verilog的区别
文章目录
前言
VHDL相对于Verilog HDL,给人最深刻的印象便是臃肿,掌握起来比较难。
本文摘自《FPGA之道》,学会站在巨人的肩膀上来对比学习二者。
VHDL的并行信号赋值语句包括三种:(1)简单并行信号赋值;(2)条件信号赋值;(3)选择信号 语句赋值
共同特点:1、赋值目标必须是信号,与其他并行语句同时执行,与书写顺序及是否在块语句中无关
2、每一信号赋值语句等效于一个进程语句,所有输入信号的变化都将启动该并行语句
VHDL与Verilog的比较
对于一个长期或者想要长期从事FPGA事业的工程师来说,只懂得一种硬件描述语言显然是不够的,这是由于不同项目的平台条件、环境因素以及合作模式等的不同所必然导致的。在前面的两个章节中,已经对目前FPGA开发上两种主流的硬件描述语言——VHDL与Verilog——进行了比较详细的基本语法介绍。那么在这一章节,为了能够让大家更加深入的理解和区分这两种语言,在编写或阅读代码时做到灵活切换,减少混淆,我们将从语法和语言两个方面对这两种语言的区别与联系进行一下简单的介绍。
语法比较
基本程序框架比较
VHDL基本程序框架共包括三个部分:library、entity、architecture,而Verilog基本程序框架中,只包含一个module部分。
简单的来说,VHDL中entity和architecture两部分的功能之和其实就相当于一个Verilog的module。只不过entity和architecture需要显式的去定义两者之间的对应关系,并且一个entity并不限于只有一个architecture,而module是一个接口和功能的结合体,本身就具有接口和功能两个属性。
除此以外,VHDL中具有library的声明部分,而Verilog没有,但是这并不是说Verilog语言不需要使用相应的work库、标准库、器件库或自定义库文件。这是因为Verilog在编程的时候不需要显式的去告诉编译器自己需要什么,而编译器会自动加载所有的库或者根据代码加载部分的库来进行编译。相比之下,VHDL在这方面做的更加的严谨、更加的高级,因为VHDL采用类似C语言的方式,只显式加载需要的库,而不建议一次性加载所有的库,虽然多加载一些无用的库文件也不会报错,但是这并不是一个好的代码编写习惯。
端口定义比较
VHDL中的端口类型有四种:in、out、buffer和inout ,相对应的Verilog中的端口类型只有三种:input、output和inout。它们的对应关系如下:
VHDL | Verilog |
---|---|
in | input |
out | - |
buffer | output |
inout | inout |
从上表可以看出,Verilog中的output端口的功能其实和VHDL中的buffer端口的功能相同,output端口的输出结果是可以在模块内部被引用的。当然了,可以在模块内部被引用,并不代表一定需要在模块内部引用,因此当内部代码没有使用输出端口的结果时,那么Verilog中的output和VHDL中的buffer其实也就相当于VHDL中的一个纯粹的out端口。
因此,相比于Verilog对端口类型的三个分类,VHDL中的四个分类略有冗余之嫌。
范围表示方法比较
VHDL中表示范围用关键字downto和to,而Verilog中使用“:”表示范围,两者的对应关系举例如下。在VHDL定义如下信号量,
signal a std_logic_vector(15 downto 0);
signal b std_logic_vector(0 to 15);
等同于在Verilog中定义如下寄存器类变量,
reg [15:0] a;
reg [0:15] b;
元件调用与实例化比较
VHDL中,父元件要例化一个子元件,必须先在architecture的声明部分声明该元件,然后才能在architecture的语句部分例化该元件。而Verilog中,要实例化一个模块,仅仅需要在父模块的模块实现中的语句部分直接写一条实例化语句即可。相比之下,VHDL语法严谨,但非常繁琐;Verilog语法灵活,但书写十分简便。不过好在目前主流的FPGA开发工具,都已经具有了根据写好的VHDL文件自动生成component和instance语法的功能,这将极大的方便使用VHDL的开发者。
Process与always比较
Process之于VHDL就好比always之于Verilog,它们有着相同的功能,类似的结构。都是串行语句的聚类,且整个语句块在程序运行期间会反复地执行。
这两者之间有两处细微的不同点:
一、always不支持定义语句块内使用的局部变量。
二、敏感量表的区别。always的敏感量表中的变量除了可以用逗号分隔,还可以用关键字or分隔,这点process就不行。例如:
always@(a or b) 等价于 always@(a, b);
但若写成process(a or b)将会报错。
除此以外,always描述组合逻辑时,为了简化书写,可以用通配符来代替整个敏感量表,例如上例还可写成
always(*);
这也是VHDL所不行的。
标准逻辑类型比较
VHDL中的std_logic类型,共有9个值,分别为
‘U’、‘X’、‘0’、‘1’、‘Z’、‘W’、‘L’、‘H’、’-’;
而Verilog中为四值逻辑,即
1、0、X、Z
对于FPGA来说,VHDL中的9值逻辑中 也只有’X’、‘0’、‘1’、'Z’是有意义的。因此这两种语言在逻辑值上是对等的。
至于std_logic中其他一些描述非FPGA的电路情况,例如电平强、若,Verilog中也有其定义的八种信号强度来对应,这八种强度由强到弱排列如下:
supply、strong 、pull、large、weak、medium、small、highz;
此时,若如果两个具有不同强度的信号驱动同一个线网,则竞争结果值为高强度信号的值;如果两个强度相同的信号之间发生竞争,则结果为不确定值。由于在FPGA中,我们并用不到这些描述,所以这里我们就不多做讨论。
在VHDL语言中,掌握好std_logic或者std_logic_vector类型的signal几乎就可以完成所有的程序设计;而对于Verilog语言,掌握好reg与wire两个类型的变量几乎就可以完成所有的程序设计。它们分别代表了两种语言中最主要的对应硬件连线或存储单元的逻辑数据类型。所不同的是,signal在硬件中具体是对应连线还是寄存器等存储单元是需要根据上下文来确定的;而Verilog中分的更细一些,即wire是肯定对应连线的,而reg到底是对应连线还是寄存器等存储单元是需要根据上下文来确定的。
逻辑常量赋值比较
VHDL中,逻辑常量不能以十进制表示,如果非要将一个十进制数赋给逻辑向量,必须调用类型转换函数,否则会报错。
而Verilog中,逻辑常量可以有专门的十进制表示法,并且也支持直接的整数赋值。当然了,这并不是我们推荐的做法。
命名规则比较
VHDL语法由于比较严谨,所以在标识符命名方面灵活性比较小;而Verilog相对来说就要灵活的多,可用的符号也多些,并且可以以下划线开头。
操作符号比较
VHDL与Verilog中的操作符号的功能集合基本相似,但是同样的符号在这两种语言中的意思有可能会大不相同,例如“&”符号在VHDL中是连接操作符,而在Verilog中确是逻辑与或者归约与操作符,所以在两种语言之间切换的时候需要特别注意。
功能相似归相似,但是两者的操作符集合之间确实有一些功能方面的差集,介绍如下:
一、VHDL中没有归约运算符号,所以无法方便的对一个逻辑向量进行归约运算程序书写,只能利用按位运算符号按位写出展开后的归约表达式,或者在process中利用循环语句简化代码。因此,相比之下Verilog的归约运算符号可以让代码编写者节省不少力气。
例如:a & b(a=1,b=1),出来结果为1;
归约是一元操作符,是将操作数的几个bit位当成1bit的操作数进行操作符所规定的运算,
例如:a=4’b1101,则 &a= 1&1&0&1 =0
二、关于赋值操作。Verilog中有阻塞赋值和非阻塞赋值的符号,比较方便有好的编程习惯的开发者去分别描述组合与时序逻辑。而VHDL中只能结合上下文来判断对signal的赋值是组合还是时序逻辑,如果是组合逻辑,则此时的赋值相当于是阻塞的;如果是时序逻辑,则此时的赋值相当于是非阻塞的。VHDL中对variable的赋值都相当于是阻塞的(因为它是立即生效的),不过由于variable没有确定的物理意义,所以我们一般不提倡大家使用。
三、连接符。VHDL中的连接符为“&”,只能实现普通的连接功能。相比之下,Verilog中的“{}”符号兼具连接与迭代功能,使用时要更加简便,更加灵活。
四、移位符
VHDL中支持6种移位操作,Verilog表面上支持4种实则支持3种,因此VHDL的移位操作符描述的功能更加完善一些。不过移位操作是可以被连接操作符完美替代的,而Verilog中的连接符要更加灵活一些,所以VHDL并没有因为支持的移位操作符号多一些而在这方面具有什么优势。
五、条件运算符 ?:
VHDL中并没有条件运算符的概念,不过VHDL中具有条件式和选择式赋值语句,功能是类似的。尤其选择式赋值语句是无优先级的,这点Verilog的条件运算符比不了。不过Verilog可以在always中用case来实现同样的功能,当然VHDL也可以在process中用case来实现无优先级的功能。
-
其实所谓“条件信号赋值语句”,不过是if语句与信号赋值语句的结合而已。一个并行的条件信号赋值语句是可以用一个进程来代替的:这个进程体是由if语句和信号赋值语句构成的。
-
而所谓“选择信号赋值语句”,则是case语句与信号赋值语句的结合。一个并行的选择信号赋值语句也可以用一个进程来代替:这个进程体是由case语句和信号赋值语句构成的。
注释比较
VHDL中只有单行注释,而Verilog中有单行与段落两种注释方法,因此Verilog在这方面要更加方便,更加灵活。
初始化比较
VHDL中,无论是端口、信号还是变量的初始化都是在声明的时候同时进行的,例如:
signal a : std_logic := ‘1’;
因此,当声明的信号等比较多时,初始化会显得十分凌乱与松散。相比之下,Verilog除了支持这种分布式的赋初值方式外,还可以使用了专门的initial程序块把所有寄存器变量集中起来进行集中式的初始化,这样代码显得更加整齐,并且也方便日后修改和维护。
例化与生成语句比较
VHDL与Verilog的例化语句功能几乎相同,不过Verilog还支持数组例化的方法,比较方便同时例化多个结构和连接关系相似的实例。
虽然VHDL不支持数组例化,但是VHDL中的生成语句可以完成类似的功能,同样Verilog也有自己的生成语句,功能完全与VHDL相同。从形式上来说Verilog的条件生成语句中包含generate-if与generate-case两种结构,而VHDL只支持if结构,不过由于该条件分支是用于编译时构建代码使用,所以不存在优先级结构的概念,因此Verilog中的两种条件生成结构没有本质区别。
循环语句对比
Verilog中的循环语句种类有4中,而VHDL中只有两种,不过这两者的循环语句中能够用于代码设计的主要也就是for循环语句。两者的for循环使用基本相同,一个细微的区别是VHDL的for循环中隐含的自定义了循环变量,而Verilog中需要预先显式定义好一个整型的变量作为循环语句的自变量。
子程序对比
VHDL中的子程序包括function和procedure,而Verilog中的子程序包括function和task。这两种语言中的function功能类似,procedure和task的功能也类似。不过相比之下,Verilog的语法略微更加灵活一些,例如可以描述递归功能。
自定义库与include
VHDL中允许用户通过自定义库的形式来创建一些可被多个文件所使用的公共资源,例如参数、数据类型、函数和过程。Verilog中虽然没有给用户开放库的编程方法,但是却提供了一条很有用的编译指令——include,通过该指令,也可以实现类似的构建公共资源的方法。不过相比之下,Verilog中不可以定义新的数据类型,这点不如VHDL方便。
语言比较
语言类型
VHDL是强类型语言,Verilog是弱类型语言。所以VHDL不同类型变量之间赋值一般需要强制类型转换函数,而Verilog把所有数据类型都看成按bit位组成的,所以可以轻松应对不同类型之间的赋值操作。
但是Verilog预定义好了所有的数据类型,用户无法创建自定义数据类型,这是因为Verilog的发明者希望为用户提供全面的支持;而VHDL则支持丰富的自定义数据类型以及一些高级的数据类型,例如枚举和记录,将更多的选择交给了用户,但是这样却不利于设计的重用。
Verilog语法比VHDL要灵活,更有利于编译器去做出优化,但是带来的负面影响就是可能会导致歧义,从而更易出错,相比之下VHDL的语法非常严谨,能够减少歧义的出现。
代码长度
由于VHDL其语法结构导致描述同样的逻辑功能,VHDL要比Verilog使用更多的代码,因此VHDL代码显得比较冗长,而Verilog要简洁许多。这其中最明显的对比就是它们的例化语句:Verilog可以直接实例化一个模块,而VHDL需要先声明,再例化。
描述侧重
Verilog更适合算法级、RTL、逻辑级、门级的描述;相比之下,VHDL更注重系统级的描述,更适合特大型的系统级设计。这也是为什么对于规模特别复杂的设计推荐使用VHDL。我想其中的原因之一应该就是因为VHDL中库的概念的确比Verilog中的include语法更成熟、更容易描述复杂的东西。
学习难度
Verilog的诞生汲取了很多C的语法,并且由于它是行业公司发明的,所以易用性是它的特点,一般来说,对于具有一定相关计算机软、硬件知识的读者,花上1~2个月应该就能学会Verilog。
VHDL是美国国防部发明的,所以从它诞生的目的就不是为了让人能够更容易的编写代码。并且由于其代码结构与众不同,语法也非常严谨,稍不谨慎就会出错,所以学习起来比较耗时,一般需要小半年工夫才能掌握。
市场占有
从市场占有范围上来说,目前主流的编译或仿真工具都会很好的支持这两种语言。但一般业界中Verilog的使用率比较高,而高校和科研机构中VHDL的占有率更胜一筹。
语言发展
相对来说,一般都认为VHDL比较陈腐,因为它的更新比较慢。相比之下,Verilog的更新速度就要快很多,并且变得越来越好用。
执行效率
Verilog语法的执行效率要比VHDL高效一些,这也是为什么编译工具最后生成的网表都是基于Verilog的,因为这样可以提高门级仿真的速度。