Verilog Module Basics: Struktur & Syntax
Ein module ist ein Block Verilog-Code, der eine bestimmte Funktionalität implementiert. Module können in andere Module eingebettet werden; ein höheres Modul kommuniziert mit niedrigeren über Input/Output-Ports.
Syntax
Ein Modul wird von module und endmodule umschlossen. Name folgt direkt auf module, optionale Port-Liste. Ports in der Liste dürfen im Modulkörper nicht redeklariert werden.
module ([port_list]);
// Modulinhalte
endmodule
// Modul ohne Ports
module name;
// Modulinhalte
endmodule
Alle Deklarationen (Variablen, Dataflow, Functions, Tasks, Sub-Modul-Instanzen) müssen zwischen module/endmodule stehen. Mehrere Module mit unterschiedlichen Namen pro Datei erlaubt, Reihenfolge beliebig.
Beispiel: D-Flipflop
Modul dff hat 3 Inputs (d, clk, rstn) und 1 Output (q). Verhalten: Input d wird an Output q bei positiver Clock-Flanke zugewiesen, wenn rstn high (active-low Reset).
module dff (
input d, clk, rstn,
output reg q
);
always @ (posedge clk or negedge rstn) begin
if (!rstn) q <= 0;
else q <= d;
end
endmodule
Hardware-Schema
Bei Synthese wird daraus ein D-Flipflop-Schaltplan.
Zweck eines Moduls
Ein Modul stellt eine Design-Unit mit bestimmten Verhaltensmerkmalen dar, wird bei Synthese in einen digitalen Schaltkreis umgewandelt. Beliebige Input-Kombinationen → korrespondierende Outputs. Ermöglicht Wiederverwendung für komplexere Hardware.
Beispiel: DFFs zu Shift-Register verketten.
module shift_reg (input d, clk, rstn, output q);
wire [2:0] q_net;
dff u0 (.d(d), .clk(clk), .rstn(rstn), .q(q_net[0]));
dff u1 (.d(q_net[0]), .clk(clk), .rstn(rstn), .q(q_net[1]));
dff u2 (.d(q_net[1]), .clk(clk), .rstn(rstn), .q(q_net[2]));
dff u3 (.d(q_net[2]), .clk(clk), .rstn(rstn), .q(q));
endmodule
Hardware-Schema
DFF-Instanzen per Wires verbunden wie im RTL beschrieben.
Umgekehrt: GPU-Engine in Sub-Blöcke zerlegen (Bus Interface, Instruction Extract, Data Processing…). Jeder Sub-Block = module mit I/O-Signalen. Weitere Unterteilung möglich.
Was sind Top-Level-Module?
Ein Top-Level-Modul enthält alle anderen Module und wird in keinem anderen Modul instanziiert.
Design Top-Level
Beispiel: design ist Top-Level, da es mod1, mod2 (und deren Sub-Module mod3, mod4) instantiiert.
Testbench Top-Level
Testbench enthält Stimuli für funktionale Verifikation. Design wird instanziiert (d0). Aus Simulator-Sicht ist Testbench das Top-Level-Modul.
Hierarchische Namen
Hierarchische Struktur durch Modul-Instanziierung. Top-Level = Root. Jede Instanz hat eindeutigen Namen → keine Ambiguität. Hierarchischer Name: Liste von Identifikatoren, getrennt durch Punkte . für jede Hierarchie-Ebene. Jedes Signal über hierarchischen Pfad zugreifbar.
design.mod_inst1 // Zugriff auf Modul-Instanz
design.mod_inst1.y // Signal "y" in mod_inst1
design.mod_inst2.mod_inst2.a // Signal "a" in mod4 (innerhalb mod2)
testbench.d0._net // Top-Level-Signal _net in design, aus testbench
Verilog
- Verilog meistern: Komplettes Tutorial für digitales Schaltungsdesign
- Verilog Concatenation meistern: Praktischer Leitfaden
- Verilog Essentials: Kurzer Überblick
- Verilog Assignments verstehen: Typen, Syntax und Best Practices
- Verilog Blocking vs. Non-Blocking: Wichtige Unterschiede erklärt
- Verilog Functions meistern für effizientes RTL-Design
- Verilog Tasks verstehen: Functions vs. Tasks, Syntax und Verwendung
- Verilogs hierarchischen Referenz-Gültigkeitsbereich meistern: Namenskonflikte in Modulen und Blöcken vermeiden
- Verilog Clock Generator: Design & Implementierungsleitfaden
- Verilog Math Functions meistern für effizientes Hardware-Design