综合:不可综合的运算符:= = = ,!= =,/(除法),%(取余数)。 Verilog HDL 语句及可综合性: 类别 语句 过程语句 块语句 赋值语句 条件语句 initial begin 串行块 begin - end 并行块 fork-join 持续赋值assign 过程赋值 =、<= if – else case , casez , casex for 循环语句 repeat while forever `define 编译向导语句 `include `ifdef, `else , `endif 可综合性 否 是 是 否 是 是 是 是 是 否 否 否 是 是 是 可综合设计的特点: 1、不使用初始化语句。
2、不使用带有延时的描述。
3、不使用循环次数不确定的循环语句,如:forever、while等。 4、尽量采用同步方式设计电路。
5、除非是关键路径的设计,一般不调用门级元件来描述设计的方法,建议采用行为语句来完成设计。
6、用always过程块描述组合逻辑,应在信号敏感列表中列出所有的输入信号。
7、所有的内部寄存器都应该能够被复位,在使用FPGA实现设计时,应尽量使用器件的全局复位端作为系统总的复位。
8、在verilog模块中,任务(task)通常被综合成组合逻辑的形式,每个函数(function)在调用时通常也被综合为一个独立的组合电路模块。
9、用户自定义原语(UDP)是不可综合的,它只能用来建立门级元件的仿真模型。
一般综合工具支持的Verilog HDL结构
Verilog HDL 结构 可综合性说明 module mocromodule 是 wire reg integer 数据类型 是 parameter 是 端口类型 是 input output inout 运算符 大部分可以综合 +、-、*、% 全等运算符(= = = != =)不支持 & 、~& 、| 、~| 、^ 、^~ 多数工具对除法(/)和求模(%)有限制 = = != && || | 如对除法操作,只有除数是常数,且是2的~ & | ^ ^~ 指数时才支持 >> << ?: { } 基本元件 全部可综合: and nand nor or xor xnor buf not bufif1 bufif0 但某些工具对取值为x和z有所限制 notif1 notif0 pullup pulldown 持续赋值assign 是
1
过程赋值:阻塞赋值(=) 非阻塞赋值(<=) 条件语句 if- else case casez casex endcase for循环语句 always过程语句 begin-end 块语句 function endfunction task endtask 编译向导:`include `define `ifdef `else `endif
支持,但对同一reg型变量只能采用阻塞和非阻塞赋值中的一种进行赋值 一般支持,有的综合器不支持casex casez 是 是 是 一般支持,少数综合器不支持 是 一般综合工具忽略的Verilog HDL 结构 Veriolg HDL 结构 可综合性说明 延时控制 scalared vectored 这些结构和语句在综合时全被忽略 specify small large medium weak1 weak0 highz0 highz1 pull0 pull1 time 有些综合工具将其视为整数(integer) wait 有些综合工具有限制地支持
一般综合工具不支持的Verilog HDL 结构 Verilog HDL结构 可综合性说明 在assign持续赋值中,等式左边含有变量的位选择 全等运算符(= = =、!= =) cmos nmos rcmos rnmos pmos rpmos 多数综合器对这些结构和语句不支持,deassign defparam event 用这些语句描述的程序代码不能转化force release 为具体的电路网表结构,但这些结构能fork join forever repeat while 够被仿真工具所支持。 initial rtran tran tranif0 tranif1 rtranif0 rtranif1 table endtable primitive endprimitive 移位运算符:Verilog HDL提供向右(>>)及向左(<<)两种运算符,运算符高位或地位一旦移出即予丢弃,其空缺的位则予以补零。 连续赋值语句(assign)、case语句、if…else语句都是可以综合的
initial 语句内若包含有多个语句时,必须以begin end 作聚合;单一的初值赋值,因此并不需以begin end做聚合。
循环(Loops) 并不能单独地在程序中存在,而必须在initial和always块中才能使用。 initial过程块中的语句仅执行一次,而always块中的语句是不断重复执行的。 编写顶层模块的注意事项
每个端口除了要声明是输入 、输出还是双向外,还要声明其数据类型,是连线型(wire)还是寄存器型(reg),如果没有声明则综合器默认为wire型。 1、 输入和双向端口不能声明为寄存器型。 2、 在测试模块中不需要定义端口。
编写testbentch所归纳的心得
2
module 模块名称; 将input 定义为 reg; 将output定义为 wire; 引用欲测试的module 别名 initial begin 设定reg 初始值 end
always处理变化值 endmodule
在always 、initial 过程块内,被赋值的每一个信号都必须定义成寄存器型。
net型和reg型的变量可以声明为(signed)变量;操作数可以从无符号数转换为有符号数。 例如: wire signed[3:0] a; reg signed[7:0] out;
系统函数$signed 和$usigned,以实现无符号数转化为有符号数,或者有符号数转化为无符号数。
例如:c=$signed(s); 算术移位操作符:‘>>>’, ‘<<<’,对于有符号数,执行算术移位操作的时,将符号填补移出的位。例如:定义有符号数:8’b10100011,则执行逻辑移位操作和算术移位操作后的值分别如下:
A>>3; //逻辑右移后其值为:8’b00010100 A>>>3; //算术右移后其值为 8’b11110100
阻塞赋值(=)和非阻塞赋值(<=)的应用注意事项:
1、 非阻塞赋值不能用于“assign”持续赋值中,一般只出现在“initial”和“always”等过
程块中,对reg型变量进行赋值。象assign out<=a+b;这样的语句是错误的。
2、 当用“always”块来描述组合逻辑时,既可以用阻塞赋值,也可以采用非阻塞赋值。但
在同一个过程块中,最好不要同时用阻塞赋值和非阻塞赋值,虽然同时 这两种赋值方式在综合时并不一定会出错。
3、 在向函数的返回值赋值时,应该使用阻塞赋值“=”。
4、 不能在一个以上的“always”过程块中对同一个变量赋值,这样会引起冲突,在综合时
会报错。
5、 在一个模块中,严禁对同一变量既进行阻塞赋值,又进行非阻塞赋值,这样在综合时会
报错。
6、 对时序逻辑描述和建模,应尽量使用非阻塞赋值方式,此外,若在同一个“always”过
程块中描述时序和组合逻辑混合电路时,也最好使用非阻塞赋值方式。 7、 对于阻塞赋值来说,赋值语句的顺序对最后的综合结果有着直接的影响。
而对于非阻塞赋值,不用考虑赋值语句的排列顺序。 布局与布线(Auto Placement & Route, AP&R)
布局的目的在于产生制作掩膜所需的GDSII 文件。 CTS(时钟树综合)必须尽可能地使同一个Tree内Clock到达的时间一致,即使Clock Skrew越小越好。
3