Synopsys Design Compiler チュートリアル(dc_shell)：基本操作から実践テクニックまで



この記事は、Aviral Mittal氏によって作成されたSynopsys Design Compilerのチュートリアルを日本語で解説し、再構成したものです。VHDLのカウンター回路を例に、設計データの読み込みから制約設定、コンパイル（論理合成）、レポート出力までの一連のフローを学びます。

元記事作成者: Aviral Mittal 
チュートリアル用ファイル ([元リンク](http://www.vlsiip.com/dc_shell/))

コマンドスクリプト: [ダウンロード](http://www.vlsiip.com/dc_shell/counter_top.tcl)
VHDLソースコード:
[counter_top.vhd](http://www.vlsiip.com/dc_shell/counter_top.vhd)
[counter.vhd](http://www.vlsiip.com/dc_shell/counter.vhd)
TSMCライブラリでの合成結果ネットリスト: [ダウンロード](http://www.vlsiip.com/dc_shell/counter_top_flat.vlog)


# 基本的な合成フロー
#### ステップ0: Design Compilerの起動
まず、Design CompilerのTclモード（dc_shell-t）を起動します。


```
unix> dc_shell-t
```
#### ステップ1: テクノロジライブラリの設定
合成には、ターゲットとなる製造プロセス（Fab）のセル情報やタイミング情報が含まれた**テクノロジライブラリ（.dbファイル)** が必要です。

1(a). ライブラリの検索パス設定
.dbファイルが格納されているディレクトリをsearch_pathに設定します。


```
set search_path {/homes/amittal/s5/work/physical_lib/corelib/tsmc_090_g_art}
```
1(b). ターゲットライブラリの指定
設計をマッピングするターゲットライブラリを指定します。


```
set target_library {scadv_tsmc_cln90g_lvt_ss_0p9v_125c.db}
```
1(c). リンクライブラリのパス追加 (オプション)
合成済みライブラリ（.db）など、追加で読み込むライブラリの検索パスを追加します。カレントディレクトリなどを指定できます。


```
lappend search_path {[exec pwd]}
lappend search_path {.}
```
1(d). リンクライブラリの指定 (オプション)
IPなどの合成済みモジュールをリンクする場合に指定します。

```
set link_library {PLL10CCMID_W_125_1.35.db}
```
#### ステップ2: 設計ファイルの読み込み
合成対象のRTL（ハードウェア記述言語）ファイルを読み込みます。

2(a). Verilogの場合
```
read_verilog counter.v
```
2(b). VHDLの場合 (このチュートリアルではこちらを使用)
```
read_vhdl counter.vhd
read_vhdl counter_top.vhd
```
2(c). ddc形式の場合 (Synopsys独自フォーマット)
```
read_ddc counter.ddc
```
#### ステップ3: 設計制約の設定
回路が満たすべき性能（速度、面積など）を制約としてツールに与えます。

3(a). 動作周波数の設定
create_clockコマンドでクロックを定義します。以下の例では、周期10ns（100MHz）のdesign_clkというクロックを作成し、トップモジュールのclkポートに割り当てています。

```
create_clock -period 10 -name design_clk clk
```

3(b). 入力遅延の設定
入力信号が、設計ブロックの外部から入力ポートに到着するまでにかかる遅延時間を設定します。

```
set_input_delay 4.0 [remove_from_collection [all_inputs] clk] -clock design_clk
```
3(c). 出力遅延の設定
出力ポートから出た信号が、設計ブロックの外部にある次段のフリップフロップでキャプチャされるまでにかかる遅延時間を設定します。

```
set_output_delay 7.0 [all_outputs] -clock design_clk
```
(qiita追記;以上の数値は`.lib`ファイルにある`time_scale`に記載された数値が単位である。)

3(d). 面積制約の設定
set_max_area 0と設定することで、Design Compilerに対して可能な限り最小の面積で合成するように指示します。

```
set_max_area 0
```
## ステップ4〜15: 詳細な最適化設定 (オプション)
ここでは、より高度な設定を行います。プロジェクトの要件に応じて設定してください。

#### ステップ4: クロックゲーティング (低消費電力化)

```
set_clock_gating_style -minimum_bitwidth 2
```
#### ステップ5: Formal Verification用ファイル出力
```
set_svf -append "counter.svf"
```
#### ステップ6: 動作条件 (Operating Conditions) の設定
```
set_operating_conditions \
    -analysis_type on_chip_variation \
    -max_library tcbn65lpwc_ccs \
    -max WCCOM \
    -min_library tcbn65lpwc_ccs \
    -min WCCOM
```

#### ステップ7: タイミングディレーティング (Derating) シリコン上のばらつきを補償するためのマージンを設定します。

```
set_timing_derate -min -late  1.05
set_timing_derate -min -early 1.00
```
#### ステップ8: クロック不確定性 (Uncertainty) クロックスキューなどの変動要因を考慮に入れます。


```
set_clock_uncertainty -setup 0.500 [all_clocks]
set_clock_uncertainty -hold  0.000 [all_clocks]
#### ステップ9: 入力ポートの駆動セル (Driving Cell) 設定
```
```
set_driving_cell -lib_cell DFD1 -mult 1.0 -library tcbn65lpwc_ccs -pin Q [remove_from_collection [all_inputs] [collection_to_list [get_clocks]]]
```
#### ステップ10: 出力ポートの負荷 (Load) 設定

```
set_load [expr 2 * [load_of [get_pin tcbn65lpwc_ccs/INVD4/I]]] [all_outputs]
```
#### ステップ11: 使用禁止セル (Don't Use) の設定

```
set_dont_use [get_lib_cell tcbn65lphvtwc_ccs/*DEL*]
```

#### ステップ12: 最大遷移時間 (Max Transition) の設定

```
set_max_transition 0.500 [current_design]
```
#### ステップ13: パスグルーピング 特定のパスをグループ化し、最適化の優先度を制御します。

```
set ports_clock_root [get_ports [all_fanout -flat -clock_tree -level 0]]
group_path -name INP_PATHS -from [remove_from_collection [all_inputs] $ports_clock_root] -critical_range 10.0
```
#### ステップ14: レジスタ最適化

```
# 定数値を持つFFを自動削除
set compile_seqmap_propagate_constants true
# 未接続のFFを削除しない
set compile_delete_unloaded_sequential_cells false
```

#### ステップ15: 同期リセットのマッピング


```
set hdlin_ff_always_sync_set_reset "true"
```

#### ステップ16: コンパイル (論理合成) の実行
いよいよ論理合成を実行します。

(a) トップレベルデザインを指定してコンパイル
current_designでトップモジュールを指定し、compileコマンドを実行します。-map_effort highは、より良い結果を得るために時間をかけて最適化するオプションです。

```
current_design counter_top
compile -map_effort high
```
(b) DC Ultraを使用する場合
より高性能なcompile_ultraコマンドを使用することもできます。

```
compile_ultra
```
# 順序回路の出力反転を抑制する場合
```
compile_ultra -no_seq_output_inversion
```
## ステップ17〜19: 結果の出力
合成結果をファイルに出力します。

#### ステップ17: ネットリストの出力
ddc形式:
```
write -format ddc -output counter.ddc -hier
```

Verilog形式:
```
write -format verilog -output counter.vlog -hier
```
#### ステップ18: デザインの平坦化 (Flatten) 階層構造をなくして、1つのモジュールにまとめることもできます。

```
ungroup -all -flatten
write -format verilog -output counter_flat.vlog
```
#### ステップ19: タイミングレポートの出力 合成後のタイミング結果をレポートとして保存します。

```
report_timing > counter_timing.rep
```
#### ステップ20: Design Compilerの終了
```
quit
```

# その他の便利なコマンドとTIPS
Tclスクリプトによるレジスタ一覧の取得
設計内のすべてのレジスタ名を取得し、ファイルに書き出すTclスクリプトの例です。

```
# すべてのレジスタのセル情報をレポート
report_cell [all_registers]

# ファイルを開く
set file_handle [open my_regs.txt a]

# all_registersコレクション内の各要素に対してループ処理
foreach_in_collection el [all_registers] {
    # オブジェクト名（レジスタ名）を取得
    set reg_name [get_object_name $el]
    # ファイルに書き出す
    puts $file_handle $reg_name
}

# ファイルを閉じる
close $file_handle
```
False Pathの設定について
set_false_pathは、タイミング解析の対象外としたいパスを指定するコマンドです。重要な注意点として、クロック定義などの基本的な制約がない状態では、set_false_pathが正しく機能しない場合があります。タイミング解析を行う際は、まずクロックと入出力遅延を適切に設定することが重要です。

階層区切り文字の変更
Design Compilerのデフォルトの階層区切り文字は / ですが、これを . などに変更したい場合があります。その逆も可能です。以下の例では、. を / に置換しています。

```
define_name_rules no_dot -restricted "." -replacement_char "/"
change_names -rules no_dot -hierarchy
```
DesignWareコンポーネントの合成
DesignWareライブラリ（dw_foundation.sldb）に含まれるコンポーネント（例: DW_minmax）を正しく合成するには、synthetic_libraryとlink_libraryにdw_foundation.sldbを明示的に指定する必要があります。

```# 合成ライブラリとしてdw_foundation.sldbを指定
set synthetic_library [list /path/to/synopsys/libraries/syn/dw_foundation.sldb]

# リンクライブラリに"*"（すべてのライブラリ）とdw_foundation.sldbを追加
set link_library "* dw_foundation.sldb"
```