RTL設計段階における構造的検証は、論理合成を実行する前に必須の品質ゲートです。多くの設計者が「合成後にエラーが出れば直せばよい」と考えがちですが、これは時間効率と問題特定精度の両面で重大なリスクを伴います。Design Compiler(DC)のGUIモードを活用すれば、elaborate完了直後の未最適化設計をリアルタイムに可視化し、接続ミスやパラメータ誤設定といった80%以上の初期バグを数分で検出できます。
なぜelaborate後のGUI表示が有効か
elaborateはRTLコードを内部データ構造に変換するフェーズであり、この時点ではまだ最適化・マッピングが一切行われていません。そのため、以下のようなRTL本来の構造が忠実に再現されます:
- モジュール間のインスタンス関係(含むジェネリック/parameter値)
- 信号の物理的接続経路(バス幅・ドライバ/ローダ関係)
- 条件文やアサーションの静的構造(合成ツールによる解釈前状態)
最小限のコマンドセットで始める
以下の3行で環境を立ち上げ、即座に可視化が可能です:dc_shell -gui
read_verilog -format sverilog top.sv
elaborate top
その後、設計の健全性を確認するため、以下の診断コマンドを推奨します:
# モジュール階層の全表示
report_hierarchy -full -indent 2
# 全ポートの接続状態一覧(未接続ポートをフィルタ)
get_ports -filter "direction==in && !is_connected"
# 特定ネットのドライバとローダを取得
set drv [get_pins -of_objects [get_nets data_bus] -filter "direction==out"]
set load [get_pins -of_objects [get_nets data_bus] -filter "direction==in"]
GUI操作の効率化テクニック
グラフィカルインターフェースでは、以下の操作が反復作業を大幅に削減します:- Ctrl+Shift+F:選択中のネットまたはセルに自動ズーム
- Alt+左ドラッグ:ビューのパン(マウスホイールはズーム)
- 右クリック → "Show Connectivity":ピンレベルでの接続詳細表示
- Shift+クリック複数選択:関連信号群を同時にハイライト
代表的な検証シナリオ
不正なバス幅接続の検出
RTLでwr_data[31:0]をrd_data[15:0]に誤って接続した場合、GUI上では太さの異なる2本の線が交差して描画され、直感的に異常が認識できます。Tclからも検証可能です:
foreach net [get_nets -hierarchical "*data*"] {
set width [get_attribute $net width]
if {$width < 16} {
echo "Warning: Narrow bus detected: $net ($width bits)"
}
}
パラメータ伝搬の検証
ジェネリックインスタンスの実際の値は、GUI上で該当セルを右クリック→「Properties」で確認できます。Tclでも即座に取得可能:set fifo_inst [get_cells uut.fifo_ctrl]
set actual_depth [get_attribute $fifo_inst parameters.DEPTH]
if {$actual_depth != 1024} {
echo "ERROR: Expected DEPTH=1024, got $actual_depth"
}
意図しない最適化の防止
デバッグ用信号やテスト構造は、合成時に削除されないように明示的に保護します:set_debug_nets [get_nets -hier "dbg_*"]
set_dont_touch $debug_nets
set_dont_use [get_lib_cells *DFF*] -hier
大規模設計向けの最適化戦略
10万セルを超える設計では、全階層を一度に展開するとGUIが重くなるため、以下の制御を推奨:# 表示階層をトップ+1階層のみに制限
set_display -hier_level 1
# 電源/GNDネットを非表示化
set_power_net_visibility -off
# 特定モジュールのみを強調表示
highlight_cell [get_cells uut.ctrl_fsm]
自動化支援スクリプト例
CDC(クロックドメインクロス)パスの事前検出スクリプト:proc find_cdc_paths {} {
set all_nets [get_nets -hierarchical]
set cdc_candidates {}
foreach n $all_nets {
set src_clk [get_clocks -of_object [get_pins -of_object $n -filter "direction==out"]]
set dst_clk [get_clocks -of_object [get_pins -of_object $n -filter "direction==in"]]
if {[llength $src_clk] && [llength $dst_clk] && $src_clk ne $dst_clk} {
lappend cdc_candidates $n
}
}
if {[llength $cdc_candidates]} {
highlight_net -color orange $cdc_candidates
echo "[llength $cdc_candidates] CDC paths found."
}
}