Verilog Spickzettel
Zuletzt aktualisiert
Modulstruktur & Ports
Ein Modul ist der grundlegende Baustein - es hat einen Namen und eine Portliste.
| Syntax | Bedeutung |
|---|---|
module adder(...); ... endmodule | Ein Modul und seinen Rumpf definieren |
input clk; | Ein Eingangsport |
output q; | Ein Ausgangsport |
output reg q; | Ein Ausgang, der aus einem always-Block getrieben wird |
input [7:0] data; | Ein 8-Bit-Eingangsbus (Vektor) |
inout sda; | Ein bidirektionaler Port |
adder u1 (.a(x), .b(y), .sum(s)); | Ein Modul über benannte Ports instanziieren |
Datentypen
wire modelliert eine Verbindung; reg hält einen Wert, den prozeduraler Code zuweist.
| Element | Funktion |
|---|---|
wire w; | Ein Netz, getrieben von assign oder einem Modulausgang |
reg r; | Hält einen Wert, der in einem always-/initial-Block zugewiesen wird |
wire [3:0] bus; | Ein 4-Bit-Vektor (Bits 3 bis 0) |
reg [7:0] count; | Ein 8-Bit-Register |
bus[2] | Ein einzelnes Bit auswählen |
bus[3:1] | Einen Bit-Ausschnitt auswählen (Part-Select) |
reg mem [0:255]; | Ein Speicher: ein Array von Registern |
parameter WIDTH = 8; | Eine benannte Konstante für das Modul |
Zahlenliterale
Das Format ist <size>'<base><value> - Größe in Bits, Basis als b/o/d/h.
| Syntax | Bedeutung |
|---|---|
4'b1010 | 4-Bit-Binär, Wert 10 |
8'hFF | 8-Bit-Hex, Wert 255 |
8'hff | Dasselbe - Hex-Ziffern sind nicht case-sensitiv |
16'd255 | 16-Bit-Dezimal, Wert 255 |
3'o7 | 3-Bit-Oktal, Wert 7 |
8'b1010_1100 | Unterstriche gruppieren Ziffern zur besseren Lesbarkeit |
1'bx | Ein unbekannter (x) Bitwert |
1'bz | Ein hochohmiger (z) Bitwert |
Operatoren
Bitweise, logische, Vergleichs- und Reduktionsoperatoren.
| Operator | Funktion |
|---|---|
& | ^ ~ | Bitweise AND, OR, XOR, NOT |
&& || ! | Logische AND, OR, NOT (geben 1 Bit zurück) |
== != < > <= >= | Vergleichsoperatoren |
<< >> | Links- und Rechtsverschiebung |
+ - * / % | Arithmetische Operatoren |
&bus | Reduktions-AND (AND aller Bits) |
|bus | Reduktions-OR (OR aller Bits) |
^bus | Reduktions-XOR (Parität aller Bits) |
{a, b} | Verkettung; {4{1'b1}} repliziert zu 4'b1111 |
Kontinuierliche Zuweisung
assign treibt ein wire kontinuierlich - verwende es für kombinatorische Logik.
| Syntax | Bedeutung |
|---|---|
assign y = a & b; | Treibt y mit dem AND von a und b |
assign sum = a + b; | Berechnet kontinuierlich eine Summe |
assign y = sel ? a : b; | Ternär - ein 2-zu-1-Multiplexer |
assign {c, s} = a + b; | Übertrag und Summe zusammen erfassen |
assign y = ~en; | Ein wire aus einem invertierten Signal treiben |
Prozedurale Blöcke
always und initial führen Anweisungen aus; die Sensitivitätsliste steuert wann.
| Syntax | Bedeutung |
|---|---|
always @(*) begin ... end | Kombinatorische Logik (bei jeder Eingangsänderung) |
always @(posedge clk) | Läuft bei jeder steigenden Taktflanke (sequentiell) |
always @(negedge clk) | Läuft bei jeder fallenden Taktflanke |
always @(posedge clk or posedge rst) | Getakteter Block mit asynchronem Reset |
initial begin ... end | Läuft einmal zum Zeitpunkt 0 (Testbenches, nur Simulation) |
begin ... end | Mehrere Anweisungen gruppieren |
#10 | 10 Zeiteinheiten verzögern (nur Simulation) |
Blocking vs. Non-blocking
Verwende = für kombinatorische Logik, <= für getaktete sequentielle Logik.
| Syntax | Bedeutung |
|---|---|
a = b; | Blocking - wird der Reihe nach, sofort ausgeführt |
a <= b; | Non-blocking - alle RHS zuerst gelesen, dann zugewiesen |
always @(*) y = a & b; | Kombinatorisch: blocking = verwenden |
always @(posedge clk) q <= d; | Ein Flip-Flop: non-blocking <= verwenden |
= und <= in einem Block mischen | Vermeide es - eine häufige Fehlerquelle |
Kontrollfluss
Bedingungen und mehrwegige Verzweigungen innerhalb prozeduraler Blöcke.
| Syntax | Bedeutung |
|---|---|
if (cond) ... else ... | Bedingte Anweisung |
if (a) x = 1; else x = 0; | Einzeiliges if/else |
case (sel) ... endcase | Mehrwegige Verzweigung auf einem Wert |
2'b00: y = a; | Ein case-Element |
default: y = 0; | Ausweich-case-Element |
for (i = 0; i < 8; i = i + 1) | Schleife (oft innerhalb von generate oder Simulation) |
repeat (4) @(posedge clk); | Eine Anweisung N-mal wiederholen |
Häufige Muster
Bausteine, die du immer wieder schreibst, plus Testbench-Tasks.
| Muster | Syntax |
|---|---|
| D-Flip-Flop | always @(posedge clk) q <= d; |
| Register mit Reset | always @(posedge clk) if (rst) q <= 0; else q <= d; |
| Zähler | always @(posedge clk) count <= count + 1; |
| FSM-Zustandsregister | always @(posedge clk) state <= next_state; |
| FSM-Folgezustandslogik | always @(*) case (state) ... endcase |
| Einen Wert ausgeben | $display("q = %b", q); |
| Bei Änderung ausgeben | $monitor("t=%0t q=%b", $time, q); |
| Die Simulation beenden | $finish; |
Jedes Stück Verilog-Syntax, das du brauchst, auf einer Seite. Dieser Verilog-Spickzettel ist eine Schnellreferenz für die Hardwarebeschreibungssprache - Module und Ports deklarieren, Datentypen wählen, kombinatorische und sequentielle Logik schreiben sowie die always-Block-Muster, die echte Schaltungen beschreiben.
Die Syntax hier ist Standard-Verilog (IEEE 1364) und funktioniert in gängigen Simulatoren wie Icarus Verilog und Verilator. Kopiere, was du brauchst, oder probiere es live im Verilog-Playground aus - schreibe ein Modul, simuliere es und sieh dir die Ausgabe in deinem Browser an.
Verilog-Spickzettel FAQ
Ist dieser Verilog-Spickzettel kostenlos?
Was ist der Unterschied zwischen wire und reg?
wire modelliert eine physische Verbindung und muss kontinuierlich getrieben werden - durch eine assign-Anweisung oder einen Modulausgang -, daher verwendest du es für kombinatorische Netze. Ein reg hält seinen Wert, bis prozeduraler Code ihn ändert, also verwendest du es für alles, was innerhalb eines always- oder initial-Blocks zugewiesen wird. Trotz des Namens wird ein reg nicht immer zu einem Hardware-Register; es bedeutet nur, dass der Wert prozedural gesetzt wird.Was ist der Unterschied zwischen blocking und non-blocking Zuweisung?
=) wird sofort und der Reihe nach ausgeführt, wie eine normale Programmieranweisung, also verwende sie für kombinatorische Logik in always @(*)-Blöcken. Die non-blocking Zuweisung (<=) wertet zuerst alle rechten Seiten aus und aktualisiert dann die linken Seiten gemeinsam, was Flip-Flops korrekt modelliert - also verwende sie in getakteten always @(posedge clk)-Blöcken. Beide in einem Block zu mischen ist eine klassische Quelle von Simulationsfehlern.