ハードウェア合成の基本原理
ハードウェア記述言語(HDL)から物理回路を生成する合成処理は、主に3段階で構成される。最初にHDL記述を技術非依存のRTLネットリストに変換(変換フェーズ)、次にターゲット技術ライブラリの論理素子へマッピング(マッピングフェーズ)、最後に遅延や面積の制約条件に基づきネットリストを最適化(最適化フェーズ)する。
Verilog記述と回路マッピング
合成品質はVerilogコーディングスタイルに依存する。同期/非同期回路の分離、ラッチ発生の回避、抽象化レベルの制御が重要である。代表的なVerilog構文と生成回路の対応関係を示す。
条件分岐の実装
always @(Ctrl, A, B) begin
if (Ctrl)
Result = A & B;
else
Result = A | B;
end
上記コードはマルチプレクサを生成し、制御信号Ctrlに応じてAND/OR演算を選択する。内部でOAI22セルを使用する場合、論理式は次式で表現される:
\[ \text{Result} = \overline{(C + X) \cdot (\overline{C} + Y)} \]
条件網羅不足によるラッチ生成
// 条件未定義の場合
always @(Score) begin
if (Score < 5)
Grade = FAIL;
else if (Score < 10)
Grade = PASS;
end
未定義条件領域が存在すると合成ツールはデータ保持用ラッチを生成する。全条件を明示的に定義することで回避可能:
always @(Score) begin
if (Score < 5)
Grade = FAIL;
else if (Score < 10)
Grade = PASS;
else
Grade = EXCELLENT; // 全条件定義
end
Design Compilerのワークフロー
事前合成準備
- ライブラリ設定:技術ライブラリ(
target_library)、リンクライブラリ(link_library)、シンボルライブラリを定義 - 設計読み込み:
analyzeとelaborateでHDLを中間表現に変換 - 設計分割:組合せ回路を単一モジュールに集約、レジスタ出力推奨、モジュールサイズ均等化
設計制約設定
制約駆動合成の核心となる工程:
create_clock -period 10 [get_ports CLK]
set_input_delay -max 4 -clock CLK [all_inputs]
set_output_delay -max 5.4 -clock CLK [all_outputs]
set_max_area 0
set_load [load_of tech_lib/inv1a0/A] [all_outputs]
クロック制約の高度化
- クロック不確かさ:
set_clock_uncertainty 0.5 [get_clocks CLK] - 仮想クロック:
create_clock -name VIRT_CLK -period 15 - マルチサイクルパス:
set_multicycle_path 2 -from FF1 -to FF2
合成実行と最適化
3段階の最適化プロセス:
- 構造レベル:演算子共有、DesignWare選択
- 論理レベル:構造化(
set_structure true) vs 平坦化(set_flatten true) - ゲートレベル:設計ルール遵守の技術マッピング
タイミング違反対応戦略:
compile -map_effort high // 高努力合成
compile -incremental_mapping // インクリメンタル最適化
set_critical_range 1.5 [current_design] // クリティカルパス範囲設定
合成後処理
レポート生成とネットリスト出力:
report_timing > timing.rpt
report_area > area.rpt
write -format verilog -hierarchy output/netlist.v
実践的合成スクリプト例
# 環境設定
set target_library "stdcell.db"
set link_library "* $target_library memory.db"
# 設計読み込み
analyze -format verilog design.v
elaborate TOP
current_design TOP
# 制約設定
source constraints.tcl
# 合成実行
compile_ultra
# 結果出力
report_constraint -all_violators
write_sdc output.sdc