![]() |
| by Manuel Cernuda |
以前のVerilog HDLでは、alwaysを使って組み合わせ回路を書く場合には
Sensitivity Listに入力を全て列挙しなければならず面倒で、またバグの温床でもありました。
例えばこんな感じです。
always @ ( color or a or b or c or ... ) begin
case (color)
RED : x = a;
BLUE : x = b & c;
....;
endcase
end
Verilog 2001ではalways @*がサポートされてかなりの簡潔に記述できるようになり、Sensitivity Listの記入漏れの問題は起きにくくなりました。
しかし、それでもまだ実はシミュレーション時に問題が起こる可能性があります。
always @* begin
case (color)
RED : x = a;
BLUE : x = b & c;
PINK : x = my_function(d, e, f);
....;
endcase
end
function my_function;
input sig_a;
input sig_b;
input sig_c;
begin
my_function = sig_a | sig_b | sig_c | SIG_X;
end
endfunction
always @*はalways内で直接使用している信号までしかsensitiveではなく、
例えば上の例の様な記述の場合、my_function()の中で使用しているSIG_Xに変化があったとしてもalways @*の出力xは変化しません。
このような問題を解決できるのがSystemVerilogのalways_combです。
always_comb begin
case (color)
RED : x = a;
BLUE : x = b & c;
PINK : x = my_function(d, e, f);
....;
endcase
end
このようにalways @*の場合と同様に記述出来ます(functionの内部は省略)。
しかし、always_combの場合はalways @*と違い、内部に含まれるfunctionが使用している信号に対してもsensitiveになります。つまり、この場合はSIG_Xの変化にもalways_combの出力xが連動します。
その他にも、always_combではalways @*と比べて以下のような違いがあります。
・時刻0で一度always_comb内部が実行される
・always_comb内でドライブされている信号は他の場所でドライブできない
・always_comb内ではwait()やfork...joinなどのタイミングをブロックするような制御が行えない
他にもSystemVerilogではalways_latchやalways_ffなどが追加されていますが特にこのalways_combが重要ですね。
alwaysで組み合わせ回路を記述する場合は是非使うようにしましょう。
最後に、昔書いた組み合わせ回路の記事のリンクを貼っておきます。
ここではalwaysで組み合わせ回路を記述する場合の短所としてregで出力を宣言しなければならないと書きましたが、SystemVerilogでは新たにlogicが追加されたので便利になりました。
functionを使う場合は、always_combの中に入れておくとより安全でしょう。
こちらで別の例が詳細されていたのでリンクしときます。

0 件のコメント:
コメントを投稿