Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> Verilog

Условная компиляция в Verilog: `ifdef, `ifndef, `elsif

Verilog поддерживает директивы компилятора, указывающие, как обрабатывать код. Например, часть кода может реализовывать определенную функцию, и нужен способ исключить её из дизайна, если функция не используется.

Это решается условной компиляцией: код оборачивается в директивы, которые говорят компилятору включать или исключать код, если заданный именованный флаг установлен.

Синтаксис

Условная компиляция достигается через `ifdef и `ifndef. Эти ключевые слова могут появляться где угодно в дизайне и могут вкладываться друг в друга.

`ifdef включает код до следующего `else или `endif, если макрос FLAG определен через `define.

// Стиль 1: только `ifdef
`ifdef <FLAG>
// Statements
`endif

// Стиль 2: `ifdef с `else
`ifdef <FLAG>
// Statements
`else
// Statements
`endif

// Стиль 3: `ifdef с дополнительными ifdef
`ifdef <FLAG1>
// Statements
`elsif <FLAG2>
// Statements
`elsif <FLAG3>
// Statements
`else
// Statements
`endif

`ifndef включает код до `else или `endif, если макрос FLAG не определен через `define.

Пример дизайна с `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 включается в компиляцию и дизайн его получает.

Экспериментируйте: добавляйте и убирайте +define+INCLUDE_RSTN в 'Compile & Run Options' слева, чтобы увидеть разницу.

Пример `ifdef `elsif

Два $display в отдельных областях `ifdef без дефолтного `else. По умолчанию ничего не печатается. Если определен MACRO1 или MACRO2, соответствующее сообщение включается и печатается.

module tb;
  initial begin
    `ifdef MACRO1
      $display ("This is MACRO1");
    `elsif MACRO2
      $display ("This is MACRO2");
    `endif
  end
endmodule

Simulation Log

# Без макросов
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.

Пример `ifndef `elsif

Тот же код с `ifndef — результаты противоположные.

module tb;
  initial begin
    `ifndef MACRO1
      $display ("This is MACRO1");
    `elsif MACRO2
      $display ("This is MACRO2");
    `endif
  end
endmodule

Simulation Log

# Без макросов
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.

Вложенный `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

Simulation Log

# Без макросов
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.

Обратите внимание: пока родительский макрос не определен, определение любого вложенного макроса внутри него не заставляет компилятор подхватывать вложенный код. Например, NEST1_A или WHITE без FLAG не включают вложенный код.

Verilog

  1. Освоение Verilog: полное руководство по проектированию цифровых схем
  2. Освоение конкатенации в Verilog: практическое руководство
  3. Понимание назначений в Verilog: типы, синтаксис и лучшие практики
  4. Блокирующие и неблокирующие назначения в Verilog: ключевые различия
  5. Мастерство функций в Verilog для эффективного RTL дизайна
  6. Понимание задач (Tasks) в Verilog: отличия от функций, синтаксис и применение
  7. Генератор тактового сигнала в Verilog: проектирование и реализация
  8. Мастерство задач отображения в Verilog: эффективная отладка и логирование
  9. Мастерство математических функций Verilog для эффективного аппаратного дизайна
  10. Мастерство $timeformat в Verilog: точность и контроль отображения времени