??set_input_delay屬于時序約束中的IO約束,我之前的時序約束教程中,有一篇關于set_input_delay的文章,但里面寫的并不是很詳細,今天我們就來詳細分析一下,這個約束應該如何使用。
??首先還是需要明確一點,這個約束沒有延遲的作用,如果需要對輸入信號做延遲,就要使用IODELAY這種原語。
什么是input_delay?
??input_delay是指輸入的數據到達FPGA的pad時相對于時鐘邊沿的延遲有多大,單位是ns,數值可以是正,也可以是負。

假設時鐘是沒有skew的,那么上圖中的input_delay就等于Clock to Out
+Trace Dealy
,即上游器件的時鐘到觸發器輸出的延時+PCB上的布線延遲,即Tco+Tdelay
。
但我們實際的應用,碰到的大多數情況都是隨路時鐘,也就是說上游器件輸出數據的同時也會輸出時鐘給FPGA,就像下圖所示:

set_input_delay語法
set_input_delay?[?clock?]?[?reference_pin?]?[?clock_fall]
????[?rise]?[?fall]?[?max]?[?min]?[?add_delay]?[?network_latency_included]
????[?source_latency_included]?[?quiet]?[?verbose]??
Name | Description |
---|---|
[-clock] |
Relative clock |
[-reference_pin] |
Relative pin or port |
[-clock_fall] |
Delay is relative to falling edge of clock |
[-rise] |
Specifies rising delay |
[-fall] |
Specifies falling delay |
[-max] |
Specifies maximum delay |
[-min] |
Specifies minimum delay |
[-add_delay] |
Don't remove existing input delay |
[-network_latency_included] |
Specifies network latency of clock already included |
[-source_latency_included] |
Specifies source latency of clock already included |
[-quiet] |
Ignore command errors |
[-verbose] |
Suspend message limits during command execution |
|
Delay value |
|
List of ports |
下面來詳細說明一下:
-clock
:input_delay一般是相對時鐘而言的,而且默認是相對于上升沿,我們可以通過clock_fall
參數來指定下降沿,這里的時鐘可以是虛擬時鐘;
-reference_pin
:指定相對于某個pin上的時鐘邊沿,跟-clock
的參數其實是一個意思,畢竟時鐘也是通過pin輸入進來的;
-clock_fall
:指定相對于時鐘下降沿
-rise
:指定端口的上升轉換的輸入延遲
-fall
:指定端口的下降沿的輸入延遲
-max
:最大延遲
-min
:最小延遲,我們做input delay主要就是約束這兩個參數
-add_delay
:以增量的方式添加延遲,如果不加該參數,默認行為是替換現有的延時
-network_latency_included
:表示參考時鐘的網絡延遲也包含在延遲中
-source_latency_included
:跟上一個參數類似的含義,該參數表示時鐘的源端延遲包含在延時中
-quiet
:忽略指令的錯誤信息,即便指令錯了也依然返回TCL_OK
-verbose
:命令執行期間忽略消息數量的限制,就是說會返回該指令的所有的message
delay
:延遲值
objects
:端口列表
Vivado Timing Constraints Wizard
很多約束時鐘vivado中的Timing Constraints Wizard
工具會方便很多,對于input delay的約束,界面如下:

我們需要設置的就是數據相對于時鐘的最大和最小的延時,trce_dly_min
和trce_dly_max
是指布線的延遲,一般隨路時鐘跟數據都會采用等長布線的方式,因此可以設置為0即可。
在設置完成后,下面的Tcl Command Preview
中就會出現約束的tcl語法,這種方式對于該約束是很了解或者懶得手寫約束的朋友來說非常的方便。

Examples
1.輸入數據比時鐘延遲3ns的delay:
create_clock?-name?clk?-period?10?[get_ports?clk_in]
set_input_delay?-clock?clk?3?[get_ports?DIN]
2.輸入數據相對于時鐘的下降沿有2ns的delay:
set_input_delay?-clock_fall?-clock?clk?2?[get_ports?DIN]
3.復位管腳相對于BUFG輸出的時鐘有2ns的delay:
set_input_delay?-clock?wbClk?2?-reference_pin?[get_pin?wbClk_IBUF_BUFG_inst/O]?[get_ports?reset]
4.時鐘虛擬時鐘的約束
虛擬失蹤的具體時鐘方式可以參考另一篇文章
外部IO的參考時鐘比設計中主時鐘的路徑上多了一個BUFFER

create_clock?-name?sysclk?-period?10?[get_ports?clkin]
create_clock?-name?virtclk?-period?10
set_clock_latency?-source?1?[get_clock?virtclk]
set_input_delay?-clock?virtclk?-max?4?[get_ports?dina]
set_input_delay?-clock?virtclk?-min?2?[get_ports?dina]
5.雙沿時鐘的約束,對上升沿和下降沿都需要進行約束
create_clock?-name?clk_ddr?-period?6?[get_ports?DDR_CLK_IN]
set_input_delay?-clock?clk_ddr?-max?2.1?[get_ports?DDR_IN]
set_input_delay?-clock?clk_ddr?-max?1.9?[get_ports?DDR_IN]?-clock_fall?-add_delay
set_input_delay?-clock?clk_ddr?-min?0.9?[get_ports?DDR_IN]
set_input_delay?-clock?clk_ddr?-min?1.1?[get_ports?DDR_IN]?-clock_fall?-add_delay
具體案例
比如某器件手冊的輸出時鐘與數據的setup和hold要求如下圖:

該時鐘雙沿采樣,在時鐘邊沿到來后,結合input_delay的最大最小延遲的定義,可以知道:
- 最小延遲就是hold time,因為如果比hold time還小了,那保持時間就不滿足了,即1.2ns
- 最大延遲是時鐘周期-setup time,這里上下沿之間的間隔是4ns,因此max delay是2.8ns
因此input delay的約束如下:
set_input_delay?-clock?[get_clocks?rx_clk]?-min?1.200?[get_ports?RXD0]?-add_delay
set_input_delay?-clock?[get_clocks?rx_clk]?-min?1.200?[get_ports?RXD1]?-add_delay
set_input_delay?-clock?[get_clocks?rx_clk]?-min?1.200?[get_ports?RXD2]?-add_delay
set_input_delay?-clock?[get_clocks?rx_clk]?-min?1.200?[get_ports?RXD3]?-add_delay
set_input_delay?-clock?[get_clocks?rx_clk]?-min?1.200?[get_ports?RXC]?-add_delay
set_input_delay?-clock?[get_clocks?rx_clk]?-max?2.800?[get_ports?RXD0]?-add_delay
set_input_delay?-clock?[get_clocks?rx_clk]?-max?2.800?[get_ports?RXD1]?-add_delay
set_input_delay?-clock?[get_clocks?rx_clk]?-max?2.800?[get_ports?RXD2]?-add_delay
set_input_delay?-clock?[get_clocks?rx_clk]?-max?2.800?[get_ports?RXD3]?-add_delay
set_input_delay?-clock?[get_clocks?rx_clk]?-max?2.800?[get_ports?RXC]?-add_delay
set_input_delay?-clock?[get_clocks?rx_clk]?-min?1.200?[get_ports?RXD0]?-clock_fall?-add_delay
set_input_delay?-clock?[get_clocks?rx_clk]?-min?1.200?[get_ports?RXD1]?-clock_fall?-add_delay
set_input_delay?-clock?[get_clocks?rx_clk]?-min?1.200?[get_ports?RXD2]?-clock_fall?-add_delay
set_input_delay?-clock?[get_clocks?rx_clk]?-min?1.200?[get_ports?RXD3]?-clock_fall?-add_delay
set_input_delay?-clock?[get_clocks?rx_clk]?-min?1.200?[get_ports?RXC]?-clock_fall?-add_delay
set_input_delay?-clock?[get_clocks?rx_clk]?-max?2.800?[get_ports?RXD0]?-clock_fall?-add_delay
set_input_delay?-clock?[get_clocks?rx_clk]?-max?2.800?[get_ports?RXD1]?-clock_fall?-add_delay
set_input_delay?-clock?[get_clocks?rx_clk]?-max?2.800?[get_ports?RXD2]?-clock_fall?-add_delay
set_input_delay?-clock?[get_clocks?rx_clk]?-max?2.800?[get_ports?RXD3]?-clock_fall?-add_delay
set_input_delay?-clock?[get_clocks?rx_clk]?-max?2.800?[get_ports?RXC]?-clock_fall?-add_delay
因此,只要記住:
- min_delay就是上游器件的hold time
- max_delay是時鐘周期-上游器件的setup time
- 如果是雙沿的話,就是半個時鐘周期,而且還需要對時鐘的下降沿進行約束
?
審核編輯:湯梓紅
評論