Diferența dintre atribuirea de blocare și nonblocare Verilog

Citeam această pagină http://www.asic-world.com/verilog/verilog_one_day3.html când am întâlnit următoarele:

În mod normal, trebuie să resetăm flip-flop-urile, astfel de fiecare dată când ceasul face trecerea de la 0 la 1 (posedge), verificăm dacă resetarea este afirmată (resetare sincronă), apoi continuăm cu logica normală. Dacă ne uităm cu atenție, vedem că, în cazul logicii combinaționale, am avut „=” pentru atribuire, iar pentru blocul secvențial am avut operatorul „< =”. Ei bine, „=” blochează atribuirea și „< =” este o atribuire care nu blochează. „=” execută cod secvențial în interiorul unui început / sfârșit, în timp ce nonblocarea „< =” se execută în paralel.

Eram destul de sigur că atribuțiile de nonblocare erau secvențiale în timp ce atribuțiile de blocare erau paralele. La urma urmei, puteți efectua sarcini de blocare cu instrucțiuni de atribuire în afara blocurilor întotdeauna și toate acestea rulează în paralel. Este aceasta o greșeală sau comportamentul este diferit în interiorul unui bloc întotdeauna? Și, dacă comportamentul este diferit în interiorul unui bloc întotdeauna, pot fi efectuate atribuții de nonblocare în afara unui bloc întotdeauna?

Răspuns

era destul de sigur că atribuțiile de nonblocare erau secvențiale în timp ce atribuțiile de blocare erau paralele.

Blocarea atribuirii se execută „în serie” deoarece o atribuire de blocare blochează execuția următoarei instrucțiuni până la finalizare. Prin urmare, rezultatele următoarei instrucțiuni pot depinde de finalizarea primei.

Alocarea fără blocare se execută în paralel, deoarece descrie atribuțiile care apar toate în același timp. Rezultatul unei declarații pe linia a doua nu va depinde de rezultatele declarației de pe prima linie. În schimb, a doua linie se va executa ca și cum prima linie nu s-ar fi întâmplat încă.

Comentarii

  • Deci, ce se întâmplă cu atribuirea instrucțiunilor? Sunt doar într-o clasă întreagă a lor?
  • Da, instrucțiunile assign apar în afara blocurilor întotdeauna și sunt utilizate în general pentru a descrie combinatorial (ne-blocat) ) logica (în timp ce blocurile sunt întotdeauna, cu unele excepții, descriu logica secvențială). AFAIK, instrucțiunile assign execută întotdeauna ” în paralel ” ori de câte ori LHS-ul lor are o modificare a valorii .
  • Bine … Încep să am impresia că Verilog nu este ‘ cel mai mult limbaj proiectat elegant. Aceasta va fi ca și cum ați învățat C.
  • Verilog a fost conceput pentru a ” descrie ” hardware care există deja. Folosirea acestuia ca limbaj pentru proiectarea (sintetizarea) hardware-ului este un hack.
  • dacă Verilog ” ca învățarea C ” este o problemă, aruncați o privire la VHDL. Unii oameni au preferințe destul de puternice pentru unul sau altul. Pentru unii, VHDL este prea prea detaliat. Pentru mine, ‘ este mult mai bine gândit. (semantica de atribuire semnal / variabilă este mult mai clară decât blocarea / non de exemplu). stackoverflow.com/questions/13954193/… și sigasi .com / content / vhdls-crown-jewel Este posibil să o preferați sau să o urâți. Dar merită să aruncăm o privire ‘.

Răspuns

Declarațiile de atribuire nu sunt nici „blocante”, nici „nonblocante”, sunt „continue”. Ieșirea unei instrucțiuni de atribuire este întotdeauna egală cu funcția specificată a intrărilor sale. Alocările de „blocare” și „nonblocare” există numai în blocurile întotdeauna.

O atribuire de blocare are efect imediat după ce este procesată. O alocare de nonblocare are loc la sfârșitul procesării „deltei de timp” curente.

blocurile întotdeauna pot fi utilizate pentru a modela fie logica combinatorială, fie secvențială (systemverilog are always_comb și always_ff pentru a face acest lucru explicit). logica combinatorie este de obicei mai eficientă de utilizat = dar de obicei nu contează cu adevărat.

La modelarea logicii secvențiale (de ex. întotdeauna @ (posedge clk)) utilizați în mod normal analize care nu blochează. Acest lucru vă permite să terminați „starea după marginea ceasului” în termeni de „starea dinaintea marginii ceasului”.

Uneori este util să utilizați atribuții de blocare în blocuri secvențiale întotdeauna ca „variabile”. Dacă faceți acest lucru, atunci există două reguli cheie care trebuie luate în considerare.

  1. Nu accesați un reg care este setat cu atribuții de blocare în interiorul unui bloc secvențial întotdeauna din afara blocului întotdeauna în care este atribuit.
  2. Nu amestecați atribuții de blocare și neblocare la același reg.

Încălcarea acestor reguli poate duce la eșecuri de sinteză și / sau diferențe de comportament între simulare și sinteză.

Comentarii

  • ” ” Nu accesați un reg care este setat cu atribuții de blocare în interiorul unui bloc secvențial întotdeauna bloc din exteriorul blocului întotdeauna este atribuit în. ” ” Puteți explica acest lucru?
  • Blocuri secvențiale diferite întotdeauna nu au un Ordin. Deci, citirea unui set ” reg ” cu o evaluare de blocare într-un bloc întotdeauna dintr-un alt bloc întotdeauna va duce la un comportament imprevizibil.
  • Și chiar dacă pare să funcționeze în simulare, un instrument de sinteză ar trebui să se uite la asta și să spună ” nope „. Folosesc regiuni locale pentru acele varuri intermediare și mă asigur că sunt întotdeauna atribuite la fiecare ceas înainte de a fi citite, astfel încât să nu existe ‘ stocare ‘ este implicit.
  • IIRC cel puțin în quartus este considerat doar un avertisment, nu o eroare.
  • Nu ar trebui să utilizați atribuirea de nonblocare în logica combinațională, se poate bloca simularea. Pentru mai multe detalii, consultați acest răspuns: electronics.stackexchange.com/a/506047/238188

Răspuns

Termenul Alocare blocare încurcă oamenii, deoarece cuvântul blocare pare să sugereze logică secvențială în timp. Dar în logica sintetizată nu înseamnă acest lucru , deoarece totul funcționează în paralel .

Poate că un termen mai puțin confuz ar fi atribuire imediată , care ar diferenția rezultatele intermediare ale logicii combinaționale de intrări în elemente de memorie netransparente (de exemplu registre cu ceas), care pot avea atribuire întârziată .

Din punct de vedere legal, totul funcționează foarte bine. Puteți, de fapt, să considerați = ca o operațiune blocare (secvențială în timp) chiar și în always_comb secvențe. Cu toate acestea, distincția dintre secvențial de timp și paralel nu face absolut nicio diferență în acest caz, deoarece always_comb blocul este definit pentru a se repeta până când secvența de instrucțiuni converge pe o stare stabilă – exact ceea ce va face circuitul hardware (dacă îndeplinește cerințele de sincronizare).

Subsetul sintetizabil al Verilog (și în special SystemVerilog) este extrem de simplu și ușor de utilizat – după ce cunoașteți expresiile necesare. Trebuie doar să treceți de utilizarea inteligentă a terminologiei asociate cu așa-numitele elemente comportamentale din limbă.

Comentarii

  • În stilurile de codare comportamentale ( în comparație cu RTL ), distincția între blocare și non-blocare poate fi relevantă. În unele cazuri, instrumentul de sinteză poate fi capabil să deducă RTL echivalent funcțional din proiectarea componentelor comportamentale.
  • Desigur, procedural Modul SystemVerilog, aplicabil în special instrucțiunilor initial din blocurile program, utilizează atribuirea blocării (secvențiale în timp) exclusiv. Acest lucru este util pentru proiectarea testbench , dar în general nu pentru specificațiile RTL.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *