谈 VHDL/Verilog 的可综合性以及对初学者的一些建议
一、HDL 不是硬件设计语言
过去笔者曾碰到过不少 VHDL 或 Verilog HDL 的初学者问一些相似的问题,诸如如何实现除法、开根号,
如何写循环语句等等。在这个论坛上,也时常能看到一些网友提出这一类的问题。
对于这些问题,首先要明确的是 VHDL 和 Veriglog 并非是针对硬件设计而开发的语言,只不过目前被我们
用来设计硬件。HDL 是 Hardware Description Language 的缩写,正式中文名称是“硬件描述语言”。也就
是说,HDL 并不是“硬件设计语言(Hardware Design Language)”。别看只差这一个单词,正是这一个单词
才决定了绝大部分电路设计必须遵循 RTL 的模式来编写代码,而不能随心所欲得写仅仅符合语法的 HDL
代码。
二、HDL 的来历
之所以是“硬件描述语言”,要从 HDL 的来历说起。
VHDL 于 1980 年开始在美国国防部的指导下开发,完成于 1983 年,并于 1987 年成为 IEEE 的标准。当
初开发这种语言,是出于美国国防部采购电子设备的需要。美军的装备采购自私人企业,时常要面对这样
一种风险:如果某种武器大量装备部队,而其中某个零件的供应商却在几年后倒闭了,那这种武器的再生
产、维修和保养都会出现大问题。而电子设备、尤其是集成电路的内部结构较为复杂,若出现前面所说的
情况要找其他公司生产代用品非常困难。于是美国防部希望供应商能以某种形式留下其产品的信息,以保
证一旦其破产后能由其他厂商迅速生产出代用品。
显然,当初的设计文档显然是不能交出来的,这在美国会涉及商业机密和知识产权问题。于是美国防部就
想出了一种折衷的方法——描述硬件的语言,也就是 VHDL。通过 VHDL,供应商要把自己生产的集成电
路芯片的行为描述出来:比如说,加了什么样的信号后过多少时间它能输出什么等等。这样,如果有必要
让其他厂商生产代用品,他们只需照着 VHDL 文档,设计出行为与其相同的芯片即可。这样的代用品相当
于是新厂商在不了解原产品结构的情况下独立设计的,所以不太会涉及知识侵权。
Verilog HDL 也形成于差不多的年代,是由 Gateway Design Automation 公司大约在 1983 年左右开发的。
其架构同 VHDL 相似,但主要被用来进行硬件仿真。或许私人公司更注重实用,Verilog 要比 VHDL 简洁
得多。
由此可见,这两种最流行的用于电路设计的语言,没有一种是为了设计硬件而开发的(更何况 80 年代还没
有现在的那些功能强大的
EDA 软件呢)。因此,当初制订 HDL 语言标准的时候,并没有考虑这些代码如何
用硬件来实现。换句话说,有些代码写起来简单,实现起来却可能非常复杂,或者几乎不可能实现。
三、HDL 代码的可综合性
现在回到最初的问题上。为什么诸如除法、循环之类的 HDL 代码总是会出错?
由上一部分可知,任何符合 HDL 语法标准的代码都是对硬件行为的一种描述,但不一定是可直接对应成电
路的设计信息。行为描述可以基于不同的层次,如系统级,算法级,寄存器传输级(RTL)、门级等等。以目
前大部分 EDA 软件的综合能力来说,只有 RTL 或更低层次的行为描述才能保证是可综合的。而众多初学
者试图做的,却是想让软件去综合算法级或者更加抽象的硬件行为描述。
比如说,要想实现两个变量相除的运算,若在代码中写下 C=A/B,你将会发现只有一些模拟软件在前仿真
中能正确执行这句代码,但几乎任何软件都不能将其综合成硬件。不要怪软件太笨。试想一下,如果我们
自己笔算除法是怎么做的?从高位到低位逐次试除、求余、移位。试除和求余需要减法器,商数和余数的
中间结果必须有寄存器存储;而此运算显然不能在一个时钟周期里完成,还需要一个状态机来控制时序。
一句简单的 C=A/B 同所有这些相比显得太抽象,对于只能接受 RTL 或更低层次描述的 EDA 软件来说确实
太难实现。而如果代码是类似于(Verilog)
always @(posedge clk)
c<=A/B; 这样的,要求除法在一个时钟延上完成,那更是不可能实现的。(注:有些 FPGA 的配套软件提供
乘除法的运算模块,但也只能支持直接调用,不支持把形如 C=A/B 的语句综合成除法模块。)