論理合成を実際にやってみる
(1) ここで学ぶ内容
概要
- 論理合成の動作を理解し、論理合成の方針立てについて学ぶ
- 階層やクロックスキューなどの対処方法について学ぶ
目標
以下の項目を理解し説明できる
- 論理合成の方針
- 論理式とゲートの最適化
- 平坦化と構造化
- 階層合成
- クロックスキューとその対策
LSIの開発に論理合成ツールを使う場合は今まで学んだこと以外に注意すべきことがあります。ここでは大規模な回路を論理合成するときに考え方や注意点を教えます。
(2) 論理合成の方針
- チップ全体の中で、論理合成対象と対象外のブロックに分ける
- 論理合成対象外のブロックは、最上位階層で接続する
- 回路検証(RTL検証、ゲートレベル検証)は、チップ全体で行う
LSIを開発する場合、論理合成ツールはすべての回路を合成できるわけではありません。
論理合成できる部分とできない部分を切り分けなければなりません。
論理合成できない部分はASICベンダが提供するメモリやCPUなどのハードマクロ、パッドを含めたI/Oバッファです。
論理合成できるのはHDLで作成したユーザ回路ブロックです。
これらのブロックは最上位階層で接続し、LSI全体のネットリストを完成させます。
回路の検証は論理合成前と後にチップ全体で行います。
ASICベンダのハードマクロを使用する場合には、検証用のモデルを提供してもらいましょう。
(3) 論理式とゲートの最適化
always @( posedge CK
or posedge RES )
begin
if ( RES==1'b1 )
Q <= 8'h00;
else
Q <= Q + 8'h01;
end
最適化は
論理式の最適化
ゲートレベルの最適化
の2段階で行われる
回路の最適化は compile コマンドを使用
graph TD
V[~.v] --> COM[compile]
DB[~.db] --> COM
COM --> FLAT[平坦化]
FLAT --> STRUC[構造化]
STRUC --> GATE[ゲート最適化]
COM --> GATE
GATE --> OUT1[平坦化合成]
GATE --> OUT2[構造化合成]
GATE --> OUT3[インクリメンタル合成]
論理式の最適化には
平坦化
構造化
の2つの方法がある
compile -incremental
回路の最適化には compile コマンドを使用します。
compile コマンドは論理式の最適化とゲートレベルの最適化の2段階で最適化を行います。
論理式の最適化には平坦化と構造化の2種類があります。平坦化は同時に構造化も行います。
それぞれ平坦化:set_flatten コマンド、構造化:set_structure コマンドを使用します。
compile コマンドを実行すると論理式の抽出をして論理式の最適化を行います。
その後ゲートマッピングを行いゲートの最適化をします。
合成済みの回路に対して2回目以降の最適化を行う場合には、コンパイルコマンドにインクリメンタルオプションをつけて最適化を行います。
インクリメンタルオプションをつけると論理式の最適化は行わずにゲートレベルの最適化のみ行います。
論理式レベルの最適化を2回目以降に行うと結果が悪くなることがあります。
2回目以降の最適化はゲートレベルのみで行うようにしましょう。
(4) 平坦化と構造化
平坦化
- 回路を2段論理で構成
- 回路規模は増大する
- 遅延時間は小さい
graph LR
A((A))
B((B))
C((C))
Y((Y))
notA[INV]
notB[INV]
notC[INV]
A --> notA
B --> notB
C --> notC
and1[AND]
and2[AND]
and3[AND]
and4[AND]
A --> and1
B --> and1
C --> and1
notA --> and2
notB --> and2
C --> and2
A --> and3
notB --> and3
notC --> and3
notA --> and4
B --> and4
notC --> and4
or1[OR]
and1 --> or1
and2 --> or1
and3 --> or1
and4 --> or1
or1 --> Y
構造化
- 回路を多段論理で構成
- 回路規模は小さくなる
- 遅延時間が大きくなりやすい
graph LR
A((A))
B((B))
C((C))
Y((Y))
notA1[INV]
notB1[INV]
and1[AND]
and2[AND]
or1[OR]
A --> notA1
B --> notB1
notA1 --> and1
B --> and1
A --> and2
notB1 --> and2
and1 --> or1
and2 --> or1
notX[INV]
notC1[INV]
and3[AND]
and4[AND]
or2[OR]
or1 --> notX
C --> notC1
notX --> and3
C --> and3
or1 --> and4
notC1 --> and4
and3 --> or2
and4 --> or2
or2 --> Y
論理式の最適化には平坦化と構造化の二つの方法があります。
平坦化とは回路を2段階論理で構成する方法です。
例としてA、B、Cの3つの変数の排他的論理和を求める回路を考えてみましょう。
2段論理の回路はANDゲートとORゲートの二段で回路を構成することができます。
このため回路規模は大きくなりますが、遅延時間は小さくなります。
構造化とは回路を多段論理で構成する方法です。
多段論理で回路を構成した場合、平坦化した回路にくらべ回路規模は小さくなりますが、ゲートの段数が増えるため遅延時間は大きくなります。
平坦化するためのコマンドは set_flatten、構造化のコマンドは set_structure です。
これらのコマンドの特徴をよく理解し、状況に応じて使い分けてください。
(5) 階層合成
ドライブ能力
BCD60
BCD24
負荷容量
階層をもった回路を論理合成する場合を24時間時計CLOCK24を例に考えてみましょう。
このCLOCK24は下位階層として二つのモジュールがあります。
分のカウンタMIN、時間のカウンタHOURの二つです。
CLOCK24はこの二つのモジュールを接続して構成されています。
下位階層と上位階層の最適化の制約条件は違うので上位階層の制約条件を設定して再度最適化します。
この場合下位階層はすでにゲート回路になっているので、compile –incremental コマンドでゲートレベルの最適化のみ行います。
(6) 階層合成用のコマンド
下位階層に同じモジュールが複数個ある場合、compile コマンドは動作しない
BCD60が2個あるので最適化できない
BCD60
BCD60
BCD24
ungroup
最良の結果が得られるが、合成時間が長い
BCD24
※SECとMINの枠が消え、フラットになっている
uniquify
set_dont_touch コマンドよりも合成時間が長い
BCD60_0
BCD60_1
BCD24
set_dont_touch
uniquify コマンドに比べて合成時間が短い
BCD60⃠
BCD60⃠
BCD24
回路を論理合成するとき、下位階層で同じモジュールが複数個ある場合は compile コマンドは動作しません。
前のページの24時間時計CLOCK24に秒のカウンタSECを追加した例をみてみましょう。
このCLOCK24は下位階層として3つのモジュールがあります。
これらの下位階層は論理合成済みです。
この中でSECとMINはBCD60という同じモジュールで構成されています。
このように同じモジュールが2個ある場合には、このままでは最適化できません。
このような場合最適化するための3つのコマンドがあります。
uniquify コマンド、ungroup コマンド、set_dont_touch コマンドです。
uniquify コマンドは複数つかわれているモジュールをコピーして違う名前のモジュールを作ります。
この例ではBCD60をコピーしてBCD60_0とBCD60_1という二つのモジュールをつくります。
ungroup コマンドは複数使われているモジュールを指定して階層を破壊し、フラットな回路にします。
set_dont_touch コマンドは複数使われているモジュールを指定して、最適化の対象から外します。
これらの方法はそれぞれ長所、短所があります。
set_dont_touch → uniquify → ungroup の順で合成時間が長くなります。
回路規模や遅延時間などの回路品質は ungroup が一番よく、uniquify、set_dont_touch と続きます。
下位階層がすでに十分最適化されている場合など状況に応じて、set_dont_touch コマンドを使用しましょう。
これらの特徴をよく理解して状況に応じて使い分けましょう。
(7) クロックスキューとは
配線長の違いなどで FF ごとにクロック信号のタイミングがずれる現象
graph TD
CLK((CLK)) --> BUF[INV]
BUF --> N1(( ))
N1 --> FF1[FF]
N1 --> N2((赤い点))
N2 --> FF2[FF]
style N2 fill:red,stroke:red
style FF1 fill:#b3e5fc
style FF2 fill:#b3e5fc
誤動作の原因になる
クロックの配線の長さの違い等によりフリップフロップごとにクロック信号のタイミングがずれることをクロックスキューといいます。
このクロックスキューは回路の誤作動の原因になります。
クロックスキューがどのような誤作動を引き起こすかみてみましょう。
クロックのずれなし(正常)
graph LR
D((D)) --> U1[U1]
U1 --> U1Q((U1Q))
U1Q --> U2[U2]
U2 --> Q((Q))
CLK((CLK)) --> inv1[INV]
inv1 --> inv2[INV]
inv2 --> U1
CLK --> inv3[INV]
inv3 --> inv4[INV]
inv4 --> U2
タイミング
- D : __/‾‾‾‾\__
- U1のクロック: _/‾\_/‾\_
- U1Q : ____/‾‾‾‾\
- U2のクロック: _/‾\_/‾\_
- Q : ________/‾
クロックのずれあり(誤動作)
graph LR
D((D)) --> U1[U1]
U1 --> U1Q((U1Q))
U1Q --> U2[U2]
U2 --> Q((Q))
CLK((CLK)) --> inv1[INV]
inv1 --> inv2[INV]
inv2 --> U1
CLK --> U2
タイミング
左はクロックスキューがない場合の動作です。
クロック信号は二つのフリップフロップに同時に到着します。入力Dはクロックの二回目の立ち上がりエッジ後に出力Qに伝わります。
それに対して右はクロックスキューがある場合の動作です。
U2に対するクロック信号が遅れると入力DがU1Qに伝わった後で、U2のクロックが立ち上がり出力Qが変化します。
一つのクロックの立ち上がりで二つのフリップフロップをデータが突き抜け誤動作しています。
このようにクロックスキューは回路の誤動作の原因になるので対策が必要です。
もふねこ:
クロックスキュー(Clock Skew)は、大きなLSIを作るときに絶対避けられない「タイミングのズレ」のことだよ🐾
ツールに「スキューがある前提で安全に作ってね」って教える set_clock_uncertainty と set_fix_hold は、実務でも必須のおまじないだから、しっかり覚えておこうね!
(8) クロックスキューによる誤動作防止
クロックスキューによる誤動作を防止するためのコマンド
set_clock_uncertainty スキュー値 クロック名
スキューの値を与えるset_fix_hold クロック名
スキューによる誤動作を回避するために遅延を調整する
graph LR
D((D)) --> U1[U1]
U1 --> buf1[BUF]
buf1 --> buf2[BUF]
buf2 --> U2[U2]
U2 --> Q((Q))
CLK((CLK)) --> inv1[INV]
inv1 --> inv2[INV]
inv2 --> U1
CLK --> inv3[INV]
inv3 --> inv4[INV]
inv4 --> U2
set_clock_uncertainty と set_fix_hold は 必ず設定する
クロックスキューによる誤動作を防止するためのコマンドを紹介します。
一つは set_clock_uncertainty コマンドです。これはクロックスキューの値を与えるコマンドです。クロックスキューの値を推定し、このコマンドで設定します。このコマンドを指定しないとクロックスキューの値は0になります。
もう一つは set_fix_hold コマンドです。これはクロックスキューによる誤動作を回避するために遅延を調整するコマンドです。
これらのコマンドを設定すると論理合成ツールは必要な部分に誤動作防止用にバッファを挿入します。
大規模な回路ではスキューの発生は避けられないので、この二つのコマンドは必ず設定しましょう。
どちらか一方だけの設定ではバッファは挿入されません。
(9) 修了判定1
回路図やレポートで回路規模や遅延時間の違いを確認する。
遅延時間はレポートのデータ到着時刻を確認する。
| Y | Y | ||
|---|---|---|---|
| 0000 | 0 | 1000 | 8 |
| 0001 | 1 | 1001 | 9 |
| 0010 | 2 | 1010 | A |
| 0011 | 3 | 1011 | b |
| 0100 | 4 | 1100 | c |
| 0101 | 5 | 1101 | d |
| 0110 | 6 | 1110 | E |
| 0111 | 7 | 1111 | F |
平坦化スクリプト : seg7_flatten.scr
構造化回路記述 : seg7_structure.v
構造化スクリプト : seg7_structure.scr
合成結果レポートの確認
平坦化 (flatten) のレポート
****************************************
レポート : area
回路 : SEG7_FLATTEN
****************************************
ポート数: 11
ネット数: 37
セル数: 33
セル種類: 8
組み合わせ回路: 53
非組み合わせ回路: 0
合計: 53
****************************************
レポート : timing
回路 : SEG7_FLATTEN
****************************************
ライブラリ: hd350s
配線遅延モデル: hd350s_05k
コンディション: MAX567
-----------------------------------------------------------
Y[0] (in) 0.00 0.00
D (out) 0.00 14.10
データ到着時刻 14.10
-----------------------------------------------------------
- 入力ポート: Y[3:0] (左端に配置)
- 出力ポート: A, B, C, D, E, F, G (右端に配置)
- 構造的特徴: 多数のANDゲートとORゲートが並列に並び、入力から出力までの経路が浅い「2段論理」構造。
- 結線状態: 各入力 Y[3]〜Y[0] とその反転信号が、中央の多数のANDゲートに分配され、その出力が最終段のORゲートで集約されて各セグメント(A~G)に出力される。回路図全体が縦に非常に長く、平坦な構成。
構造化 (structure) のレポート
****************************************
レポート : area
回路 : SEG7_STRUCTURE
****************************************
ポート数: 11
ネット数: 41
セル数: 37
セル種類: 11
組み合わせ回路: 52
非組み合わせ回路: 0
合計: 52
****************************************
レポート : timing
回路 : SEG7_STRUCTURE
****************************************
ライブラリ: hd350s
配線遅延モデル: hd350s_05k
コンディション: MAX567
-----------------------------------------------------------
Y[0] (in) 0.00 0.00
B (out) 0.00 21.16
データ到着時刻 21.16
-----------------------------------------------------------
- 入力ポート: Y[3:0] (左下端に配置)
- 出力ポート: F, G, E, D, B, A (右端に分散して配置)
- 構造的特徴: ゲートが横方向に何段も連なる「多段論理」構造。回路図全体が階段状に深い階層を持っている。
- 結線状態: 共通の論理式(サブ式)が抽出され、あるゲートの出力が次のゲートの入力として再利用されるため、入力から出力までの経路が長く、入り組んだ接続となっている。
(10) 修了判定2
回路図やレポートで回路規模や遅延時間の違いを確認する。
遅延時間はレポートのデータ到着時刻を確認する。
スクリプト1: clock24_dont_touch.scr
回路記述2 : clock24_uniquify.v
スクリプト2: clock24_uniquify.scr
回路記述3 : clock24_ungroup.v
スクリプト3: clock24_ungroup.scr
BCD60
BCD60
BCD24
合成結果レポートの比較
スクリプト1:set_dont_touch合成
- 入力ポート: CLK(logic_1), RESET, MODE24
- 出力ポート: SECLSB[3:0], MINLSB[3:0], MINMSB[2:0], HOURLSB[3:0], HOURMSB[1:0], SECMSB[2:0]
- 構造的特徴: BCD60COUNT (SEC用), BCD60COUNT (MIN用), BCD24COUNT (HOUR用) の3つの大きなブラックボックスがそのまま維持されている。階層構造は破壊されていない。
- 結線状態: 1段目のBCD60COUNTのキャリー出力が、2段目のBCD60COUNTの入力へ直列に繋がり、さらに3段目のBCD24COUNTへ繋がる構成。
****************************************
レポート : area
回路 : CLOCK24
****************************************
ポート数: 23
ネット数: 27
セル数: 4
セル種類: 3
組み合わせ回路: 158
非組み合わせ回路: 181
合計: 339
****************************************
レポート : timing
回路 : CLOCK24
****************************************
クロック CLK (rise edge) 0.00 0.00
HOUR/LSB_reg[3]/D (FD2) 0.00 37.65
データ到着時刻 37.65
クロック CLK (rise edge) 20.00 20.00
クロックスキュー -1.00 19.00
ライブラリのセットアップタイム -0.80 18.20
データ到着要求時刻 18.20
-----------------------------------------------------------
データ到着要求時刻 18.20
データ到着時刻 -37.65
-----------------------------------------------------------
タイミング余裕 -19.45
スクリプト2:uniquify合成
- 入力ポート: CLK(logic_1), RESET, MODE24
- 出力ポート: MINLSB[3:0], MINMSB[2:0], HOURLSB[3:0], HOURMSB[1:0], SECLSB[3:0], SECMSB[2:0]
- 構造的特徴: dont_touch時と同じく3つのブラックボックスがあるが、1段目の名前が「BCD60COUNT_1」、2段目が「BCD60COUNT」となっており、同じモジュールが別々の名前(固有化)として展開されている。
****************************************
レポート : area
回路 : CLOCK24
****************************************
ポート数: 23
ネット数: 26
セル数: 3
セル種類: 3
組み合わせ回路: 251
非組み合わせ回路: 190
合計: 441
****************************************
レポート : timing
回路 : CLOCK24
****************************************
クロック CLK (rise edge) 0.00 0.00
HOUR/LSB_reg[2]/D (FD2) 0.00 18.19
データ到着時刻 18.19
クロック CLK (rise edge) 20.00 20.00
クロックスキュー -1.00 19.00
ライブラリのセットアップタイム -0.80 18.20
データ到着要求時刻 18.20
-----------------------------------------------------------
データ到着要求時刻 18.20
データ到着時刻 -18.19
-----------------------------------------------------------
タイミング余裕 0.01
スクリプト3:ungroup合成
- 入力ポート: CLK(logic_1), RESET, MODE24 (左端に配置)
- 出力ポート: MINLSB[3:0], MINMSB[2:0], HOURLSB[3:0], HOURMSB[1:0], SECLSB[3:0], SECMSB[2:0] (右端に配置)
- 構造的特徴: BCD60COUNTなどの階層枠(ブラックボックス)が完全に消滅し、すべてのフリップフロップと組み合わせ論理(AND, OR, INVなど)が平坦に展開されている。
- 結線状態: 回路全体にわたって細かいゲートが数百個レベルで複雑に絡み合う、非常に巨大な多段ゲート回路となっている。遅延時間が大幅に最適化(37.65 → 18.19)されているのが視覚的にも複雑さから読み取れる。
****************************************
レポート : area
回路 : CLOCK24
****************************************
ポート数: 23
ネット数: 111
セル数: 91
セル種類: 23
組み合わせ回路: 240
非組み合わせ回路: 190
合計: 430
****************************************
レポート : timing
回路 : CLOCK24
****************************************
クロック CLK (rise edge) 0.00 0.00
HOUR/LSB_reg[2]/D (FD2) 0.00 18.19
データ到着時刻 18.19
クロック CLK (rise edge) 20.00 20.00
クロックスキュー -1.00 19.00
ライブラリのセットアップタイム -0.80 18.20
データ到着要求時刻 18.20
-----------------------------------------------------------
データ到着要求時刻 18.20
データ到着時刻 -18.19
-----------------------------------------------------------
タイミング余裕 0.01