搜索
您的当前位置:首页正文

verilog语言的综合与不可综合

来源:六九路网
Verilog的综合与不可综合

综合说明编的代码可以对应出具体的电路,不可综合说明没有对应的电路结构。不可综合的代码编译通过,只能看到输出,不能实现电路,就是不能用来制作具体的芯片。

一、基本

Verilog中的变量有线网类型和寄存器类型。线网型变量综合成wire,而寄存器可能综合成WIRE,锁存器和触发器。

二:verilog语句结构到门级的映射 1、连续性赋值:assign

连续性赋值语句逻辑结构上就是将等式右边的驱动左边的结点。因些连续性赋值的目标结点总是综合成由组合逻辑驱动的结点。Assign语句中的延时综合时都将忽视。 2、过程性赋值:

过程性赋值只出现在always语句中。

阻塞赋值和非阻塞赋值就该赋值本身是没有区别的,只是对后面的语句有不同的影响。 建议设计组合逻辑电路时用阻塞赋值,设计时序电路时用非阻塞赋值。

过程性赋值的赋值对象有可能综合成wire,latch,和flip-flop,取决于具体状况。如,时钟控制下的非阻塞赋值综合成flip-flop。

过程性赋值语句中的任何延时在综合时都将忽略。 建议同一个变量单一地使用阻塞或者非阻塞赋值。

3、逻辑操作符:

逻辑操作符对应于硬件中已有的逻辑门

4、算术操作符:

Verilog中将reg视为无符号数,而integer视为有符号数。因此,进行有符号操作时使用integer,使用无符号操作时使用reg。

5、进位:

通常会将进行运算操作的结果比原操作数扩展一位,用来存放进位或者借位。如: Wire [3:0] A,B; Wire [4:0] C; Assign C=A+B;

C的最高位用来存放进位。

6、关系运算符:

关系运算符:<,>,<=,>=

和算术操作符一样,可以进行有符号和无符号运算,取决于数据类型是reg,net还是integer。

PDF 文件使用 \"pdfFactory Pro\" 试用版本创建 www.fineprint.com.cn

7、相等运算符:==,!=

注意:===和!==是不可综合的。

可以进行有符号或无符号操作,取决于数据类型

8、移位运算符:

左移,右移,右边操作数可以是常数或者是变量,二者综合出来的结果不同。

9、部分选择:

部分选择索引必须是常量。

10、BIT选择:

BIT选择中的索引可以用变量,这样将综合成多路(复用)器。

11、敏感表:

Always过程中,所有被读取的数据,即等号右边的变量都要应放在敏感表中,不然,综合时不能正确地映射到所用的门。

12、IF:

如果变量没有在IF语句的每个分支中进行赋值,将会产生latch。如果IF语句中产生了latch,则IF的条件中最好不要用到算术操作。Case语句类似。Case的条款可以是变量。 如果一个变量在同一个IF条件分支中先赎值然后读取,则不会产生latch。如果先读取,后赎值,则会产生latch。

13、循环:

只有for-loop语句是可以综合的。

14、设计时序电路时,建议变量在always语句中赋值,而在该always语句外使用,使综合时能准确地匹配。建议不要使用局部变量。

15、不能在多个always块中对同一个变量赎值

16、函数

函数代表一个组合逻辑,所有内部定义的变量都是临时的,这些变量综合后为wire。

17、任务:

任务可能是组合逻辑或者时序逻辑,取决于何种情况下调用任务。

18、Z:

Z会综合成一个三态门,必须在条件语句中赋值

19、参数化设计:

优点:参数可重载,不需要多次定义模块

PDF 文件使用 \"pdfFactory Pro\" 试用版本创建 www.fineprint.com.cn

四:模块优化 1、资源共享:

当进程涉及到共用ALU时,要考虑资源分配问题。可以共享的操作符主要有:关系操作符、加减乘除操作符。通常乘和加不共用ALU,乘除通常在其内部共用。

2、共用表达式: 如:C=A+B;

D=G+(A+B);

两者虽然有共用的A+B,但是有些综合工具不能识别.可以将第二句改为:D=G+C;这样只需两个加法器.

3、转移代码:

如循环语句中没有发生变化的语句移出循环.

4、避免latch:

两种方法:1、在每一个IF分支中对变量赋值。2、在每一个IF语句中都对变量赋初值。

5:模块:

综合生成的存储器如ROM或RAM不是一种好方法。最好用库自带的存储器模块。

五、验证: 1、敏感表:

在always语句中,如果敏感表不含时钟,最好将所有的被读取的信号都放在敏感表中。

2、异步复位:

建议不要在异步时对变量读取,即异步复位时,对信号赎以常数值。 欢迎进入超前MCU技术论坛对关于verilog综合-个人小结进行讨论!

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。

建立可综合模型的原则:要保证Verilog HDL赋值语句的可综合性,在建模时应注意以下要点:

1)不使用initial。 2)不使用#10。

3)不使用循环次数不确定的循环语句,如forever、while等。 4)不使用用户自定义原语(UDP元件)。 5)尽量使用同步方式设计电路。

PDF 文件使用 \"pdfFactory Pro\" 试用版本创建 www.fineprint.com.cn

6)除非是关键路径的设计,一般不采用调用门级元件来描述设计的方法,建议采用行为语句来完成设计。

7)用always过程块描述组合逻辑,应在敏感信号列表中列出所有的输入信号。

8)所有的内部寄存器都应该能够被复位,在使用FPGA实现设计时,应尽量使用器件的全局复位端作为系统总的复位。

9)对时序逻辑描述和建模,应尽量使用非阻塞赋值方式。对组合逻辑描述和建模,既可以用阻塞赋值,也可以用非阻塞赋值。但在同一个过程块中,最好不要同时用阻塞赋值和非阻塞赋值。

10)不能在一个以上的always过程块中对同一个变量赋值。而对同一个赋值对象不能既使用阻塞式赋值,又使用非阻塞式赋值。

11)如果不打算把变量推导成锁存器,那么必须在if语句或case语句的所有条件分支中都对变量明确地赋值。

12)避免混合使用上升沿和下降沿触发的触发器。

13)同一个变量的赋值不能受多个时钟控制,也不能受两种不同的时钟条件(或者不同的时钟沿)控制。

14)避免在case语句的分支项中使用x值或z值。

不可综合语句:

1)initial 只能在test bench中使用,不能综合。

2)events event在同步test bench时更有用,不能综合。 3)real 不支持real数据类型的综合。 4)time 不支持time数据类型的综合。

5)force 和release 不支持force和release的综合。

6)assign 和deassign 不支持对reg 数据类型的assign或deassign进行综合,支持对wire数据类型的assign或deassign进行综合。

7)fork join 不可综合,可以使用非块语句达到同样的效果。 8)primitives 支持门级原语的综合,不支持非门级原语的综合。 9)table 不支持UDP 和table的综合。

10)敏感列表里同时带有posedge和negedge

如:always @(posedge clk or negedge clk) begin...end 这个always块不可综合。

11)同一个reg变量被多个always块驱动

12)延时 以#开头的延时不可综合成硬件电路延时,综合工具会忽略所有延时代码,但不会报错。如:a=#10 b;这里的#10是用于仿真时的延时,在综合的时候综合工具会忽略它。也就是说,在综合的时候上式等同于a=b; 13)与X、Z的比较

可能会有人喜欢在条件表达式中把数据和X(或Z)进行比较,殊不知这是不可综合的,综合工具同样会忽略。所以要确保信号只有两个状态:0或1。

PDF 文件使用 \"pdfFactory Pro\" 试用版本创建 www.fineprint.com.cn

来自:人人网日志

可综合指那些可以综合成FPGA(ASIC)中某种结构的语言要素。而不可综合则主要用于设计的验证、仿真。比如流行的quartusII或xinlinx软件只支持可综合的verilog语言。

因为Verilog是一种硬件描述语言,所以在写Verilog语言时,首先要有所要写的module在硬件上如何实现的概念,而不是去想编译器如何去解释这个module. 比如在决定是否使用reg定义时,要问问自己物理上是不是真正存在这个register, 如果是,它的clock是什么? D端是什么?Q端是什么?有没有清零和置位?同步还是异步?再比如上面讨论的三态输出问题,首先想到的应该是在register的输出后面加一个三态门,而不是如何才能让编译器知道要“赋值”给一个信号为三态。同样,Verilog中没有“编译”的概念,而只有综合的概念。

写硬件描述语言的目的是为了综合,所以说要想写的好就要对综合器有很深的了解,这样写出来的代码才有效率。

曾经接触过motorola苏州设计中心的一位资深工程师,他忠告了一句:就是用verilog描述电路的时候,一定要清楚它实现的电路,很多人只顾学习verilog语言,而不熟悉它实现的电路,这是设计不出好的电路来的

一般写verilog code时,对整个硬件的结构应该是很清楚了,最好有详细的电路图画出,时序问题等都应该考虑清楚了。可以看着图直接写code。

要知道,最初Verilog是为了实现仿真而发明的.不可综合的Verilog语句也是很重要的.因为在实际设计电路时,除了要实现一个可综合的module外,你还要知道它的外围电路是怎样的,以及我的这个电路与这些外围电路能否协调工作.这些外围电路就可以用不可综合的语句来实现而不必管它是如何实现的.因为它们可能已经实际存在了,我仅是用它来模拟的.

所以,在写verilog的时候应该要先明确我是用它来仿真的还是综合的.要是用来综合的话,就必须要严格地使用可综合的语句,而且不同的写法可能产生的电路会有很大差别,这时就要懂一些verilog综合方法的知识.就像前面说的,脑子里要有一个硬件的概念.特别是当综合报错时,就要想一想我这种写法能不能用硬件来实现,verilog毕竟还不是C,很多写法是不可实现的.要是这个module仅是用来仿真的,就要灵活得多了,这时你大可不必太在意硬件实现.只要满足它的语法,实现你要的功能就行了.

有网友说关于#10 clk=~clk的问题,虽然这种语句是不可综合的,但是在做simulation和verification是常常用它在testbench中来产生一个clock信号。再比如常常用到的大容量memory, 一般是不会在片上实现的,这个时候也需要一个unsynthesizable module. mengxy所言切中肯罄。

我们设计的module的目的是为了可以综合出功能正确,符合标准的电路来。我想这是个反复的过程,就像我们在写design flow中总要注明前仿真,综合后的仿真,以及后仿真等。仿真是用来验证我们的设计的非常重要的手段。而verilog里那些看是无聊的语句这个时候就会发挥很大的作用。

我想,用过verilog_xl的兄弟应该深有体会。verilog_xl里的操作,可以用verilog里的系统命令来完成。通过最近的应聘我也深有体会,很多公司看中你在写code时,是否考虑到timing,architecture,DFT等,这也说明verilog中的任何语句都是非常重要的。 要写代码前必须对具体的硬件有一个比较清晰的概念。但是想一次完成可综合代码就太夸张了,verilog的自顶向下设计方法就是从行为建模开始的,功能验证了以后再转向可综

PDF 文件使用 \"pdfFactory Pro\" 试用版本创建 3 www.fineprint.com.cnÿ

合模型.太在意与可综合令初期设计变得太累

很同意这种看法,在做逻辑结构设计时,综合的因素是要考虑的,但是有很多东西不能考虑的过于细致,就是在设计的时候不能过于紧卡时延,面积等因素,因为这样以来综合后优化的余量就会很小,反而不利与设计的优化,如果在时延和面积要求不是很紧张的情况下,其实代码写的行为级,利用综合工具进行优化也是一种方法。偶就听说有一家很有名的公司,非常相信综合工具的优化能力,从来不作综合后仿真的.当然,如果面积和时延的要求很高,最好还是把代码写的底层一点,调用库单元时,也要充分考虑其面积和时延的因素

PDF 文件使用 \"pdfFactory Pro\" 试用版本创建 ÿ www.fineprint.com.cn

因篇幅问题不能全部显示,请点此查看更多更全内容

Top