Was "Operator" in Verilog bedeutet
Operatoren nehmen signalführende Ausdrücke und produzieren neue signalführende Ausdrücke. a + b ist Hardware - der Synthesizer macht daraus einen Addierer. a == b ist Hardware - es baut einen Komparator. Nichts davon ist "Code, der läuft"; alles ist "Schaltungen, die der Operator beschreibt".
Das gesamte Operator-Menü ist klein genug, um es auswendig zu lernen. Dieses Doc deckt die arithmetischen, vergleichenden, logischen und bedingten Operatoren ab. Bitweise und Reduktion behandelt die Bit-Operatoren ohne direkte Software-Entsprechung.
Arithmetik: + - * / %
Drei Dinge wissen:
- Division ist Ganzzahldivision.
7/2ist3, nicht3.5. Verilog hat keinen Float-Typ (gut,real, aber der ist simulation-only). - Division und Modulo sind in Hardware teuer. Ein
/4ist fein (der Synthesizer macht daraus ein Rechtsshift), aber ein/nmit laufzeit-variablemnbaut einen mehrtaktigen Dividierer, den du fast nie willst. - Überlauf läuft um. Werden zwei N-Bit-Unsigned-Werte addiert, die N Bits überschreiten, wird auf N Bits abgeschnitten. Willst du den Carry erfassen, deklariere das Ergebnis ein Bit breiter:
wire [7:0] a, b;
wire [8:0] sum = a + b; // 9-Bit-Summe erfasst Carry-Out
Vergleich: == != < > <= >=
Alle sechs Vergleichsoperatoren liefern ein 1-Bit-Ergebnis: 1, wenn wahr, 0, wenn falsch, x, wenn einer der Operanden ein x- oder z-Bit hat. Um den x/z-Fall zu handhaben, greife zu === und !== (den Case-Equality-Operatoren), behandelt in X- und Z-Werte.
<= ist hier der Vergleichsoperator (kleiner-gleich). Dieselben Zeichen bedeuten auch non-blocking-Zuweisung in einem prozeduralen Block (q <= d). Der Kontext unterscheidet: in einem Ausdruck ein Vergleich; links von einem zugewiesenen Wert eine Zuweisung. Die Überschneidung ist verwirrend, aber für den Parser eindeutig.
Logik: && || !
Logische Operatoren behandeln ihre Operanden als Booleans (alles ungleich Null ist wahr, Null ist falsch) und liefern ein 1-Bit-Ergebnis:
Der entscheidende Unterschied, den du verinnerlichen musst: Logisches && ist nicht bitweises &.
4'b1100 && 4'b0011 // 1 (beide ungleich Null, logisches AND wahr)
4'b1100 & 4'b0011 // 4'b0000 (keine Bitposition in beiden 1)
Gleiches für || vs |. Nimm logisch in if-Bedingungen und ?:-Prädikaten; nimm bitweise, wenn du jede Bitposition unabhängig AND/OR willst.
&& und || sind im C-Sinn kurzschließend: die rechte Seite wird nicht ausgewertet, wenn das Ergebnis bereits durch die linke feststeht. Das zählt für Testbenches, die Pointer oder Funktionsaufrufe prüfen; für synthetisierbares RTL spielt es selten eine Rolle, weil dort sowieso alles parallel passiert.
Der bedingte Operator: ?:
Der Ternäre ist dein bester Freund für Multiplexer und bedingte Ausdrücke:
Das Muster cond ? a : b ist ein 1-Bit-Select 2-zu-1-Multiplexer in Hardware. Sie zu verketten ist für 3- und 4-Wege-Selects okay, aber darüber hinaus ist eine case-Anweisung (siehe Case-Anweisung) deutlich lesbarer.
Der ?:-Operator ist auch die übliche Art, einem Register einen Default-Wert zu geben, den du nur manchmal überschreibst:
next_value = update ? new_data : next_value;
Breitenregeln: Die Anfängerfalle
Die Breitenregeln von Verilogs Arithmetik-Operatoren sind berüchtigt für ihre Überraschungen. Kurzfassung:
- Die Breite des Ergebnisses ist das Maximum der Breiten der Eingänge.
- Wird das Ergebnis einem breiteren Ziel zugewiesen, wird mit Nullen erweitert (oder mit Vorzeichen erweitert, wenn signed).
- Die Breite von Zwischenrechnungen ist ebenfalls die Ergebnisbreite, also passiert Überlauf in der Zwischenrechnung.
Die erste Multiplikation läuft über, weil die Operandenbreiten beide 8 Bit sind, die Ergebnisbreite damit 8 Bit, und 40000 passt nicht. Die zweite funktioniert, weil wir a vor der Multiplikation explizit erweitert haben.
Die Fix-Techniken:
- Nutze den Konkatenationsoperator
{8'b0, a}zur Null-Erweiterung. - Nutze
$unsigned(a)oder$signed(a), um die Interpretation zu beeinflussen. - Caste Zwischenausdrücke auf breitere Größen, wenn du unsicher bist.
Operator-Präzedenz
Die Tabelle wirst du nicht auswendig lernen, aber ein paar Regeln helfen:
*,/,%binden enger als+,-.- Vergleich bindet enger als Logik (
&&,||). - Der bedingte Operator
?:hat sehr niedrige Präzedenz - in größeren Ausdrücken meist Klammern um seine Zweige nötig. - Im Zweifel klammern. Der Simulator rechnet pro Zeichen nichts ab.
out = (mode == 2'd0) ? a + b : a - b; // mit Klammern klarer
Wie es weitergeht
Du hast jeden Operator gesehen, der wie sein Software-Verwandter aussieht. Das nächste Doc - Bitweise und Reduktion - behandelt die Operatoren ohne direkte Software-Entsprechung: bitweises AND/OR/XOR pro Bit, plus die Reduktionsformen, die einen ganzen Vektor auf ein einzelnes Bit kollabieren.
Häufig gestellte Fragen
Welche Operatoren unterstützt Verilog?
Verilog hat vier große Operator-Familien: Arithmetik (+, -, *, /, %), Vergleich (==, !=, <, >, <=, >=), Logik (&&, ||, !) und bitweise/Reduktion (&, |, ^, ~, ~&, ~|, ~^). Dazu kommen Shift-Operatoren (<<, >>, <<<, >>>), Konkatenation {}, Replikation {N{...}} und der bedingte ?:.
Was ist der Unterschied zwischen && und & in Verilog?
&& ist logisches AND - es behandelt jeden Operanden als Boolean (Null oder Nicht-Null) und gibt ein 1-Bit-Ergebnis. & ist bitweises AND - es paart Bits positionsweise. 4'b1100 && 4'b0011 ist 1 (beide sind ungleich Null); 4'b1100 & 4'b0011 ist 4'b0000. Nimm && in Bedingungen, & für Bit-Operationen.
Wie funktioniert Division in Verilog?
Ganzzahldivision - der Nachkommateil wird verworfen. 7 / 2 ist 3, nicht 3.5. Der %-Operator liefert den Rest: 7 % 2 ist 1. Division durch Null produziert in der Simulation x (Unknown). Beide Operatoren sind theoretisch synthetisierbar, erzeugen aber auf FPGAs und ASICs sehr große, langsame Hardware - vermeide sie in synthetisierbaren Pfaden, außer der Divisor ist eine Zweierpotenz.
Was ist der bedingte Operator in Verilog?
?: ist der ternäre oder bedingte Operator, übernommen von C. cond ? a : b ergibt a, wenn cond wahr (ungleich Null) ist, und b sonst. Es ist das meistgenutzte Konstrukt für Multiplexer-artige Logik: out = sel ? in1 : in0 baut einen 2-zu-1-Mux. Ketten von ?: bauen breitere Multiplexer, aber case ist ab zwei Eingängen meist klarer.