補足 - ハザード
組合せ回路の入力が変化したときに生じる、出力の過渡的な変化をハザード(hazard)という。グリッチ(glitch)とかヒゲ(髭)ともいう。
ハザードが出る原因は、入力から出力までに(分岐・合流により)複数経路がある場合に、経路によって(素子段数や配線長が異なるため)伝搬遅延に差があるからである。伝搬遅延は次の条件に依存するので、ハザードも微妙な条件の違いで出たりするので厄介である。
・環境条件(温度、電圧):「寒い日はなぜか誤動作しがち」
・デバイスの固体差:「何年も生産して来たのに、最近のロットはなぜか誤動作する」
・合成結果:「ソースは変えてないのに別ファミリのFPGAに移植したら誤動作した」(→補足-FPGAの合成結果によってハザードが出る例)
◇
例1) イネーブル付FF
下図のb_regはa_regをイネーブル信号とするFFである。自分がb_reg=1かつ入力もb1_reg=1ならば、イネーブル信号がa_reg=0→1→0と変化してもb_reg=1のままのはずである。しかしa_reg=1→0と変化したとき、a_regの遅延差でb_inが一瞬0になるハザードが発生しうる。このハザードをclk_aと非同期なclk_bでたまたまサンプリングしてしまうとb_regが0にひっくり返ってしまう。
◇◇
次の例は、組合せ回路内では分岐してないが、元が同じ信号が合流している点で同様である。
例2) パルス幅の伸長
下図はclk_aの1パルスをほぼ同じクロック周期のclk_bへ転送するとき、とりこぼさないようにORして2クロック幅に伸長している。しかしパルスがa0_regからa1_regへ移動するとき、a0_regとa1_regの伝搬遅延差でen_aが一瞬0になるハザードが発生しうる。このハザードをclk_aと非同期なclk_bでたまたまサンプリングしてしまうと、パルスを取りこぼしてしまいb_regは0のままになる。