IEEE 1364.1は、共通の合成可能なサブセットを定義しようとする、Verilogレジスタ転送レベル合成というタイトルの1364Verilog標準の付属物です。ただし、Jerryが指摘しているように、さまざまなツールがさまざまな構成をサポートしており、ツール固有の動作を判断するには、ツールのドキュメントを参照する必要があります。
合成可能なVerilogの正式な(BNFスタイルの)構文定義はありません。コードが合成可能かどうかは、構文だけでなく使用法にも依存します。たとえば、のようalways @(a) o = a || b
に感度が不完全なalways構文で記述された動作は、合成できません。(ほとんどのツールは、感度リストが完全であるかのようにそのコードを合成するため、シミュレーション/合成の不一致が発生する可能性があります。)
ラッチや多重駆動ネットなどの回路構造は、Verilog記述から合成できますが、ほとんどの設計ルールでは許可されていないか、推奨されていません。ターゲットライブラリの選択を考えると、サポートされていない、または推奨されない合成可能な構造もあります。たとえば、選択したFPGAテクノロジでサポートされている最大値よりも大きいRAMを記述したり、ターゲットライブラリに存在しない場合のトライステートドライバを記述したりします。
合成可能なVerilogに固執する一般的な構成は次のとおりです。
assign
連続割り当て(ステートメント)でモデル化された組み合わせロジック
- 常にブロックでモデル化された組み合わせロジック。ブロッキング割り当てを使用する必要があり、完全な感度リストがあるか、
always @*
- 常にブロックでモデル化されたシーケンシャルロジック(フリップフロップ)。非ブロッキング割り当てを使用する必要があり、ポーズクロックのみ(同期リセットまたは非リセットフロップの場合)またはポーズクロックとポーズまたはネガエッジリセット(非同期リセットフロップの場合)のいずれかがあります。感度リストにあります。
シーケンシャルロジックの最も安全なコーディングスタイルは、シーケンシャルalwaysブロックにリセットロジックのみをコーディングすることです。
always @(posedge clk or posedge reset)
if (reset)
q <= reset_value;
else
q <= next_value;
ただし、注意が必要な場合は、シーケンシャルブロックに追加の組み合わせロジックをコーディングできます。これを行うことが理にかなっている一般的なケースは、フロップの前のマルチプレクサです。
always @(posedge clk)
if (!sel)
q <= sel0_value;
else if (sel)
q <= sel1_value;
else
q <= 'bx;