天天看點

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的布線是固定的)。

繼續閱讀