9

私がこれまでに読んだすべての本で言及されている一般的な経験則は、クロックの立ち上がりエッジまたは立ち下がりエッジによって駆動される always ブロックでノンブロッキング割り当てを使用する必要があるということです。反対に、組み合わせ論理の記述にはブロッキング割り当てを使用する必要があります。この規則は私には理にかなっており、例の作成者はそれを徹底的に守っています。

ただし、製品コードの 1 つで次の Verilog を見つけました。

always @* begin
   in_ready <= out_ready || ~out_valid;
end

ノンブロッキング割り当て<=が使用されていることに注意してください。この場合、複数の割り当てがないため、違いはないと思います。しかし、これについての説明が見つからないようです。問題は、特定の always ブロックの範囲内でも、より大きな設計の一部としても、違いがあるのか​​、それとも違いがないのかということです。

4

4 に答える 4

8

もちろん、これは私のコーディング ガイドライン #3 ( http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf ) に違反していますが、動作します。

組み合わせロジックのコード化にノンブロッキング代入の使用を避ける理由は、シミュレーションのパフォーマンスにあります。Munkymorgy の例では、always ブロックがトリガーされた後、すべての方程式の右辺 (RHS) を評価し、always ブロックの先頭に戻り、方程式の LHS を更新します。 always ブロックは、再びシミュレーターに方程式の右辺を評価させ、always ブロックの先頭に移動してから、方程式の左辺を更新します。大きなブロックの場合、これにより、always ブロックを介して複数の反復が発生し、対応するシミュレーション ペナルティが発生する可能性があります。

単純な 1 行の例では、内部シミュレーション ペナルティはありませんが、他の場所でクロス割り当てペナルティが発生する可能性があります。

優れたコーダーは一貫して優れたコーディング習慣を使用しています。コードを変更します。コードを変更するとシミュレーション結果が損なわれる場合は、コードの別の場所に埋め込まれている別の悪いコーディング習慣があります。コードはそれほど脆弱であってはなりません。

于 2012-06-27T21:58:17.787 に答える
5

無関係だが悪い習慣。

単一の割り当てが副作用を引き起こすとは思えません。always ブロックは右側の変更をトリガーし、in_ready を更新します。ブロックするものは何もないため、ブロックしないことで問題が発生することはありません。

より大きなデザインの場合:

always @* begin 
  in_ready    <= out_ready || ~out_valid  ;
  other_ready <= in_ready  || other_ready ;
end

組み合わせであるため、解決するには追加のデルタステップが必要になる可能性があるため、よくわかりません。

于 2012-06-21T15:31:15.363 に答える