⼀、verilog语法,可否综合总体有以下区分:
(1)所有综合⼯具都⽀持的结构:
always,assign,begin,end,case,wire,tri,supply0,supply1,reg,integer,default,for,function,and,nand,or,nor,xor,xnor,buf,not,bufif0,bufif1,notif0,notif1,if,inout,inpu 可综合的运算符包括:> , < , >= , <= , == , != , >>, << (位移量为变量,则会综合出通⽤位移器), &, |, ^ , +, - ,*, /(某些综合⼯具可能不⽀持) {[ ],[ ]} :部分选取和位选取操作,这个有点复杂。
部分选取仅⽀持常量部分选取。如:
1 module PartSelect( 2 in_a, 3 in_b , 4 out_c); 5
6 input [3:0] in_a, in_b; 7 output [3:0] out_c; 8
9 assign out_c[2:0] = {in_a[2],in_b[3:2]};10
11 endmodule
12 // out_c[2:0] 和 in_b[3:2]即为部分选取
位选取⽀持常量和⾮常量选取,⾮常量选取时会⽣成多路选择器或译码器。如:
1 //常量位选取
2 module ConstantBitSelect( 3 in_a, 4 in_b, 5 in_c, 6 out_d 7 ); 8
9 input [3:0] in_a,in_b,in_c;10 output [3:0] out_d;11
12 assign out_d[2:0] = {in_a[2],in_b[1:0]};13 assign out_d[3] = in_c[2];14 endmodule
15 //这⾥in_a[2],out_d[3] , in_c[2]都是位选取。
1 module NotConstantBitSelectRight( 2 Data, 3 Index, 4 Dout 5 );
6 input [0:3] Data; 7 input [1:2] Index; 8 output Dout; 9
10 assign Dout=Data[Index]; //选取Data其中⼀位赋值给Dout11 endmodule
12 //综合的⽹表如下图。这⾥的⾮常量下标位选取产⽣了多路选择器。
1 module NotConstantBitSelectLeft( 2 Mem, 3 Store, 4 Addr 5 );
6 output[7:0] Mem; 7 input Store; 8 input [1:3]Addr; 9
10 assign Mem[Addr]=Store; //将Mem其中某⼀位修改为Store11 endmodule
12 //综合⽹表如下图,这⾥⾮常量下标的位选择⽣成了译码器
(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)尽量使⽤同步⽅式设计电路。
(6)除⾮是关键路径的设计,⼀般不采⽤调⽤门级元件来描述设计的⽅法,建议采⽤⾏为语句来完成设计。 (7)⽤always过程块描述组合逻辑,应在敏感信号列表中列出所有的输⼊信号。
(8)所有的内部寄存器都应该能够被复位,在使⽤FPGA实现设计时,应尽量使⽤器件的全局复位端作为系统总的复位。
(9)对时序逻辑描述和建模,应尽量使⽤⾮阻塞赋值⽅式。对组合逻辑描述和建模,既可以⽤阻塞赋值,也可以⽤⾮阻塞赋值。但在同⼀个过程块中,最好不要同时⽤阻塞赋值和⾮阻塞赋值。
(10)不能在⼀个以上的always过程块中对同⼀个变量赋值。⽽对同⼀个赋值对象不能既使⽤阻塞式赋值,⼜使⽤⾮阻塞式赋值。 (11)如果不打算把变量推导成锁存器,那么必须在if语句或case语句的所有条件分⽀中都对变量明确地赋值。 (12)避免混合使⽤上升沿和下降沿触发的触发器。
(13)同⼀个变量的赋值不能受多个时钟控制,也不能受两种不同的时钟条件(或者不同的时钟沿)控制。 (14)避免在case语句的分⽀项中使⽤x值或z值。三、 不能综合的语句: (1)initial
只能在test bench中使⽤,不能综合。(我⽤ISE9.1综合时,有的简单的initial也可以综合,不知道为什么) (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。
因篇幅问题不能全部显示,请点此查看更多更全内容