此設計範例顯示自訂程式,您可以在 SDC 檔案中使用,該程式會退回傳送針腳的所有頻率清單。如果您需要在不了解設計中的其他頻率名稱的情況下建立產生的頻率,這個程式會很有説明。使用 動態 SDC 限制設計範例簡化設計重複使用 ,提供了更多詳細資訊以及如何使用此頁面中所述自訂程式的範例。
程式的完整代碼位於頁面底部,並遵循程式運作方式的完整解釋。若要在 SDC 檔案中使用get_clocks_driving_pins自訂程式,請確保程式已定義,然後像任何其他 SDC 命令一樣將其呼叫。有兩種簡單的方法可確保在使用前已定義程式:
- 將程式碼儲存在單獨的 SDC 檔案中,並將 SDC 檔案納入專案中。
- 在使用get_clocks_driving_pins自訂程式之前,將程式碼複製並貼在任何 SDC 檔案的頂部。
獨立的 SDC 檔案
將程式碼儲存在單獨的 SDC 檔案中,使程式碼與其他限制區分開,並使在其他專案中重複使用更加簡單。如果您使用單獨的 SDC 檔案,則必須將程式中的 SDC 檔案新增到專案中的檔案清單中,而且必須顯示在任何使用此程式的 SDC 檔案上方。在讀取 SDC 檔案時,將其列于其他 SDC 檔案上方,可確保 Quartus® II 軟體在使用程式之前先定義程式。
複製與貼貼
在相同的 SDC 檔案中複製並貼上程式碼,在專案中產生較少的 SDC 檔案。如果您為其他設計師將重新使用的模組建立 SDC 檔案,在單一 SDC 檔案中包含所有限制與支援程式可能最簡單。您必須在第一次使用程式之前將程式碼包含在 SDC 檔案中,以便在使用前加以定義。通常,您會將其置於檔案的頂端,以滿足此需求。
腳本操作
在提供針腳的設計中取得所有頻率清單需要三個主要步驟:
- 獲取所有頻率,並建立從目標節點到目標節點時鐘的對應。
- 取得一份節點清單,上面有頻率,這些節點位於通往特定針腳的風扇路徑上。
- 從該節點清單中,找到最靠近指定針腳的節點,然後將該節點上的頻率退回。
步驟 1。取得所有頻率並建立對應
下列 Tcl 代碼會在設計中取得所有頻率,並建立從節點到節點時鐘的對應(含 Tcl 陣列)。
在設計foreach_in_collection clock_id [all_clocks] { 設定clock_name [get_clock_info-name $clock_id] # 每一個 頻率套用在節點中,在 [ all_clocks] 中捕捉 { 陣列未設定nodes_with_clocks [ 陣列集 nodes_with_clocks [清單] # 反覆運算。取得目標節點 的收集foreach_in_collection target_id [get_clock_info -target $clock_id] { # 將 頻率名稱與其目標節點 設定target_name [get_node_info-name $target_id] lappend nodes_with_clocks ($target_name) $clock_name {
虛擬頻率沒有目標,因此從未使用虛擬頻率進行對應。在下列完整程式碼中,儲存目標節點類型 (註冊、針腳、單元或埠) 的相關資訊,以便日後使用。
步驟 2。在 Fanin Path 中使用頻率取得節點
第二個步驟是尋找節點子集,這些節點的頻率位於風扇路徑至指定針腳的路徑上。對於每個具有頻率的節點(在步驟 1 中找到),請透過節點將風扇固定到指定的針腳。如果有風扇,節點位於通往針腳的風扇路徑上。如果沒有風扇,節點不在通往針腳的風扇路徑上。
下列 Tcl 代碼會透過所有節點與步驟 1 的頻率反覆運算,並使用get_fanins指令來判斷每個節點是否在指定針腳的風扇路徑上。如果節點位於指定針腳的風扇路徑上,則節點會儲存在pin_drivers清單中。
設定pin_drivers [清單] # 在 映射中,在步驟 1 前方node_with_clocks [陣列名稱稱nodes_with_clocks] { 中所建立的所有節點上反覆運算[ # 透過目前的節點 集 fanin_col [get_fanins -clock - 透過 $node_with_clock $pin_name] # 如果至少有一個風扇節點, 目前的節點位於 通往特定針腳的 # fanin 路徑上, 所以,儲存它。 如果 { 0 < [get_collection_size $fanin_col] \ { lappend pin_drivers $node_with_clocks \
以下所列完整程式碼使用節點類型的其他資訊,指定特定類型集合,用於get_fanins指令的直通值。
步驟 3。尋找最接近指定針腳的節點
pin_drivers變數現在有一份清單,其中列出所有節點的頻率,這些節點位於風扇路徑上的特定針腳。此步驟會找到最接近指定針腳的節點。雖然pin_drivers清單中有多個節點,但代碼會取用清單中的前兩個節點,並檢查其中一個節點是否位於通往另一個節點的風扇路徑上。如果位於風扇路徑上,則第一節點必須比第二節點遠離針腳,因此可以從清單中移除。
而 { 1 < [llength $pin_drivers] { { # 在pin_drivers清單中取得前兩個節點 設定node_a [lindex $pin_drivers 0] 設定為 node_b [lindex $pin node_b_drivers 1] # 檢查node_b是否在node_a設定的風扇路徑 上,fanin_col [get_fanins -時鐘 -透過 $node_b $node_a] # 如果至少有一個風扇節點, node_b必須 比node_a更遠離指定的針腳。 # 如果沒有風扇節點,node_b必須 比node_a更接近 # 指定的針腳。 如果 { 0 < [get_collection_size] { # node_a更接近針腳。 # 從pin_drivers清單中移除 node_b pin_drivers [lreplace $pin_drivers 1 1] [ 其他 { # node_b更接近針腳。 # 從pin_drivers清單中移除 node_a pin_drivers [lreplace $pin_drivers 0 0] ] = # pin_drivers中留下的一個節點是驅動特定針腳設定的節點 node_driving_pin pin_drivers [lindex $pin_drivers 0] # 從步驟 1 中查找對應節點上的時鐘,然後 將$nodes_with_clocks ($node_driving_pin) 退回
以下所列完整程式碼使用節點類型的其他資訊,指定特定類型集合,用於get_fanins指令的直通值。
完整程式碼
以下列出get_clocks_driving_pin自訂程式的完整代碼。它包含其他錯誤檢查與支援功能,未詳細描述以上。
proc get_clocks_feeding_pin { pin_name { 在步驟 1 之前,執行錯誤檢查,以確保pin_name # 傳遞到程式中僅匹配一個和一個針腳。 # 如果錯誤與一個和只有一個針腳不符,則退回錯誤。 設定pin_col [get_pins -compatibility_mode $pin_name], 如果 { 0 == [get_collection_size $pin_col] { 返回 -代碼錯誤「沒有針腳比$pin_name」[ elseif { 1 < [get_collection_size $pin_col] { { { 退回代碼錯誤「$pin_name 相符 [get_collection_size $pin_col]\ 針腳,但必須只匹配一個 」[ # 程式中使用的變數初始化變數 摳取 { 陣列未設定nodes_with_clocks \ 捕捉 { 陣列未設定node_types [ 陣列集 nodes_with_clocks [清單] 陣列設定node_types [清單] 設定pin_drivers [清單] # 步驟 1。在設計中獲取所有頻率,並在 設計 foreach_in_collection clock_id [all_clocks] { 設定 clock_name [get_clock_info-name $clock_id] 設定clock_target_col[get_clock_info- 目標$clock_id] 設定clock_target_col[get_clock_info-目標$clock_id] 設定 中建立對應。取得目標節點的收集 foreach_in_collection target_id [get_clock_info -target $clock_id] { # 將 頻率名稱與其目標節點 設定target_name [get_node_info-name $target_id] lappend nodes_with_clocks ($target) $clock_name)$clock_name #儲存目標節點的類型,供日後使用 設定target_type [get_node_info -type $target_id] 設定 node_types($target_name)$target_type { # 步驟 2。取得一份節點清單,上面有時鐘,這些節點位於通往 特定針腳的 # 風扇路徑上 , 在 映射中,所有節點都以第 1 步 前node_with_clocks [陣列名稱稱nodes_with_clocks] \ \ 使用目標節點的類型建立特定類型的 # 集合,以在get_fanins指令中建立 -透過價值。 switch-exact--$node_type($node_with_clocks){"pin"{ set through_col [get_pins $node_with_clocks] [ 「埠」{set through_col [get_ports $node_with_clocks] [ 「cell」{ 設定 through_col [get_cells $node_with_clocks] [ "reg" { 設定through_col [get_registers $node_with_clocks] [ 預設 { 退回 -代碼錯誤 「$node_type ($node_with_clocks) 未 按腳本 作為風扇類型來處理\# 透過目前的節點 設定fanin_col [get_fanins -clock -透過 $through_col $pin_name] 將任何風扇固定在指定的針腳上 。如果至少有一個風扇節點,目前的節點位於 通往指定針腳的 # fanin 路徑上,所以請將其儲存。 如果 { 0 < [get_collection_size $fanin_col] [ { lappend pin_drivers $node_with_clocks \ # 在步驟 3 之前,請執行錯誤檢查,以確保設計中至少有一個具有 頻率的節點位於通往 # 特定針腳的風扇路徑上。 如果 { 0 == [llength $pin_drivers] \ { 退回 -代碼錯誤「找不到任何具有驅動$pin_name」的節點 。從步驟 2 中建立的節點清單中,找到 最靠近指定針腳的節點 #,然後將節點上的頻率退回。 而 { 1 < [llength $pin_drivers] \ { # 在pin_drivers清單中取得前兩個節點 設定node_a [lindex $pin_drivers 0] 設定為 node_b [lindex $pin_drivers 1] # 使用目標節點的類型 ,為get_fanins指令中的「直通價值」建立特定類型的 # 集合。 switch-exact--$node_type ($node_b) { 「針腳」{ 設定 through_col [get_pins $node_b] [ 「埠」{ 設定 through_col [get_ports $node_b] [ 「cell」{ 設定 through_col [get_cells $node_b] reg" { 設定 through_col [get_registers $node_b] [ 預設 { 退回 -代碼錯誤 「$node_type ($node_b) 未 按腳本作為風扇類型處理\" \ # 檢查node_b是否在node_a 的風扇路徑上設定fanin_col [get_fanins -時鐘 -透過 $through_col $node_a] # 如果至少有一個風扇節點,node_b必須 比node_a更遠離指定的針腳。 # 如果沒有風扇節點,node_b必須 比node_a更接近 # 指定的針腳。 如果 { 0 < [get_collection_size $fanin_col] \ \ # node_a更接近針腳。 # 從pin_drivers清單中移除 node_b pin_drivers [lreplace $pin_drivers 1 1] [ 其他 { # node_b更接近針腳 # 從 pin_drivers 設定的pin_drivers清單中移除 node_a [lrange pin_drivers $pin_drivers 1 end] = # pin_drivers中留下的一個節點是驅動特定針腳 集的節點node_driving_pin [lindex $pin_drivers 0] # 從步驟 1 中查找節點上的時鐘然後將它們 退回$nodes_with_clocks ($node_driving_pin) \