天天看点

GPIO的同步性约束

需求问题:需要使用3个GPIO实现相同的脉冲信号,三个信号之间的上升沿时延不能超过200ps。

测试环境:ZYNQ7020的黑金开发板

测试过程:

代码:

module gpio_jitter_test   (
    input                               clk_osc             ,   //50M
    output                              ld_0                ,
    output                              ld_1                ,
    output                              ld_2                
);

    wire                                clk;
    reg     [9:0]                       counter = 4'h0;
    (* dont_touch="true" *) reg                                 ld;
    
    assign ld_0                         = ld;
    assign ld_1                         = ld;
    assign ld_2                         = ld;

    BUFG BUFG_inst (
        .O(clk              ), // 1-bit output: Clock output
        .I(clk_osc          )  // 1-bit input: Clock input
    );
    
    always @(posedge clk) begin
        counter                         <= counter + 1'b1;
    end
    
    always @(posedge clk) begin
        if (counter<10'h2) begin
            ld                          <= 1'b1;
        end
        else begin
            ld                          <= 1'b0;
        end
    end
    
endmodule
           

开始选择了三个GPIO管脚约束,其他未加任何约束。时序很不好。

开启约束之路:

方法一:

(1) 将管脚配置为fast模式

set_property SLEW FAST [get_ports ld_0]

set_property SLEW FAST [get_ports ld_1]

set_property SLEW FAST [get_ports ld_2]

改观不大,更多是影响管脚上的上升沿和下降沿敏感性,对相互之间的延时没有太大影响。

(2) 布局中发现,寄存器进行了备份

GPIO的同步性约束

(3) 加上don’t touch,避免寄存器复制

GPIO的同步性约束

延时集中于寄存器输出至管脚的obuf之间,ld0和ld1相互之间的延时133ps,ld2和ld1延时在228ps。由于ld2管脚距离ld1之间过远。

GPIO的同步性约束

(4) 由于U21下方的管脚没有在开发板上接出来,没办法精确测量;将三个管脚改为U12,U11,U10。

GPIO的同步性约束
GPIO的同步性约束

由此可见,虽然管脚相邻,但是走线的长度差距还是很大,导致延时超过300ps。

(5) 添加max_delay和min_delay,三个管脚的max_delay 为4.6ns,min_delay为4.5ns。max_delay选择为datapath。

set_max_delay -datapath_only -from [get_pins ld_reg/C] -to [get_ports ld_0] 4.600
set_max_delay -datapath_only -from [get_pins ld_reg/C] -to [get_ports ld_1] 4.600
set_max_delay -datapath_only -from [get_pins ld_reg/C] -to [get_ports ld_2] 4.600

set_min_delay -from [get_pins ld_reg/C] -to [get_ports ld_0] 4.500
set_min_delay -from [get_pins ld_reg/C] -to [get_ports ld_1] 4.500
set_min_delay -from [get_pins ld_reg/C] -to [get_ports ld_2] 4.500
           
GPIO的同步性约束

测试结果:

GPIO的同步性约束

测了三组上升沿之间的差值分布数据:

1) ld_1 - ld_0 -130ps

2) ld_1 – ld_2 -250ps

3) ld_2 – ld_0 +50ps

结果分析:

从时序报告中,ld_0 最后一步走线delay是4.546ns,ld_1最后一步走线delay是4.663ns,ld_2的delay是4.535ns。

所以,理论值分析

1) ld_1 - ld_0 = (-4.663)-(-4.546)=117ps

2) ld_1 – ld_2 = (-4.663)-(-4.535)=128ps

3) ld_2 – ld_0 = (-4.535)-(-4.546)=11ps

由上面数据分析,第二组测试结果偏差较大,原因可能是ld0和ld1是一对差分线,ld2是另外一对差分线,ld0和ld1走线的长度一致,但是ld2走线不同,但是和ld0 ld1差值有些过大,问题在哪??

跟FAE交流后,发现在FPGA的管脚上存在pin delay,这个并不在时序报告中(pin delay不在时序报告中体现)。如何导出pin delay?tcl命令行中:

输入 link_design –part xc7z020i-clg484; write_csv filename

会输出7020的pin delay文件,如下图

GPIO的同步性约束

因此三个管脚的delay应该是:

Delay(ld0) = -(4.546+210.804/1000)=-4.756ns

Delay(ld1) = -(4.663+217.94/1000)=-4.881ns

Delay(ld2) = -(4.535+79.947/1000)=-4.615ns

1) ld_1 - ld_0 = (-4.756)-(-4.881)=-125ps

2) ld_1 – ld_2 = (-4.881)-(-4.615)=-266ps

3) ld_2 – ld_0 = (-4.615)-(-4.756)=141ps

与实际测量值比较

测了三组上升沿之间的差值分布数据:

1) ld_1 - ld_0 -130ps

2) ld_1 – ld_2 -250ps

3) ld_2 – ld_0 +60ps

从这个结果中,假设ld0与ld1的板上pcb布线延时为x,ld2板上布线延时为y,则理论值计算中:

4) ld_1 - ld_0 = (-4.756-x)-(-4.881-x)=-125ps

5) ld_1 – ld_2 = (-4.881-x)-(-4.615-y)=-(266+x-y)ps

6) ld_2 – ld_0 = (-4.615-y)-(-4.756-x)=(141+x-y)ps

由1) 2) 4)5)可解出 x-y=-21ps,带入6)则 ld2-ld0=120ps, 由于1)与4),2)与5)之间存在测量的误差,这部分可能引入到计算中,因此包含了20ps左右的误差,这样看来,理论值与测量值的差距为120-60-20=40ps,与实际测量值偏差还是有些大。

这个原因就不好找了,可能由于手抖的测量问题,也可能是ld0与-ld1的实际pcb走线并不相等,差别还是客观存在的。再次不再深入分析。

方法一结论:

方法一,当前FPGA可以满足3个GPIO信号之间200ps(FPGA内部)的时延范围。

需要注意的问题:

1) 工程阶段,需要根据实际逻辑情况进行约束,会增加工程测试时间;

2) 3个GPIO一定要选择在FPGA管脚的物理上相邻位置,同时要查询pin_delay的表格找到delay相近的三个管脚,最好上下各空出一个io管脚,保证管脚附近有充足的布线资源和寄存器资源,这一点非常重要;

3) 由于逻辑确定后,FPGA走线延时可以确定,因此可以对此进行一定的校正。

方法二、

跟FAE沟通后,又提供了一种思路,使用OBUF中的寄存器。这意味着ld信号出来之后是在各个GPIO的管脚位置开始分叉,用各自的寄存器驱动相应的pad。时延就变成了两个因素影响:(1)各个GPIO寄存器的clock skew;(2)各个GPIO寄存器与pad的之间的pin delay+logic delay+net delay(时延非常小)。

步骤:

(1) 代码中删除don’t touch

(2) 约束文件中增加:set_property IOB TRUE [get_ports ld_?]

(3) 增加到8个ld接口,方便观察时序变化情况。

布局布线后,发现每一个之前OBUF附近的寄存器都使用起来了,ld_reg复制了多份。旧的布局(方法一中布局)如下图:

GPIO的同步性约束

新的布局如下图:

GPIO的同步性约束

时序情况如下:

GPIO的同步性约束

可以看到各个GPIO之间的延时大概差别在200ps以内。

方法二结论:

方法二,当前FPGA可以满足3个GPIO信号之间200ps(FPGA内部)的时延范围。

最终总结!!

两种方法:

1) 使用max_delay, min_delay配合don’t touch进行约束,对于资源不紧张时候可以尝试,延时控制范围更好。

2) 使用IOB TRUE 进行约束,对于资源紧张是可以使用,也能够达到200ps要求,但是延时基本固定(因为OBUF的寄存器与pad的布线是固定的)。

继续阅读