산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> verilog

Verilog `ifdef: 조건부 컴파일 완벽 가이드

Verilog는 컴파일러에게 코드를 특정 방식으로 처리하도록 지시하는 몇 가지 컴파일러 지시자를 지원합니다. 예를 들어, 코드의 일부가 특정 기능의 구현을 나타내는데, 해당 기능이 사용되지 않으면 코드를 설계에 포함하지 않는 방법이 필요합니다.

이는 조건부 컴파일로 해결할 수 있습니다. 설계자는 코드를 컴파일러 지시자로 감싸서, 주어진 플래그가 설정되었을 때 컴파일러가 코드를 포함하거나 제외하도록 할 수 있습니다.

문법

조건부 컴파일은 Verilog `ifdef와 `ifndef 키워드로 달성할 수 있습니다. 이 키워드들은 설계 어디에나 나타날 수 있으며 서로 중첩될 수 있습니다.

`ifdef 키워드는 주어진 매크로(FLAG)가 `define 지시자로 정의된 경우, 다음 `else 또는 `endif까지의 코드 조각을 포함하도록 컴파일러에게 지시합니다.

// 스타일 #1: 단일 `ifdef
`ifdef <FLAG>
  // 문장들
`endif

// 스타일 #2: `else 부분 포함
`ifdef <FLAG>
  // 문장들
`else
  // 문장들
`endif

// 스타일 #3: 추가 ifdef들
`ifdef <FLAG1>
  // 문장들
`elsif <FLAG2>
  // 문장들
`elsif <FLAG3>
  // 문장들
`else
  // 문장들
`endif

`ifndef 키워드는 주어진 매크로(FLAG)가 `define 지시자로 정의되지 않은 경우, 다음 `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은 설계 컴파일에 포함되지 않으므로 포트리스트에 나타나지 않습니다. 그러나 INCLUDE_RSTN 매크로가 컴파일 파일 목록에 포함된 아무 Verilog 파일에서 정의되거나, 컴파일러 명령줄로 전달되면 rstn이 컴파일에 포함되고 설계에 나타납니다.

왼쪽 패인의 'Compile & Run Options'에서 +define+INCLUDE_RSTN을 추가/제거하며 차이를 실험해 보세요.

Verilog `ifdef `elsif 예제

다음 예제는 별도의 `ifdef 범위 안에 두 개의 display 문이 있으며 기본 `else 부분이 없습니다. 따라서 기본적으로 아무것도 표시되지 않습니다. MACRO1 또는 MACRO2 매크로가 정의되면 해당 display 메시지가 포함되어 시뮬레이션 중에 표시됩니다.

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 결합(Concatenation) & 복제(Replication) 연산자 실전 가이드
  3. Verilog 할당문 이해: 유형, 문법, 모범 사례
  4. Verilog 차단 vs 비차단 할당: 핵심 차이점 완벽 이해
  5. Verilog 함수 마스터하기: 효율적인 RTL 설계를 위한 활용법
  6. Verilog 태스크 이해: 함수와의 차이점, 문법, 활용법
  7. Verilog 클럭 생성기: 설계 및 구현 가이드
  8. Verilog 디스플레이 태스크 마스터하기: 효율적인 디버깅 및 로깅
  9. Verilog 수학 함수 마스터하기: 효율적인 하드웨어 설계를 위한 활용
  10. Verilog $timeformat 마스터하기: 정밀도 및 표시 제어