9.1 IO 接口
本小節(jié)中的示例說明了該如何定義 DUA 輸入和輸出接口的約束。后面的小節(jié)介紹了 SRAM 和 DDR SDRAM 接口的時序約束示例。
9.1.1 輸入接口
有兩種指定輸入接口時序要求的方法:
以 AC 約束的形式指定 DUA 輸入端的波形。
指定外部邏輯到輸入的路徑延遲。
指定輸入端口的波形
考慮圖 9-1 中所示的輸入 AC 約束:輸入 CIN 在時鐘 CLKP 的上升沿之前 4.3ns 必須保持穩(wěn)定,并且必須要保持穩(wěn)定直到時鐘上升沿之后 2ns。
圖 9-1
首先考慮 4.3ns 的約束,給定時鐘周期為 8ns(如圖 9-1 所示),這約束了從虛擬觸發(fā)器(驅(qū)動該輸入的觸發(fā)器)到輸入端口 CIN 的延遲。從虛擬觸發(fā)器時鐘引腳到 CIN 的延遲最大為 3.7ns(= 8.0-4.3), 這樣可確保輸入 CIN 處的數(shù)據(jù)在上升沿之前 4.3ns 到達(dá)。因此,AC 約束的這一部分可以等效地指定為 3.7ns 的最大輸入延遲。
AC 約束還指出,輸入 CIN 在時鐘上升沿之后 2ns 必須繼續(xù)保持穩(wěn)定,這也約束了虛擬觸發(fā)器的延遲,即從虛擬觸發(fā)器到輸入 CIN 的延遲必須至少為 2.0ns。因此,最小輸入延遲指定為 2.0ns。
以下是輸入延遲約束:
create_clock -name CLKP -period 8 [get_ports CLKP]
set_input_delay -min 2.0 -clock CLKP [get_ports CIN]
set_input_delay -max 3.7 -clock CLKP [get_ports CIN]
以下是設(shè)計在這些輸入延遲約束下的路徑報告,首先是建立時間檢查:
指定的最大輸入延遲(3.7ns)被添加到了數(shù)據(jù)路徑中。建立時間檢查會確保 DUA 內(nèi)部的延遲小于 4.3ns,這樣就可以鎖存到正確的數(shù)據(jù)。接下來是保持時間檢查:
最小輸入延遲將被添加到保持時間檢查的數(shù)據(jù)路徑中。該檢查可確保最早的數(shù)據(jù)在時鐘沿之后的 2ns 處才變化,這樣就不會覆蓋觸發(fā)器上捕獲到的先前數(shù)據(jù)。
指定輸入端口的路徑延遲
已知連接到輸入的外部邏輯的路徑延遲后,指定輸入約束就是一件很簡單的事情了。將沿外部邏輯路徑到輸入的任何延遲全部相加起來,然后使用 set_input_delay 命令去指定路徑延遲。
圖 9-2 給出了一條輸入的外部邏輯路徑示例。Tck2q 和 Tc1 延遲相加就是外部延遲,知道了 Tck2q 和 Tc1,就可以直接獲得輸入延遲,即 Tck2q + Tc1。
圖 9-2
外部邏輯的最大和最小路徑延遲可以轉(zhuǎn)換為以下輸入延遲約束:
create_clock -name RCLK -period 10 [get_ports RCLK]
set_input_delay -max 6.2 -clock RCLK [get_ports INIT]
set_input_delay -min 3.0 -clock RCLK [get_ports INIT]
上述輸入延遲約束的時序檢查路徑報告與 8.1 節(jié)和 8.2 節(jié)中的報告類似。
請注意,在計算設(shè)計內(nèi)部觸發(fā)器數(shù)據(jù)引腳的實際到達(dá)時間時,將會根據(jù)執(zhí)行的是最大路徑(建立時間)檢查還是最小路徑(保持時間)檢查,分別選擇將輸入延遲的最大值或最小值添加到數(shù)據(jù)路徑延遲中去。
9.1.2 輸出接口
與輸入接口類似,也可以使用兩種方法來指定輸出時序要求:
以 AC 約束的形式指定 DUA 輸出端的波形。
指定輸出到外部邏輯的路徑延遲。
指定輸出端口的波形
考慮圖 9-3 中所示的輸出 AC 約束:在時鐘 CLKP 的上升沿之前 2ns,輸出 QOUT 就應(yīng)保持穩(wěn)定。同樣,輸出 QOUT 需要保持穩(wěn)定直到時鐘上升沿之后的 1.5ns 為止。通??蓮呐c QOUT 接口的外部模塊的建立時間和保持時間要求中獲得這些約束值。
圖 9-3
以下是對輸出端口時序要求進(jìn)行的約束:
create_clock -name CLKP -period 6 -waveform {0 3} [get_ports CLKP]
set_output_delay -clock CLKP -max 2.0 [get_ports QOUT]
set_output_delay -clock CLKP -min -1.5 [get_ports QOUT]
最大輸出路徑延遲指定為了 2.0ns,這將確保數(shù)據(jù) QOUT 在時鐘沿前 2ns 之前允許改變。從虛擬觸發(fā)器的角度來看,最小輸出路徑延遲指定為了 -1.5ns,這用于確保在輸出 QOUT 上 1.5ns 的保持時間要求。1.5ns 的保持時間要求就是 set_output_delay 中指定的最小值 -1.5。
以下是建立時間檢查的路徑報告:
在建立時間檢查中,將從下一個時鐘沿減去最大的輸出延遲,以確定在 DUA 輸出處數(shù)據(jù)需要到達(dá)的時間。
接下來是保持時間檢查的路徑報告:
在保持時間檢查中,將從捕獲時鐘邊沿中減去最小的輸出延遲(-1.5ns),以確定滿足保持時間要求的 DUA 輸出的數(shù)據(jù)最早到達(dá)時間。注意,最小輸出延遲為負(fù)值很常見。
指定輸出端口的路徑延遲
在這種情況下,將明確指定外部邏輯的路徑延遲。請參見圖 9-4 中的示例:
圖 9-4
讓我們首先檢查建立時間,由 Tc2_max 和 Tsetup 可獲得最大輸出延遲(set_output_delay -max)。為了檢查 DUA 內(nèi)部觸發(fā)器(例如 UFF0)和虛擬觸發(fā)器之間輸出路徑的建立時間要求,最大輸出延遲可指定為 Tc2_max + Tsetup。
接下來,讓我們檢查保持時間,由 Tc2_min 和 Thold 可獲得最小輸出延遲(set_output_delay -min)。由于捕獲觸發(fā)器的保持時間被添加到了捕獲時鐘路徑中,因此最小輸出延遲指定為 Tc2_min-Thold。
以下是輸出延遲約束:
create_clock -name SCLK -period 5 [get_ports SCLK]
set_output_delay -max 3.1 -clock SCLK [get_ports RDY]
set_output_delay -min 1.45 -clock SCLK [get_ports RDY]
這些路徑報告與 8.1 節(jié)和 8.2 節(jié)中的報告相似。
9.1.3 時序窗口內(nèi)的輸出變化
set_output_delay 命令可用于指定輸出信號相對于時鐘的最大和最小到達(dá)時間。本節(jié)考慮特殊情況,當(dāng)輸出只能在相對于時鐘沿的時序窗口內(nèi)發(fā)生改變時,可以指定輸出延遲約束來驗證時序,在驗證源同步(source synchronous)接口的時序時尤其常用。
在源同步接口中,時鐘也與數(shù)據(jù)一起輸出。在這種情況下,通常時鐘和數(shù)據(jù)之間需要有一個時序關(guān)系。例如,可能僅在時鐘上升沿附近的特定時序窗口內(nèi)才能改變輸出數(shù)據(jù)。
源同步接口的時序要求如下圖 9-5 所示:
圖 9-5
該時序要求:DATAQ 的每個比特位(bit)只能在指定的時序窗口中改變,即在時鐘上升沿之前 2ns 以及時鐘上升沿之后 1ns 之間。這與前面各節(jié)中討論的輸出延遲約束有很大的不同,在前幾節(jié)中,要求數(shù)據(jù)引腳在時鐘上升沿附近的指定時序窗口中保持穩(wěn)定。
我們以 CLKM 為主時鐘創(chuàng)建了一個衍生時鐘 CLK_STROBE,方便去指定與該接口要求相對應(yīng)的時序約束。
create_clock -name CLKM -period 6 [get_ports CLKM]
create_generated_clock -name CLK_STROBE -source CLKM -divide_by 1 [get_ports CLK_STROBE]
通過結(jié)合建立時間和保持時間檢查以及多周期路徑約束來指定時序窗口要求。該時序要求對應(yīng)在單個上升沿(相同的發(fā)起沿和捕獲沿)處進(jìn)行建立時間檢查。因此,我們將多周期建立時間指定為 0。
- set_multicycle_path 0 -setup -to [get_ports DATAQ]
另外,保持時間檢查必須在同一時鐘沿上執(zhí)行,因此我們需要將多周期保持時間指定為 -1。
- set_multicycle_path -1 -hold -to [get_ports DATAQ]
現(xiàn)在,相對于時鐘 CLK_STROBE 指定輸出的時序約束:
set_output_delay -max -1.0 -clock CLK_STROBE [get_ports DATAQ]
set_output_delay -min +2.0 -clock CLK_STROBE [get_ports DATAQ]
請注意,輸出延遲約束中指定的最小值大于最大值。之所以會這樣,是因為在這種情況下,輸出延遲約束并不對應(yīng)于實際的邏輯塊。與典型的輸出接口(其中輸出延遲約束對應(yīng)于輸出處的邏輯塊)不同,源同步接口中的 set_output_delay 約束只是一種機(jī)制,用于驗證輸出是否被限制在了時鐘有效沿附近的指定窗口內(nèi)才能切換 。因此,我們才會有最小輸出延遲大于最大輸出延遲這樣的一種異常情況。
這是針對以上約束的建立時間檢查路徑報告:
請注意,數(shù)據(jù)發(fā)起沿和捕獲沿都為在 0 時刻處的相同時鐘沿。該報告顯示 DATAQ 在 0.61ns 處變化,而 CLK_STROBE 在 0.09ns 處變化。由于 DATAQ 可以在 CLK_STROBE 的 1ns 內(nèi)被允許變化,因此在考慮了 0.3ns 的時鐘不確定性后,正裕量為 0.18ns。
以下是保持時間檢查的路徑報告,用于檢查時鐘另一側(cè)的界限:
在上述最小路徑分析中,DATAQ 在 0.48ns 處到達(dá),而 CLK_STROBE 在 0.09ns 處到達(dá)。由于要求是數(shù)據(jù)最早可以在 CLK_STROBE 之前 2ns 處發(fā)生改變,因此在考慮了 50ps 的時鐘不確定度后,我們獲得了 2.35ns 的正裕量。
源同步接口的另一個示例如圖 9-6 所示。在這種情況下,輸出時鐘是主時鐘的二分頻,并且是數(shù)據(jù)同步接口的一部分。輸出 POUT 被限制在 QCLKOUT 之前 2ns 和之后 1ns 之間才能進(jìn)行改變。
圖 9-6
以下是這種情況的時序約束:
create_clock -name CLKM -period 6 [get_ports CLKM]
create_generated_clock -name QCLKOUT -source CLKM -divide_by 2 [get_ports QCLKOUT]
set_multicycle_path 0 -setup -to [get_ports POUT]
set_multicycle_path -1 -hold -to [get_ports POUT]
set_output_delay -max -1.0 -clock QCLKOUT [get_ports POUT]
set_output_delay -min +2.0 -clock QCLKOUT [get_ports POUT]
以下是建立時間檢查的路徑報告:
請注意,多周期路徑約束已將建立時間檢查沿向后移了一個周期,以便在同一時鐘沿執(zhí)行檢查。輸出 POUT 在 0.61ns 處變化,而時鐘 QCLKOUT 在 0.27ns 處變化?;谠跁r鐘沿 1ns 內(nèi)允許變化的要求,并考慮 0.30ns 的時鐘不確定度,我們可得 0.36ns 的正裕量。
接下來是保持時間檢查的路徑報告,用于檢查時序窗口要求的另一個約束:
路徑報告顯示,數(shù)據(jù)是在 QCLKOUT 時鐘邊沿之前的 2ns 時序窗口內(nèi)才發(fā)生改變的,并且有 2.17ns 的正裕量。
9.2 SRAM 接口
SRAM 接口中的所有數(shù)據(jù)傳輸僅發(fā)生在時鐘的有效沿處,所有信號僅在有效時鐘沿處由 SRAM 鎖存或由 SRAM 發(fā)起。組成 SRAM 接口的信號包括命令(command)、地址(address)、控制輸出總線(CAC)、雙向數(shù)據(jù)總線(DQ)和時鐘。在寫周期(write cycle)中,DUA 將數(shù)據(jù)寫到 SRAM 中去,數(shù)據(jù)和地址從 DUA 傳送到 SRAM 中去,并都在有效時鐘沿處被鎖存在 SRAM 中。在讀周期(read cycle)中,地址信號仍然從 DUA 傳送到 SRAM 中去,而數(shù)據(jù)信號則是由 SRAM 輸出給 DUA 的。因此,地址和控制信號是單向的且方向為從 DUA 到 SRAM,如圖 9-7 所示。通常將延遲鎖定環(huán) DLL(Delay-Locked Loop)放置在時鐘路徑中,DLL 允許在必要時延遲時鐘信號,以解決由于 PVT 和其它外部變化而導(dǎo)致接口上各種信號的延遲變化。通過考慮這些變化,在往返于 SRAM 的讀周期和寫周期中,都將有良好的時序裕度可用于數(shù)據(jù)傳輸。
圖 9-7
圖 9-8 顯示了典型 SRAM 接口的 AC 特性。請注意,圖 9-8 中的數(shù)據(jù)輸入和數(shù)據(jù)輸出是指 SRAM 看到的方向。來自 SRAM 的 Data out 是 DUA 的輸入,進(jìn)入 SRAM 的 Data in 是 DUA 的輸出。
圖 9-8
圖 9-8 中的要求可以轉(zhuǎn)換為用于 DUA 與 SRAM 之間接口的以下 IO 接口約束:
create_clock -name PLL_CLK -period 5 [get_pins UPLL0/CLKOUT]
create_generated_clock -name SRAM_CLK -source [get_pins UPLL0/CLKOUT] -divide_by 1 [get_ports SRAM_CLK]
set_output_delay -max 1.5 -clock SRAM_CLK [get_ports ADDR[*]]
set_output_delay -min -0.5 -clock SRAM_CLK [get_ports ADDR[*]]
set_output_delay -max 1.7 -clock SRAM_CLK [get_ports DQ[*]]
set_output_delay -min -0.8 -clock SRAM_CLK [get_ports DQ[*]]
set_input_delay -max 3.2 -clock SRAM_CLK [get_ports DQ[*]]
set_input_delay -min 1.7 -clock SRAM_CLK [get_ports DQ[*]]
以下是典型地址引腳的建立時間檢查路徑報告:
建立時間檢查將驗證地址信號是否在 SRAM_CLK 時鐘沿之前 1.5ns(SRAM 地址引腳的建立時間)到達(dá) SRAM。
以下是相同地址引腳的保持時間檢查路徑報告:
保持時間檢查將驗證地址信號在 SRAM_CLK 時鐘沿之后是否繼續(xù)保持穩(wěn)定了 0.5ns。