时序约束学习拓展(二):I/O约束笔记 + BUFIO & IDDR协调方法
参考:
https://cloud.tencent.com/developer/article/1652378
FPGA 静态时序分析与约束(1)_分析建立时间是否满足时序要求时要使用慢速模型;分析保持时间是否满足时序要求时-CSDN博客
放置失败问题:
在 Zynq7045 FPGA 中通过IDELAYE2驱动 BUFIO (xilinx.com)
[Place 30-512] Clock region assignment has failed. Clock buffer 'rgmii_top_inst0/rgmii_dphy_inst0/BUFIO_inst_eth_rxc' (BUFIO) is placed at site BUFIO_X0Y17 in CLOCKREGION_X0Y4. Its loads need to be placed in the area enclosed by clock regions CLOCKREGION_X0Y4 and CLOCKREGION_X0Y4. One of its loads 'rgmii_top_inst0/rgmii_dphy_inst0/IDELAYE2_inst_eth_rxc' (IDELAYE2) is placed in site IDELAY_X1Y349 in CLOCKREGION_X1Y6 which is outside the permissible area. [Place 30-99] Placer failed with error: 'Clock placer failed' Please review all ERROR, CRITICAL WARNING, and WARNING messages during placement to understand the cause for failure. [Common 17-69] Command failed: Placer could not place all instances
You are right that the documentation says that it can be driven by general interconnect... But... You really don't want to do that. If you are trying to capture a hight speed input (and I am inferring that you do since you are playing with the IDELAY), then you need to use a clocking scheme that reliably captures the interface. To do this, you need to stay entirely in dedicated clocking resources. That means using CCIO -> IBUF -> IDELAY -> BUFIO -> IDDR.CLK -> BUFR -> {fabric logic receiving data from the IDDR} I/O -> IBUF -> IDELAY -> IDDR.D These are all dedicated connections and will yield the best and reproducible timing. Taking a "side trip" into general interconnect will totally mess up timing; you will get different timing characteristics from run to run. My suggestion to you is, rather than trying to figure a way to make this connection legal, is to figure a way to do without it. I see that you said IOBUF (rather than IBUF), so I guess that at some times this is not an input clock, but is something else, and I presume your "some combinatorial logic" is to only clock the IDDR when the clock is a valid input clock. Perhaps a better way is to always capture the data in the IDDR (even when the CLK is not a valid clock), but just not use the data captured by the IDDR during clock periods where the clock is not a clock.
[Route 35-7] Design has 1 unroutable pin, potentially caused by placement issue or user provided physical constraints. Resolution: Please check if the unroute is caused by an incorrect physical constraint on the driver/load pair of the unrouted net. If so, please remove or modify the constraint and re-run placer. [Route 35-4445] route_design is terminated due to errors/critical warnings issued before and during initial routing. The issues reported cannot be resolved later in route_design. Resolution: Please review previous errors/critical warnings messages to determine the reason for router exit during initial routing stage. To know the state of route database please run report_route_status.
[路线 35-7] 设计有 1 个不可布线的引脚,可能是由布局问题或用户提供的物理约束引起的。
解决方法:请检查未布线是否是由于未布线网络的驱动器/负载对上的物理约束不正确导致的。如果是这样,请删除或修改约束并重新运行放置器。
[Route 35-4445] 由于在初始布线之前和期间发出错误/严重警告,route_design 被终止。报告的问题无法稍后在route_design 中解决。
解决方案:请查看以前的错误/严重警告消息,以确定路由器在初始路由阶段退出的原因。要了解路线数据库的状态,请运行report_route_status。
IO约束
因为FPGA内部的约束对于源寄存器与目的寄存器都很明确。但是输入时,我们不清楚源寄存器的时钟与数据路径;输出时,我们不清楚目的寄存器的建立时间保持时间。综上所述,我们需要进行IO约束去告诉FPGA这些信息,进而让EDA软件去帮助我们分析。
Inputdelay
计算公式一:
input delay max=(Tco+Td_bd)max−Tcd−Tc_bd
input delay min=(Tco+Td_bd)min−Tcd−Tc_bd
其实对于大多数PCB板做了等长处理,所以一般T d b d与T c b d相等,而且Tco-Tcd在上游器件得技术手册中是给出得,一般命名为T co,那么对于PCB板做了等长处理得器件,
可以得下式:
input delay max = Tco(max)
input delay min = Tco(min)
其实在PCB做了等长处理之后,所谓的输入最大最小延迟就是上游器件Tco的最大值最小值。
所以对于PCB做了等长处理的电路,我们只需要进行查找技术手册找到相应的Tco即可。
其实我们可以查看EDA的时序分析路径,可以发现所谓的input delay max与input delay min分别在分析建立时间与保存时间的路径分析中被使用。
set_input_delay:
在数据从输入端口到触发器FF,即从上游器件到FPGA内部DFF时,需要使用set_input_delay延时,在设计输入延时时,vivado在编译时会根据设置的延时大小调用延时模块,完成对输入数据延时的设置:
SDR
# Center-Aligned Rising Edge Source Synchronous Inputs # # For a center-aligned Source Synchronous interface, the clock # transition is aligned with the center of the data valid window. # The same clock edge is used for launching and capturing the # data. The constraints below rely on the default timing # analysis (setup = 1 cycle, hold = 0 cycle). # # input ____ __________ # clock |_________| |_____ # | # dv_bre | dv_are # <------>|<------> # __ ________|________ __ # data __XXXX____Rise_Data____XXXX__ # set input_clock <clock_name>; # Name of input clock set input_clock_period <period_value>; # Period of input clock set dv_bre 0.000; # Data valid before the rising clock edge set dv_are 0.000; # Data valid after the rising clock edge set input_ports <input_ports>; # List of input ports # Input Delay Constraint set_input_delay -clock $input_clock -max [expr $input_clock_period - $dv_bre] [get_ports $input_ports]; set_input_delay -clock $input_clock -min $dv_are [get_ports $input_ports]; # Report Timing Template # report_timing -from [get_ports $input_ports] -max_paths 20 -nworst 1 -delay_type min_max -name src_sync_cntr_rise_in -file src_sync_cntr_rise_in.txt;
DDR
# Center-Aligned Double Data Rate Source Synchronous Inputs # # For a center-aligned Source Synchronous interface, the clock # transition is aligned with the center of the data valid window. # The same clock edge is used for launching and capturing the # data. The constraints below rely on the default timing # analysis (setup = 1/2 cycle, hold = 0 cycle). # # input ____________________ # clock _____________| |_____________ # | | # dv_bre | dv_are dv_bfe | dv_afe # <------>|<------> <------>|<------> # _ ________|________ ________|________ _ # data _XXXX____Rise_Data____XXXX____Fall_Data____XXXX_ # set input_clock <clock_name>; # Name of input clock set input_clock_period <period_value>; # Period of input clock (full-period) set dv_bre 0.000; # Data valid before the rising clock edge set dv_are 0.000; # Data valid after the rising clock edge set dv_bfe 0.000; # Data valid before the falling clock edge set dv_afe 0.000; # Data valid after the falling clock edge set input_ports <input_ports>; # List of input ports # Input Delay Constraint set_input_delay -clock $input_clock -max [expr $input_clock_period/2 - $dv_bfe] [get_ports $input_ports]; set_input_delay -clock $input_clock -min $dv_are [get_ports $input_ports]; set_input_delay -clock $input_clock -max [expr $input_clock_period/2 - $dv_bre] [get_ports $input_ports] -clock_fall -add_delay; set_input_delay -clock $input_clock -min $dv_afe [get_ports $input_ports] -clock_fall -add_delay; # Report Timing Template # report_timing -rise_from [get_ports $input_ports] -max_paths 20 -nworst 2 -delay_type min_max -name src_sync_cntr_ddr_in_rise -file src_sync_cntr_ddr_in_rise.txt; # report_timing -fall_from [get_ports $input_ports] -max_paths 20 -nworst 2 -delay_type min_max -name src_sync_cntr_ddr_in_fall -file src_sync_cntr_ddr_in_fall.txt;
Output Delay
为什么要设置输出延迟,因为我们得保证下游器件得建立时间和保存时间,使得下游器件成功操作。因为如果我们不建立输出延迟,那么有时候很难满足下游器件得建立时间与保持时间。这样做有两个目的:
1、告诉FPGA输出的时候需要满足的数据与时钟的延迟。
2、使得EDA工具可以计算是否存在时序违例。
定义2:output delay:FPGA的输出采样沿时钟与输出数据稳定情况下的时间差,必须同时满足最大值与最小值。也就是说至少在output delay的时间内输出数据在采样沿的周围是稳定的
从上面的定义,我们便可以知道output delay两个值的设置依据(在PCB时钟走线与数据走线等长的情况下):
# Double Data Rate Source Synchronous Outputs # # Source synchronous output interfaces can be constrained either by the max data skew # relative to the generated clock or by the destination device setup/hold requirements. # # Max Skew Case: # The skew requirements for FPGA are known from system level analysis. # # forwarded __________________________ # clock ____________| |______________ # | | # bre_skew|are_skew bfe_skew|afe_skew # <------>|<------> <------>|<------> # ______ | __________ | ______ # data ______XXXXXXXXXXXXXXXXX__________XXXXXXXXXXXXXXXXX______ # # Example of creating generated clock at clock output port # create_generated_clock -name <gen_clock_name> -multiply_by 1 -source [get_pins <source_pin>] [get_ports <output_clock_port>] # gen_clock_name is the name of forwarded clock here. It should be used below for defining "fwclk". set fwclk <clock_name>; # forwarded clock name (generated using create_generated_clock at output clock port) set fwclk_period <period_value>; # forwarded clock period (full-period) set bre_skew 0.000; # skew requirement before rising edge set are_skew 0.000; # skew requirement after rising edge set bfe_skew 0.000; # skew requirement before falling edge set afe_skew 0.000; # skew requirement after falling edge set output_ports <output_ports>; # list of output ports # Output Delay Constraints set_output_delay -clock $fwclk -max [expr $fwclk_period/2 - $afe_skew] [get_ports $output_ports]; set_output_delay -clock $fwclk -min $bre_skew [get_ports $output_ports]; set_output_delay -clock $fwclk -max [expr $fwclk_period/2 - $are_skew] [get_ports $output_ports] -clock_fall -add_delay; set_output_delay -clock $fwclk -min $bfe_skew [get_ports $output_ports] -clock_fall -add_delay; # Report Timing Template # report_timing -rise_to [get_ports $output_ports] -max_paths 20 -nworst 2 -delay_type min_max -name src_sync_ddr_out_rise -file src_sync_ddr_out_rise.txt; # report_timing -fall_to [get_ports $output_ports] -max_paths 20 -nworst 2 -delay_type min_max -name src_sync_ddr_out_fall -file src_sync_ddr_out_fall.txt;
# Double Data Rate Source Synchronous Outputs # # Source synchronous output interfaces can be constrained either by the max data skew # relative to the generated clock or by the destination device setup/hold requirements. # # Setup/Hold Case: # Setup and hold requirements for the destination device and board trace delays are known. # # forwarded _________________________________ # clock __________| |______________ # | | # tsu_r | thd_r tsu_f | thd_f # <------>|<-------> <------>|<-----> # ________|_________ ________|_______ # data @ destination XXX__________________XXXXXXXXXXXXXXXX________________XXXXX # # Example of creating generated clock at clock output port # create_generated_clock -name <gen_clock_name> -multiply_by 1 -source [get_pins <source_pin>] [get_ports <output_clock_port>] # gen_clock_name is the name of forwarded clock here. It should be used below for defining "fwclk". set fwclk <clock-name>; # forwarded clock name (generated using create_generated_clock at output clock port) set tsu_r 0.000; # destination device setup time requirement for rising edge set thd_r 0.000; # destination device hold time requirement for rising edge set tsu_f 0.000; # destination device setup time requirement for falling edge set thd_f 0.000; # destination device hold time requirement for falling edge set trce_dly_max 0.000; # maximum board trace delay set trce_dly_min 0.000; # minimum board trace delay set output_ports <output_ports>; # list of output ports # Output Delay Constraints set_output_delay -clock $fwclk -max [expr $trce_dly_max + $tsu_r] [get_ports $output_ports]; set_output_delay -clock $fwclk -min [expr $trce_dly_min - $thd_r] [get_ports $output_ports]; set_output_delay -clock $fwclk -max [expr $trce_dly_max + $tsu_f] [get_ports $output_ports] -clock_fall -add_delay; set_output_delay -clock $fwclk -min [expr $trce_dly_min - $thd_f] [get_ports $output_ports] -clock_fall -add_delay; # Report Timing Template # report_timing -rise_to [get_ports $output_ports] -max_paths 20 -nworst 2 -delay_type min_max -name src_sync_ddr_out_rise -file src_sync_ddr_out_rise.txt; # report_timing -fall_to [get_ports $output_ports] -max_paths 20 -nworst 2 -delay_type min_max -name src_sync_ddr_out_fall -file src_sync_ddr_out_fall.txt;