在為計時分析器編寫自定義腳本時,應瞭解不同的 Tcl API 函數如何處理節點名稱中的實體和實例名稱並返回這些名稱。Quartus® II 軟體中有一個名為 「節點名稱的顯示實體名稱」的 設置,用於控制是否顯示帶有或不帶實體名稱的節點名稱。
Tcl API 函數 get_registers 始終可以接受包含其篩選器的實體的名稱,而不管「 節點名稱」的「顯示實體名稱」設置如何。 get_registers 函數始終根據節點名稱的 「顯示實體名稱」的設置返回名稱。
表 1 顯示了命令 get_registers <filter>返回的節點名稱的示例,其中設計包含一個名為 ram:my_ram|ctrl:ctrl_1|addr[0] 的寄存器。
Tcl API 函數get_pins,並且get_cells的行為與get_registers不同。get_pins和get_cells函數僅接受並返回包含實例名稱的名稱。它們不接受或傳回帶有實體的名稱,而不管節點名 的「顯示實體名」的值如何。
表 2 顯示了 get_pins <filter>返回的節點名稱的示例,其中設計包括一個名為 ram:my_ram|ctrl:ctrl_1|addr[0] 的寄存器,其時鐘引腳名為 clk。 get_cells 函數的行為方式相同,儘管它接受並返回單元格名稱。
注意:
- get_pins函數會生成一條警告,指示指定的篩選器無法與引腳匹配。
當您意識到get_registers 、 get_pins和get_cells處理和返回包含實體的節點名稱的方式存在差異時,可以避免在組合函數時可能發生的細微問題。下面的示例演示當節點名稱的顯示實體名稱處於關閉狀態時有效的代碼,但在打開時失敗。
foreach_in_collection reg_id [get_registers foo*] { set reg_name [get_node_info -name $reg_id] # ... set pin_id [get_pins ${reg_name}|clk] # 如果reg_name包含實體,則get_pins調用始終失敗 }
當 節點名稱的顯示實體名稱 處於關閉狀態時,變數reg_name不包含實體名稱,因此 get_pins 調用成功。當 「節點名稱的顯示實體名稱」 處於打開狀態時,變數reg_name包含實體名稱,因此 get_pins 調用將失敗。
解決方案
避免潛在問題的最簡單方法是關閉 節點名稱的「顯示實體名稱」 , 並僅使用實體名稱來引用節點。此解決方案可確保 get_registers 返回的名稱是僅實例名稱,並且可與 get_pins 和 get_cells 一起使用。
如果未關閉「 節點名稱的顯示實體名稱」 ,並且將 get_registers 傳回的名稱傳遞給 get_pins 或 get_cells,則必須確保刪除所有實體名稱。您可以使用簡單的 regsub 運算式來刪除大多數實體名稱。以下 Tcl 命令從節點名稱中刪除所有實體名稱,只要實體名稱僅包含字母、數位和下劃線(\w 字元類中的字元)。
regsub -all {w*:™ $reg_name {] reg_name
列出的正則表示式模式不會處理 HDL 識別子中的每個有效字元。它不處理生成的實體名稱,這些名稱包含反斜杠 (\)、簡單 Verilog HDL 標識符中的美元符號字元 ($)、轉義的 Verilog HDL 識別符或 VHDL 中的擴展標識符。您可以建構更高級的正規表達式來處理具有這些字元的實體名稱,但關閉「 節點名稱的顯示實體名稱」更簡單。
下面的示例演示如何將 regsub 運算式與上面的非工作範例整合。在下面的示例中,regsub 運算式從寄存器名稱中刪除實體名稱(受所述字元排除項的約束),因此 get_pins 調用不會失敗。無論 節點名稱 的"顯示實體名稱"的值如何,該示例都有效。
foreach_in_collection reg_id [get_registers foo*] { set reg_name [get_node_info -name $reg_id] regsub -all {\w*:} $reg_name {} reg_name # reg_name不再包含實體 # ... set pin_id [get_pins ${reg_name}|clk] # reg_name不再包含實體,因此get_pins成功 }