Verilog Cheat Sheet
Ultimo aggiornamento
Struttura del modulo e porte
Il modulo è il blocco di base: ha un nome e un elenco di porte.
| Sintassi | Significato |
|---|---|
module adder(...); ... endmodule | Definire un modulo e il suo corpo |
input clk; | Una porta di ingresso |
output q; | Una porta di uscita |
output reg q; | Un'uscita pilotata da un blocco always |
input [7:0] data; | Un bus di ingresso a 8 bit (vettore) |
inout sda; | Una porta bidirezionale |
adder u1 (.a(x), .b(y), .sum(s)); | Istanziare un modulo con porte nominate |
Tipi di dati
wire modella una connessione; reg contiene un valore assegnato dal codice procedurale.
| Elemento | Cosa fa |
|---|---|
wire w; | Una net pilotata da assign o dall'uscita di un modulo |
reg r; | Contiene un valore assegnato dentro un blocco always/initial |
wire [3:0] bus; | Un vettore a 4 bit (bit da 3 a 0) |
reg [7:0] count; | Un registro a 8 bit |
bus[2] | Selezionare un singolo bit |
bus[3:1] | Selezionare una porzione di bit (part-select) |
reg mem [0:255]; | Una memoria: un array di registri |
parameter WIDTH = 8; | Una costante con nome per il modulo |
Letterali numerici
Il formato è <size>'<base><value>: dimensione in bit, base come b/o/d/h.
| Sintassi | Significato |
|---|---|
4'b1010 | Binario a 4 bit, valore 10 |
8'hFF | Esadecimale a 8 bit, valore 255 |
8'hff | Uguale: le cifre esadecimali non distinguono maiuscole e minuscole |
16'd255 | Decimale a 16 bit, valore 255 |
3'o7 | Ottale a 3 bit, valore 7 |
8'b1010_1100 | I trattini bassi raggruppano le cifre per leggibilità |
1'bx | Un bit di valore sconosciuto (x) |
1'bz | Un bit ad alta impedenza (z) |
Operatori
Operatori bit a bit, logici, di confronto e di riduzione.
| Operatore | Cosa fa |
|---|---|
& | ^ ~ | AND, OR, XOR, NOT bit a bit |
&& || ! | AND, OR, NOT logici (restituiscono 1 bit) |
== != < > <= >= | Operatori di confronto |
<< >> | Shift a sinistra e a destra |
+ - * / % | Operatori aritmetici |
&bus | AND di riduzione (AND di tutti i bit) |
|bus | OR di riduzione (OR di tutti i bit) |
^bus | XOR di riduzione (parità di tutti i bit) |
{a, b} | Concatenazione; {4{1'b1}} si replica in 4'b1111 |
Assegnazione continua
assign pilota un wire in modo continuo: usalo per la logica combinatoria.
| Sintassi | Significato |
|---|---|
assign y = a & b; | Pilota y con l'AND di a e b |
assign sum = a + b; | Calcola una somma in modo continuo |
assign y = sel ? a : b; | Ternario: un multiplexer 2 a 1 |
assign {c, s} = a + b; | Cattura riporto e somma insieme |
assign y = ~en; | Pilota un wire con un segnale invertito |
Blocchi procedurali
always e initial eseguono istruzioni; la sensitivity list controlla quando.
| Sintassi | Significato |
|---|---|
always @(*) begin ... end | Logica combinatoria (qualsiasi cambio di input) |
always @(posedge clk) | Esegue a ogni fronte di salita del clock (sequenziale) |
always @(negedge clk) | Esegue a ogni fronte di discesa del clock |
always @(posedge clk or posedge rst) | Blocco sincronizzato con reset asincrono |
initial begin ... end | Esegue una sola volta al tempo 0 (testbench, solo simulazione) |
begin ... end | Raggruppa più istruzioni |
#10 | Ritardo di 10 unità di tempo (solo simulazione) |
Bloccante e non bloccante
Usa = per la logica combinatoria e <= per la logica sequenziale sincronizzata.
| Sintassi | Significato |
|---|---|
a = b; | Bloccante: si esegue in ordine, subito |
a <= b; | Non bloccante: prima si leggono tutti i lati destri, poi si assegna |
always @(*) y = a & b; | Combinatoria: usa il bloccante = |
always @(posedge clk) q <= d; | Un flip-flop: usa il non bloccante <= |
Mescolare = e <= nello stesso blocco | Evitalo: è una fonte comune di bug |
Controllo del flusso
Condizioni e diramazioni multiple dentro i blocchi procedurali.
| Sintassi | Significato |
|---|---|
if (cond) ... else ... | Istruzione condizionale |
if (a) x = 1; else x = 0; | if/else su una riga |
case (sel) ... endcase | Diramazione multipla su un valore |
2'b00: y = a; | Un elemento case |
default: y = 0; | Elemento case di riserva |
for (i = 0; i < 8; i = i + 1) | Ciclo (spesso dentro generate o in simulazione) |
repeat (4) @(posedge clk); | Ripete un'istruzione N volte |
Pattern comuni
Blocchi che scrivi di continuo, più i task per i testbench.
| Pattern | Sintassi |
|---|---|
| Flip-flop D | always @(posedge clk) q <= d; |
| Registro con reset | always @(posedge clk) if (rst) q <= 0; else q <= d; |
| Contatore | always @(posedge clk) count <= count + 1; |
| Registro di stato della FSM | always @(posedge clk) state <= next_state; |
| Logica dello stato successivo della FSM | always @(*) case (state) ... endcase |
| Stampare un valore | $display("q = %b", q); |
| Stampare a ogni cambiamento | $monitor("t=%0t q=%b", $time, q); |
| Terminare la simulazione | $finish; |
Tutta la sintassi Verilog che ti serve, in una sola pagina. Questa Verilog cheat sheet è un riferimento rapido per il linguaggio di descrizione dell'hardware: dichiarare moduli e porte, scegliere i tipi di dati, scrivere logica combinatoria e sequenziale, e i pattern dei blocchi always che descrivono circuiti reali.
La sintassi è Verilog standard (IEEE 1364) e funziona nei simulatori più diffusi come Icarus Verilog e Verilator. Copia ciò che ti serve o provalo dal vivo nel playground Verilog: scrivi un modulo, simulalo e guarda l'output nel browser.
Domande frequenti sulla Verilog cheat sheet
Questa Verilog cheat sheet è gratuita?
Qual è la differenza tra wire e reg?
wire modella una connessione fisica e deve essere pilotato in modo continuo (da un'istruzione assign o dall'uscita di un modulo), quindi lo usi per le net combinatorie. Un reg mantiene il suo valore finché il codice procedurale non lo cambia, quindi lo usi per tutto ciò che viene assegnato dentro un blocco always o initial. Nonostante il nome, un reg non diventa sempre un registro hardware; significa solo che il valore viene impostato in modo procedurale.Qual è la differenza tra assegnazione bloccante e non bloccante?
=) si esegue subito e in ordine, come una normale istruzione di programmazione, quindi usala per la logica combinatoria nei blocchi always @(*). L'assegnazione non bloccante (<=) valuta prima tutti i lati destri e poi aggiorna insieme i lati sinistri, modellando correttamente i flip-flop, quindi usala nei blocchi sincronizzati always @(posedge clk). Mescolare le due nello stesso blocco è una fonte classica di bug in simulazione.