ロジック(論理)・シュミレーションの関するメモです。
'X' 伝搬問題
シュミレーションを流していると、信号に 'X' が増えてゆく事がある。波形を見ると真っ赤になっているので心臓に良くない。どこかで発生した 'X'(アンノーン、不定値) が時間とともに回路のなかで伝搬、爆発してシュミレーションが失敗する。RTLのシュミレーションで問題なかったテストベンチがネットリストだと失敗するケースはこの症状の場合が多いかもしれない。さて、どうして'X'が発生するのか?
- 入力ポートがちゃんとつながってない
- 対策: オープンなポートを見つけて、つなげる(もしくは、0,1で固定)
- ラッチがきちんとリセットできていない
- 対策:X状態のラッチセルの特定、そのセルのリセット方法の確認
- 初期化が必要なクロックゲートセル
- 対策:X状態のクロックゲートセルの特定、そのセルのリセット方法の確認
- ループで'X'から抜け出せない
- 対策: 一時的に値を強制的にセットして(Force,Release文)、Xのループを断ち切る
- TristateのIO信号(inout ポート)、Z状態のバス信号が入力側でXに
- 対策: 一時的に値を強制的にセット(Force,Release文)や入力信号をゲートできるようにしておく
- タイミングエラー(遅延シュミレーション)
- 対策: 論理合成のタイミング制約の見直し
などがある。基本的な作業は、「地道に発生源をつきとめて対策を施してゆく」 しかない。大雑把な流れは
- 動作を波形で見てみる
- 最初に(もしくは最初から)'X'になってる信号を洗い出す
- 回路(HDL)を確認して、Testbenchの実装やライブラリの修正等で調整する
- ポートならテストベンチを修正、入力信号を与える。
- 場合によってはForce文で値を(一時的に)固定する
- ラッチの場合、動作によってはうまく初期化出来ないことがある(非同期リセットなど、もしくはリセットが無い回路)。この場合、Force文で入力をよしなに操作したり、ラッチのモデルを修正したりする
- タイミングエラーの場合は、警告が出るので発生源の特定は容易だが、修正はタイミング制約や回路の見直しとなる。
- 時間がないとき、Holdの場合は、こっそり遅延を挿入して様子を見る
- ポートならテストベンチを修正、入力信号を与える。
で、波形のダンプが曲者である。何も考えていないと、超巨大なVCDファイルが生成されてファイルシステムが一杯になる。そのため
- VCDでダンプする場合
- 最初は、トップか上位の階層だけダンプして、問題のありそうな時間を特定する
- VCDのダンプ時間と、階層をよしなに調整して、問題の信号やインスタンスを特定する。 例えば、
- あるモジュールの内部信号を一旦全部表示してみて、X以外の信号をバッサリ削除する(初期にXになる信号だけ残す)
- つぎに、最初に(最初から)Xになる信号とそのインスタンスを特定
- インスタンスのコードを確認
- VCDのダンプ時間と、階層をよしなに調整して、問題の信号やインスタンスを特定する。 例えば、
- 最初は、トップか上位の階層だけダンプして、問題のありそうな時間を特定する
- 論理シュミレーターのGUI上で波形を選びながら実行する
- 各社の解析ツールを使ってみる
余談、RISC-VのRocketCoreの内部レジスタの多くはリセットされない(初期値に依存しない)。RTLのシュミレーションでは乱数値がセットされる。しかしながら、これがネットリストのシュミレーションになると曲者で、標準のラッチは初期値が 'X' なので、そのまま動かすと内部信号が真っ赤になる。とっても困る。
参考
- 解説記事
- 解析アプリ
- Cadence Xcelium Simulator’s X-prop Technology
- Cadence JasperGold® X-Propagation Verification App
- Synopsys Xprop
- Mentor Questa X-Check