Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Industrial programming >> Verilog

Verilog `ifdef: Compilação Condicional Explicada

Verilog suporta diretivas de compilador que direcionam como o código deve ser tratado. Por exemplo, uma parte do código pode implementar um recurso e deve haver forma de não incluí-lo se o recurso não for usado.

Isso é resolvido com compilação condicional, onde o designer envolve o código em diretivas que dizem ao compilador para incluir ou excluir o código quando uma flag nomeada está definida.

Sintaxe

Compilação condicional usa `ifdef e `ifndef. Podem aparecer em qualquer lugar no design e ser aninhadas.

`ifdef diz ao compilador para incluir o código até o próximo `else ou `endif se a macro FLAG estiver definida via `define.

// Estilo #1: Apenas `ifdef
`ifdef <FLAG>
// Instruções
`endif

// Estilo #2: `ifdef com `else
`ifdef <FLAG>
// Instruções
`else
// Instruções
`endif

// Estilo #3: `ifdef com `elsif adicionais
`ifdef <FLAG1>
// Instruções
`elsif <FLAG2>
// Instruções
`elsif <FLAG3>
// Instruções
`else
// Instruções
`endif

`ifndef inclui o código se a macro FLAG não estiver definida via `define.

Exemplo de Design com `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

Testbench

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

Por padrão, rstn não será incluído na compilação e não aparecerá na portlist. Se a macro INCLUDE_RSTN for definida em qualquer arquivo Verilog da lista de compilação ou passada via linha de comando, rstn será incluído.

Experimente adicionar/remover +define+INCLUDE_RSTN em 'Compile & Run Options' para ver a diferença.

Exemplo Verilog `ifdef `elsif

Duas instruções display em escopos `ifdef` separados sem `else` padrão. Por padrão nada é exibido. Se MACRO1 ou MACRO2 for definida, a mensagem correspondente é incluída.

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

Log de Simulação

# Sem macros definidas
ncsim> run
ncsim: *W,RNQUIE: Simulation is complete.

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

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

Exemplo Verilog `ifndef `elsif

Mesmo código com `ifndef, resultados opostos.

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

Log de Simulação

# Sem macros definidas
ncsim> run
This is MACRO1
ncsim: *W,RNQUIE: Simulation is complete.

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

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

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

Exemplo Verilog `ifdef Aninhado

`ifdef e variantes podem ser aninhadas para criar formas complexas de inclusão/exclusão.

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

Log de Simulação

# Sem definir macro
ncsim> run
FLAG is not defined
ncsim: *W,RNQUIE: Simulation is complete.

# Com +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.

# Com +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.

# Com +define+FLAG
ncsim> run
FLAG is defined
Only FLAG is defined
ncsim: *W,RNQUIE: Simulation is complete.

# Com +define+WHITE
ncsim> run
FLAG is not defined
ncsim: *W,RNQUIE: Simulation is complete.

# Com +define+NEST1_A
ncsim> run
FLAG is not defined
ncsim: *W,RNQUIE: Simulation is complete.

Note que enquanto o macro pai não for definido, definições de macros aninhadas não são compiladas. Por exemplo, NEST1_A ou WHITE sem FLAG não fazem o compilador incluir o código aninhado.

Verilog

  1. Domine o Verilog: Tutorial Completo para Projeto de Circuitos Digitais
  2. Dominando Concatenação Verilog: Guia Prático
  3. Entendendo Atribuições em Verilog: Tipos, Sintaxe e Boas Práticas
  4. Verilog Blocking vs Non-Blocking: Diferenças Essenciais Explicadas
  5. Dominando Funções em Verilog para Design RTL Eficiente
  6. Entendendo Tasks em Verilog: Funções vs Tasks, Sintaxe e Uso
  7. Gerador de Clock Verilog: Guia de Design e Implementação
  8. Dominando Tarefas de Display do Verilog: Depuração e Logging Eficientes
  9. Dominando Funções Matemáticas do Verilog para Design de Hardware Eficiente
  10. Dominando $timeformat do Verilog: Precisão e Controle de Exibição