[转]从Verilog到VHDL:基本语法
从学校里开始,我所接触的就一直是VerilogHDL而非更老牌的VHDL,而且后续接触的项目中也多半是Verilog的用户,坦白的讲,Verilog的活力也确实更足一些,从IEEE1800-2005开始的SystemVerilog的标准化,将Verification和Design的一体化的尝试,我个人认为,是走在正确的道路上。
所以,我确实想不到,我竟然也要回头学起VHDL来了,毕竟一些老牌公司,特别是欧洲的公司,往往因为历史原因,仍然在使用VHDL,看来终究是绕不过去的了——正如一个Design Verification工程师在目前想完全的不和SpecmanE打交道是很难的一样。
下面记载的是两种语言学习过程中的一些体会,而且更多的是从语法角度出发,算是梳理一下思路吧,而且,以前从来没有接触过VHDL,当然会存在很多非常初级的东西。
而在本文之后,打算再写一篇简单阐述下结合Cadence的IUS工具,使用SystemVerilog对VHDL进行验证的基本方法。
起手式
从Verilog撞进VHDL的世界,有些东西要先搞清楚,否则会一头雾水:
1. 大小写敏感: Verilog是大小写敏感的,VHDL则非;
2. 注释:Verilog的行注释为//,块注释为/**/;VHDL只支持行注释–;[1. 这个算是不方便的一个地方了,不过不论是在Vim还是Emacs当中,批量做行注释也很容易实现;]
基本结构
VHDL被认为是要求更严格,更多讲究的语言,相比和C类似的Verilog,架构上更严谨一些:
1. 基本结构:从上往下为
USE定义区(调用库和包);
Package定义区(自定义程序包);
Entity定义区(定义电路实体外观,I/O接口的规格);[2. Entity感觉像是C的头文件定义之类的东西,而在Verilog当中,这些其实都是被整合在Module里头一起完成了。]
Architecture定义区(描述内部功能);[3. 同上,相当于Verilog的Module内部实现。]
Configuration定义区(决定那个Architecture被使用)[4. 这也许就是之所以要分开Arch和Entity的原因,类似的效果在Verilog里实现,则需要使用那个configuration blocks/library map files这些在Verilog 2001当中增加的features,不过这些部分在Verilog当中属于Beyond language,更多的是位于语言之上的scope中了。]
2. 并行与串行:
在这一点上,VHDL和Verilog有些类似,书写在Architecture内的语句,直接被认为是并行执行,无论书写顺序的(就如同Verilog中的并列的Always语句块);而顺序执行的串行语句必须放置在进程语句(process)当中,正如Verilog的begin…end。
3. process:
和Verilog不同的是这里的Process是要求有敏感变量列表作为输入的,正如试图在Verilog中用Always语句实现组合逻辑时类似。所以当写这样的语句,不妨多回想Verilog中对于敏感变量列表的要求。
4. 例化:
在VHDL当中尝试例化一个entity,比起Verilog要麻烦不少。首先,必须在Architecture当中用Component语法来声明这个实体的Port和Generic(参数);然后才可在后续内容当中例化实体,并且用generic map和port map来进行参数赋值和port连接。
5. 库,包和配置:
VHDL这方面的组织比起Verilog显然要严密多了,使用configuration,用简单的语句,就可以把不同的architecture实现和entity实现绑定,而此时我们就能看出VHDL之所以要分开所谓entity和architecture的目的所在了。
CONFIGURATION 配置名 OF 实体名 IS
FOR 为实体选配的构造体名
END FOR;
END 配置名;
而事实上,configuration还可以直接指定某个Hierachy的某个实体究竟适用那种entity来例化,语法如下(参见VHDL Configuration):
configuration TopMixed of Top is —TopMixed是配置名,Top是实体名
for Structure —Structure是结构体名,是和实体Top相对应的结构体
for B1: Blk —B1和B2是结构体structure中的元件例化语句的标号
use entity Work.Blk(RTL);— 此语句说明,在元件例化的时候,利用用户自定义
—的实体blk来例化,其结构体是RTL
end for;
for B2: Blk
use entity Work.GateLevelBlk(Synth)— 此语句说明,元件例化B2时,利用实体
—GateLevelBLK对应的Synth构造体来例化
port map (IP => To_Vector(A),
To_Int8(OP) => F);
end for;
end for;
end TopMixed;
只不过这似乎太麻烦了一点。而Library和Package更好理解一些。用户可以将一些公共的定义统一靠Package和Package Body的关键字来定义到一个包里面去,而这些包又可以被编译在Library当中。不过Library的建立似乎只依赖于工具的解决,例如在编译的时候选择将包内容编译到某个库之中,然后再使用。
使用的过程,则是利用Library,Use等关键字来import这些内容。而要提醒的是,当前编译代码都是被认为是缺省的编入到了work库当中,所以如果需要引用代码中定义的某个包内容,应该用 work.
操作
1. 强类型语言:
VHDL是强类型语言,对类型要求非常严,一个对象只能有一种数据类型,而且不同类型数据间赋值是严格禁止的,这点Verilog用户应当注意。
2. Procedure和Function:
很好理解,直接对应Verilog的Task和Function,需要注意的就是在VHDL中还可以对Function进行重载,这个,也许有用吧。
3. 属性:
VHDL针对不同的对象,都具有不同的属性,这些属性不妨理解成Verilog当中的Predefined tasks or methods,但是似乎更加的丰富和多样,相信能够有效的减少代码量。
小结
本文目的不在于语法的教程或者指导(本来我也刚看VHDL不过一个下午而已……),更希望能够迅速、扼要的抽出VHDL和Verilog的一些区别和共性,加速学习的过程。不过,我相信,一个熟悉Verilog的工程师,在吃透了上面这些不同点后,至少可以跌跌撞撞的开始写VHDL代码了,更多的东西,自然需要在实践中去体会和学习。
接下来,我的计划是结合Cadence的IUS工具,写一写最基本的SystemVerilog对于VHDL的验证的QuickStart了。[5. 从目前了解的来看,VHDL对于验证方面的支持还真是有限,比起Verilog都有所不及,在最基本的打印,仿真控制上都要麻烦一些,所以,这种情况下,干脆一律交给SystemVerilog/Vera/E/去做,可能还更直接一些]