Verilog Hierarchischer Referenzbereich
Die meisten Programmiersprachen haben ein charakteristisches Merkmal namens Bereich die die Sichtbarkeit bestimmter Codeabschnitte für Variablen und Methoden definiert. Der Geltungsbereich definiert einen Namensraum um Kollisionen zwischen verschiedenen Objektnamen innerhalb desselben Namensraums zu vermeiden.
Verilog definiert einen neuen Geltungsbereich für Module, Funktionen, Tasks, benannte Blöcke und Generierungsblöcke.
module tb;
reg signal;
// Another variable cannot be declared with
// an already existing name in the same scope
reg signal;
// However, the name 'signal' can be reused inside
// a task because it belongs to a different scope.
task display();
reg signal = 1;
$display("signal = %0b", signal);
endtask
endmodule
Ein Bezeichner kann wie ein Signalname verwendet werden, um nur einen Elementtyp in einem bestimmten Bereich zu deklarieren. Das bedeutet, dass zwei Variablen mit unterschiedlichen oder gleichen Datentypen nicht den gleichen Namen haben können, oder ein Task und eine Variable mit dem gleichen Namen, oder sogar eine net- und gate-Instanz mit dem gleichen Namen im gleichen Geltungsbereich.
Jede Kennung in Verilog hat einen eindeutigen hierarchischen Pfadnamen, wobei jede Modulinstanz, Aufgabe, Funktion oder Name begin end
ist oder fork join
Block definiert eine neue Ebene oder einen neuen Geltungsbereich.
Hierarchisches Referenzbeispiel
module tb;
// Create two instances of different modules
A uA();
B uB();
// Create a named block that declares a signal and
// prints the value at 10ns from simulation start
initial begin : TB_INITIAL
reg signal;
#10 $display("signal=%0d", signal);
end
// We'll try to access other scopes using hierarchical
// references from this initial block
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
Simulationsprotokoll xcelium> run Hello, this is A TB signal=0 signal_1=1 signal_2=0 xmsim: *W,RNQUIE: Simulation is complete.
Namensreferenzierung nach oben
Ein Modul einer niedrigeren Ebene kann auf Elemente in einem Modul darüber in der Hierarchie verweisen. Beispielsweise wäre das Signal im TB_INITIAL-Block von der Anzeigetask in A aus sichtbar.
module A;
task display();
$display("Hello, this is A");
// Upward referencing, TB_INITIAL is visible in this module
#5 TB_INITIAL.signal = 1;
endtask
endmodule
Beachten Sie, dass das TB-Signal jetzt 1 statt 0 ist, da das Signal von Modul A aufwärts referenziert wird.
Simulationsprotokollxcelium> run Hello, this is A TB signal=1 signal_1=1 signal_2=0 xmsim: *W,RNQUIE: Simulation is complete.
Hier ist ein weiteres Beispiel mit mehreren verschachtelten Modulen, und der Blattknoten kann direkt auf Mitglieder von darüber liegenden Knoten durch hierarchische Verweise nach oben zugreifen.
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(); // or A.display()
b.display(); // or B.display()
c.display(); // or C.display()
a.b.c.display();
end
endmodule
Simulationsprotokoll xcelium> run Hello, this is A Hello, this is B Hello, this is C Hello, this is C xmsim: *W,RNQUIE: Simulation is complete.
Wenn der Compiler b.display() findet,
- Es schaut im aktuellen Geltungsbereich innerhalb von Modul D, um zu sehen, ob b definiert ist. Wenn es nicht existiert, sucht es nach dem Namen im einschließenden Bereich und bewegt sich nach oben, bis der Modulbereich erreicht ist. Wenn der Name immer noch nicht gefunden wird, geht es zum nächsten Schritt.
- Es sucht im äußersten Gültigkeitsbereich des übergeordneten Moduls und wenn es nicht gefunden wird, geht es in der Hierarchie weiter nach oben.
Verilog