Aide-mémoire Verilog
Dernière mise à jour
Structure d'un module et ports
Un module est la brique de base - il a un nom et une liste de ports.
| Syntaxe | Signification |
|---|---|
module adder(...); ... endmodule | Définir un module et son corps |
input clk; | Un port d'entrée |
output q; | Un port de sortie |
output reg q; | Une sortie pilotée depuis un bloc always |
input [7:0] data; | Un bus d'entrée 8 bits (vecteur) |
inout sda; | Un port bidirectionnel |
adder u1 (.a(x), .b(y), .sum(s)); | Instancier un module par ports nommés |
Types de données
wire modélise une connexion ; reg contient une valeur affectée par du code procédural.
| Élément | Ce qu'il fait |
|---|---|
wire w; | Un net piloté par assign ou une sortie de module |
reg r; | Contient une valeur affectée dans un bloc always/initial |
wire [3:0] bus; | Un vecteur 4 bits (bits 3 à 0) |
reg [7:0] count; | Un registre 8 bits |
bus[2] | Sélectionner un seul bit |
bus[3:1] | Sélectionner une tranche de bits (part-select) |
reg mem [0:255]; | Une mémoire : un tableau de registres |
parameter WIDTH = 8; | Une constante nommée pour le module |
Littéraux numériques
Le format est <size>'<base><value> - taille en bits, base parmi b/o/d/h.
| Syntaxe | Signification |
|---|---|
4'b1010 | Binaire 4 bits, valeur 10 |
8'hFF | Hexadécimal 8 bits, valeur 255 |
8'hff | Identique - les chiffres hex sont insensibles à la casse |
16'd255 | Décimal 16 bits, valeur 255 |
3'o7 | Octal 3 bits, valeur 7 |
8'b1010_1100 | Les tirets bas groupent les chiffres pour la lisibilité |
1'bx | Une valeur de bit inconnue (x) |
1'bz | Une valeur de bit haute impédance (z) |
Opérateurs
Opérateurs binaires, logiques, de comparaison et de réduction.
| Opérateur | Ce qu'il fait |
|---|---|
& | ^ ~ | ET, OU, OU exclusif, NON binaires |
&& || ! | ET, OU, NON logiques (renvoient 1 bit) |
== != < > <= >= | Opérateurs de comparaison |
<< >> | Décalage à gauche et à droite |
+ - * / % | Opérateurs arithmétiques |
&bus | ET de réduction (ET de tous les bits) |
|bus | OU de réduction (OU de tous les bits) |
^bus | OU exclusif de réduction (parité de tous les bits) |
{a, b} | Concaténation ; {4{1'b1}} se réplique en 4'b1111 |
Affectation continue
assign pilote un wire en continu - utilisez-le pour la logique combinatoire.
| Syntaxe | Signification |
|---|---|
assign y = a & b; | Piloter y avec le ET de a et b |
assign sum = a + b; | Calculer une somme en continu |
assign y = sel ? a : b; | Ternaire - un multiplexeur 2 vers 1 |
assign {c, s} = a + b; | Capturer ensemble la retenue et la somme |
assign y = ~en; | Piloter un wire à partir d'un signal inversé |
Blocs procéduraux
always et initial exécutent des instructions ; la liste de sensibilité contrôle le moment.
| Syntaxe | Signification |
|---|---|
always @(*) begin ... end | Logique combinatoire (tout changement d'entrée) |
always @(posedge clk) | S'exécute à chaque front montant d'horloge (séquentiel) |
always @(negedge clk) | S'exécute à chaque front descendant d'horloge |
always @(posedge clk or posedge rst) | Bloc cadencé avec reset asynchrone |
initial begin ... end | S'exécute une fois à l'instant 0 (testbenches, simulation uniquement) |
begin ... end | Grouper plusieurs instructions |
#10 | Délai de 10 unités de temps (simulation uniquement) |
Bloquant vs non bloquant
Utilisez = pour la logique combinatoire, <= pour la logique séquentielle cadencée.
| Syntaxe | Signification |
|---|---|
a = b; | Bloquant - s'exécute dans l'ordre, immédiatement |
a <= b; | Non bloquant - tous les RHS lus d'abord, puis affectés |
always @(*) y = a & b; | Combinatoire : utilisez le bloquant = |
always @(posedge clk) q <= d; | Une bascule : utilisez le non bloquant <= |
Mélanger = et <= dans un même bloc | À éviter - source fréquente de bugs |
Contrôle de flux
Conditions et branchements multivoies à l'intérieur des blocs procéduraux.
| Syntaxe | Signification |
|---|---|
if (cond) ... else ... | Instruction conditionnelle |
if (a) x = 1; else x = 0; | If/else sur une seule ligne |
case (sel) ... endcase | Branchement multivoie sur une valeur |
2'b00: y = a; | Un élément de case |
default: y = 0; | Élément de case par défaut |
for (i = 0; i < 8; i = i + 1) | Boucle (souvent dans generate ou en simulation) |
repeat (4) @(posedge clk); | Répéter une instruction N fois |
Motifs courants
Briques que vous écrivez encore et encore, plus des tâches de testbench.
| Motif | Syntaxe |
|---|---|
| Bascule D | always @(posedge clk) q <= d; |
| Registre avec reset | always @(posedge clk) if (rst) q <= 0; else q <= d; |
| Compteur | always @(posedge clk) count <= count + 1; |
| Registre d'état d'une FSM | always @(posedge clk) state <= next_state; |
| Logique d'état suivant d'une FSM | always @(*) case (state) ... endcase |
| Afficher une valeur | $display("q = %b", q); |
| Afficher au changement | $monitor("t=%0t q=%b", $time, q); |
| Terminer la simulation | $finish; |
Chaque élément de syntaxe Verilog dont vous avez besoin, sur une seule page. Cet aide-mémoire Verilog est une référence rapide pour le langage de description de matériel - déclarer des modules et des ports, choisir les types de données, écrire de la logique combinatoire et séquentielle, et les motifs de blocs always qui décrivent de vrais circuits.
La syntaxe présentée ici est du Verilog standard (IEEE 1364) et fonctionne dans les simulateurs courants comme Icarus Verilog et Verilator. Copiez ce dont vous avez besoin, ou essayez-la en direct dans le playground Verilog - écrivez un module, simulez-le et voyez la sortie dans votre navigateur.
FAQ de l'aide-mémoire Verilog
Cet aide-mémoire Verilog est-il gratuit ?
Quelle est la différence entre wire et reg ?
wire modélise une connexion physique et doit être piloté en continu - par une instruction assign ou une sortie de module - vous l'utilisez donc pour les nets combinatoires. Un reg conserve sa valeur jusqu'à ce que du code procédural la change, vous l'utilisez donc pour tout ce qui est affecté dans un bloc always ou initial. Malgré son nom, un reg ne devient pas toujours un registre matériel ; cela signifie simplement que la valeur est définie de manière procédurale.Quelle est la différence entre affectation bloquante et non bloquante ?
=) s'exécute immédiatement et dans l'ordre, comme une instruction de programmation normale, utilisez-la donc pour la logique combinatoire dans les blocs always @(*). L'affectation non bloquante (<=) évalue d'abord tous les membres de droite puis met à jour les membres de gauche ensemble, ce qui modélise correctement les bascules - utilisez-la donc dans les blocs cadencés always @(posedge clk). Mélanger les deux dans un même bloc est une source classique de bugs de simulation.