Differenza tra assegnazione di blocchi e non di blocco Verilog


15

Stavo leggendo questa pagina http://www.asic-world.com/verilog/verilog_one_day3.html quando mi sono imbattuto in quanto segue:

Normalmente dobbiamo ripristinare i flip-flop, quindi ogni volta che l'orologio effettua la transizione da 0 a 1 (posedge), controlliamo se il reset è affermato (reset sincrono), quindi proseguiamo con la logica normale. Se guardiamo da vicino, vediamo che nel caso della logica combinatoria avevamo "=" per l'assegnazione e per il blocco sequenziale avevamo l'operatore "<=". Bene, "=" sta bloccando l'assegnazione e "<=" è l'assegnazione non bloccante. "=" esegue il codice in sequenza all'interno di un inizio / fine, mentre "<=" non bloccato viene eseguito in parallelo.

Ero abbastanza sicuro che le assegnazioni non bloccanti fossero sequenziali mentre le assegnazioni bloccanti erano parallele. Dopotutto, puoi eseguire assegnazioni di blocco con istruzioni di assegnazione al di fuori dei blocchi sempre e tutte eseguite in parallelo. È un errore o il comportamento è diverso all'interno di un blocco sempre? E, se il comportamento è diverso all'interno di un blocco sempre, è possibile eseguire assegnazioni non bloccanti all'esterno di un blocco sempre?

Risposte:


21

era abbastanza sicuro che le assegnazioni non bloccanti fossero sequenziali mentre le assegnazioni bloccanti erano parallele.

L'assegnazione di blocco viene eseguita "in serie" perché un'assegnazione di blocco blocca l' esecuzione dell'istruzione successiva fino al completamento. Pertanto, i risultati dell'istruzione successiva possono dipendere dal completamento della prima.

L'assegnazione non bloccante viene eseguita in parallelo perché descrive le assegnazioni che si verificano tutte contemporaneamente. Il risultato di un'istruzione sulla 2a riga non dipenderà dai risultati dell'istruzione sulla 1a riga. Invece, la seconda riga verrà eseguita come se la prima riga non fosse ancora avvenuta.


E che dire di assegnare dichiarazioni? Sono solo in una classe a parte?
Void Star

4
Sì, le assignistruzioni si verificano al di fuori dei blocchi sempre e vengono generalmente utilizzate per descrivere la logica combinatoria (senza latch) (mentre i blocchi sempre, con alcune eccezioni, descrivono la logica sequenziale). AFAIK, le assignistruzioni vengono sempre eseguite "in parallelo" ogni volta che il loro LHS ha una variazione di valore.
The Photon,

Okay ... Sto iniziando ad avere l'impressione che Verilog non sia il linguaggio più elegantemente progettato. Sarà come aver imparato C.
Void Star

1
Verilog è stato progettato per "descrivere" l'hardware già esistente. Usarlo come linguaggio per progettare (sintetizzare) l'hardware è un hack.
The Photon,

4
se Verilog "come l'apprendimento della C" è un problema, dai un'occhiata a VHDL. Alcune persone hanno preferenze abbastanza forti per l'una o l'altra. Per alcuni, VHDL è troppo prolisso. Per me, è molto meglio pensato. (la semantica del segnale / assegnazione variabile è molto più chiara del blocco / non per esempio). stackoverflow.com/questions/13954193/...~~V~~singular~~2nd e sigasi.com/content/vhdls-crown-jewel~~V~~singular~~2nd Si può preferire o si odia. Ma vale la pena dare un'occhiata.
Brian Drummond,

6

Le istruzioni di assegnazione non sono né "bloccanti" o "non bloccanti", sono "continue". L'output di un'istruzione assegnato è sempre uguale alla funzione specificata dei suoi input. Le assegnazioni "blocco" e "non blocco" esistono solo all'interno di blocchi sempre.

Un'assegnazione di blocco ha effetto immediatamente dopo l'elaborazione. Un'assegnazione non bloccante ha luogo al termine dell'elaborazione dell'attuale "delta temporale".

sempre i blocchi possono essere usati per modellare la logica combinatoria o sequenziale (systemverilog ha always_comb e always_ff per renderlo esplicito). Quando si modella la logica combinatoria di solito è più efficiente usare = ma in genere non ha importanza.

Quando si modella la logica sequenziale (ad es. Sempre @ (posedge clk)) normalmente si usano assunzioni non bloccanti. Ciò consente di determinare lo "stato dopo il bordo dell'orologio" in termini di "stato prima del bordo dell'orologio".

A volte è utile utilizzare le assegnazioni di blocco in blocchi sequenziali sempre come "variabili". Se lo fai, allora ci sono due regole chiave da tenere a mente.

  1. Non accedere a un registro impostato con assegnazioni di blocco all'interno di un blocco sequenziale sempre esterno al blocco sempre in cui è assegnato.
  2. Non mescolare le assegnazioni di blocco e non di blocco allo stesso reg.

La violazione di queste regole può comportare errori di sintesi e / o differenze di comportamento tra simulazione e sintesi.


"" Non accedere a un registro impostato con assegnazioni di blocco all'interno di un blocco sequenziale sempre all'esterno del blocco sempre in cui è assegnato. "" Per favore, puoi spiegarlo?
user125575,

Blocchi sequenziali diversi non hanno sempre un ordine definito. Quindi la lettura di un set "reg" con un'asserzione di blocco in un blocco sempre da un altro blocco sempre porta a comportamenti imprevedibili.
Peter Green,

E anche se sembra funzionare in simulazione, uno strumento di sintesi dovrebbe guardarlo e dire "no". Uso regs locali per quei var intermedi e mi assicuro che siano sempre assegnati su ogni clock prima di essere letti, in modo che non sia implicita alcuna "memorizzazione".
Greggo,

IIRC almeno in quartus è considerato solo un avvertimento, non un errore.
Peter Green,

5

Il termine assegnazione di blocco confonde le persone perché il blocco di parole sembra suggerire una logica sequenziale nel tempo. Ma nella logica sintetizzata non significa questo , perché tutto funziona in parallelo .

Forse un termine meno confuso sarebbe l'assegnazione immediata , che differenzierebbe ancora i risultati intermedi della logica combinatoria dagli input agli elementi di memoria non trasparenti (ad esempio registri con clock), che può avere ritardato l'assegnazione .

Da un punto di vista legalistico, tutto funziona molto bene. In effetti, puoi considerare che si tratta =di un'operazione di blocco (sequenziale nel tempo) anche all'interno di always_combsequenze. Tuttavia, la distinzione tra sequenze temporali e parallele non fa assolutamente alcuna differenza in questo caso perché il always_combblocco è definito per ripetersi fino a quando la sequenza di istruzioni converge su uno stato stabile - che è esattamente ciò che farà il circuito hardware (se soddisfa i tempi requisiti).

Il sottoinsieme sintetizzabile di Verilog (e in particolare SystemVerilog) è estremamente semplice e facile da usare - una volta che conosci i modi di dire necessari. Devi solo superare l'uso intelligente della terminologia associata ai cosiddetti elementi comportamentali nel linguaggio.


Negli stili di codifica comportamentale ( rispetto a RTL ), la distinzione tra blocco e non blocco può essere rilevante. In alcuni casi, lo strumento di sintesi potrebbe essere in grado di inferire RTL funzionalmente equivalente dai progetti di componenti comportamentali.
nobar,

Naturalmente la modalità procedurale di SystemVerilog, applicabile in particolare alle initialistruzioni all'interno di programblocchi, utilizza esclusivamente l' assegnazione di blocchi (sequenziale nel tempo) . Ciò è utile per la progettazione di banchi di prova , ma generalmente non per le specifiche RTL.
nobar,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.