1

手続き型ブロックのステートメントは順次実行されるのに、ブロック 1、ブロック 2、またはブロック 3 のいずれもラッチを推論しないのはなぜでしょうか?

module testing(
    input  logic a, b, c,
    output logic x, y, z, v
    );

    logic tmp_ref, tmp1, tmp2, tmp3;

    //reference
    always_comb begin: ref_block
        tmp_ref = a & b;
        x = tmp_ref ^ c;
    end

    always_comb begin: block1
        y = tmp1 ^ c;
        tmp1 = a & b;
    end

    always @(*) begin: block2
        tmp2 <= a & b;
        z = tmp2 ^ c;
    end

    always @(c) begin: block3
        tmp3 = a & b;
        v = tmp3 ^ c;
    end
endmodule: testing

block1 では、tmp1 の新しい値が使用可能になる前に、ブロッキング割り当てを使用して y が計算されます。

block2 では、tmp2 は非ブロッキング割り当てを使用して計算されます。これにより、always ブロックが終了するまで割り当てが延期されます。一方、z はブロッキング割り当てを使用して計算され、tmp2 の新しい値はまだ利用できません。

ブロック 3 には不完全なセンシティビティ リストがあり、まだラッチがありません。

Quartus II 14.1 からの合成結果は次のとおりです。 ここに画像の説明を入力

このブロックを追加した場合にのみ、ラッチが推測されます。

//infers a latch
always @(*) begin: block4
    if (c == 1'b1) begin
        tmp4 = a & b;
        w = tmp4 ^ c;
    end
end

値が更新される前に不完全な機密リストまたは変数を使用すると、組み合わせブロックのラッチが推論されない理由を誰かが説明できますか?

4

1 に答える 1

4

組み合わせブロックで使用される割り当てのタイプは、合成には影響しません。ノンブロッキング ( <=) を使用すると、RTL (合成前) とゲート (合成後) シミュレータの不一致が発生する可能性があります。

同じことが機密リストにも当てはまり、合成は自動生成または完全なリストの動作を提供します。

クロック プロセス ( @(posedge clk)) では、ノンブロッキング ( <=) を使用して、フリップフロップのシミュレーション動作を取得します。ブロッキング ( =) を使用して、クロックされたプロセス内に組み合わせコードを含めることもできますが、スタイルを混在させることは悪いコーディング方法と見なされます。組み合わせ部分のコードは、別の組み合わせブロック ( always @*) に移動するだけです。

ラッチは基本的なメモリ要素です。回路がメモリを必要としない場合、推論されません。

例えば:

always @* begin: 
    v = (a & b) ^ c;
end

v入力によって完全に定義されるため、メモリは関与しません。と比較して :

always @* begin
  if (c == 1'b1) begin
    w = (a & b) ^ c;
  end
end

が 0 の場合c、w はその値を保持する必要があるため、ラッチが推論されます。

ラッチは悪くありませんが、ラッチが正しいデータを確実にキャプチャするように、開閉のタイミングに注意する必要があることに注意してください。したがって、推測されたラッチは通常、不良と見なされ、不適切なコーディングが原因です。

SystemVerilog には、意味的に設計意図を示す次の構文があります。

always_latch begin
  if (c == 1'b1) begin
    w = (a & b) ^ c;
  end
end
于 2015-01-24T23:45:51.510 に答える