從最初學(xué)FPGA到現(xiàn)在,遇到過(guò)太多bug,但都沒(méi)有寫過(guò)博客記錄,因?yàn)槎鄶?shù)問(wèn)題都比較簡(jiǎn)單且網(wǎng)上有比較好的答案。
但最近發(fā)現(xiàn)一個(gè)布局布線的報(bào)錯(cuò),并不是因?yàn)檫壿媽?dǎo)致的,而是用戶不清楚布局布線導(dǎo)致的,且網(wǎng)上基本上相關(guān)的解答,因此把原因分析出來(lái)。
01 相關(guān)問(wèn)題報(bào)錯(cuò)
最近一些群友碰到了如下問(wèn)題,報(bào)錯(cuò)信息為:
[Place 30-719] Sub-optimal placement for a global clock-capable IO pin-IDELAY-BUFG pair. If this sub optimal condition is acceptable for this design, you may use the CLOCK_DEDICATED_ROUTE constraint in the .xdc file to demote this message to a WARNING. However, the use of this override is highly discouraged. These examples can be used directly in the .xdc file to override this clock rule.
< set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets dclk_r] >
u_IDELAYE2 (IDELAYE2.DATAOUT) is locked to IDELAY_X0Y78
and dclk_r_BUFG_inst (BUFG.I) is provisionally placed by clockplacer on BUFGCTRL_X0Y1。
圖1 place 30-719報(bào)錯(cuò)
按照錯(cuò)誤提示,在xdc中添加如下約束,然后重新綜合、布局布線。
圖2 添加約束
然后出現(xiàn)如下錯(cuò)誤,很多人可能會(huì)直接出現(xiàn)下面的錯(cuò)誤,原因都是一樣的。 報(bào)錯(cuò)信息:
[Place 30-650] Non IO buffer dclk_IBUF_BUFG_inst{BUFG} is driving IDATAIN pin of IDELAY instance u_IDELAYE2. This will lead to unroutable situation. IDATAIN pin of IDELAY instance should always get signal from IO buffer or GND.
[Place 30-99] Placer failed with error: 'Implementation Feasibility check failed, Please see the previously displayed individual error or warning messages for more details.'
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
圖3 報(bào)錯(cuò)信息
上述報(bào)錯(cuò)其實(shí)很奇怪,因?yàn)槌绦蛑衖delaye2的IDATAIN是連接到FPGA輸入管腳的,并沒(méi)有什么問(wèn)題,報(bào)錯(cuò)不是很準(zhǔn)確。
這個(gè)錯(cuò)誤在網(wǎng)上好像還沒(méi)有具體的講解,本文解析一下具體原因,以及如何避免。
02復(fù)現(xiàn)錯(cuò)誤
之所以出現(xiàn)這個(gè)問(wèn)題,是由于不了解信號(hào)進(jìn)入fpga的走線,錯(cuò)誤使用idelaye信號(hào)導(dǎo)致的。
提供如下例程,輸入時(shí)鐘dclk與輸入數(shù)據(jù)din對(duì)齊,為了穩(wěn)定采集輸入數(shù)據(jù),內(nèi)部使用idelaye2對(duì)dclk延時(shí)24.72ns。然后內(nèi)部使用兩個(gè)ila,分別查看dclk延時(shí)前后采集到的輸入數(shù)據(jù)是否一致。
//--############################################################################################### //--# //--# File Name : top //--# Designer : 數(shù)字站 //--# Tool : Vivado 2017.4 //--# Design Date : 2024 //--# Description : //--# Version : 0.0 //--# Coding scheme : GBK(If the Chinese comment of the file is garbled, please do not save it and check whether the file is opened in GBK encoding mode) //--# //--############################################################################################### module top ( input clk ,//系統(tǒng)時(shí)鐘信號(hào); input rst ,//系統(tǒng)復(fù)位信號(hào),高電平有效; input dclk ,//串行時(shí)鐘輸入; input din ,//輸入數(shù)據(jù); output reg dout //輸出數(shù)據(jù)信號(hào); ); reg [9 : 0] din_r ; wire dclk_r ; wire clk_200m ; //例化鎖相環(huán),生成idelaye2需要的200MHz時(shí)鐘信號(hào); clk_wiz_0 u_clk_wiz ( .clk_out1 ( clk_200m ),// output clk_out1 .reset ( rst ),// input reset .clk_in1 ( clk ) // input clk_in1 ); (* IODELAY_GROUP = "IODELAY_0" *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL IDELAYCTRL u_IDELAYCTRL ( .RDY ( ),// 1-bit output: Ready output .REFCLK ( clk_200m ),// 1-bit input: Reference clock input .RST ( rst ) // 1-bit input: Active high reset input ); //例化idelaye2對(duì)時(shí)鐘信號(hào)進(jìn)行延時(shí)24*78+600=24.72ns; (* IODELAY_GROUP = "IODELAY_0" *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL IDELAYE2 #( .CINVCTRL_SEL ("FALSE" ),//Enable dynamic clock inversion (FALSE, TRUE) .DELAY_SRC ("IDATAIN" ),//Delay input (IDATAIN, DATAIN) .HIGH_PERFORMANCE_MODE ("FALSE" ),//Reduced jitter ("TRUE"), Reduced power ("FALSE") .IDELAY_TYPE ("FIXED" ),//FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE .IDELAY_VALUE (24 ),//Input delay tap setting (0-31) .PIPE_SEL ("FALSE" ),//Select pipelined mode, FALSE, TRUE .REFCLK_FREQUENCY (200.0 ),//IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0). .SIGNAL_PATTERN ("CLOCK" ) //DATA, CLOCK input signal ) u_IDELAYE2 ( .CNTVALUEOUT ( ),//5-bit output: Counter value output .DATAOUT ( dclk_r ),//1-bit output: Delayed data output .C ( clk_200m ),//1-bit input: Clock input .CE ( 1'b1 ),//1-bit input: Active high enable increment/decrement input .CINVCTRL ( 'd0 ),//1-bit input: Dynamic clock inversion input .CNTVALUEIN ( 'd0 ),//5-bit input: Counter value input .DATAIN ( 'd0 ),//1-bit input: Internal delay data input .IDATAIN ( dclk ),//1-bit input: Data input from the I/O .INC ( 'd0 ),//1-bit input: Increment / Decrement tap delay input .LD ( 'd0 ),//1-bit input: Load IDELAY_VALUE input .LDPIPEEN ( 'd0 ),//1-bit input: Enable PIPELINE register to load data input .REGRST ( rst ) //1-bit input: Active-high reset tap-delay input ); //移位輸出數(shù)據(jù); always@(posedge dclk_r)begin {dout,din_r[9:0]} <= {din_r[9:0],din}; end //ila使用延時(shí)前的時(shí)鐘采集din_r的數(shù)據(jù); ila_0 u_ila_0 ( .clk (dclk ),// input wire clk .probe0 (din_r ) // input wire [9:0] probe0 ); //ila使用延時(shí)后的時(shí)鐘采集din_r的數(shù)據(jù); ila_0 u_ila_1 ( .clk (dclk_r ),// input wire clk .probe0 (din_r ) // input wire [9:0] probe0 ); endmodule
上述例程的邏輯思路和代碼大家應(yīng)該都能夠理解,也沒(méi)有邏輯錯(cuò)誤。然后使用vivado創(chuàng)建工程,綜合,分配管教腳,最后布局布線。
綜合不會(huì)出現(xiàn)問(wèn)題,因?yàn)闆](méi)有邏輯和語(yǔ)法錯(cuò)誤,但布局布線后會(huì)出現(xiàn)圖3的錯(cuò)誤,如下圖所示。
圖4 復(fù)現(xiàn)問(wèn)題
03分析問(wèn)題
是不是覺得很離譜?邏輯沒(méi)問(wèn)題,為什么布局布線失敗。
需要通過(guò)正常的工程,才能分析出錯(cuò)誤的原因,因此先將兩個(gè)ila相關(guān)的代碼注釋掉,如下所示。
//--############################################################################################### //--# //--# File Name : top //--# Designer : 數(shù)字站 //--# Tool : Vivado 2017.4 //--# Design Date : 2024 //--# Description : //--# Version : 0.0 //--# Coding scheme : GBK(If the Chinese comment of the file is garbled, please do not save it and check whether the file is opened in GBK encoding mode) //--# //--############################################################################################### module top ( input clk ,//系統(tǒng)時(shí)鐘信號(hào); input rst ,//系統(tǒng)復(fù)位信號(hào),高電平有效; input dclk ,//串行時(shí)鐘輸入; input din ,//輸入數(shù)據(jù); output reg dout //輸出數(shù)據(jù)信號(hào); ); reg [9 : 0] din_r ; wire dclk_r ; wire clk_200m ; //例化鎖相環(huán),生成idelaye2需要的200MHz時(shí)鐘信號(hào); clk_wiz_0 u_clk_wiz ( .clk_out1 ( clk_200m ),// output clk_out1 .reset ( rst ),// input reset .clk_in1 ( clk ) // input clk_in1 ); (* IODELAY_GROUP = "IODELAY_0" *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL IDELAYCTRL u_IDELAYCTRL ( .RDY ( ),// 1-bit output: Ready output .REFCLK ( clk_200m ),// 1-bit input: Reference clock input .RST ( rst ) // 1-bit input: Active high reset input ); //例化idelaye2對(duì)時(shí)鐘信號(hào)進(jìn)行延時(shí)24*78+600=24.72ns; (* IODELAY_GROUP = "IODELAY_0" *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL IDELAYE2 #( .CINVCTRL_SEL ("FALSE" ),//Enable dynamic clock inversion (FALSE, TRUE) .DELAY_SRC ("IDATAIN" ),//Delay input (IDATAIN, DATAIN) .HIGH_PERFORMANCE_MODE ("FALSE" ),//Reduced jitter ("TRUE"), Reduced power ("FALSE") .IDELAY_TYPE ("FIXED" ),//FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE .IDELAY_VALUE (24 ),//Input delay tap setting (0-31) .PIPE_SEL ("FALSE" ),//Select pipelined mode, FALSE, TRUE .REFCLK_FREQUENCY (200.0 ),//IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0). .SIGNAL_PATTERN ("CLOCK" ) //DATA, CLOCK input signal ) u_IDELAYE2 ( .CNTVALUEOUT ( ),//5-bit output: Counter value output .DATAOUT ( dclk_r ),//1-bit output: Delayed data output .C ( clk_200m ),//1-bit input: Clock input .CE ( 1'b1 ),//1-bit input: Active high enable increment/decrement input .CINVCTRL ( 'd0 ),//1-bit input: Dynamic clock inversion input .CNTVALUEIN ( 'd0 ),//5-bit input: Counter value input .DATAIN ( 'd0 ),//1-bit input: Internal delay data input .IDATAIN ( dclk ),//1-bit input: Data input from the I/O .INC ( 'd0 ),//1-bit input: Increment / Decrement tap delay input .LD ( 'd0 ),//1-bit input: Load IDELAY_VALUE input .LDPIPEEN ( 'd0 ),//1-bit input: Enable PIPELINE register to load data input .REGRST ( rst ) //1-bit input: Active-high reset tap-delay input ); //移位輸出數(shù)據(jù); always@(posedge dclk_r)begin {dout,din_r[9:0]} <= {din_r[9:0],din}; end //ila使用延時(shí)前的時(shí)鐘采集din_r的數(shù)據(jù); //ila_0 u_ila_0 ( // .clk (dclk ),// input wire clk // .probe0 (din_r ) // input wire [9:0] probe0 //); //ila使用延時(shí)后的時(shí)鐘采集din_r的數(shù)據(jù); //ila_0 u_ila_1 ( // .clk (dclk_r ),// input wire clk // .probe0 (din_r ) // input wire [9:0] probe0 //); endmodule重新綜合、實(shí)現(xiàn)工程后,在“IMPLEMENTATION”界面下雙擊“open Implemented Design”,如下所示。

圖5 打開布局布線
在“Device”界面中找到DCLK引腳,如下圖所示。
圖6 Device界面
如下圖所示,首先點(diǎn)擊圖中1處,就能查看芯片內(nèi)部的實(shí)際走線了,如下圖所示,左邊為DCLK對(duì)應(yīng)的管腳,信號(hào)進(jìn)入管腳后,沿著綠色的走線,先到達(dá)idelaye2的輸入,經(jīng)過(guò)延時(shí)后輸出到ILOGIC。
圖7 DCLK輸入走線
將上圖中idelaye2和ilogic部分放大,如下圖所示,藍(lán)色走線是DCLK管腳輸入,紅色是idelaye2輸出繞過(guò)ilogic進(jìn)入FPGA內(nèi)部邏輯的走線。
圖8 信號(hào)走線
上述是輸入信號(hào)進(jìn)入FPGA管腳,經(jīng)過(guò)idelaye2延時(shí),繞過(guò)ilogic進(jìn)入FPGA內(nèi)部邏輯的走線。注意這部分是專用走線(固定不變的走線,只要使用idelaye2,不使用ilogic,走線就不會(huì)變),不是可編程的。
同時(shí)用戶需要知道,外部信號(hào)進(jìn)入FPGA管腳后,只有經(jīng)過(guò)ilogic(包括繞過(guò))才能被FPGA內(nèi)部邏輯所使用。
接下來(lái)分析不使用idelaye2的信號(hào)輸入走線,找到din信號(hào)對(duì)應(yīng)管腳,如下圖所示。
圖9 din進(jìn)入fpga走線
放大din在ilogic部分的走線,如下所示。din的管腳輸入信號(hào)不經(jīng)過(guò)idelaye2,同時(shí)繞過(guò)ilogic后輸入到FPGA內(nèi)部邏輯。
圖10 din的ilogic走線
對(duì)比圖8和圖10就能找到前文出現(xiàn)錯(cuò)誤的原因了。如果使用了經(jīng)過(guò)idelaye2延時(shí)前后的同一個(gè)管腳輸入信號(hào),該如何走線?
如下圖所示,在進(jìn)入內(nèi)部邏輯之前,都需要繞過(guò)ilogic。藍(lán)色和紫色為idelaye2延時(shí)前的信號(hào)進(jìn)入內(nèi)部邏輯的走線,而紅色和紫色為idelaye2延時(shí)后的信號(hào)進(jìn)入內(nèi)部邏輯的走線,紫色為兩個(gè)信號(hào)重合的走線。
一根線不能同時(shí)傳輸兩個(gè)信號(hào),因此布局布線失敗。
圖11 idelaye2延時(shí)前后的信號(hào)走線
回到前文的問(wèn)題,ila0使用了dclk沒(méi)有經(jīng)過(guò)idlaye2延時(shí)的信號(hào)作為時(shí)鐘信號(hào),而ila1使用dclk經(jīng)過(guò)idelaye2延時(shí)后的信號(hào)作為時(shí)鐘信號(hào)。
同時(shí)使用了dclk延時(shí)前后的信號(hào),最終導(dǎo)致布局布線失敗。
04解決辦法
上述問(wèn)題的原因就是內(nèi)部邏輯同時(shí)使用idelaye2延時(shí)前后的兩個(gè)信號(hào)導(dǎo)致的,最直接的方法就是不這么去用,始終只使用其中一個(gè)就可以避免。
如果實(shí)在要這么用,也有其他方法,只不過(guò)會(huì)導(dǎo)致管腳到idelaye2的走線比較長(zhǎng),而且不是專用走線(每次布局后如果idelaye2位置發(fā)生變化,則走線延時(shí)也會(huì)變),引入的延時(shí)不穩(wěn)定性會(huì)導(dǎo)致調(diào)試很麻煩,且不易于移植,一般不建議這么做。
具體實(shí)現(xiàn)思路是,既然內(nèi)部要同時(shí)使用idelaye2延時(shí)前后的信號(hào),而dclk引腳繞過(guò)ilogic的走線知有一條,那么就先讓不經(jīng)過(guò)idelaye2的信號(hào)進(jìn)入內(nèi)部邏輯,然后在使用其余管腳的idelaye2來(lái)對(duì)輸入的信號(hào)進(jìn)行延時(shí),這樣不就解決了?
對(duì)應(yīng)代碼如下所示,將兩個(gè)ila的注釋取消,同時(shí)將idelaye2的DELAY_SRC參數(shù)設(shè)置為DATAIN,輸入來(lái)自內(nèi)部邏輯。
//--############################################################################################### //--# //--# File Name : top //--# Designer : 數(shù)字站 //--# Tool : Vivado 2017.4 //--# Design Date : 2024 //--# Description : //--# Version : 0.0 //--# Coding scheme : GBK(If the Chinese comment of the file is garbled, please do not save it and check whether the file is opened in GBK encoding mode) //--# //--############################################################################################### module top ( input clk ,//系統(tǒng)時(shí)鐘信號(hào); input rst ,//系統(tǒng)復(fù)位信號(hào),高電平有效; input dclk ,//串行時(shí)鐘輸入; input din ,//輸入數(shù)據(jù); output reg dout //輸出數(shù)據(jù)信號(hào); ); reg [9 : 0] din_r ; wire dclk_r ; wire clk_200m ; //例化鎖相環(huán),生成idelaye2需要的200MHz時(shí)鐘信號(hào); clk_wiz_0 u_clk_wiz ( .clk_out1 ( clk_200m ),// output clk_out1 .reset ( rst ),// input reset .clk_in1 ( clk ) // input clk_in1 ); (* IODELAY_GROUP = "IODELAY_0" *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL IDELAYCTRL u_IDELAYCTRL ( .RDY ( ),// 1-bit output: Ready output .REFCLK ( clk_200m ),// 1-bit input: Reference clock input .RST ( rst ) // 1-bit input: Active high reset input ); //例化idelaye2對(duì)時(shí)鐘信號(hào)進(jìn)行延時(shí)24*78+600=24.72ns; (* IODELAY_GROUP = "IODELAY_0" *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL IDELAYE2 #( .CINVCTRL_SEL ("FALSE" ),//Enable dynamic clock inversion (FALSE, TRUE) .DELAY_SRC ("DATAIN" ),//Delay input (IDATAIN, DATAIN) .HIGH_PERFORMANCE_MODE ("FALSE" ),//Reduced jitter ("TRUE"), Reduced power ("FALSE") .IDELAY_TYPE ("FIXED" ),//FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE .IDELAY_VALUE (24 ),//Input delay tap setting (0-31) .PIPE_SEL ("FALSE" ),//Select pipelined mode, FALSE, TRUE .REFCLK_FREQUENCY (200.0 ),//IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0). .SIGNAL_PATTERN ("CLOCK" ) //DATA, CLOCK input signal ) u_IDELAYE2 ( .CNTVALUEOUT ( ),//5-bit output: Counter value output .DATAOUT ( dclk_r ),//1-bit output: Delayed data output .C ( clk_200m ),//1-bit input: Clock input .CE ( 1'b1 ),//1-bit input: Active high enable increment/decrement input .CINVCTRL ( 'd0 ),//1-bit input: Dynamic clock inversion input .CNTVALUEIN ( 'd0 ),//5-bit input: Counter value input .DATAIN ( dclk ),//1-bit input: Internal delay data input .IDATAIN ( 'd0 ),//1-bit input: Data input from the I/O .INC ( 'd0 ),//1-bit input: Increment / Decrement tap delay input .LD ( 'd0 ),//1-bit input: Load IDELAY_VALUE input .LDPIPEEN ( 'd0 ),//1-bit input: Enable PIPELINE register to load data input .REGRST ( rst ) //1-bit input: Active-high reset tap-delay input ); //移位輸出數(shù)據(jù); always@(posedge dclk_r)begin {dout,din_r[9:0]} <= {din_r[9:0],din}; end //ila使用延時(shí)前的時(shí)鐘采集din_r的數(shù)據(jù); ila_0 u_ila_0 ( .clk (dclk ),// input wire clk .probe0 (din_r ) // input wire [9:0] probe0 ); //ila使用延時(shí)后的時(shí)鐘采集din_r的數(shù)據(jù); ila_0 u_ila_1 ( .clk (dclk_r ),// input wire clk .probe0 (din_r ) // input wire [9:0] probe0 ); endmodule
圖12 idelaye2對(duì)內(nèi)部信號(hào)延時(shí)
重新綜合、布局布線,然后打開“Device”界面,找到dclk引腳。如下圖所示DCLK進(jìn)入FPGA后,通過(guò)藍(lán)色走線到達(dá)bufg輸入,然后經(jīng)過(guò)粉色走線到達(dá)右上角的一個(gè)管腳的idelaye2,然后黃色走線是idelaye2輸出信號(hào)。
圖13 修改后的布局
由此可知采用這種方式時(shí)藍(lán)色、粉色、黃色走線都是很長(zhǎng)的,導(dǎo)致延時(shí)特別大,有興趣的用戶可以看下時(shí)序報(bào)告,這個(gè)延時(shí)可能會(huì)比idelaye2能夠調(diào)節(jié)范圍還大,因此不建議使用。
這種使用方式不同芯片的idelaye2布局也基本上不相同,所以移植其實(shí)也麻煩。
除了約束以外,可以利用某些手段(比如bufr)去限制idelaye2布局位置,來(lái)減小走線延時(shí),但相比專用走線,還是沒(méi)有優(yōu)勢(shì)。
這種問(wèn)題能夠體現(xiàn)對(duì)于底層器件的理解,平時(shí)有時(shí)間可以留意一下器件布局布線的方式。
來(lái)源: 本文轉(zhuǎn)載自數(shù)字站公眾號(hào)
-
FPGA
+關(guān)注
關(guān)注
1642文章
21918瀏覽量
611979 -
時(shí)鐘
+關(guān)注
關(guān)注
11文章
1856瀏覽量
132659 -
布線
+關(guān)注
關(guān)注
9文章
786瀏覽量
84786 -
輸入信號(hào)
+關(guān)注
關(guān)注
0文章
471瀏覽量
12797
原文標(biāo)題:輸入信號(hào)繞過(guò)ilogic布線沖突引發(fā)的問(wèn)題(idelaye2使用)
文章出處:【微信號(hào):FPGA研究院,微信公眾號(hào):FPGA研究院】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
菜鳥想請(qǐng)教關(guān)于布局布線和chipshope的問(wèn)題。
FPGA去耦電容如何布局布線
PCB布局和布線的設(shè)計(jì)技巧
布局布線技術(shù)的發(fā)展
pcb布線心得(流程詳解、元件布局布線與EMC)
PCB布局布線的100個(gè)基本問(wèn)題解答
PCB設(shè)計(jì)布局布線技巧分享
FPGA設(shè)計(jì)的塑封式布局和布線介紹

FPGA的布局布線

FPGA設(shè)計(jì)的五個(gè)主要任務(wù)
PCB布局布線技巧104問(wèn)
fpga布局布線算法加速
FPGA布局布線的可行性 FPGA布局布線失敗怎么辦

評(píng)論