Vivado综合工具支持直接在RTL文件或XDC文件中设置综合属性。如果Vivado识别出设置的属性,会创建与之相关的逻辑电路;如果不能识别设置的属性,会将该属性和值存放在生成的网表中。因为某些属性,例如LOC约束适用于布线过程,因此必须保留该属性配置情况以用于之后的过程;
本文将介绍Vivado综合工具支持的所有属性设置,并给出Verilog示例:
1.ASYNC_REG
将reg类型配置为可以在D输入管脚接受异步数据的寄存器,或者带同步链的同步寄存器。该属性默认为FALSE,可设置为TRUE ;
(* ASYNC_REG = “TRUE” *) reg [2:0] sync_regs;//verilog示例
在异步跨时钟域场合,对于控制信号常使用双触发器完成跨时钟域操作,如下图所示:
此时对于1号寄存器要使用综合属性 ASYNC_REG有以下两个目的:
(1)表明1号触发器接受的数据来自于与接收时钟异步的时钟域;
(2)表明2号触发器是同步链上的触发器
从而保证1、2号触发器会被放在同一个slice中,减少线延时对时序的影响;
2.BLACK_BOX
当设置了该属性时,Vivado综合工具会为该模块创建一个黑盒子,模块内部的所有层次结构对外都不可见,该功能多用于调试过程。该属性可以设置在module、entity或component上,只能在RTL中设置。示例如下:
(* black_box *) module test(in1, in2, clk, out); //Verilog示例,不需要设置值
3.CASCADE_HEIGHT
该属性只适用于UltraScale架构的FPGA,用于设置将块RAM级联为大型RAM的最大长度。通常工具会根据创建的RAM选择如何级联块RAM,该属性可以用于缩短级联链的长度。需要在RTL中设置,值为0或1时表示禁止任何块RAM的级联。示例如下:
(* cascade_height = 4 *) reg [31:0] ram [(2**15) - 1:0];
4.CLOCK_BUFFER_TYPE
该属性应用于顶层模块的输入时钟端口上,设置使用哪种时钟缓冲器。默认使用BUFG,可以设置为BUFG、BUFH、BUFIO、BUFMR、BUFR或none。可以在RTL代码或者XDC文件中设置,示例如下:
CLOCK_BUFFER_TYPE Verilog Example:
(* clock_buffer_type = “none” *) input clk1;
CLOCK_BUFFER_TYPE XDC Example:
set_property CLOCK_BUFFER_TYPE BUFG [get_ports clk]
5.DIRECT_ENABLE
如果希望一个输入或信号直接作为触发器的使能信号(连接到flop的使能线上),可以使用该属性。可以在RTL或XDC中设置,示例如下:
DIRECT_ENABLE Verilog Example:
(* direct_enable = “yes” *) input ena3;
DIRECT_ENABLE XDC Example:
set_property direct_enable yes [get_nets –of [get_ports ena3]]//对于XDC文件 direct_enable只能作用于net
6.DIRECT_RESET
希望一个输入或信号直接作为触发器的复位信号(连接到flop的复位线上),可以使用该属性。可以在RTL或XDC中设置,示例与上一属性类似。注意在XDC中,这两个属性只对网络(net)类型有效,必须使用get_nets命令来获取网络对象;
DIRECT_RESET Verilog Example:
(* direct_reset = "yes" *) input rst3;
DIRECT_RESET XDC Example:
set_property direct_reset yes [get_nets –of [get_ports rst3]]
7.DONT_TOUCH
该属性与KEEP和KEEP_HIERARCHY属性作用相同,区别在于DONT_TOUCH 在布局布线过程中仍会保持作用。当其他属性与DONT_TOUCH属性发生冲突时,DONT_TOUCH属性有更高的优先级。该属性可用于配置任意信号、module、entity或component。该属性仅可用于RTL中,示例如下:
Verilog Wire Example:
(* dont_touch = “yes” *) wire sig1;
assign sig1 = in1 & in2;
assign out1 = sig1 & in2;
Verilog Module Example:
(* DONT_TOUCH = “yes” *)
module example_dt_ver
(clk,
In1,
In2,
out1);
Verilog Instance Example:
(* DONT_TOUCH = “yes” *) example_dt_ver U0
(.clk(clk),
.in1(a),
.in2(b),
out1(c));
8.DSP_FOLDING
该属性控制是否将与加法器相连的两个MAC结构转换为1个DSP原语,属性值为'yes'或‘no’,yes表示转换,只能用于RTL代码中,并且必须放在module、entity、architecture等包含MAC的逻辑单元中,示例如下:
Verilog Example:
(* dsp_folding = “yes” *) module top …..
9.DSP_FOLDING_FASTCLOCK
当使用DSP_FOLDING 时,该属性用于告诉工具哪一个端口用于连接新的高速时钟,只支持在RTL代码中设置,示例如下:
Verilog Example:
(* dsp_folding_fastclock = “yes” *) input clk_fast;
10.EXTRACT_ENABLE
设置综合工具对使能信号的管理方式。默认情况下,Vivado会根据设计自动选择是否使用寄存器的使能管脚。当默认表现没有按设计意图进行时,可以使用该属性。比如设计中一个信号没有被视作使能信号,使用该属性可以强制将信号接入到触发器的CE管脚。该属性仅可用于RTL中,示例如下:
EXTRACT_ENABLE Example (Verilog):
(* extract_enable = “yes” *) reg my_reg;
另外还有EXTRACT_RESET属性用来设置对复位信号的管理方式,作用与使用方法与EXTRACT_ENABLE相同;
11.FSM_ENCODING
该属性用于设置状态机寄存器,控制状态机的编码方式,可选参数有独热码(one_hot)、顺序编码(sequential)、johnson编码(johnson)、格雷码(gray)、自动(auto)和无(none)。默认为auto,Vivado会自动选择最佳的编码方式。可以在RTL或XDC中设置,示例如下:
FSM_ENCODING Example (Verilog):
(* fsm_encoding = “one_hot” *) reg [7:0] my_state;
12.FSM_SAFE_STATE
该属性指示Vivado综合向状态机中插入逻辑来检测是否存在非法状态,如果存在则将其修复为正常状态并放在下一个时钟周期。比如对于独热码,0101状态就是一个非法状态。可设置的值有:
auto:使用Hamming-3编码进行单bit级自动纠正;
reset_state:使用Hamming-2编码进行单bit级检测,强制状态机进入复位状态;
power_on_state:使用Hamming-2编码进行单bit级检测,强制状态机进入上电状态;
default_state:使用Hamming-2编码进行单bit级检测,强制状态机进入default状态。Default状态即为case语句中设定的状态;
该属性用于设置状态机寄存器,可以在RTL或XDC中设置,示例如下:
FSM_SAFE_STATE Example (Verilog):
(* fsm_safe_state = “reset_state” *) reg [7:0] my_state;
13.FULL_CASE
该属性仅用于Verilog中,可以自动设定case、casex、casez语句中所有创建的值。该属性只能在RTL中设置,示例如下:
FULL_CASE Example (Verilog):
(* full_case *)
case select
3’b100 : sig = val1;
3’b010 : sig = val2;
3’b001 : sig = val3;
endcase
14.GATED_CLOCK
该属性用于控制门控时钟的转换,与综合设置中的-gated_clock_conversion配合使用,设置为off禁止门控时钟转换;设置为on遇到RTL代码中的GATED_CLOCK设置会进行门控时钟转换;设置为auto工具会自动判断。示例如下:
(* gated_clock = “true” *) input clk; //Verilog示例,申明clk为门控时钟
15.IOB
IOB不是一个综合属性,它用于实现过程中。该属性指示一个寄存器是否接入到I/O缓存器。可以在RTL或XDC中设置,示例如下:
(* IOB = “true” *) reg sig1; //sig1将接到I/O buffer
16.IO_BUFFER_TYPE
该属性用于任何顶层模块的端口,指示工具如何使用缓冲器。Vivado综合默认会自动推断使用输入缓冲器或输出缓冲器,IO_BUFFER_TYPE设置为none会禁用自动推断。可以在RTL或XDC中设置,示例如下:
(* IO_BUFFER_TYPE = “none” *) input in1; //Verilog示例
17.KEEP
使用该属性阻止对信号的优化。综合时带有该属性的信号会保留在网表中,不会被优化掉或者纳入其它逻辑块中。如下面的例子,假设信号A是一个两位与门,该信号又送入另一个与门,默认情况下Vivado会把两个与门合共为一个LUT来实现相应功能,但设置KEEP属性即可保留下信号A;
KEEP不能用于模块的端口上,相应功能应该通过将-flatten_hierarchy设置为none或为模块设置DONT_TOUCH属性来实现。假设为信号B设置了KEEP,但是该信号在后面的RTL设计中并没有使用,综合会保留信号B(尽管它没有任何驱动),但是在后面的流程中还是会引发问题。另外,当KEEP属性和其它属性冲突时,KEEP有更高的优先级。
任何信号、reg、wire都可设置KEEP属性,只能在RTL中设置,示例如下:
(* keep = “true” *) wire sig1; //wire示例
assign sig1 = in1 & in2;
assign out = sig1 & in2; //sig1不会被优化掉
18.KEEP_HIERARCHY
Vivado综合工具可以展开层级结构进行优化,为模块设置KEEP_HIERARCHY属性,可以保留该模块在RTL中的输入输出端口,即保留一个完整的边界。只能在RTL中设置,示例如下:
(* keep_hierarchy = “yes” *) module bottom (in1… //模块示例
(* keep_hierarchy = “yes” *)bottom u0 (.in1(in1), … //实例化示例
19.MARK_DEBUG
该属性可将任何网络对象(net)设置为debug状态,以便在Vivado硬件管理器中调试,同时还会阻止对该信号的优化。可以在RTL或XDC中设置,示例如下:
(* MARK_DEBUG = “TRUE” *) wire debug_wire; //Verilog示例
set_property MARK_DEBUG TRUE [get_nets debug_wire] #XDC示例
20.MAX_FANOUT
设置寄存器和组合逻辑信号的最大扇出限制(即最大驱动数量)。超出该设置时,会复制一个完全相同的寄存器或组合逻辑。综合设置中的-fanout_limit是对工程整体的设置,对某一信号或寄存器单独设置MAX_FANOUT属性会忽视-fanout_limit的限制;
另一点区别是-fanout_limit不会对控制信号产生作用,如置位信号set、复位信号reset、时钟使能信号clock enable,但可以用MAX_FANOUT对这些信号的扇出进行限制。可以在RTL或XDC中设置,示例如下:
(* max_fanout = 50 *) reg sig1; //Verilog示例
21.PARALLEL_CASE
该属性仅用于Verilog中,可以将case语句强制用并行结构来实现,而不会被优化为if -elsif的结构。该属性只能在RTL中设置,示例如下:
(* parallel_case *) case select
3’b100 : sig = val1;
3’b010 : sig = val2;
3’b001 : sig = val3;
endcase
22.RAM_DECOMP
该属性用于指示综合工具如何用块RAM来实现一个较大的RAM,比如需要一个2K*36的RAM,通常会用两个2K*18的BRAM组合实现(为了提高设计速度)。如果将该属性设置为power,则会用两个1K*36的BRAM来组合实现,这样在读写过程中,使用地址使只需要一个BRAM处于活跃状态,因此可以降低功耗;
该属性只有一个可配置值即power,虽然可以降低功耗,但是会增加地址解码的时间。可以在RTL或XDC中设置,示例如下:
(* ram_decomp = “power” *) reg [size-1:0] myram [2**addr-1:0]; //Verilog示例
set_property ram_decomp power [get_cells myram] #XDC示例
23.RAM_STYLE
指示综合工具如何实现一个RAM存储器,可设置为block(使用BRAM即块RAM来实现)、distributed(使用LUT搭建分布式RAM)、registers(使用寄存器组来替代RAM)或ultra(使用UltraScale中的URAM)。
默认情况下工具会为了得到最好的设计效果而自动选择。如果该属性在定义RAM的信号处申明,则仅作用于该信号;如果在某一层次结构处申明,将作用于该层次中的所有RAM(但不会影响到该层次的子层次)。可以在RTL或XDC中设置,示例如下:
(* ram_style = “distributed” *) reg [size-1:0] myram [2**addr-1:0]; //Verilog示例
24.RETIMING_BACKWARD
该属性指示工具通过接近驱动顺序元素的逻辑向后移动寄存器,该属性与综合全局设置的retiming不同的是即使全局属性的retiming并不是处在active的状态,只要设置了该属性该属性就会发生且优先级在全局属性之前,属性值可以是‘0’或‘1’;可以在RTL或XDC中设置,示例如下:
RETIMING_BACKWARD Example (Verilog):
(*retiming_backward = 1 *) reg my_sig;
RETIMING_BACKWARD Example (XDC):
set_property retiming_backward 1 [get_cells my_sig];
该属性与RETIMING_FORWARD属性类似,这里不再赘述;
25.ROM_STYLE
指示综合工具如何实现一个ROM存储器,可设置为block(使用BRAM即块RAM来实现)或distributed(使用LUT搭建分布式ROM),默认情况下工具会为了得到最好的设计效果而自动选择。可以在RTL或XDC中设置,示例如下:
ROM_STYLE Example (Verilog):
(* rom_style = “distributed” *) reg [data_size-1:0] myrom [2**addr_size-1:0];
26.RW_ADDR_COLLISION
该属性是为了放防止RAM发生读写冲突,当RAM为简单双端口时,vivado会自动将操作模式设置为write-first;但是当读写操作的是同一个地址时,该属性就会推翻这一默认设置;属性值有'auto'、‘yes’、‘no’,auto表示维持默认设置,yes设置为write-first,no表示设置为no-change,属性仅可以再RTL中设置,示例如下:
Verilog Example:
(*rw_addr_collision = “yes” *) reg [3:0] my_ram [1023:0];
27.SHREG_EXTRACT
指示综合工具是否推断SRL结构(一种移位寄存器的实现结构)。设置为NO时不会推断SRL,设计中的移位寄存器会用寄存器组的形式实现。可以在RTL或XDC中设置,示例如下:
SHREG_EXTRACT Example (Verilog):
(* shreg_extract = “no” *) reg [16:0] my_srl;
28.SRL_STYLE
指示寄存器如何推断设计中的SRL(仅支持静态移位寄存器),可设置的值有:
注意当SRL_STYLE和SHREG_EXTRACT同时使用时,后者优先级更高。该属性仅可用于RTL设置,示例如下:
SRL_STYLE Examples (Verilog):
(* srl_style = “register” *) reg [16:0] my_srl;
29.TRANSLATE_ON/OFF
这两个属性用于指示综合工具忽略一段代码。该属性通过放在注释行中来实现,且注释必须以synthesis、synopsys、pragma、xilinx中的一个关键词为开头。但注意:如果需要忽视的代码块会影响到设计功能表现,仿真器会试图调用这段代码,因此会出现“mismatch”的情况。该属性只能在RTL中设置,Verilog示例如下:
TRANSLATE_OFF/TRANSLATE_ON Example (Verilog):
// synthesis translate_off
Code....忽略综合的代码
// synthesis translate_on
30.USE_DSP
该属性用于指示综合工具如何处理算术结构,默认情况下乘法器、乘加、乘减、乘累加类型的结构都会用DSP单元实现。虽然加法器、减法器、累加器也可以用DSP单元实现,但默认会使用逻辑单元实现,可以使用该属性将其设置为在DSP单元中实现。
参数值可选择logic(专门指示异或结构用DSP单元来实现)、yes或no(指示是否将逻辑用DSP单元实现),前者必须在module/architecture处申明,后者可以在信号、architecture、component、entity、module处申明;
老版本中为USE_DSP48,后来FPGA中增加了其它大小的新DSP块,更改为USE_DSP。虽然USE_DSP48仍然有效,但推荐使用USE_DSP命令;示例如下:
USE_DSP Example (Verilog):
(* use_dsp = “yes” *) module test(clk, in1, in2, out1);
Vivado支持在RTL中使用自定义属性,通常是为了在其它工具的综合后流程中使用。前文提到过,Vivado综合工具遇到不能识别的属性时也会将其保存到网表中,但是如果Vivado综合工具可以优化一个带有自定义属性的对象,优化后该属性也就丢失了,因此该对象必须使用DONT_TOUCH或KEEP_HIERARCHY属性来阻止优化掉带有自定义属性的对象;
自定义属性可以用于某一层次或某一信号。当作用于层次结构(hierarchy)时,必须在综合设置中将-flatten_hierarchy设置为none,或者配置一个KEEP_HIERARCHY属性。因为默认情况下综合会展开所有的层次结构,优化设计之后,再按RTL设计来重组设计结构,这样自定义属性可能会丢失。示例代码如下:
Example with Custom Attribute on Hierarchy (Verilog):
(* my_att = “my_value”, DONT_TOUCH = “yes” *) module test(....
当作用于信号(signal)时,也要用DONT_TOUCH或KEEP属性来避免优化导致自定义属性丢失。比如一个信号根据RTL代码可能会用寄存器也可能用net来实现。综合工具会检查同时带有自定义属性和DONT_TOUCH属性的对象,如果net是由寄存器驱动,综合会将自定义属性复制到寄存器和net上,因为这种情况下会有使用自定义属性的多种方法。示例代码如下:
Example with Custom Attribute on a Signal (Verilog):
(* my_att = “my_value”, DONT_TOUCH = “yes” *) reg my_signal;
上文提到的属性有些可以用在XDC文件中。总的来说,那些在综合开始阶段使用的属性和对编译有影响的属性只能用在RTL中;用于综合结束阶段和描述综合如何创建逻辑的属性可以用在XDC文件中;
比如KEEP和DON’T_TOUCH就不允许用在XDC中,因为当综合从XDC文件中读取到属性时,这两个属性可能早已在综合过程中被优化掉了。在XDC文件中设定综合属性可以按照如下语法模板:
set_property
For example:
set_property MAX_FANOUT 15 [get_cells in1_int_reg]
另外,在Elaborated设计中也可以设置属性。先打开Elaborated设计,在原理图窗口中或RTL网表窗口中选择需要设置属性的对象:
在属性窗口的Properties标签中,修改属性值。如果没有目标属性,则右键->Add Properties,选择添加属性。点击保存即可将属性设置添加到XDC文件中;