A
シミュレーションでも合成でも、コード内の の最終値について非決定論的なものは何もありません。
ただし、厳密に言えば、デザインに のトリガーが含まれている場合、シミュレーションと合成が一致しない可能性がありますA
。次の例を検討してください。
module test(input clk, output reg a, b);
always @(posedge clk) begin
a <= 0;
a <= 1;
end
initial b = 0;
always @(posedge a) begin
b <= !b;
end
endmodule
そしてテストベンチ:
module tb;
reg clk = 0;
always #5 clk = ~clk;
wire a, b;
test uut (clk, a, b);
initial begin
$monitor("clk=%b a=%b b=%b", clk, a, b);
repeat (100) @(posedge clk);
$finish;
end
endmodule
シミュレーション中、 update と の両方a <= 0
がa <= 1
NBA イベント リージョンにプッシュされ、順番に実行されるため、a
常に設定されます。ただし、 も実行されるため、クロック サイクルごとa <= 0
にゼロ幅の負のパルスがオンになります。a
このパルスは、2 番目の常にブロックをトリガーします。これはシミュレーション出力です (Icarus Verilog および Modelsim でテスト済み)。
clk=0 a=x b=0
clk=1 a=1 b=1
clk=0 a=1 b=1
clk=1 a=1 b=0
clk=0 a=1 b=0
clk=1 a=1 b=1
clk=0 a=1 b=1
clk=1 a=1 b=0
clk=0 a=1 b=0
clk=1 a=1 b=1
clk=0 a=1 b=1
clk=1 a=1 b=0
clk=0 a=1 b=0
...
ただし、合成ではa
、定数値 1 とb
定数値 0 が割り当てられるだけです。(Yosys および Xilinx Vivado でテスト済み)。したがって、合成後のシミュレーション出力は次のようになります。
clk=0 a=1 b=0
clk=1 a=1 b=0
clk=0 a=1 b=0
clk=1 a=1 b=0
clk=0 a=1 b=0
clk=1 a=1 b=0
clk=0 a=1 b=0
clk=1 a=1 b=0
clk=0 a=1 b=0
clk=1 a=1 b=0
clk=0 a=1 b=0
clk=1 a=1 b=0
clk=0 a=1 b=0
clk=1 a=1 b=0
(理論的には、最初の行はまだ と言うことができますが、テストの両方のツールが行っa=x
たように、適切な合成ツールはすべてa
-flip-flop を最適化します。)
それ以外には、そのコードに潜在的な問題はありません.@Morganが彼の答えで正しく指摘したように、これは、条件付き割り当てを使用して特殊なケースをエンコードする前に、出力信号の「デフォルト値」を定義するための非常に一般的なコーディング手法です(if
および/またはcase
)。