大家都应该懂的FPGA设计常识

Table of Contents

代码风格

1. 多使用 开发工具自带(vivado, ISE)自带的代码模板

2. 使用流水结构来降低逻辑层数 

3. 在模块边界上使用寄存器而非组合逻辑 

3. 采用适当的 RAM 和 DSP 的实现方式(是否选用硬核)

4. 在综合后或是逻辑优化(opt_design)后的时序报告上分析代码优化的方向

5. 尽量避免使用异步复位

时序约束

1. 时序约束顺序(顺序很重要)

2. 将最好的资源用在最差的路劲上

3. 时序报告要满足时序或者仅余300ps以内的时序违例

4. 时钟约束

5. I/0 约束

6. 时序例外约束

7. 高级时钟约束

CDC(Clock Domain Crossing)跨时钟

1. 简单同步器

2. 用FIFO隔离CDC 

I/O约束 

1. Input约束

 2. Output约束


代码风格


1. 多使用 开发工具自带(vivado, ISE)自带的代码模板

2. 使用流水结构来降低逻辑层数 

3. 在模块边界上使用寄存器而非组合逻辑 

3. 采用适当的 RAM 和 DSP 的实现方式(是否选用硬核)

4. 在综合后或是逻辑优化(opt_design)后的时序报告上分析代码优化的方向

5. 尽量避免使用异步复位

1. 同步复位优缺点:

  • 优点:

    1. 有利于仿真器的仿真
    2. 可以使所设计的系统成为100%的同步时序电路,这便大大有利于时序分析,而且综合出来的fmax一般较高。
    3. 因为他只有在时钟有效电平到来时才有效,所以可以滤除高于时钟频率的毛刺。

  • 缺点:

    1. 复位信号的有效时长必须大于时钟周期,才能真正被系统识别并完成复位任务。同时还要考虑,诸如:clk skew,组合逻辑路径延时,复位延时等因素。
    2. 由于大多数的逻辑器件的目标库内的DFF都只有异步复位端口,所以,倘若采用同步复位的话,综合器就会在寄存器的数据输入端口插入组合逻辑,这样就会耗费较多的逻辑资源。

2. 异步复位优缺点:

  • 优点:

    1. 大多数目标器件库的dff都有异步复位端口,因此采用异步复位可以节省资源。
    2. 异步复位信号识别方便,而且可以很方便的使用FPGA的全局复位端口GSR。

  • 缺点:

    1. 在复位信号释放(release)的时候容易出现问题。具体就是说:倘若复位释放时恰恰在时钟有效沿附近,就很容易使寄存器输出出现亚稳态,从而导致亚稳态。
    2. 复位信号容易受到毛刺的影响。

3. 总结:一般都推荐使用异步复位,同步释放的方式,而且复位信号低电平有效。

时序约束


1. 时序约束顺序(顺序很重要

  •   第一次运行只需约束所有时钟
  •   在时钟约束的情况下,再加入关键I/O约束
  •   最后考虑必要的时序例外约束

2. 将最好的资源用在最差的路劲上

3. 时序报告要满足时序或者仅余300ps以内的时序违例

4. 时钟约束

  • 端口进来的时钟以及 GT 的输出 RXCLK/TXCLK 都必须 由用户使用 create_clock 自主创建为主时钟
  • 如果是差分输入的时钟,可以仅仅在差分对的 P 侧用 get_ports 获取端口,并使用 create_clock 创建。
    create_clock -name clk_200 -period 5 [get_ports clk200_p] 

     

  • MMCM/PLL/BUFR 的输出作为衍生时钟,可以由 Vivado 自动推导,无需用户创建,但是由用户来指定这类衍生时钟的名字,只需写明create_generated_clock 的三个 option。
    create_generated_clock  -name my_clk_name [get_pins mmcm0/CLKOUT] \ 
                            -source [get_pins mmcm0/CLKIN] \ 
                            -master_clock main_clk 

     

  • 使用寄存器和组合逻辑搭建的分频器等, 工具不能自动推导衍生时钟,必须由用户使用 create_generated_clock 来创建。

5. I/0 约束

  • 不加任何 I/O 约束的端口时序要求被视作无穷大
  • XDC 中的 set_input_delay / set_output_delay 对应于 UCF 中 OFFSET IN / OFFSET OUT,但视角相反。OFFSET IN / OFFSET OUT是从 FPGA 内部延时的角度来约束端口时序,set_input_delay / set_output_delay 则是从系统角度来约束
  • 典型的 I/O 时序,包括系统同步、源同步、SDR 和 DDR 等等

6. 时序例外约束

  • 时序例外约束包括set_max_delay/set_min_delay,set_multicycle_path,set_false_path 等
  • 除了要满足 XDC 的先后顺序优先级外,还受到自身优先级的限制
  • 一个总的原则就是针对同一条路径,对约束目标描述越具体的优先级越高
set_max_delay 15 from [get_clocks clk1] -to [get_clocks clk2] --> 优先级最高
set_max_delay 12 from [get_clocks clk1]

7. 高级时钟约束

  • 时序的零起点,用 create_clock定义的主时钟的起点即时序的“零起点,”在这之前的上游路径延时都被工具自动忽略
  • 时钟定义的先后顺序,在同一个点上,由用户定义的时钟会覆盖工具自动推导的时钟,且后定义的时钟会覆盖先定义的时钟。若 要二者并存,必须使用 -add 选项。
    create_clock -name sysclk -period 10 [get_ports sys_clk] 
    create_generated_clock -name clkbufg -source [get_ports sys_clk] -divide_by 1 \ 
                                                 [get_pins clk_infra_i/clkfsm_buf/O] 
    create_generated_clock -name clkbufr -source [get_ports sys_clk] -divide_by 1 \ 
                      [get_pins clk_infra_i/sys_clk_buf/O] -add -master_clock sysclk
    

     

  • 同步时钟和异步时钟,两个主时钟 ssclkin 和 sysclk 由不同的端口进入 FPGA,再经由不同的时钟网络传递,要将 它们设成异步时钟,可以使用如下约束。其中,-include_generated_clocks 表示所有衍生钟自动跟其主时钟一组,从而与其它组的时钟之间为异步关系。不加这个选项则仅仅将时钟关系的约束应用在主时钟层面。
    set_clock_groups -name sys_ss_async –asynchronous \ 
                     -group [get_clocks -include_generated_clocks sysclk] \ 
                     -group [get_clocks -include_generated_clocks ssclkin] 
    

     

  • 重叠(单点多个)时钟,重叠时钟是指多个时钟共享完全相同的时钟传输网络,例如两个时钟经过一个 MUX 选择后输出的时钟, 在有多种运行模式的设计中很常见。所以需要补齐时钟关系的约束。
    set_clock_groups -physically_exclusive \ 
                     -group [get_clocks clk125] \ 
                     -group [get_clocks clk250]

    在很多情况下,除了共同的扇出,其中一个时钟或两个都还驱动其它的时序元件,此时建议的做法是在clkcore_buf的输出端上创建两个重叠的衍生钟,并将其时钟关系约束为-physically_exclusive表示不可能同时通过。这样做可以最大化约束覆盖率,也是 ISE 和 UCF 中无法做到的。

    create_generated_clock  -name clk125_bufgctrl \ 
                            -divide_by 1 [get_pins bufgctrl_i/O] \ 
                            -source [get_ports bufgctrl_i/I0] 
    create_generated_clock  -name clk250_bufgctrl \ 
                            -divide_by 1 [get_pins bufgctrl_i/O] \ 
                            -source [get_ports bufgctrl_i/I1] \ 
                            -add -master_clock clk250 
     
    set_clock_groups    –physically_exclusive \ 
                        –group clk125_bufgctrl \ 
                        –group clk250_bufgctrl 

    CDC(Clock Domain Crossing)跨时钟


    - 所谓安全的 CDC路径是指那些源时钟和目标时钟拥有相同的来源.
    - 所谓不安全的 CDC路径则表示源时钟和目标时钟不同,且由不同的端口进入 FPGA,在芯片内部不共享时钟网络。

1. 简单同步器

  • 对于单根跨时钟域路径,一般采用简单同步器 (Simple Synchronizer),就是由至少两级 CE 端和 Reset/Clear 端接死的寄存器序列来处理。
  • 为了更长的平均无故障时间MTBF(Mean Time Between Failures),需要ASYNC_REG的约束,把用作简单同步器的多个寄存器放入同一个SLICE,以降低走线延时的不一致和不确定性。
    set_property ASYNC_REG TRUE [get_cells [list sync0_reg sync1_reg]]

2. 用FIFO隔离CDC 

 

  • Build-in 硬核 FIFO,这种FIFO就是用FPGA内部的BRAM来搭建,所有控制逻辑都是BRAM内部,是推荐的FIFO实现方式。对于XDC约束,只要像简单同步器的时钟关系约束一样,用set_clock_groups将读写时钟约束为异步即可。
  • 带有格雷码控制的FIFO,为了在亚稳态下做读写指针抽样也能正确判断空满状态,设计中也常用一种带有格雷码控制的 FIFO 来实现异步时钟域的隔离。计数器和读写指针等需要用 BRAM外部的逻辑搭建,这样的结构就不能简单约束set_clock_groups,还要考虑这些外部逻辑如何约束,转而采用set_max_delay来约束这些跨时钟域路径,一般情况下IP catalog产生的FIFO,自带约束文件XDC,所以只要保证FIFO的读写时钟域没有被用户的XDC约束为false path或异步clock groups。
  • CDC约束方案的对比
  1. 全部忽略的约束,最大化全部忽略 CDC 路径的约束,即采用 set_clock_groups 或是 set_false_path 对时钟关系进行约束,从而对跨时钟域的路径全部忽略。
  • 示例:set_clock_groups -asynchronous -group clkA -group clkB

  • 优势:简单、快速、执行效率高。

  • 劣势:会掩盖时序报告中所有的跨时钟域路径,容易误伤,不利于时序分析。

  1. 使用 datapath_only 约束,datapath_only 是从 ISE 时代的 UCF 中继承过来的约束,在 XDC中必须作为一个选项跟 set_max_delay配合使用,可以约束在时钟之间,也可以对具体路径进行约束。
  • 示例:set_max_delay 10 -datapath_only -from clkA -to clkB
  • 优势:简便、执行效率较高。
  • 劣势:1)需要特别留意是否设置了过于严格的约束,因为使用者经常会使用较快的时钟周期来约束跨时钟域路径 。2)注意约束优先级的关系,是否跟设计中其它的约束有冲突 3) set_max_delay 而没有配套设置 set_min_delay 的情况下,同一路径只做 setup 分析而不做 hold 分析。
  1. 逐条进行时序例外约束,对设计中的 CDC路径分组或逐条分析,采用不同的时序例外约束,如set_false_path,set_max_delay 和 set_multicycle_path 等来约束。
  • 示例:set_false_path -from [get_cells a/b/c/_meta] -to [get_cells a/b/c/_sync]
  • 优势:灵活、针对性好、便于时序分析和调试。
  • 劣势:1)逐条约束会占用大量时间来调试和分析,效率低下。2) 时序例外的优先级比较复杂,多种时序例外约束共存的情况下,很容易产生意想不到的冲突,进一步增加调试时间,降低效率。3) 这么做极容易产生臃肿的 XDC 约束文件,而且时序例外的执行更耗内存,直接导致工具运行时间变长。

I/O约束 


XDC 中可以用于 I/O 约束的命令包括 set_input_delay / set_output_delay 和 set_max_delay/set_min_delay。其中,只有那些从FPGA 管脚进入和/或输出都不经过任何时序元件的纯组合逻辑路径可以用set_max_delay / set_min_delay来约束,其余I/O时序路径都必须由set_input_delay/set_output_delay来约束。如果对FPGA的I/O不加任何约束,Vivado会缺省认为时序要求为无穷大,不仅综合和实现时不会考虑I/O时序,而且在时序分析时也不会报出这些未约束的路径。

1. Input约束

set_input_delay -clock   -max  -min 

 2. Output约束

set_output_delay -clock   -max  -min 

你可能感兴趣的:(FPGA)