HDL可综合&不可综合

verilog HDL和VHDL相比有很多优点,有C语言基础的话很容易上手。搜集了一些网上大神的经验总结和书上的例子,所以对于和我一样的初学者,这篇博客应该还是很有提高作用的,至于具体语法,任何一本书都讲的很详细。

0. HDL历史

HDL 是 Hardware Description Language 的缩写,中文名“硬件描述语言”,并不是“硬件设计语言(HardwareDescription Language)”。正是这个单词,决定了绝大多数部分电路设计必须遵循RTL的模式来编写代码,而不能随心所欲的写仅仅符合语法的HDL代码。

VHDL 于1980年开始在美国国防部的指导下开发,完成于1983年,并于1987年成为IEEE 的标准。Verilog HDL也形成于差不多的年代,是由Gateway Design Automation 公司大约在1983年左右开发的。其架构同VHDL 相似,但主要被用来进行硬件仿真。探究HDL语言的历史,就能明白这两种最流行的用于电路设计的语言,没有一种是为了设计硬件而开发的(更何况80年代还没有现在的那些功能强大的EDA软件呢)。因此,当初制订 HDL语言标准的时候,并没有考虑这些代码如何用硬件来实现。换句话说,有些代码写起来简单,实现起来却可能非常复杂,或者几乎不可能实现。

1. 可综合

1. 所有综合工具都支持的结构

[plain] view plaincopy在CODE上查看代码片派生到我的代码片

  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  

有些工具支持,有些工具不支持:casex,casez,wand,triand,wor,trior,real,disable,forever,arrays,memories,repreat,task,while

2. 建立可综合模块的原则

  1. 不要用initial(FPGA上电时初始状态不定,一般需要上电复位信号,在复位信号有效的时候进行初始化,上电复位信号可以由外部手动输入,也可以系统自己产生,转一篇博客,P.S.现在的综合软件功能已经足够强大,即使写了initial语句,在ISE13.3中仍然是可综合的,而且没有warning和info的提示)
  2. 不使用#10(在仿真中有用,实际在硬件上不会实现)
  3. 不使用循环次数不定的循环语句,如forever、while等
  4. 不使用用户自定义原语(UDP原件)
  5. 除非是关键路径设计,一般不采用调用门级原件描述的设计的方法,建议采用行为语句完成设计
  6. 尽量使用同步方式设计电路
  7. 用always语句描述组合逻辑时,在敏感信号列表中要列出所有输入信号
  8. 所有的内部寄存器都应该可以被复位,在FPGA设计时应尽量使用器件的全局复位端信号作为系统的总复位
  9. 时序逻辑使用非阻塞赋值,组合逻辑使用阻塞赋值,同一过程块中不要同时使用阻塞和非阻塞两种方式
  10. 不要在不同的always过程块中对同一变量赋值(否则综合时会提示有多驱动源错误,multiple source),对同一赋值对象,不能既使用阻塞赋值,又使用非阻塞赋值
  11. 如果不打算把变量综合成锁存器,在if语句或case语句的所有分支中都要对变量明确赋值(不能省去else或default,原理:在省去的情况下,变量的值会保持原来的值不变,所以系统会综合出一个锁存器)
  12. 避免混合使用上升沿和下降沿触发器
  13. 同一变量的赋值不能受多个时钟控制,也不能受两种不同时钟条件(或不同时钟沿)控制
  14. 避免在case语句中使用x或z值

2. 不可综合

1. 所有综合工具都支持的结构

[plain] view plaincopy在CODE上查看代码片派生到我的代码片

  1. time,defparam,$finish,fork,join,initial,delays,UDP,wait  

2. 不可综合语句

  1. initial 只能在Testbench中使用,不能综合
  2. events 在Testbench中更有用,不能综合
  3. real 不支持real类型的综合
  4. time 不支持time类型的综合
  5. force 和release
  6. assign 和 deassign 不支持对reg类型的数据进行assign和deassign综合,支持对wire类型进行assign和deassign的综合
  7. fork join 不可综合,可以用非块语句达到同样的效果
  8. primitives 支持门级原语综合,不支持非门级原语综合
  9. table 不支持table和UDP的综合
  10. 敏感符列表中同时有posedge和negedge,如always @ ( posedge clk or negedge clk ) begin ...end
  11. 同一个reg被多个always块驱动
  12. 延时,不可综合为硬件电路延时,综合工具会忽略延时,但是不会报错
  13. 与x、z比较,综合工具会忽略,所以要保证信号只有两个状态,0或1

3. 判断是否可综合

用一句简单的话概括:电脑永远没有你聪明。具体来说,通常EDA软件对HDL代码的综合能力总是比人差。对于一段代码,如果你不能想象出一个较直观的硬件实现方法,那 EDA软件肯定也不行。一般来说:在 RTL 级的描述中,所有逻辑运算和加减法运算、以及他们的有限次组合,基本上是可综合的,否则就有无法综合的可能性。当然,这样的标准仍然有缺陷,更况且EDA的技术也在不断发展,过去无法综合的代码或许将来行,某些软件不支持的代码换个软件或许行。比如固定次数的循环,含一个常数参数的乘法运算等等,有些EDA软件支持对它们的综合,而有些软件不行。

所以,正确的判断仍然要靠实践来积累经验。当你可以较准确判断代码的可综合性的时候,你对HDL的掌握就算完全入门

猜你喜欢

转载自blog.csdn.net/linuxheik/article/details/88368011