工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial programming >> Verilog

Verilog `ifdef:条件付きコンパイルの解説

Verilogはいくつかのコンパイラディレクティブをサポートしており、これらは本質的にコンパイラにコードを特定の方法で扱うよう指示します。例えば、コードの一部がある機能の実装を表しており、その機能が使用されない場合はコードを設計に含めない方法が必要です。

これは条件付きコンパイルで解決できます。設計者はコードをコンパイラディレクティブでラップし、与えられた名前付きフラグが設定されているときにコードをコンパイルに含めるか除外するかをコンパイラに指示できます。

構文

条件付きコンパイルは、Verilogの`ifdefと`ifndefキーワードで実現できます。これらのキーワードは設計のどこにでも出現でき、互いにネストできます。

キーワード`ifdefは、`defineディレクティブを使用して与えられたマクロ(FLAGと呼ばれる)が定義されている場合、次の`elseまたは`endifまでのコード片を含めるようコンパイラに指示します。

// スタイル #1: 単一の`ifdefのみ
`ifdef <FLAG>
// 文
`endif

// スタイル #2: `else部分ありの`ifdef
`ifdef <FLAG>
// 文
`else
// 文
`endif

// スタイル #3: 追加のifdefありの`ifdef
`ifdef <FLAG1>
// 文
`elsif <FLAG2>
// 文
`elsif <FLAG3>
// 文
`else
// 文
`endif

キーワード`ifndefは、`defineディレクティブを使用して与えられたマクロ(FLAGと呼ばれる)が定義されていない場合、次の`elseまたは`endifまでのコード片を含めるようコンパイラに指示します。

`ifdefを使用した設計例

module my_design (
  input clk, d,
  `ifdef INCLUDE_RSTN
  input rstn,
  `endif
  output reg q
);
  always @ (posedge clk) begin
    `ifdef INCLUDE_RSTN
    if (!rstn) begin
      q <= 0;
    end else
    `endif
    begin
      q <= d;
    end
  end
endmodule

テストベンチ

module tb;
  reg clk, d, rstn;
  wire q;
  reg [3:0] delay;
  
  my_design u0 (
    .clk(clk),
    .d(d),
    `ifdef INCLUDE_RSTN
    .rstn(rstn),
    `endif
    .q(q)
  );
  
  always #10 clk = ~clk;
  
  initial begin
    integer i;
    {d, rstn, clk} <= 0;
    #20 rstn <= 1;
    for (i = 0; i < 20; i=i+1) begin
      delay = $random;
      #(delay) d <= $random;
    end
    #20 $finish;
  end
endmodule

デフォルトでは、rstnは設計のコンパイル時に含まれず、ポートリストに現れません。しかし、コンパイル対象ファイルリストに含まれる任意のVerilogファイルで、またはコンパイラへのコマンドライン引数として、INCLUDE_RSTNというマクロが定義されている場合、rstnはコンパイルに含まれ、設計に現れます。

左ペインの'Compile & Run Options'から+define+INCLUDE_RSTNを追加/削除して違いを確認してください。

Verilog `ifdef `elsif の例

以下の例では、デフォルトの`else部分を持たない別々の`ifdefスコープ内に2つのdisplay文があります。したがって、デフォルトでは何も表示されません。マクロMACRO1またはMACRO2のいずれかが定義されている場合、対応する表示メッセージが含まれ、シミュレーション中に表示されます。

module tb;
  initial begin
    `ifdef MACRO1
      $display ("This is MACRO1");
    `elsif MACRO2
      $display ("This is MACRO2");
    `endif
  end
endmodule
# マクロ未定義の場合
ncsim> run
ncsim: *W,RNQUIE: Simulation is complete.

# +define+MACRO1の場合
ncsim> run
This is MACRO1
ncsim: *W,RNQUIE: Simulation is complete.

# +define+MACRO2の場合
ncsim> run
This is MACRO2
ncsim: *W,RNQUIE: Simulation is complete.

Verilog `ifndef `elsif の例

同じコードを`ifndefで書くと、結果は逆になります。

module tb;
  initial begin
    `ifndef MACRO1
      $display ("This is MACRO1");
    `elsif MACRO2
      $display ("This is MACRO2");
    `endif
  end
endmodule
# マクロ未定義の場合
ncsim> run
This is MACRO1
ncsim: *W,RNQUIE: Simulation is complete.

# +define+MACRO1の場合
ncsim> run
ncsim: *W,RNQUIE: Simulation is complete.

# +define+MACRO2の場合
ncsim> run
This is MACRO1
ncsim: *W,RNQUIE: Simulation is complete.

# +define+MACRO1 +define+MACRO2の場合
ncsim> run
This is MACRO2
ncsim: *W,RNQUIE: Simulation is complete.

Verilog ネストした `ifdef の例

`ifdefとその変種は、複雑なコードの包含/除外を定義済みマクロで作成するために、互いにネストできます。

module tb;
  initial begin
    `ifdef FLAG
      $display ("FLAG is defined");
      `ifdef NEST1_A
        $display ("FLAG and NEST1_A are defined");
        `ifdef NEST2
          $display ("FLAG, NEST1_A and NEST2 are defined");
        `endif
      `elsif NEST1_B
        $display ("FLAG and NEST1_B are defined");
        `ifndef WHITE
          $display ("FLAG and NEST1_B are defined, but WHITE is not");
        `else
          $display ("FLAG, NEST1_B and WHITE are defined");
        `endif
      `else
        $display ("Only FLAG is defined");
      `endif
    `else
      $display ("FLAG is not defined");
    `endif
  end
endmodule
# マクロ未定義の場合
ncsim> run
FLAG is not defined
ncsim: *W,RNQUIE: Simulation is complete.

# +define+FLAG +define+NEST1_Bの場合
ncsim> run
FLAG is defined
FLAG and NEST1_B are defined
FLAG and NEST1_B are defined, but WHITE is not
ncsim: *W,RNQUIE: Simulation is complete.

# +define+FLAG +define+NEST1_B +define+WHITEの場合
ncsim> run
FLAG is defined
FLAG and NEST1_B are defined
FLAG, NEST1_B and WHITE are defined
ncsim: *W,RNQUIE: Simulation is complete.

# +define+FLAGのみの場合
ncsim> run
FLAG is defined
Only FLAG is defined
ncsim: *W,RNQUIE: Simulation is complete.

# +define+WHITEのみの場合
ncsim> run
FLAG is not defined
ncsim: *W,RNQUIE: Simulation is complete.

# +define+NEST1_Aのみの場合
ncsim> run
FLAG is not defined
ncsim: *W,RNQUIE: Simulation is complete.

親マクロが定義されていない限り、その中にネストされた他のマクロの定義はコンパイルされないことに注意してください。例えば、FLAGなしでNEST1_AやWHITEマクロを定義しても、コンパイラはネストされたコードを拾いません。

Verilog

  1. Verilogマスター:デジタル回路設計のための完全チュートリアル
  2. Verilog連結マスター:実践ガイド
  3. Verilog代入文の理解:種類、構文、ベストプラクティス
  4. Verilogブロッキング代入とノンブロッキング代入:違いを徹底解説
  5. Verilog関数のマスター:効率的なRTL設計のために
  6. Verilogタスクの理解:関数との違い、構文、使用法
  7. Verilogクロックジェネレータ:設計と実装ガイド
  8. Verilog表示タスクのマスター:効率的なデバッグとログ出力
  9. Verilog数学関数のマスター:効率的なハードウェア設計のために
  10. Verilog $timeformatのマスター:精度と表示制御
  11. 任意のスコープでのVerilog timescale理解と表示