FPGA講座-10 initial文とalways文

initial文とalways文の違い

図1 initial文とalways文の違い

 initial文は、シミュレーションにおいて一度だけ実行される処理を記述するための構文です。主にテストベンチや一部のシミュレーション専用の初期化処理に使用されます。FPGAのハードウェアとしては合成されません。図1の例において、initial文で記述されたCLK信号は、10ns後に”0″に設定し、その10ns後に”1″を設定すると、そのまま”1″を設定し続けます。

 always文は、条件が合致するたびに繰り返し実行される処理を記述します。主に設計するハードウェア回路そのものを記述するために使用され、FPGAの実際の回路に合成されます。図1の例において、always文で記述されたCLK信号は、実はinitial文の記述と同じです。しかしながら、always文の場合、10ns後に”0″に設定し、その10ns後に”1″を設定すると先頭に戻り、10ns後に再び”0″に設定します。このループを繰り返すため、周期20nsのクロック信号を生成することができます。

  initial文 always文
実行数 シミュレーション中に1度のみ トリガ条件に応じて何度でも実行
用途 初期化やテストベンチの記述 ハードウェア回路の記述
ハードウェア合成 合成されない 合成される
トリガ条件 トリガ条件なし(開始時に自動実行) トリガ条件を指定(”@条件”で記述)
使用例 テストベンチでの信号初期化 クロック同期回路や組み合わせ回路

ブロッキング代入とノンブロッキング代入

図2 ブロッキング代入(左)とノンブロッキング代入(右)の違い

 ブロッキング代入は、記述された順番に代入を実行する代入方法です。代入された値が即座に反映され、その結果を次の文で利用することができます。図2の左のブロッキング代入の場合、CLK信号の立ち上がりエッジで”A”に”DIN”を代入し、”DIN”が代入された”A”を”B”に代入します。そのため、CLK信号の立ち上がりエッジで取り込まれた”DIN”が、”A”と”B”に代入されます。

 ノンブロッキング代入は、並列的に代入が実行される代入方法です。代入は同じクロックサイクル内で実施されますが、値の更新は全ての計算が完了した後に反映されます。図2の右のノンブロッキング代入の場合、CLK信号の立ち上がりエッジで”A”に”DIN”を代入し、”B”には前に取り込まれた”A”のデータが代入されます。そのため、CLK信号の立ち上がりエッジで取り込まれた”DIN”が”A”に代入され、次のCLK信号の立ち上がりエッジで”DIN”が代入された”A”が”B”に代入されます。

 つまり、図2の場合において、ブロッキング代入は2個のフリップフロップが並列に配列されているのに対して、ノンブロッキング代入は2個のフリップフロップが直列に接続されており、シフトレジスタ回路を構成しています。

理想的なブロッキング代入の記述方法

 上記の説明において、always文にはノンブロッキング代入が使用されるように思われるかもしれません。しかしながら、実際は図3のようにブロッキング代入でレジスタが構成されています。

図3 理想的なブロッキング代入の記述

 always文で処理する変数(レジスタ)は、図3のように1個のみとします。このように記述すると、図2のノンブロッキング代入で記述したalways文と同じ動作を実現することができます。