joi, 10 februarie 2011

Capitolul VI

Abordarea comportamentală.

 6.1  Noţiuni generale.
Specificarea sistemelor în stil structural şi flux de date sunt foarte utile, însă se utilizează mai mult sau mai puţin la nivelele inferioare de descriere a limbajului. Valoarea reală a limbajelor HDL de nivel înalt aşa ca Verilog HDL este în posibilitatea lor de a descrie funcţionalitatea sistemului.
În acest capitol vom discuta despre descrierea comportamentală a sistemelor digitale utilizând mijloacele oferite de sintaxa Verilog.
Înainte de a intra în detalii, trebuie de avut în vedere câteva lucruri. Aşa cum nu pot exista specificaţii de flux de date fără fire (net), nu există specificaţii comportamentale fără registre.
Specificaţiile comportamentale au mult comun cu fluxul de date, pentru că sunt de asemenea bazate pe atribuiri. Însă atribuirile, în specificaţiile comportamentale, au o altă sintaxă şi sunt cuprinse în blocuri comportamentale.
Multe declaraţii funcţionale aşa ca cele condiţionale şi de selecţie sau cicluri precăutate aici sunt similare cu cele din limbajul C.


6.1  Variabile şi parametri.

 6.1.1        Sunt oare Net-urile deajuns?
Net-urile sunt o formă normală de specificare. Fiecare semnal are o valoare anumită dacă este conectată la o sursă de semnal. Când sursa de semnal este deconectată, semnalul trece în stare de impedanţă înaltă. Un compartiment similar îl reprezintă firele (net) şi de fapt au fost elaborate pentru reprezentarea acestui fenomen fizic.
Când dorim să descriem comportamentul unui circuit mai complex sau a unui sistem cu vre-un algoritm, avem nevoie de ceva similar cu variabilele din limbajele de programare. O variabilă nu necesită permanent să fie conectată la o sursă, mai degrabă i se atribuie o valoare. Variabila îşi păstrează valoarea atâta timp cât e nevoie după care i se poate atribui altă valoare în caz de necesitate. Dacă vom utiliza un fir (net) el va lua valoarea ,,z’’ îndată ce se deconectează de la sursa lui. Pentru a preîntâmpina pierderea valorii semnalului se introduce un alt tip de variabilă numită registru (reg). El de acum este capabil de a păstra valoarea între atribuiri.

6.1.2       Registrele.
Formal un Registru este definit ca o ,,abstracţie a unui element de stocare’’. Mai simplu de spus este un echivalent Verilog a unei variabile din limbajele C sau Pascal. De fapt dacă cunoaştem C putem observa că declaraţia de registru este similară cu declaraţia de variabilă.
Un registru este declarat în mod similar cu firul (net) – unica diferenţă este că în locul cuvântului rezervat wire se foloseşte cuvântul reg la fel ca şi la fire (net) există mai multe tipuri de registre. Afară de registrul obişnuit, utilizat în special pentru valori logice, putem utiliza regiştri de tip integer, real, time şi realtime.
reg – acest registru păstrează valoarea atribuită până la următoarea atribuire. El, însă, nu este un echivalent a unui registru fizic real construit ca un bistabil pe semnal de ceas, de aceea nu i se atribuie nici un semnal de ceas.
Înainte de a i se atribui vre-o valoare, el predefinit este ,,x’’ (spre deosebire de fire (nets) unde valoarea predefinită este ,,z’’). Unui registru cu mai mulţi biţi i se poate atribui şi o valoare negativă (care este stocată ca complimentar prin 2), însă când acest registru este un operand, valoarea lui este tratată ca fără semn.

Declaraţia variabilei de tip reg constă în cuvântul cheie reg urmat de numele variabilei, Mai multe registre pot specifica într-o singură declaraţie identificatorii lor trebue să fie separaţi prin virgulă.
time – este un tip special de registru preconizat pentru a forţa şi manipula cu timpul de simulare, căruia i se poate  atribui valori utilizând funcţia de sistem $time, cât şi pentru depanare şi simulare. Comportamentul lui este asemănător cu un registru de 64 biţi.
Declaraţia variabile de tip time constă în cuvântul cheie time urmat de numele variabilei. Se pot specifica mai mulţi regiştri de acest tip într-o declaraţie, identificatorii cărora sunt separaţi prin virgule.
integer – acest tip de registru serveşte pentru manipularea cu mulţimile numerelor. Comportamentul lui este asemănător cu a unui registru normal cu două excepţii importante.
-    mărimea predefinită este nu un bit ci 32 de biţi (în dependenţă de implementare);
-    când unui integer i se atribuie o valoare negativă, după care este utilizat ca operand el este mereu considerat că deţine o valoare negativă (integer păstrează valorile ca valori cu semn).
Regiştrii de tip integer nu au o valoare predefinită deci nu e neapărat să atribuiţi vre-o valoare acestei variabile. La începutul simulării ea va avea valoarea zero (în majoritatea simulatoarelor).
Declaraţia variabilelor de tip integer constă în cuvântul cheie integer urmată de numele ei. Într-o singură declaraţie se pot specifica mai multe variabile de acest tip indicatorii lor fiind separaţi prin virgule.
real – Registrele de tip real servesc pentru stocarea numerelor reale (adică neîntregi). Valorile pot fi specificate într-o notaţie zecimală sau ştiinţifică. Sunt câteva restricţii în aplicarea registrelor de tip real:
-    setul de operaţii posibile este limitat;
-    nu pot avea declaraţii de rang;
-    valoarea predefinită este zero.
Numerele reale se pot converti în întregi prin rotungire spre cel mai apropiat număr de zero. În simularea Verilog atribuirea unui registru real la un integer şi invers le converteşte implicit.
Declararea se face la fel ca şi la celelalte registre.
realtime – Acest tip este presupus să fie utilizat pentru reprezentarea timpului utilizând numere reale, însă se mai poate utiliza în locul tipului real. Declararea se face ca şi la celelalte tipuri.
6.2.3    Vectori şi Tablouri.
Vectorii registru de tip reg se pot declara în acelaşi mod ca şi firele (net) prin declararea rangului lor între cuvântul cheie ce determină tipul vectorului şi numele lui.
Verilog dă posibilitatea de a declara tablouri de regiştri ceia ce de fapt nu e valabil pentru fire (neturi). La prima vedere principala diferenţă dintre vectori şi tablouri este modul de declarare, adică pe lângă rangul vectorului se mai declară şi rangul locaţiei. Pentru vector rangul se găseşte între declararea tipului şi numelui. Pentru tablouri rangul locaţiei, se declară după identificatorul lui adică numele lui.
Diferenţa principăală dintre vector şi tablou este că:
-    un vector este un obiect de o mărime de n biţi;
-    un tablou este un argument a n obiecte care au mai mulţi biţi.
Mai mult decât atât, unui vector i se poate atribui o valoare nouă printr-o simplă atribuire, ceia ce nu e valabil pentru un tablou.
Un tablou poate fi compus din regiştri de tip reg, integer sau time, însă nu pot fi de tip real sau realtime.

6.2.4    Elementul tabloului. Cuvântul de memorie ca operand.
Expresiile în Verilog pot conţine referinţe către memorii adică câtre un tabel de regiştri, însă cu o restricţie, ca operand, se poate face referinţă doar la o locaţie întreagă de memorie, numită cuvânt de memorie.
Acesta rezultă din faptul că memoria este un vector de vectori, iar adresarea se face doar la elementul întreg al vectorului. Dacă avem nevoie să utilizăm un singur bit sau o consecutivitate de biţi dintr-o locaţie de memorie cuvântul de memorie trebuie copiat într-un registru temporar iar biţii necesari pot fi accesaţi tocmai din acest registru.
Sintaxa adresării memoriei constă în numele memoriei şi expresia pentru adresa locaţiei.
mem_nume[addr_expr]
Expresia poate fi de orice gen, chiar şi să conţină cuvinte din aceiaşi memorie care permite o adresare indirectă. De exemplu, dacă avem nevoie să accesăm o locaţie de memorieadresa căreia e stocată în locaţia a 12-ea a aceiaşi memorii, se poate scri:
MyMem[MyMem[12]]
6.2.5    Constante în Verilog.
Scopul principal al utilizării constantelor este aplicarea unui nume în locul unei valori literale, numele la fel ca valori ,,legate-hard’’. În aşa mod, codul devine mult mai citeţ deoarece schimbarea valorii constantei va afecta toate instanţele modului unde se utilizează această constantă.
Dacă se utilizează o valoare legată hard, adică literară, este nevoie de a verifica mai atent codul, rând cu rând, pentru a fi siguri că toate valorile sunt corecte.
Constantele rămân neschimbate într-un modul şi nu se pot utiliza ca variabile (adică nu i se poate atribui o valoare nouă) ele nu sunt nici fire nici regiştri. Constantele în Verilog se numesc parametri.
6.2.6    Declararea şi utilizarea parametrilor.


Declararea parametrilor are următoarea sintaxă:
-    cuvântul cheie parameter;
-    numele parametrului;
-    valoarea parametrului specificată după simbolul ,,=’’;
-    semnul (;) la sfârşitul liniei.
Două sau mai multe constante pot fi specificate într-o singură declaraţie, perechile nume_valoare fiind separate prin virgule.
Cel mai des parametrii sunt utilizaţi pentru reprezentarea reţinerilor (întârzierilor) şi mărimile obiectelor (mărimea şinelor sau a vectorilor). În consecinţă parametrii se pot găsi în declaraţiile de ranguri şi contor în cicluri.
Ex 
    
-  parametru ca parametru de timp:

      parameter PropDel=3;
      assign #PropDel Y=X;(  assign #3 Y=X;)

     - parametru ca mărimea unui obiect:
      parameter BusWidth=8
      reg [BusWidth-1 : 0] Data Bus;

     - parametru ca contor a ciclului:
      parameter LoopIter=3
      for (k=0; k

6.3    Bazele comportamentale


6.3.1    Trecerea de la flux de date la comportament.

Toate specificaţiile comportamentale necesită o incapsulare în unul sau mai multe definiţii ca specificaţii procedurale. La fel ca şi atribuirile continue sau instanţele, specificaţiile comportamentale sunt incluse în interiorul modulului, şi se execută concurent.
Există două tipuri de blocuri comportamentali.
    iniţial block
    always block

Fiecare modul poate conţine orice număr de blocuri de ambele tipuri însă ele nu pot fi localizate unul în interiorul altuia.

Dacă un bloc conţine mai multe expresii, ele trebuiesc grupate in interiorul perechii  begin – end sau fork – join. Prima pereche se utilizează în expresiile secvenţiale, cealaltă se aplică la executarea expresiilor concurente.
 
6.3.2    Blocuri comportamentale.
Ambele blocuri comportamentale – iniţial şi always – se comportă identic cu excepţia unui singur lucru:
-    conţinutul unui bloc iniţial se execută chiar de la începutul timpului de simulare (time=0) şi numai o singură dată;
-    blocul always de asemenea începe la momentul time=0 pentru timpul de simulare, însă conţinutul lui se execută într-un ciclu infinit şi durează atâta timp cât durează simularea.
Într-un modul poate fi mai multe blocuri de ambele tipuri. Şi toate blocurile se execută concurent începând cu time=0 pentru  timpul de simulare.
Deoarece valoarea predefinită a regiştrilor este valoarea ,,z’’ – impondanţa înaltă, este necesară o iniţializare a lor în zero sau altă valoare înainte de a începe simularea.
Blocurile iniţial sunt utilizate pentru iniţializarea variabilelor (registrelor) la începutul simulării.
Blocurile always, pe de altă parte, reprezintă comportamentul unui circuit digital care îşi menţine comportamentul pe durata funcţionării lui.
6.3.3    Atribuiri variabilelor.

Cea mai importantă operaţie într-o specificare comportamentală este atribuirea unei expresii la o variabilă. Asemenea atribuiri, formal, sunt numite atribuiri procedurale şi diferă de atribuirea continuă prin mai multe lucruri, printre care:
-    destinaţia atribuirii (partea stângă a relaţiei) trebuie să fie de tip registru (reg, integer,real sau time), un bit, sau o secvenţă de vector a unui registru, şi nu poate fi de tip net.;
-    nu există cuvinte cheie de precedare a atribuirii;
-    trebuie să fie specificată în interiorul unui bloc comportamental (iniţial sau always);
-    atribuirea continuă schimbă valoarea firului (net) destinaţiei când un oarecare operand din partea dreaptă îşi schimbă valoarea. Atribuirea schimbă valoarea registrului numai  când atribuirea se execută în conformitate cu secvenţa de operaţii într-un bloc comportamental.

reg A
integer LoopCount;
reg [7:0] VecM;
initial
  begin
   A=1’b0;
   Lop Count=0;
   VecM=9’b0;
 End

6.3.4    Reţineri în atribuiri.

Una din regulile principale dale simulării modulelor este că simulatorul Verilog nu va progresa fără vre-o oarecare relaţie temporală de tipul delay sau event. Fără ele timpul de simulare va rămâne mereu zero şi toate relaţiile se vor executa ,,imediat’’.
Cea mai răspândită metodă este utilizarea reţinerilor regulare a atribuirilor. Aşa reţineri sunt specificate în acelaşi mod ca şi reţinerile în atriburea continuă (caracterul cu numărul de unităţi, în faţa relaţiei de atribuire), însă menirea lor este diferită în interiorul codului.
Fiecare reţinere specifică timpul între momentul când a fost detectată relaţia (de către simulator) şi execuţia ei. Cu alte cuvinte, este timpul dintre execuţia a două relaţii.

module clockgenerator;
    Regclk;
        Parameter HalfCycle=20;
      Iniţial clk=1’b0;
        Always #HalfCycle clk=~clk;
Endmodule
 

6.3.5    Execuţia blocurilor comportamentale.
Cum are loc execuţia blocurilor comportamentali? Vom examina simularea blocurilor comportamentali ce conţin reţineri. Pentru a ne conecta mai bine pe ordinea operaţiilor dar nu pe operaţii ca atare vom utiliza aici un exemplu mai mult formal, cu nişte nume generice în locul unor expresii reale.
Când simularea începe, se activează toate blocurile comportamentale. Indiferent de conţinutul blocului, prima expresie de după begin se execută fără vre-o reţinere. Dacă următoarea relaţie/expresie nu conţine reţineri, ea se execută în acelaşi moment de timp (time=0), şi aşa mai departe, până când se întâlneşte un bloc de reţinere. Timpul de simulare progresează cu numărul de unităţi temporale specificate de reţinere, după care se execută următoarea expresie/reţinere. În cazul când nu mai sunt relaţii în bloc, adică se defectează cuvântul cheie end, blocul este suspendat pentru totdeauna dacă este un bloc iniţial.
În caz că este un bloc always controlul se transmite din nou primei expresii care vine imediat după cuvântul begin de la începutul blocului.
6.4    Relaţii mai complexe

6.4.1    În afară de Atribuiri.

De cele mai multe ori atribuirile procedurale în blocurile comportamentale sunt insuficiente pentru a reprezenta o funcţionalitate dorită. Deseori atribuirile depind nu numai de valoarea operanzilor ci şi de careva condiţii adăugătoare, care pot schimba rezultatul operaţiilor. Careva operaţii pot avea nevoie să se repete, însă nu chiar infinit pe durata activităţii blocului always.
În aceste situaţii se utilizează relaţii mai complexe. Aşa relaţii ca relaţii condiţionale, selectare multimplă sau cicluri, există în limbajele de programare, şi de fapt aceste relaţii în Verilog sunt similare cu ecivalentele celor din C.

6.4.2    Operaţii condiţionale.

Unele operaţii se execută numai când se îndeplineşte o anumită condiţie. Asemenea operaţii se numesc condiţionale. Implimentarea lor în Verilog se face în modul următor:

if (relaţia) expresie 1;
else expresie 2;

Această operaţie Verilog implică următoarele cazuri:
- dacă ,,relaţia’’ este evaluată şi rezultatul este ,,true’’ (ne egal cu zero) atunci se va executa expresia 1. Aici poate fi o singură expresie sau un bloc de expresii incluse în perechea begin-end.
- Dacă ,,relaţia’’ se evaluează şi rezultatul este ,,false’’, ,,zero’’ ori o valoare (,,x’’ sau ,,z’’), atunci se execută expresia 2, ca şi în cazul precedent aici poate fi o expresie sau un bloc de expresii incluse în pereche begin-end. Cazul elese se poate omite, şi în cazul când relaţia este falsă, nu se execută nimic.

 
6.4.3    Selecţie multiplă
Expresiile cu relaţii if-else-if din secţiunea precedenta se urmăresc cam incomod, de ce? Când o expresie are mai mult decât o atribuire, lucrurile se complica puţin. Din fericire în locul relaţiilor if-else-if putem folosi cuvântul relaţii de selecţie multiplă, specificat prin cuvântul cheie case.
Expresia care e specificată în parantezele de după cuvântul cheie case se verifică şi se compară cu fiecare din valorile specificate in relaţiile ce urmează. Prima relaţie care va satisface condiţia va implica executarea expresiei corespunzătoare. Daca nici una din relaţii nu satisface condiţia dorită, se va executa ramura default.
case – compară toţi biţii existenţi pentru toate 4 valori logice. Pentru a interpreta valoarea „z” ca  „don’t care”, se poate utiliza  casez in loc de case, şi casex în cazul interpretării valorilor „x”.

6.4.4    Cicluri


Scopul ciclurilor este de a repeta careva expresii specificate. Expresiile se repetă de un număr specificat de ori sau atâta timp cât este respectată o oarecare condiţie.
Sunt 4 tipuri de construcţii de cicluri, denumite după cuvintele lor cheie: forever, repeat, while şi for.
Ele sunt similare ci ciclurile în limbajul C.
-    forever este cel mai simplu ciclu şi repetă infinit conţinutul lui;
-    repeat execută conţinutul de un număr stabilit de ori care este specificat de numărul constant plasat îndată după cuvântul cheie;
-    while nu specifică numărul de iteraţii ci condiţia pentru execuţie;
-    for este cel mai flexibil ciclu în care se specifică condiţia iniţială, condiţia de terminare, şi atribuirea de reînnoire a variabilei de control în fiecare execuţie.
 
 6.5     Control avansat asupra Comportamentului.


6.5.1    Controlul timpului în blocurile comportamentale.


Un control mai complex în blocurile comportamentale îl putem efectua cu expresii condiţionale. Ele însă nu sunt dependente de scurgerea timpului. Am putea căuta de acum o construcţie care permite un asemenea control: reţinerea/întârzierea. Asemenea reţineri pot fi specificate nu numai pentru atribuiri ci şi pentru oricare expresie într-un bloc comportamental. Reţinerea specificată în faţa expresiei reţine execuţia întregii expresii pentru un număr anumit de unităţi temporale.
O reţinere la fel poate fi specificată şi în interiorul unei expresii. Asemenea reţinere este specificată îndată după semnul de atribuire ce (,=’) şi are o interpretare diferită de cea precedentă. Partea dreaptă a expresiei se execută imediat iar după o reţinere rezultatul i se atribuie părţii stângi.
6.5.2    Evenimente


Reţinerea nu este unicul mod de control a comportamentului pe parcursul timpului de execuţie pentru expresiile procedurale (comportamentale). Altă metodă este legată de evenimente, adică schimbări în registre sau fire (net). Cel mai tipic exemplu este frontul pozitiv sau negativ a semnalului de clock care se utilizează pentru sincronizarea operaţiilor într-un circuit.
Expresiile de control prin evenimente sunt specificate prin simbolul ,,@’’, urmat de numele de registru sau net. Şi influenţează execuţia unei expresii. Această construcţie, de control prin evenimente, poate fi localizată în acelaşi mod ca şi reţinerile, adică înainte sau în interiorul expresiilor.
În afară de evenimentele obişnuite (adică o schimbare provoacă activarea expresiei), se mai utilizează evenimentele mai sofisticate ca negedge şi posedge.

@(clk) Q=D;                     
@(posedge clk) Q=D;
@(negedge clk) Q=D;

6.5.3    Expresia Wait.

Controlul prin evenimente se referă la schimbarea unei valori a unui semnal sau variabile. Uneori nu schimbarea valorii acestei este important, ci valoarea ca atare, adică cum ar fi semnalul enable a unui bufer tristate. Un asemenea eveniment senzitiv pe nivel se poate obţine cu expresia wait.
Expresia wait începe cu cuvântul cheie wait, urmată de o condiţie. Ce cele mai multe ori ca condiţie se utilizează valoarea semnalului enable:

  Wait (enable) expresie;

Expresia wait reţine execuţia unei expresii sau a unui bloc până când condiţia devine ,,true’’.
Evenimentul senzitiv pe nivel poate fi deasemenea utilizat pentru suspendarea execuţiei unui block fără ai adăuga vre-o expresie, adică wait.

6.5.4    Lista de sensivităţi.
Când o relaţie este activată de un semnal se spune că ea este senzitivă la acest semnal.
Verilog nu restricţionează sensivitatea numai la un semnal, ci permite specificarea expresiilor cu sensivităţi la orice număr de evenimente. Aşa evenimente sunt reparate prin cuvântul cheie or şi împreună compun listă de sensivităţi.
Controlul prin evenimente şi listelor de sensivităţi în particular se utilizează în special în vblocurile always. O dată ce controlul prin elemente poate fi specificat pentru orice expresie, expresiile incluse într-o pereche begin-end la fel pot fi manipulate cu ajutorul evenimentelor. Această construcţie de control într-o specificaţie always se plasează îndată după cuvântul cheie always. În acest caz, evenimentele se referă blocuri ce urmează, şi e scris după cuvântul cheie din considerentele că codul să fie mai citeţ.
Lisat de sencivităţi permite suspendarea şi reluarea ciclului infint a blocurilor always, adică: execuţia blocului se suspendează la începutul fiecprii iteraţii până când un semnal din lista de sensivităţi se va schimba.



6.5.5    Atribuire Non-Blocking.
Atribuirea Non Blocking implică concurenţa într-un bloc de expresii secvenţial.
Un exemplu clasic poate fi utilizarea reţinerilor în interiorul atribuirilor. Aşa cum ne sugerează denumirea acestei atribuiri, când se utilizează o atribuire non-blocking, reţinerea (specificate într-o atribuire) se utilizează pentru întârzierea atribuirii valorii rezultante părţii stângi, însă, controlul se transmite următoarei expresii, indiferent de valoarea reţinerii.
Ca rezultat atribuirei non-blocking se pot executa în paralel cu alte blocuri şi expresii. Pentru a distinge atribuirile non-blocking de cele blocking (obişnuite) se utilizează un alt semn de atribuire ,,<=’’.
De ce avem nevoie să utilizăm atribuiri non-blocking? În primul, aceste atribuiri permit modelarea transferului multiplu concomitent a datelor după un eveniment comun. O atribuire non-blocking va forţa execuţia secvenţială în dată ce apare evenimentul.
În al doilea rând, citirea (evaluarea părţii drepte) şi scrierea (atribuirea reală) sunt reparate în această atribuire, eliminând condiţiile necesare de exemplu de schimb a valorilor între variabile pentru aceste atribuiri. 
6.5.6    Blocuri paralele.


Atribuirile non-blocking implică paralelism în blocurile comportamentale, însă utilizarea lor este restricţionată. Există, însă, o metodă mai generală pentru a defini expresii paralele în interiorul blocurilor procedurale iniţial şi always pentru ca orice expresie să se execute şi să simuleze în paralel, se utilizează perechea fork – join  în locul begin – end.
Toate expresiile specificate în interiorul unui bloc paralel se execută în paralel. În consecinţă, orice reţinere specificată în interiorul expresiei se referă la momentul de start a blocului dar nu la sfârşitul execuţiei expresiei precedente ca şi în cazul blocurilor secvenţiale. De fapt se poate compara ca specificaţiile fluxurilor de date.
6.6    Test - Specificaţii comportamentale
       Să se selecteze afirmaţiile corecte:
1.    Un registru Verilog e echivalent cu un registru harware.
2.    Reţinerile în specificaţiile comportamentale se utilizează similar ca şi în atribuirile continue.
3.    Într-o declaraţie rangul unui tablou urmează după identificatorul lui.
4.    Parameter este numele Verilog pentru constante.
5.    Toate specificaţiile comportamentale necesită o incapsulare într-un bloc ,,iniţial’’ sau ,,always’’.
6.    Specificarea blocurilor ,,iniţial’’ şi ,,always’’ se face în diferit mod.
7.    Partea din stânga a unei atribuiri în interiorul unui bloc iniţial sau always poate fi un registru sau net.
8.    Nu este posibil de a accesa un singur bit a memoriei.
9.    Orice bloc ,,iniţial’’ se execută numai odată.
10.    Înaintea cuvântului else nu se poate pune ;
11.    Case tratează ,,x’’ şi ,,z’’ ca valori ,,don’t care’’ pe când careX şi careZ ca le tratează respectiv literal.
12.    Argumentul pentru ,,posedge’’ trebuie specificat în paranteze, adică ,,posedge (cek)’’.
13.    Atribuirea non-blocking permite atribuirea concurentă.
14.    Semnalele în lista de sensivităţi sunt separate prin ,,;’’
15.    Controlul prin evenimente se poate aprecia pentru orice specificaţie comportamentală.