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 Hiërarchische Referentie Scope: Naamconflicten in Modules en Blokken vermijden

Meeste programmeertalen hebben een karakteristiek kenmerk genaamd scope dat de zichtbaarheid van bepaalde codesecties voor variabelen en methoden definieert. De scope definieert een namespace om botsing tussen verschillende objectnamen binnen dezelfde namespace te voorkomen.

Verilog definieert een nieuwe scope voor modules, functies, tasks, benoemde blokken en generate-blokken.

module tb;
  reg signal;
  // Een andere variabele kan niet gedeclareerd worden met
  // een al bestaande naam in dezelfde scope
  reg signal; // Fout!
  // De naam 'signal' kan wel hergebruikt worden binnen
  // een task want die behoort tot een andere scope.
  task display();
    reg signal = 1;
    $display("signal = %0b", signal);
  endtask
endmodule

Een identifier, zoals een signaalnaam, kan gebruikt worden om slechts één type item in een gegeven scope te declareren. Dit betekent dat twee variabelen van verschillende of dezelfde datatypes niet dezelfde naam mogen hebben, of een task en een variabele met dezelfde naam, of zelfs een net en gate-instantie met dezelfde naam in dezelfde scope.

Elke identifier in Verilog heeft een unieke hiërarchische padnaam, waarbij elke module-instantie, task, functie of benoemd begin end of fork join blok een nieuw niveau of scope definieert.

Hiërarchische Referentie Voorbeeld

module tb;
  // Maak twee instanties van verschillende modules
  A uA();
  B uB();

  // Maak een benoemd blok dat een signaal declareert en
  // de waarde print op 10ns vanaf simulatiestart
  initial begin : TB_INITIAL
    reg signal;
    #10 $display("signal=%0d", signal);
  end

  // We proberen andere scopes te benaderen met hiërarchische
  // referenties vanuit dit initial-blok
  initial begin
    TB_INITIAL.signal = 0;
    uA.display();
    uB.B_INITIAL.B_INITIAL_BLOCK1.b_signal_1 = 1;
    uB.B_INITIAL.B_INITIAL_BLOCK2.b_signal_2 = 0;
  end
endmodule
module A;
  task display();
    $display("Hello, this is A");
  endtask
endmodule

module B;
  initial begin : B_INITIAL
    #50;
    begin : B_INITIAL_BLOCK1
      reg b_signal_1;
      #10 $display("signal_1=%0d", b_signal_1);
    end
    #50;
    begin : B_INITIAL_BLOCK2
      reg b_signal_2;
      #10 $display("signal_2=%0d", b_signal_2);
    end
  end
endmodule

Simulatie-log

xcelium> run
Hello, this is A
TB signal=0
signal_1=1
signal_2=0
xmsim: *W,RNQUIE: Simulation is complete.

Opwaartse Naamreferentie

Een lager niveau module kan items refereren in een module erboven in de hiërarchie. Bijvoorbeeld, signal in TB_INITIAL-blok zou zichtbaar zijn vanuit de display-task in A.

module A;
  task display();
    $display("Hello, this is A");
    // Opwaartse referentie, TB_INITIAL is zichtbaar in deze module
    #5 TB_INITIAL.signal = 1;
  endtask
endmodule

Let op dat TB signal nu 1 is in plaats van 0, door de opwaartse referentie-wijziging die module A aan het signaal maakte.

Simulatie-log

xcelium> run
Hello, this is A
TB signal=1
signal_1=1
signal_2=0
xmsim: *W,RNQUIE: Simulation is complete.

Hier is nog een voorbeeld met meerdere geneste modules en de bladknoot kan direct leden van bovenliggende knopen benaderen via opwaartse hiërarchische referentie.

module tb;
  A a();
  function display();
    $display("Hello, this is TB");
  endfunction
endmodule

module A;
  B b();
  function display();
    $display("Hello, this is A");
  endfunction
endmodule

module B;
  C c();
  function display();
    $display("Hello, this is B");
  endfunction
endmodule

module C;
  D d();
  function display();
    $display("Hello, this is C");
  endfunction
endmodule

module D;
  initial begin
    a.display(); // of A.display()
    b.display(); // of B.display()
    c.display(); // of C.display()
    a.b.c.display();
  end
endmodule

Simulatie-log

xcelium> run
Hello, this is A
Hello, this is B
Hello, this is C
Hello, this is C
xmsim: *W,RNQUIE: Simulation is complete.

Wanneer de compiler b.display() vindt:

  1. Het kijkt in de huidige scope binnen module D of b gedefinieerd is. Als niet, kijkt het naar de naam in de omringende scope en gaat omhoog tot het modulescope bereikt is. Als de naam nog steeds niet gevonden is, gaat het naar de volgende stap.
  2. Het kijkt in de parent-module's buitenste scope en als het niet gevonden wordt, gaat het verder op in de hiërarchie.

Verilog

  1. Verilog beheersen: Complete tutorial voor digitale schakelingontwerp
  2. Verilog concatenatie beheersen: Een praktische gids
  3. Verilog Essentials: Een beknopt overzicht
  4. Verilog-toewijzingen begrijpen: types, syntax en best practices
  5. Verilog Blocking vs. Non-Blocking: belangrijkste verschillen uitgelegd
  6. Verilog-functies beheersen voor efficiënt RTL-ontwerp
  7. Verilog Tasks begrijpen: Functions vs Tasks, Syntax en Gebruik
  8. Verilog Hiërarchische Referentie Scope: Naamconflicten in Modules en Blokken vermijden
  9. Verilog Clock Generator: Ontwerp & Implementatie Gids
  10. Verilog Display Tasks beheersen: Efficiënt Debuggen & Loggen
  11. Verilog Math Functions beheersen voor efficiënt Hardware-ontwerp