Vivado使用技巧(24):HDL/XDC中设置综合属性

Vivado综合工具支持直接在RTL文件或XDC文件中设置综合属性。如果Vivado识别出设置的属性,会创建与之相关的逻辑电路;如果不能识别设置的属性,会将该属性和值存放在生成的网表中。因为某些属性,比如LOC约束适用于布线过程,因此必须保留该属性配置情况。

本文将介绍Vivado综合工具支持的所有属性设置,并给出Verilog示例。

1.ASYNC_REG
该属性将reg类型配置为可以在D输入管脚接受异步数据的寄存器,或者带同步链的同步寄存器。该属性默认为FALSE,可设置为TRUE。可在RTL或XDC中设置。示例如下:
(* ASYNC_REG = “TRUE”) reg [2:0] sync_regs; //Verilog示例

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 *) reg [31:0] ram [(2**15)-1:0]; //Verilog示例

4.CLOCK_BUFFER_TYPE
该属性应用于顶层模块的输入时钟端口上,设置使用哪种时钟缓冲器。默认使用BUFG,可以设置为BUFG、BUFH、BUFIO、BUFMR、BUFR或none。该设置只能在RTL设计中,示例如下:
(* clock_buffer_type = “none” *) input clk1; //Verilog示例

5.DIRECT_ENABLE
如果希望一个输入或信号直接作为触发器的使能信号(连接到flop的使能线上),可以使用该属性。可以在RTL或XDC中设置,示例如下:
(* direct_enable = “yes” *) input ena1; //Verilog示例
set_property direct_enable yes [get_nets -of [get_ports ena1]] #XDC示例

6.DIRECT_RESET
如果希望一个输入或信号直接作为触发器的复位信号(连接到flop的复位线上),可以使用该属性。可以在RTL或XDC中设置,示例与上一属性类似。注意在XDC中,这两个属性只对网络(net)类型有效,必须使用get_nets命令来获取网络对象。

7.DONT_TOUCH
该属性与KEEP和KEEP_HIERARCHY属性作用相同,区别在于DONT_TOUCH 在布局布线过程中仍会保持作用。当其他属性与DONT_TOUCH属性发生冲突时,DONT_TOUCH属性有更高的优先级。该属性可用于配置任意信号、module、entity或component。该属性仅可用于RTL中,示例如下:
(* DONT_TOUCH = “yes” *) wire sig1; //wire示例
assign sig1 = in1 & in2;
assign out = sig1 & in2; //sig1不会被优化掉
(* DONT_TOUCH = “yes” *) module test (clk… //该层次与接口不会被优化掉

8.EXTRACT_ENABLE
设置综合工具对使能信号的管理方式。默认情况下,Vivado会根据设计自动选择是否使用寄存器的使能管脚。当默认表现没有按设计意图进行时,可以使用该属性。比如设计中一个信号没有被视作使能信号,使用该属性可以强制将信号接入到触发器的CE管脚。该属性仅可用于RTL中,示例如下:
(* extract_enable = “yes” *) reg my_reg; //Verilog示例

另外还有EXTRACT_RESET属性用来设置对复位信号的管理方式,作用与使用方法与EXTRACT_ENABLE相同。

9.FSM_ENCODING
该属性用于设置状态机寄存器,控制状态机的编码方式,可选参数有独热码(one_hot)、顺序编码(sequential)、johnson编码(johnson)、格雷码(gray)、自动(auto)和无(none)。默认为auto,Vivado会自动选择最佳的编码方式。可以在RTL或XDC中设置,示例如下:
(* fsm_encoding = “one_hot” *) reg [7:0] my_state; //Verilog示例

10.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 = “reset_state” *) reg [7:0] my_state; //Verilog示例

    11.FULL_CASE
    该属性仅用于Verilog中,可以自动设定case、casex、casez语句中所有未创建的值。该属性只能在RTL中设置,示例如下:
    (* full_case *) case select
    3’b100 : sig = val1;
    3’b010 : sig = val2;
    3’b001 : sig = val3;
    endcase

    12.GATED_CLOCK
    该属性用于控制门控时钟的转换,与综合设置中的-gated_clock_conversion配合使用,设置为off禁止门控时钟转换;设置为on遇到RTL代码中的GATED_CLOCK设置会进行门控时钟转换;设置为auto工具会自动判断。示例如下:
    (* gated_clock = “true” *) input clk; //Verilog示例,申明clk为门控时钟

    13.IOB
    IOB不是一个综合属性,它用于实现过程中。该属性指示一个寄存器是否接入到I/O缓存器。可以在RTL或XDC中设置,示例如下:
    (* IOB = “true” *) reg sig1; //sig1将接到I/O buffer

    14.IO_BUFFER_TYPE
    该属性用于任何顶层模块的端口,指示工具如何使用缓冲器。Vivado综合默认会自动推断使用输入缓冲器或输出缓冲器,IO_BUFFER_TYPE设置为none会禁用自动推断。可以在RTL或XDC中设置,示例如下:
    (* IO_BUFFER_TYPE = “none” *) input in1; //Verilog示例

    15.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不会被优化掉

    16.KEEP_HIERARCHY
    Vivado综合工具可以展开层级结构进行优化,为模块设置KEEP_HIERARCHY属性,可以保留该模块在RTL中的输入输出端口,即保留一个完整的边界。只能在RTL中设置,示例如下:
    (* keep_hierarchy = “yes” *) module bottom (in1… //模块示例
    (* keep_hierarchy = “yes” *)bottom u0 (.in1(in1), … //实例化示例

    17.MARK_DEBUG
    该属性可将任何网络对象(net)设置为debug状态,以便在Vivado硬件管理器中调试,同时还会阻止对该信号的优化。可以在RTL或XDC中设置,示例如下:
    (* MARK_DEBUG = “TRUE” *) wire debug_wire; //Verilog示例
    set_property MARK_DEBUG TRUE [get_nets debug_wire] #XDC示例

    18.MAX_FANOUT
    设置寄存器和组合逻辑信号的最大扇出限制(即最大驱动数量)。超出该设置时,会复制一个完全相同的寄存器或组合逻辑。综合设置中的-fanout_limit是对工程整体的设置(详情见第22篇),对某一信号或寄存器单独设置MAX_FANOUT属性会忽视-fanout_limit的限制。

    另一点区别是-fanout_limit不会对控制信号产生作用,如置位信号set、复位信号reset、时钟使能信号clock enable,但可以用MAX_FANOUT对这些信号的扇出进行限制。可以在RTL或XDC中设置,示例如下:
    (* max_fanout = 50 *) reg sig1; //Verilog示例

    19.PARALLEL_CASE
    该属性仅用于Verilog中,可以将case语句强制用并行结构来实现,而不会被优化为if -elsif的结构。该属性只能在RTL中设置,示例如下:
    (* parallel_case *) case select
    3’b100 : sig = val1;
    3’b010 : sig = val2;
    3’b001 : sig = val3;
    endcase

    20.RAM_DECOMP
    该属性用于指示综合工具如何用块RAM来实现一个较大的RAM。比如需要一个2K*36的RAM,通常会用两个2K18的BRAM组合实现(为了提高设计速度)。如果将该属性设置为power,则会用两个1K36的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示例

    21.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示例

    22.ROM_STYLE
    指示综合工具如何实现一个ROM存储器,可设置为block(使用BRAM即块RAM来实现)或distributed(使用LUT搭建分布式ROM),默认情况下工具会为了得到最好的设计效果而自动选择。可以在RTL或XDC中设置,示例如下:
    (* rom_style = “distributed” *) reg [size-1:0] rom [2**addr-1:0]; //Verilog示例

    23.SHREG_EXTRACT
    指示综合工具是否推断SRL结构(一种移位寄存器的实现结构)。设置为NO时不会推断SRL,设计中的移位寄存器会用寄存器组的形式实现。可以在RTL或XDC中设置,示例如下:
    (* SHREG_EXTRACT = “no” *) reg [16:0] my_srl; //Verilog示例

    24.SRL_STYLE
    指示寄存器如何推断设计中的SRL(仅支持静态移位寄存器),可设置的值有:

  • register:仅使用寄存器资源实现移位寄存器;
  • srl:使用SRL结构实现移位寄存器;
  • srl_reg:SRL尾部保留一个寄存器;
  • reg_srl:SRL头部保留一个寄存器;
  • reg_srl_reg:SRL的首尾各保留一个寄存器;
  • block:使用块RAM实现移位寄存器。
  • 注意当SRL_STYLE和SHREG_EXTRACT同时使用时,后者优先级更高。该属性仅可用于RTL设置,示例如下:
    (* SRL_STYLE = “register” *) reg [16:0] my_srl; //Verilog示例

    25.TRANSLATE_ON/OFF
    这两个属性用于指示综合工具忽略一段代码。该属性通过放在注释行中来实现,且注释必须以synthesis、synopsys、pragma中的一个关键词为开头。但注意:如果需要忽视的代码块会影响到设计功能表现,仿真器会试图调用这段代码,因此会出现“mismatch”的情况。该属性只能在RTL中设置,Verilog示例如下:
    // synthesis translate_off
    Code…
    // synthesis translate on

    26.USE_DSP
    老版本中为USE_DSP48,后来FPGA中增加了其它大小的新DSP块,更改为USE_DSP。虽然USE_DSP48仍然有效,但推荐使用USE_DSP命令。

    该属性用于指示综合工具如何处理算术结构,默认情况下乘法器、乘加、乘减、乘累加类型的结构都会用DSP单元实现。虽然加法器、减法器、累加器也可以用DSP单元实现,但默认会使用逻辑单元实现,可以使用该属性将其设置为在DSP单元中实现。

    参数值可选择logic(专门指示异或结构用DSP单元来实现)、yes或no(指示是否将逻辑用DSP单元实现),前者必须在module/architecture处申明,后者可以在信号、architecture、component、entity、module处申明。示例如下:
    (* use_dsp = “yes” *) module test(in1, in2, clk. out); //Verilog示例

    使用自定义属性
    Vivado支持在RTL中使用自定义属性,通常是为了在其它工具的综合后流程中使用。前文提到过,Vivado综合工具遇到不能识别的属性时也会将其保存到网表中,但是如果Vivado综合工具可以优化一个带有自定义属性的对象,优化后该属性也就丢失了,因此该对象必须使用DONT_TOUCH或KEEP_HIERARCHY属性来阻止优化掉带有自定义属性的对象。

    自定义属性可以用于某一层次或某一信号。当作用于层次结构(hierarchy)时,必须在综合设置中将-flatten_hierarchy设置为none,或者配置一个KEEP_HIERARCHY属性。因为默认情况下综合会展开所有的层次结构,优化设计之后,再按RTL设计来重组设计结构(详情见第22篇),这样自定义属性可能会丢失。示例代码如下:
    (* my_att = “value”, DONT_TOUCH = “yes” *) module test(in1, … //Verilog示例

    当作用于信号(signal)时,也要用DONT_TOUCH或KEEP属性来避免优化导致自定义属性丢失。比如一个信号根据RTL代码可能会用寄存器也可能用net来实现。综合工具会检查同时带有自定义属性和DONT_TOUCH属性的对象,如果net是由寄存器驱动,综合会将自定义属性复制到寄存器和net上,因为这种情况下会有使用自定义属性的多种方法,有些属性也被希望能同时用于寄存器 和net。示例代码如下:
    (* my_att = “value”, DONT_TOUCH = “yes” *) reg sig; //Verilog示例

    在XDC文件中使用综合属性
    上文提到的属性有些可以用在XDC文件中。总的来说,那些在综合开始阶段使用的属性和对编译有影响的属性只能用在RTL中;用于综合结束阶段和描述综合如何创建逻辑的属性可以用在XDC文件中。

    比如KEEP和DON’T_TOUCH就不允许用在XDC中,因为当综合从XDC文件中读取到属性时,这两个属性可能早已在综合过程中被优化掉了。在XDC文件中设定综合属性可以按照如下语法模板:
    set_property

    另外,在Elaborated设计中也可以设置属性。先打开Elaborated设计,在原理图窗口中或RTL网表窗口中选择需要设置属性的对象。

    在属性窗口的Properties标签中,修改属性值。如果没有目标属性,则右键->Add Properties,选择添加属性。点击保存即可将属性设置添加到XDC文件中。

    文章来源:FPGADesigner的博客
    *本文由作者授权转发,如需转载请联系作者本人

    最新文章