Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Industrial programming >> Verilog

Verilog \`ifdef: Conditionele compilatie uitgelegd

Verilog ondersteunt een paar compiler-directives die de compiler essentieel vertellen de code op een bepaalde manier te behandelen. Een deel van de code kan bijvoorbeeld een implementatie van een bepaalde feature vertegenwoordigen en er moet een manier zijn om de code niet in het ontwerp op te nemen als de feature niet gebruikt wordt.

Dit kan opgelost worden met conditionele compilatie waarbij de ontwerper de code kan omhullen met compiler-directives die de compiler vertellen om de code wel of niet voor compilatie op te nemen wanneer de gegeven vlag gezet is.

Syntax

Conditionele compilatie kan bereikt worden met Verilog \`ifdef en \`ifndef trefwoorden. Deze trefwoorden kunnen overal in het ontwerp voorkomen en kunnen genest worden.

Het trefwoord \`ifdef vertelt de compiler simpelweg om het stuk code op te nemen tot de volgende \`else of \`endif als de gegeven macro FLAG gedefinieerd is met een \`define-directive.

// Stijl #1: Alleen enkele \`ifdef
\`ifdef <FLAG>
// Statements
\`endif

// Stijl #2: \`ifdef met \`else deel
\`ifdef <FLAG>
// Statements
\`else
// Statements
\`endif

// Stijl #3: \`ifdef met additionele ifdefs
\`ifdef <FLAG1>
// Statements
\`elsif <FLAG2>
// Statements
\`elsif <FLAG3>
// Statements
\`else
// Statements
\`endif

Het trefwoord \`ifndef vertelt de compiler om het stuk code op te nemen tot de volgende \`else of \`endif als de gegeven macro FLAG niet gedefinieerd is met een \`define-directive.

Ontwerpvoorbeeld met \`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

Let op dat standaard rstn niet meegenomen wordt tijdens compilatie van het ontwerp en dus niet in de poortlijst verschijnt. Als echter een macro INCLUDE_RSTN gedefinieerd is in een Verilog-bestand dat deel uitmaakt van de compilatielijst of via de commandoregel aan de compiler doorgegeven, wordt rstn meegenomen in de compilatie en heeft het ontwerp het.

Experimenteer door +define+INCLUDE_RSTN toe te voegen of te verwijderen uit 'Compile & Run Options' in het linkerdeelvenster om het verschil te zien.

Verilog \`ifdef \`elsif Voorbeeld

Het volgende voorbeeld heeft twee display-statements binnen afzonderlijke \`ifdef-scopes zonder een standaard \`else-deel. Dit betekent dat standaard niets getoond wordt. Als de macro MACRO1 of MACRO2 gedefinieerd is, wordt het bijbehorende display-bericht meegenomen en getoond tijdens simulatie.

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

Simulatie-log

# Zonder macro's gedefinieerd
ncsim> run
ncsim: *W,RNQUIE: Simulation is complete.

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

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

Verilog \`ifndef \`elsif Voorbeeld

Deze code kan ook geschreven worden met \`ifndef en de resultaten zijn precies het tegenovergestelde.

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

Simulatie-log

# Zonder macro's gedefinieerd
ncsim> run
This is MACRO1
ncsim: *W,RNQUIE: Simulation is complete.

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

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

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

Verilog Geneste \`ifdef Voorbeeld

\`ifdef en varianten kunnen genest worden om complexe manieren van code-inclusie en -exclusie te creëren met gedefinieerde macro's.

module tb;
  initial begin
    \`ifdef FLAG
      $display ("FLAG is gedefinieerd");
      \`ifdef NEST1_A
        $display ("FLAG en NEST1_A zijn gedefinieerd");
        \`ifdef NEST2
          $display ("FLAG, NEST1_A en NEST2 zijn gedefinieerd");
        \`endif
      \`elsif NEST1_B
        $display ("FLAG en NEST1_B zijn gedefinieerd");
        \`ifndef WHITE
          $display ("FLAG en NEST1_B zijn gedefinieerd, maar WHITE niet");
        \`else
          $display ("FLAG, NEST1_B en WHITE zijn gedefinieerd");
        \`endif
      \`else
        $display ("Alleen FLAG is gedefinieerd");
      \`endif
    \`else
      $display ("FLAG is niet gedefinieerd");
    \`endif
  end
endmodule

Simulatie-log

# Zonder macro's definiëren
ncsim> run
FLAG is niet gedefinieerd
ncsim: *W,RNQUIE: Simulation is complete.

# Met +define+FLAG +define+NEST1_B
ncsim> run
FLAG is gedefinieerd
FLAG en NEST1_B zijn gedefinieerd
FLAG en NEST1_B zijn gedefinieerd, maar WHITE is niet
ncsim: *W,RNQUIE: Simulation is complete.

# Met +define+FLAG +define+NEST1_B +define+WHITE
ncsim> run
FLAG is gedefinieerd
FLAG en NEST1_B zijn gedefinieerd
FLAG, NEST1_B en WHITE zijn gedefinieerd
ncsim: *W,RNQUIE: Simulation is complete.

# Met +define+FLAG
ncsim> run
FLAG is gedefinieerd
Alleen FLAG is gedefinieerd
ncsim: *W,RNQUIE: Simulation is complete.

# Met +define+WHITE
ncsim> run
FLAG is niet gedefinieerd
ncsim: *W,RNQUIE: Simulation is complete.

# Met +define+NEST1_A
ncsim> run
FLAG is niet gedefinieerd
ncsim: *W,RNQUIE: Simulation is complete.

Let op: zolang de parent-macro niet gedefinieerd is, wordt de definitie van geneste macro's binnenin niet gecompileerd. Bijvoorbeeld, NEST1_A of WHITE macro-definities zonder FLAG laten de compiler de geneste code niet oppikken.

Verilog

  1. Verilog beheersen: Complete tutorial voor digitale schakelingontwerp
  2. Verilog concatenatie beheersen: Een praktische gids
  3. Verilog-toewijzingen begrijpen: types, syntax en best practices
  4. Verilog Blocking vs. Non-Blocking: belangrijkste verschillen uitgelegd
  5. Verilog-functies beheersen voor efficiënt RTL-ontwerp
  6. Verilog Tasks begrijpen: Functions vs Tasks, Syntax en Gebruik
  7. Verilog Clock Generator: Ontwerp & Implementatie Gids
  8. Verilog Display Tasks beheersen: Efficiënt Debuggen & Loggen
  9. Verilog Math Functions beheersen voor efficiënt Hardware-ontwerp
  10. Verilog $timeformat beheersen: Precisie en Weergave-controle
  11. Verilog Timescales begrijpen en printen in elke Scope