集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 3109|回复: 3

[转载] 谈VHDL/Verilog的可综合性以及对初学者的一些建议

[复制链接]
老怪甲 该用户已被删除
老怪甲 发表于 2010-4-13 11:27:36 | 显示全部楼层 |阅读模式
本帖最后由 fpgaw 于 2010-10-29 09:42 编辑

一、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的语句综合成除法模块 。)
又比如,一个很多初学者常见的问题是试图让HDL进行循环运算,形同(Verilog):
for (i=0; iparity = parity xor data;
一些功能比较简单的综合软件会完全拒绝综合循环语句;而一些功能较强的软件仅当wordlength是常数的时候能综合;当wordlength为变量 时,任何软件都不能综合上面的语句。这是因为硬件规模必须是有限的、固定的。当综合软件遇到循环语句时,总是将其展开成若干条顺序执行的语句,然后再综合 成电路。若wordlength是常数,则展开的语句数是确定的,具有可综合性;而若它是变量时,展开的语句数不确定,对应的硬件电路数量也不能确定,无 法被综合。或许有人说用计数器就能实现变量循环,但这情形又和上面的除法运算相同。那需要额外的硬件,用来存储中间结果和进行时序控制,象上面那样的循环 语句对此描述得太抽象,软件接受不了。
四、如何判断自己写的代码是可综合的?
用一句简单的话概括:电脑永远没有你聪明。具体来说,通常EDA软件对HDL代码的综合能力总是比人差。对于一段代码,如果你不能想象出一个较直观的硬件 实现方法,那EDA软件肯定也不行。比如说,加法器、多路选择器是大家都很熟悉的电路,所以类似A B-C,(A>B)?C 这 样的运算一定可以综合。而除法、开根、对数等等较复杂的运算,必须通过一定的算法实现,没有直观简单的实现方法,则可以判断那些计算式是不能综合的,必须 按它们的算法写出更具体的代码才能实现。此外,硬件无法支持的行为描述,当然也不能被综合(比如想在FPGA上实现DDR内存那样的双延触发逻辑,代码很 容易写,但却不能实现)。
不过,这样的判断标准非常主观模糊,遇到具体情况还得按设计人员自己的经验来判断。如果要一个相对客观的标准,一般来说:在RTL级的描述中,所有逻辑运 算和加减法运算、以及他们的有限次组合,基本上是可综合的,否则就有无法综合的可能性。当然,这样的标准仍然有缺 陷,更况且EDA的技术也在不断发展,过 去无法综合的代码或许将来行,某些软件不支持的代码换个软件或许行。比如固定次数的循环,含一个常数参数的乘法运算等等,有些EDA软件支持对它们的综 合,而有些软件不行。
所以,正确的判断仍然要靠实践来积累经验。当你可以较准确判断代码的可综合性的时候,你对HDL的掌握就算完全入门 了。
作者:董培良
电机和电子工程 系博士生
英国University of Nottingham
风云道 发表于 2010-4-19 23:54:03 | 显示全部楼层
对整体了解HDL语言有帮助,但希望楼主可以具体的说一下什么可以综合,什么不可以!!
TCL 发表于 2010-4-20 10:50:33 | 显示全部楼层
回复 2# 风云道


    要保证Verilog HDL赋值语句的可综合性,在建模时应注意以下要点:
(1)不使用initial。
    (2)不使用#10。
    (3)不使用循环次数不确定的循环语句,如forever、while等。
    (4)不使用用户自定义原语(UDP元件)。
    (5)尽量使用同步方式设计电路。
    (6)除非是关键路径的设计,一般不采用调用门级元件来描述设计的方法,建议采用行为语句来完成设计。
    (7)用always过程块描述组合逻辑,应在敏感信号列表中列出所有的输入信号。
    (8)所有的内部寄存器都应该能够被复位,在使用FPGA实现设计时,应尽量使用器件的全局复位端作为系统总的复位。
    (9)对时序逻辑描述和建模,应尽量使用非阻塞赋值方式。对组合逻辑描述和建模,既可以用阻塞赋值,也可以用非阻塞赋值。但在同一个过程块中,最好不要同时用阻塞赋值和非阻塞赋值。
    (10)不能在一个以上的always过程块中对同一个变量赋值。而对同一个赋值对象不能既使用阻塞式赋值,又使用非阻塞式赋值。
    (11)如果不打算把变量推导成锁存器,那么必须在if语句或case语句的所有条件分支中都对变量明确地赋值。
    (12)避免混合使用上升沿和下降沿触发的触发器。
    (13)同一个变量的赋值不能受多个时钟控制,也不能受两种不同的时钟条件(或者不同的时钟沿)控制。
    (14)避免在case语句的分支项中使用x值或z值。
(1)所有综合工具都支持的结构:always,assign,begin,end,case,wire,tri,aupply0,supply1,reg,integer,default,for,function,and,nand,or,nor,xor,xnor,buf,not,bufif0,bufif1,notif0,notif1,if,inout,input,instantitation,module,negedge,posedge,operators,output,parameter。
    (2)所有综合工具都不支持的结构:time,defparam,$finish,fork,join,initial,delays,UDP,wait。
    (3)有些工具支持有些工具不支持的结构:casex,casez,wand,triand,wor,trior,real,disable,forever,arrays,memories,repeat,task,while。
通常需要综合成硬件实现时,写成可综合的风格,写验证时候,可以随便一些..当然了,要确切的弄明白,还是要多实践啊!!
Sunlife 发表于 2015-4-8 14:27:21 | 显示全部楼层
只有RTL或更低层次的行为描述才能保证是可综合的。而众多初学 者试图做的,却是想让软件去综合算法 级或者更加抽象的硬件行为描述。
比如说,要想实现两个变量相除的运算,若在代码中写下C=A/B,你将会发现只有一些模拟 软件在前仿真中能正确执行这句代码,但几乎任何软件都不能将其综合成硬件。不要怪软件太笨。试想一下,如果我们自己笔算除法是怎么做的?从高位到低位逐次试除、求余、移位。试除和求余需要减法器,商数和余数的中间结果必须有寄存器存储
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2024-11-16 09:52 , Processed in 0.074185 second(s), 24 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表