Verilog Assignments verstehen: Typen, Syntax und Best Practices
Das Zuweisen von Werten auf Nets und Variablen wird als Assignment bezeichnet. Es gibt drei grundlegende Formen:
- Prozedural (Procedural)
- Kontinuierlich (Continuous)
- Prozedural-kontinuierlich (Procedural Continuous)
Zulässige LHS-Werte
Eine Zuweisung besteht aus zwei Teilen – der rechten Seite (RHS) und der linken Seite (LHS) – die durch ein Gleichheitszeichen (=) oder ein Kleiner-Gleich-Zeichen (<=) getrennt sind.
| Assignment-Typ | Linke Seite (LHS) |
|---|---|
| Prozedural |
|
| Kontinuierlich |
|
| Prozedural-kontinuierlich |
|
Die RHS kann jeden Ausdruck enthalten, der zu einem endgültigen Wert ausgewertet wird, während die LHS ein Net oder eine Variable angibt, dem der Wert der RHS zugewiesen wird.
module tb;
reg clk;
wire a, b, c, d, e, f;
reg z, y;
// clk steht auf der LHS, die Negation von clk bildet die RHS
always #10 clk = ~clk;
// y ist die LHS, die Konstante 1 ist die RHS
assign y = 1;
// f ist die LHS, der Ausdruck aus a,b,d,e bildet die RHS
assign f = (a | b) ^ (d & e);
always @ (posedge clk) begin
// z ist die LHS, der Ausdruck aus a,b,c,d bildet die RHS
z <= a + b + c + d;
end
initial begin
// Variablennamen links bilden die LHS, 0 ist die RHS
a <= 0; b <= 0; c <= 0; d <= 0; e <= 0; clk <= 0;
end
endmodule
Prozedurale Zuweisung (Procedural Assignment)
Prozedurale Zuweisungen treten innerhalb von Prozeduren wie always, initial, task und function auf und dienen dazu, Werte auf Variablen zu legen. Die Variable behält den Wert bis zur nächsten Zuweisung an dieselbe Variable.
Der Wert wird auf die Variable gelegt, wenn die Simulation diese Anweisung zu einem bestimmten Zeitpunkt während der Simulationszeit ausführt. Dies kann durch Kontrollfluss-Anweisungen wie if-else-if, case-Anweisungen und Schleifenmechanismen gesteuert und modifiziert werden.
reg [7:0] data;
integer count;
real period;
initial begin
data = 8'h3e;
period = 4.23;
count = 0;
end
always @ (posedge clk)
count++;
Variablendeklaration mit Zuweisung
Ein Anfangswert kann einer Variable zum Zeitpunkt ihrer Deklaration zugewiesen werden, wie im folgenden Beispiel gezeigt. Die Zuweisung hat keine Dauer und behält den Wert bei, bis die nächste Zuweisung an dieselbe Variable erfolgt. Beachten Sie, dass Variablendeklarationszuweisungen an Arrays nicht erlaubt sind.
module my_block;
reg [31:0] data = 32'hdead_cafe;
initial begin
#20 data = 32'h1234_5678;
// data hat dead_cafe von Zeit 0 bis Zeit 20
// Ab Zeit 20 erhält data den Wert 12345678
end
endmodule
reg [3:0] a = 4'b4;
// ist äquivalent zu
reg [3:0] a;
initial a = 4'b4;
Wenn die Variable sowohl bei der Deklaration als auch zum Zeitpunkt 0 in einem initial-Block initialisiert wird, wie unten gezeigt, ist die Auswertungsreihenfolge nicht garantiert, weshalb entweder 8'h05 oder 8'hee resultieren kann.
module my_block;
reg [7:0] addr = 8'h05;
initial addr = 8'hee;
endmodule
reg [3:0] array [3:0] = 0; // illegal
integer i = 0, j; // deklariert zwei Integers i,j; i wird 0 zugewiesen
real r2 = 4.5, r3 = 8; // deklariert zwei Reals r2,r3 mit Werten 4.5, 8
time startTime = 40; // deklariert Time-Variable mit Anfangswert 40
Prozedurale Blöcke und Zuweisungen werden in einem späteren Abschnitt detaillierter behandelt.
Kontinuierliche Zuweisung (Continuous Assignment)
Hier klicken für ein schrittweises Simulationsbeispiel!
Diese wird verwendet, um Werte auf skalare und Vektor-Nets zuzuweisen und tritt immer dann auf, wenn sich die RHS ändert. Sie bietet eine Möglichkeit, kombinatorische Logik zu modellieren, ohne eine Gatterverknüpfung spezifizieren zu müssen, und erleichtert das Treiben des Nets mit logischen Ausdrücken.
// Beispielmodell eines AND-Gatters
wire a, b, c;
assign a = b & c;
Immer wenn b oder c seinen Wert ändert, wird der gesamte Ausdruck in der RHS ausgewertet und a wird mit dem neuen Wert aktualisiert.
Net-Deklaration mit Zuweisung
Dies ermöglicht es, eine kontinuierliche Zuweisung in derselben Anweisung vorzunehmen, die das Net deklariert. Da ein Net nur einmal deklariert werden kann, ist nur eine Deklarationszuweisung pro Net möglich.
wire penable = 1;
Prozedural-kontinuierliche Zuweisung (Procedural Continuous Assignment)
Dies sind prozedurale Anweisungen, die es erlauben, Ausdrücke kontinuierlich auf Nets oder Variablen zuzuweisen. Es gibt zwei Typen:
assign...deassignforce...release
assign / deassign
Dies überschreibt alle prozeduralen Zuweisungen an eine Variable und wird durch deassign mit demselben Signal deaktiviert. Der Wert der Variable bleibt unverändert, bis die Variable durch eine prozedurale oder prozedural-kontinuierliche Zuweisung einen neuen Wert erhält. Die LHS einer assign-Anweisung darf kein Bit-Select, Part-Select oder Array-Referenz sein, kann aber eine Variable oder eine Verkettung von Variablen sein.
reg q;
initial begin
assign q = 0;
#10 deassign q;
end
force / release
Diese sind den assign - deassign-Anweisungen ähnlich, können aber auch auf Nets und Variablen angewendet werden. Die LHS kann ein Bit-Select eines Nets, Part-Select eines Nets, eine Variable oder ein Net sein, aber keine Referenz auf ein Array und kein Bit/Part-Select einer Variable. Die force-Anweisung überschreibt alle anderen Zuweisungen an die Variable, bis sie mit dem Schlüsselwort release freigegeben wird.
reg o, a, b;
initial begin
force o = a & b;
...
release o;
end
Verilog
- Verilog meistern: Komplettes Tutorial für digitales Schaltungsdesign
- Verilog Concatenation meistern: Praktischer Leitfaden
- Verilog Functions meistern für effizientes RTL-Design
- Verilog Tasks verstehen: Functions vs. Tasks, Syntax und Verwendung
- Verilog Clock Generator: Design & Implementierungsleitfaden
- Verilog Math Functions meistern für effizientes Hardware-Design
- Verilog $timeformat meistern: Präzision und Anzeigesteuerung
- Verilog Timescales an jedem Scope verstehen und ausgeben
- Datei-E/A in Verilog meistern: Öffnen, Lesen, Schreiben und Schließen
- Verilog für Einsteiger: Hello-World-Beispiel