14.06.2014 Views

Circuite integrate numerice – Limbajul ABEL si aplicatii ale ...

Circuite integrate numerice – Limbajul ABEL si aplicatii ale ...

Circuite integrate numerice – Limbajul ABEL si aplicatii ale ...

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

INTRODUCERE IN LIMBAJUL <strong>ABEL</strong>-HDL<br />

1. Limbaje de descriere hardware (HDL-Hardware Description language)<br />

Metodele tradiţion<strong>ale</strong> de proiectare a unui <strong>si</strong>stem numeric (circuit logic) sunt cele bazate<br />

pe ecuaţiile booleene sau pe reprezentarea schematică.<br />

Orice circuit logic este alcatuit pană la urmă dintr-un număr oarecare de porţi <strong>si</strong>/sau<br />

circuite bistabile, care sunt blocurile funcţion<strong>ale</strong> de bază. Proiectarea se făcea in mod<br />

tradiţional pe baza ecuaţiilor boolene. Pentru a optimiza această metodă s-au dezvoltat tehnici<br />

cum ar fi minimizarea ecuaţiilor, care permite utilizarea mai eficientă a porţilor <strong>si</strong> circuitelor<br />

bistabile. Metoda ecuaţiilor boolene presupune scrierea practic a unei ecuatii, pentru fiecare<br />

circuit bistabil <strong>si</strong> pentru fiecare bloc de porţi. Pentru un <strong>si</strong>stem secvenţial numărul de ecuaţii<br />

este cel putin egal cu cel al circuitelor bistabile(registrelor). Dacă <strong>si</strong>stemul nostru are sute de<br />

circuite bistabile vom avea <strong>si</strong> sute de ecuaţii. Astfel, de<strong>si</strong> teoretic orice <strong>si</strong>stem numeric poate fi<br />

descris pe baza ecuaţiilor boolene, aceasta descriere(ca metodă) este total nepractică daca<br />

avem zeci, sute sau mii de ecuaţii.<br />

Metodele bazate pe reprezentarea schematică (Schematics) sunt metode care folosesc<br />

o reprezentare grafică a <strong>si</strong>stemului numeric <strong>si</strong> care realizează in acela<strong>si</strong> timp o extindere a<br />

metodei ecuaţiilor boolene, prin utilizarea <strong>si</strong> a altor blocuri funcţion<strong>ale</strong>, mai complexe decât<br />

porţile <strong>si</strong> circuitele bistabile. Ele prezintă avantajul ca permit o proiectare ierarhică <strong>si</strong> pun in<br />

evidenţa mai bine relaţiile care există intre diversele blocuri funcţion<strong>ale</strong>. Mulţi ani de zile<br />

aceste metode au fost con<strong>si</strong>derate optime pentru reprezentarea unui <strong>si</strong>stem numeric. Odată cu<br />

cresterea complexităţii <strong>si</strong>stemelor reprezentate <strong>si</strong> ele au devenit nepractice. Se mai utilizează<br />

pentru <strong>si</strong>steme de complexitate mică sau medie.<br />

Marele dezavantaj al metodelor tradiţion<strong>ale</strong> de proiectare este că un <strong>si</strong>stem trebuie<br />

specificat ca o reţea de elemente interconectate. In realitate insă un <strong>si</strong>stem numeric este<br />

specificat prin comportarea (behaviour) sa in anumite circumstanţe specificate. Proiectantul<br />

trebuie să ajungă de la aceasta formă de specificare la un set de ecuaţii sau o reprezentare<br />

grafica. Acest pas important poate fi in intregime eliminat prin utilizarea unui limbaj de<br />

descriere hardware(HDL).<br />

Un alt dezavantaj al metodelor tradiţion<strong>ale</strong> este modul in care este descris un <strong>si</strong>stem<br />

complex. Este greu să lucrăm cu sute de ecuaţii, dar este incă po<strong>si</strong>bil. Un <strong>si</strong>stem insă, care ar<br />

fi descris prin mii de ecuaţii, este practic inabordabil prin această metodă. Mai mult, <strong>si</strong> o<br />

reprezentare schematică in care apar sute sau mii de blocuri funcţion<strong>ale</strong> devine de neinţeles.<br />

O descriere din punct de vedere al comportării <strong>si</strong>stemului poate fi insa automat<br />

convertită intr-un cod sursă HDL, cod care este apoi implementat prin intermediul unor<br />

programe de <strong>si</strong>nteză.<br />

<strong>Limbajul</strong> <strong>ABEL</strong> (Advanced Boolean Equation Language) este un limbaj evoluat care<br />

permite o descriere din punct de vedere comportamental a unui circuit logic.<br />

<strong>ABEL</strong> este de asemenea un limbaj din categoria limbajelor de descriere hardware (HDL-<br />

Hardware Description Language), dezvoltat la origine de firma Data I/O pentru programarea<br />

dispozitivelor logice programabile (PLD-Programmable Logic Devices). Există şi alte limbaje<br />

<strong>si</strong>milare, foarte utilizate, cum ar fi VHDL sau Verilog. Comparativ cu acestea <strong>ABEL</strong> este<br />

mult mai <strong>si</strong>mplu, dar VHDL sau Verilog sunt mai adecvate pentru descrierea unor <strong>si</strong>steme<br />

complexe. Prin raportare la alte limbaje de programare cunoscute <strong>ABEL</strong> este un limbaj care s-<br />

ar <strong>si</strong>tua intre limbajul de asamblare <strong>si</strong> C, VHDL-ul este <strong>si</strong>milar limabajului ADA, iar Verilogul<br />

este <strong>si</strong>milar limabjului C.<br />

<strong>ABEL</strong> este un limbaj HDL care poate fi utilizat pentru a descrie comportarea unui<br />

<strong>si</strong>stem sub mai multe forme, cum ar fi: ecuaţii logice, tabele de adevăr sau diagrame de stare,<br />

utilizând instrucţiuni <strong>si</strong>milare cu cele din limbajul C. Un compilator <strong>ABEL</strong> permite şi<br />

<strong>si</strong>mularea funcţională a <strong>si</strong>stemului folo<strong>si</strong>nd vectorii de test, precum şi implementarea sa<br />

1


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

folo<strong>si</strong>nd un dispozitiv PLD incepand de la cele mai <strong>si</strong>mple (PAL sau GAL) <strong>si</strong> terminand cu<br />

cele mai complexe (CPLD-Complex Programmable Logic Devices sau FPGA- Field<br />

programmable Gate Array).<br />

2. Structura unui fişier sursă <strong>ABEL</strong><br />

Un fişier sursă <strong>ABEL</strong> constă din următoarele elemente:<br />

Antet(Header): incluzând Module, [ Options şi Title ]<br />

Declaraţii: Pin, Constant, Node, Sets, States, Library.<br />

Descrieri logice: Equations, Truth-table sau State_diagram<br />

[Vectori de test: Test_vectors ]<br />

End<br />

Cuvintele cheie <strong>ale</strong> limbajului (recunoscute de <strong>ABEL</strong> drept comenzi, directive, etc.)<br />

nu sunt dependente de tipul de literă folo<strong>si</strong>t (mare sau mic) pe când identificatorii<br />

definiţi de utilizator depind de tipul de literă!!. De exemplu MODULE este acelaşi lucru cu<br />

module, dar identificatorul out1 este diferit de Out1!<br />

O machetă(template) tipică a unui modul sursă <strong>ABEL</strong> este dată mai jos:<br />

module nume modul<br />

[title <strong>si</strong>r]<br />

[identificator_dispozitiv device tip_dispozitiv;]<br />

declaratii pini<br />

alte declaratii<br />

equations<br />

ecuatii<br />

[Test_Vectors]<br />

[vectori de test]<br />

end nume modul<br />

Cuvintele cheie utilizate de limbajul <strong>ABEL</strong> sunt date în continuare:<br />

CASE, DECLARATIONS, DEVICE, ELSE, ENABLE, END, ENDCASE, ENDWITH,<br />

EQUATIONS, FUNCTIONAL_BLOCK, FUSES, GOTO, IF, IN, INTERFACE(într-un<br />

modul top), INTERFACE(într-un submodul), ISTYPE, LIBRARY, MACRO, MODULE,<br />

NODE, PIN, PROPERTY, STATE(ca declaraţie), STATE(în state_diagram),<br />

STATE_DIAGRAM, STATE_REGISTER, TEST_VECTORS, THEN, TITLE, TRACE,<br />

TRUTH_TABLE, TEST_VECTORS, WITH .<br />

Următoarea sursă <strong>ABEL</strong> este un exemplu de implementare a unui semisumator de un<br />

bit folo<strong>si</strong>nd un circuit PLD de tip PAL22V10:<br />

module primul_meu_circuit;<br />

title 'semisumator '<br />

PAL200 device '22V10';<br />

" pini intrare<br />

A, B pin 3, 5;<br />

" pini ie<strong>si</strong>re<br />

SUM, Carry_out pin 15, 18 istype 'com';<br />

equations<br />

SUM = (A & !B) # (!A & B) ;<br />

2


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

Carry_out = A & B;<br />

end primul_meu_circuit;<br />

3. Declaraţii<br />

Module: fiecare fişier sursă începe cu o astfel de instrucţiune urmată de un nume al<br />

modulului (identificator). Proiectele mari pot conţine mai multe module, fiecare cu propriile<br />

declaraţii title, equations, end, etc.<br />

Title: este opţional şi poate fi folo<strong>si</strong>t pentru identificarea proiectului. Numele trebuie să fie<br />

cuprins între ghilimele (<strong>si</strong>mple). Linia respectivă este ignorată de compilator fiind utilă numai<br />

pentru documentare.<br />

Şir: reprezintă este o serie de caractere ASCII cuprinse între ghilimele <strong>si</strong>mple ( ` ). Şirurile<br />

sunt folo<strong>si</strong>te pentru instrucţiunile TITLE, OPTIONS , precum şi în declararea atributelor<br />

pentru pin şi node.<br />

device: este o declaraţie opţională şi asociază un identificator de dispozitiv cu un anume<br />

circuit PLD. Este de dorit evitarea utilizării acestei declaraţii în fişierul sursă deoarece<br />

astfel se păstrează independenţa proiectului de tipul de circuit. Atunci când se lucrează<br />

cu un mediu de programare integrat declararea tipului de circuit se face la crearea proiectului,<br />

dar poate fi modificată oricând şi ulterior.<br />

comentarii: comentariile pot apărea oriunde în fişierul sursă , încep cu ghilimele duble ( ")şi<br />

se termină fie tot cu ghilimele duble, fie la sfârşitul liniei (care <strong>si</strong>tuaţie apare prima) .<br />

pin: prin aceste declaraţii compilatorul asociază numele <strong>si</strong>mbolice cu conexiunile externe <strong>ale</strong><br />

dispozitivului. Formatul este următorul (pin_id - identificator pin):<br />

[!]pin_id pin [nr. sau cod pin] [istype 'atribut'] ;<br />

Se pot specifica mai mulţi pini pe aceiaşi linie sursa:<br />

[!]pin_id , [!]pin_id, [!]pin_id pin [nr. pin, [nr. pin, [nr. pin]]] [istype 'atribut'];<br />

Exemplu:<br />

IN1, IN2, A1 pin 2, 3, 4;<br />

OUT1 pin 9 istype 'reg';<br />

ENABLE pin;<br />

!Chip_select pin 12 istype 'com';<br />

!S0..!S6 pin istype 'com';<br />

Nu este neapărat nevoie să specificăm un număr de pin. Numerele de pin pot fi specificate şi<br />

mai târziu, în faza de implementare a proiectului, utilizând un fişier de constrângeri<br />

utilizator (user constraint file), proiectul având astfel un caracter mai general şi mai flexibil.<br />

! indică un semnal activ în 0 -Low ( semnalul va fi inversat).<br />

istype este un atribut opţional; variante: 'com' pentru a indica natura combinaţională a<br />

semnalului de ieşire sau 'reg' pentru un semnal de tip registru (memorat într-un bistabil).<br />

Acest atribut este folo<strong>si</strong>t doar pentru pini de ieşire sau noduri interne (node).<br />

3


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

node: declaraţiile node (nod intern) au acelaşi format ca declaraţiile pin; fiind însă vorba de<br />

semn<strong>ale</strong> interne care nu au ca echiv<strong>ale</strong>nt o conexiune externă, numărul de pin lipseşte.<br />

Exemplu: temp1 node [istype 'com'];<br />

alte declaraţii permit definirea unor constante, mulţimi (sets), macro-uri sau expre<strong>si</strong>i care<br />

pot <strong>si</strong>mplifica programul.<br />

Declararea unei constante are următorul format:<br />

id [, id],... = expre<strong>si</strong>e [, expre<strong>si</strong>e].. ;<br />

Exemple:<br />

A = 21;<br />

c = .C. ;<br />

x = .x.<br />

z = .Z. ;<br />

ADDR = [1,0,1,1];<br />

LARGE = B & C;<br />

Data = [D3, D2, D1, D0];<br />

Data = [D3..D0];<br />

Ultimele două declaraţii sunt echiv<strong>ale</strong>nte. Folo<strong>si</strong>rea " .. " reprezintă o modalitate comodă de<br />

descriere a unui domeniu (range). Declaraţia respectivă utilizează practic o notaţie vectorială:<br />

de fiecare dată când vom folo<strong>si</strong> Data într-o ecuaţie ne vom referi de fapt la vectorul<br />

[D3,D2,D1,D0].<br />

Constante speci<strong>ale</strong>(predefinite)<br />

În <strong>ABEL</strong> se pot utiliza o serie de constante cu o semnificaţie specială. Cele mai<br />

importante sunt :<br />

.C. , .c. – descrie o tranziţie completă a unui semnal de ceas folo<strong>si</strong>t ca intrare (L,H,L; _| -- |_ )<br />

.X. , .x. – descrie o valoare indiferentă (don’t care)<br />

.Z., .z. - descrie o valoare tri-state<br />

4. Numere<br />

Numerele pot fi utilizate folo<strong>si</strong>nd patru baze de numeraţie diferite: binar, octal,<br />

zecimal şi hexazecimal. Baza implicită este zecimal (fără prefixare).<br />

Se utilizează următoarele prefixe:<br />

Binar ^b<br />

Octal ^o<br />

Zecimal ^d (implicit)<br />

Hexazecimal ^h<br />

Exemple: 35 , ^h35 , ^b101, ^h4FFB<br />

5. Mulţimi (sets)<br />

O mulţime este o colecţie de semn<strong>ale</strong> sau constante utilizate pentru a face referire la un<br />

grup de semn<strong>ale</strong> folo<strong>si</strong>nd un <strong>si</strong>ngur nume. Utilizarea mulţimilor <strong>si</strong>mplifică semnificativ<br />

operaţiile logice: orice operaţie aplicată unei mulţimi este aplicată de fapt fiecărui element al<br />

ei. O mulţime este descrisă printr-un şir de constante sau semn<strong>ale</strong>, separate prin virgulă sau<br />

operatorul domeniu ( .. ), şir cuprins obligatoriu între paranteze pătrate [] .<br />

Exemple:<br />

[D0,D1,D2,D4,D5]<br />

[D0..D6] " domeniul poate fi enumerat crescător<br />

[b6..b0] " domeniul poate fi enumerat <strong>si</strong> descrescător<br />

4


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

[D7..D15]<br />

[b1,b2,a0..a3] " un (sub)domeniu într-o mulţime mai mare<br />

[!S7..!S0] " domeniu descrescător de semn<strong>ale</strong> declarate active –low (în 0)<br />

Următoarea declaratie nu este permisă : [D0, X] , unde X este de asemenea o mulţime X =<br />

[X3..X0]; în schimb se poate scrie corect: [D0, X3..X0];<br />

b. Operaţii cu mulţimi<br />

Cea mai mare parte a operaţiilor poate fi aplicată şi unei mulţimi, operaţia efectuânduse<br />

asupra fiecărui element al mulţimii. Operaţiile se efectuează conform priorităţii<br />

operatorilor, operaţiile cu aceiaşi prioritate se efectuează de la stânga la dreapta (dacă nu<br />

există paranteze).<br />

Exemplul 1:<br />

Semn<strong>ale</strong> = [D2,D1,D0]; " declararea multimii Semn<strong>ale</strong><br />

Semn<strong>ale</strong> = [1,0,1] & [0,1,1]; " rezulta Semn<strong>ale</strong> = [0,0,1]<br />

Exemplul 2:<br />

[A,B] = C & D; este de fapt echiv<strong>ale</strong>nt cu două instrucţiuni:<br />

A = C & D;<br />

B = C & D;<br />

Exemplul 3:<br />

[A1,B1] = [D1,D2] & [C3,C2];<br />

este echiv<strong>ale</strong>nt cu: [A1,B1] = [D1 & C3, D2 & C2];<br />

astfel vom avea A1 = D1 & C3, <strong>si</strong> B1= D2 & C2.<br />

Exemplul 4:<br />

X & [A,B,C]; care este echiv<strong>ale</strong>nt cu<br />

[X&A, X&B, X&C];<br />

În cazul următoarei expre<strong>si</strong>i lucrurile stau puţin diferit: 2 & [A,B,C]; acum numărul<br />

zecimal "2" este convertit în reprezentare binară şi completat cu zerouri dacă este necesar<br />

(010). Astfel ecuaţia de mai sus este echiv<strong>ale</strong>ntă cu:<br />

[0 & A, 1 & B, 0 & C];<br />

Exemplul 5:<br />

A = [A2,A1,A0]; "declaratii de multimi<br />

B = [B2,B1,B0 ];<br />

A # B; este echiv<strong>ale</strong>nt cu [A2 # B2, A1 # B1, A0 # B0];<br />

!A; este echiv<strong>ale</strong>nt cu [!A2,!A1,!A0];<br />

Exemplul 6:<br />

[b3,b2,b1,b0] = 2; " echiv<strong>ale</strong>nt cu b3=0,b2=0,b1=1,b0=0.<br />

Exemplul 7: Să presupunem că avem următoarea ecuaţie (pentru ieşirea unui decodificator):<br />

Chip_Sel = !A7 & A6 & A5 & A4;<br />

Mai întâi definim mulţimea Adr :<br />

Adr = [A7,A6,A5,A4];<br />

Ecuaţia propriu-zisă va fi:<br />

Chip_Sel = Adr == [0,1,1,1];<br />

Care este echiv<strong>ale</strong>nt cu:<br />

5


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

Chip_Sel = !A7 & A6 & A5 & A4;<br />

Dacă A7=0, A6=1 , A5=1 <strong>si</strong> A4=1 expre<strong>si</strong>a Adr ==[0,1,1,1] este adevărată (sau 1) şi<br />

Chip_Sel va fi şi el 1 (sau adevărat).<br />

Altă modalitate de a scrie aceiaşi ecuaţie este:<br />

Chip_Sel = Adr = = 7; " 7 zecimal = 0111 binar.<br />

6. Operatori<br />

Există patru tipuri de operatori de bază: logici, aritmetici, relaţionali şi de a<strong>si</strong>gnare.<br />

a. Operatori logici<br />

Setul implicit de operatori logici (la nivel de bit) este descris în tabelul de mai jos..<br />

Folo<strong>si</strong>nd directiva @ALTERNATE se poate eventual comuta la un set alternativ de operatori<br />

logici.<br />

Operator (implicit) Descriere<br />

Operator alternativ<br />

! NOT (complement faţă de 1) /<br />

& AND *<br />

# OR +<br />

$ XOR ( or exclu<strong>si</strong>v ) :+:<br />

!$ XNOR ( nor exclu<strong>si</strong>v) :*:<br />

b. Operatori aritmetici<br />

În continuare sunt prezentaţi operatorii aritmetici. Ultimii cinci operatori nu pot fi<br />

utilizaţi cu operanzi de tip mulţimi. Semnul - poate avea semnificaţii diferite: prezent între 2<br />

operanzi are semnificaţia de scădere (sau adunare complement faţă de 2), dar prezent în faţa<br />

unui operand are semnificaţia de complement faţă de 2.<br />

Operator Exemplu Descriere<br />

- -D1 Complement faţă de 2 (schimbare de semn)<br />

- C1-C2 Scădere<br />

+ A+B Adunare<br />

Următorii operatori nu sunt folo<strong>si</strong>ţi cu mulţimi:<br />

* A*B Înmulţire<br />

/ A/B Împărţire întreagă fără semn<br />

% A%B Modulo: restul lui A/B<br />

>B Deplasare B dreapta cu B biţi<br />

c. Operatori relaţionali<br />

Aceşti operatori produc valoarea booleană adevărat True (-1) sau fals False (0).<br />

Valoarea –1 în cod complement faţă de 2 este reprezentată în binar având toţi biţii în 1 (de ex.<br />

dacă operandul are 8 biţi : 1111 1111 ).<br />

Operator Exemplu Descriere<br />

== A==B sau 3==5 (false) Egal<br />

!= A!=B sau 3 != 5 (true) Diferit<br />

< A= A>=B sau !0 >= 5 (true) Mai mare sau egal<br />

6


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

Operatorii relaţionali sunt fără semn: !0 este complementul faţă de 1 al lui 0 sau<br />

11111111 (dacă operandul are 8 biţi) care are valoarea 255 în reprezentare fără semn. Astfel<br />

!0 > 9 este adevărat. Din acelaşi motiv şi expre<strong>si</strong>a –1 >5 este adevărată.<br />

O expre<strong>si</strong>e relaţională poate fi folo<strong>si</strong>tă şi împreună cu expre<strong>si</strong>i <strong>numerice</strong>, ea fiind substituită<br />

cu –1 sau 0 funcţie de rezultatul evaluării. De exemplu avem expre<strong>si</strong>a A = B !$ (C == D);<br />

aici A va fi egal cu B dacă C este egal cu D (adevărat sau 111… ; B XNOR 1 egal cu B) ,<br />

altfel A va fi egal cu complementul lui B .<br />

d. Operatori de a<strong>si</strong>gnare<br />

Aceşti operatori sunt folo<strong>si</strong>ţi în ecuaţii pentru a a<strong>si</strong>gna valoarea unei expre<strong>si</strong>i unui<br />

semnal de ieşire sau unui nod intern. Există două tipuri de astfel de operatori: combinaţionali<br />

şi de tip registru.<br />

În cazul unui operator combinaţional a<strong>si</strong>gnarea are loc imediat, fără nici o întârziere.<br />

În cazul operatorului de tip registru a<strong>si</strong>gnarea are loc odată cu următorul impuls de ceas al<br />

bistabilului asociat ieşirii sau nodului intern. Un exemplu <strong>si</strong>mplu de definire a unui bistabil ar<br />

fi :<br />

Q1 pin istype 'reg';<br />

Q1 : = D;<br />

Prima instrucţiune (declaraţie) defineşte bistabilul Q1, iar a doua instrucţiune (ecuaţie) spune<br />

că ieşirea bistabilului va lua valoarea intrării D la următoarea tranziţie activă a semnalului de<br />

ceas.<br />

Operator Descriere<br />

= A<strong>si</strong>gnare combinaţională<br />

: = A<strong>si</strong>gnare de tip registru<br />

e. Prioritatea operatorilor(precedenţa)<br />

Prioritatea operatorilor este dată în următorul tabel , în ordine crescătoare de la 1 la 4.<br />

Operatorii cu aceiaşi prioritate sunt evaluaţi de la stânga la dreapta.<br />

Prioritate Operator Descriere<br />

1 - Negare<br />

1 ! NOT<br />

2 & AND<br />

2 > deplasare dreapta<br />

2 * înmulţire<br />

2 / împărţire fără semn<br />

2 % modulo<br />

3 + adunare<br />

3 - scădere<br />

3 # OR<br />

3 $ XOR<br />

3 !$ XNOR<br />

4 == egal<br />

4 != diferit<br />

4 < mai mic<br />

4 mai mare<br />

4 >= mai mare sau egal<br />

7


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

7. Descrierea logică<br />

Descrierea logică poate fi făcută cu ajutorul ecuaţiilor, tabelelor de adevăr sau a<br />

diagramelor de stare.<br />

a. Ecuaţii (equations)<br />

Se utilizează cuvântul cheie equations pentru a începe descrierea logică. Expre<strong>si</strong>ile<br />

pot conţine operatorii descrişi anterior precum şi instrucţiunea "When-Then-Else".<br />

Instrucţiunea "When-Then-Else" poate fi folo<strong>si</strong>tă în ecuaţii pentru a descrie o funcţie<br />

logică (ea se mai utilizează şi în diagramele de stare pentru a descrie o succe<strong>si</strong>une de stări).<br />

Formatul instrucţiunii "When-Then-Else" este următorul :<br />

sau<br />

WHEN condiţie THEN element = expre<strong>si</strong>e;<br />

ELSE ecuaţie;<br />

WHEN condiţie THEN ecuaţie;<br />

Exemple de ecuaţii:<br />

SUM = (A & !B) # (!A & B) ;<br />

A0 := EN & !D1 & D3 & !D7;<br />

WHEN (A == B) THEN D1_out = A1;<br />

ELSE WHEN (A == C) THEN D1_out = A0;<br />

WHEN (A>B) THEN { X1 :=D1; X2 :=D2; }<br />

Se pot utiliza şi acoladele { } pentru a grupa diverse secţiuni în blocuri. Textul dintrun<br />

bloc poate avea una sau mai multe linii. Blocurile pot fi folo<strong>si</strong>te în ecuaţii, tabele de adevăr<br />

sau directive.<br />

b. Tabele de adevăr ( truth_table )<br />

Cuvântul cheie cu care se începe descrierea este truth_table şi <strong>si</strong>ntaxa este:<br />

TRUTH_TABLE ( in_ids - > out_ids )<br />

intrări - > ieşiri ;<br />

sau<br />

TRUTH_TABLE ( in_ids : > reg_ids )<br />

intrări : > ieşiri_registre ;<br />

sau<br />

TRUTH_TABLE<br />

( in_ids :> reg_ids -> out_ids )<br />

intrări :> ieşiri_regiştrii -> ieşiri;<br />

în care "->" este folo<strong>si</strong>t pentru ieşiri combinaţion<strong>ale</strong> şi " : >" pentru ieşiri de tip registru,<br />

in_ids – identificatori intrari , out_ids – identificatori ieşiri, reg_ids – identificatori registre.<br />

8


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

Prima linie a unei tabele de adevăr (între paranteze) defineşte intrările şi ieşirile, iar<br />

următoarele linii corespondenţele între valorile de intrare şi cele de ieşire. Fiecare linie trebuie<br />

să se termine cu ; .<br />

Intrările şi ieşirile pot fi semn<strong>ale</strong> <strong>si</strong>ngulare sau mulţimi. Când se utilizează mulţimi se<br />

foloseşte notaţia normală pentru acestea (5). O valoare indiferentă este reprezentată prin ".X."<br />

(o constantă predefinită a limbajului <strong>ABEL</strong>).<br />

Exemplul 1: descrierea unui semisumator<br />

TRUTH_TABLE ( [ A, B] -> [Sum, Carry_out] )<br />

[ 0, 0 ] -> [0, 0 ] ;<br />

[ 0, 1 ] -> [1, 0 ] ;<br />

[ 1, 0 ] -> [1, 0 ] ;<br />

[ 1, 1 ] -> [1, 1 ] ;<br />

Dacă vom defini o mulţime IN = [A,B]; şi respectiv o mulţime OUT = [Sum, Carry_out];<br />

tabela de adevăr poate deveni mai <strong>si</strong>mplă:<br />

TRUTH_TABLE (IN -> OUT )<br />

0 -> 0;<br />

1 -> 2;<br />

2 -> 2;<br />

3 -> 3;<br />

Exemplul 2: Un XOR cu două intrări plus o intrare de activare, activă în 1 :<br />

TRUTH_TABLE ([EN, A, B] -> OUT )<br />

[ 0, .X.,.X.] -> .X. ;<br />

[ 1, 0 , 0 ] -> 0 ;<br />

[ 1, 0 , 1 ] -> 1 ;<br />

[ 1, 1 , 0 ] -> 1 ;<br />

[ 1, 1 , 1 ] -> 0 ;<br />

Exemplul 3: Tabelele de adevăr pot fi utilizate şi pentru descrierea maşinilor secvenţi<strong>ale</strong>, în<br />

cazul acestui exemplu fiind vorba de un numărător binar <strong>si</strong>ncron de 3 biţi, cu ieşirea de<br />

transport OUT (generată în starea 111). Se utilizează 3 bistabili QA, QB <strong>si</strong> QC care vor fi şi<br />

ieşirile numărătorului.<br />

MODULE CNT3;<br />

"declaratii<br />

CLOCK pin; " intrare ceas<br />

RESET pin; " intrare reset<br />

OUT pin istype 'com'; " ie<strong>si</strong>re transport (combinaţional)<br />

QC,QB,QA pin istype 'reg'; " ie<strong>si</strong>ri numarator (tip registru, bistabili)<br />

[QC,QB,QA].CLK = CLOCK; "semnalul de ceas pentru bistabili<br />

[QC,QB,QA].AR = RESET; " reset a<strong>si</strong>ncron pentru aceia<strong>si</strong> bistabili<br />

TRUTH_TABLE<br />

( [QC, QB, QA] :> [QC,QB,QA] -> OUT)<br />

[ 0 0 0 ] :> [ 0 0 1 ] -> 0;<br />

[ 0 0 1 ] :> [ 0 1 0 ] -> 0;<br />

[ 0 1 0 ] :> [ 0 1 1 ] -> 0;<br />

[ 0 1 1 ] :> [ 1 0 0 ] -> 0;<br />

[ 1 0 0 ] :> [ 1 0 1 ] -> 0;<br />

[ 1 0 1 ] :> [ 1 1 0 ] -> 0;<br />

9


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

[ 1 1 0 ] :> [ 1 1 1 ] -> 0;<br />

[ 1 1 1 ] :> [ 0 0 0 ] -> 1;<br />

END CNT3;<br />

Observatie Pentru utilizarea exten<strong>si</strong>ilor de tip .DOT (cum ar fi .CLK şi .AR) vezi secţiunea<br />

7d.<br />

c. Diagrame de stare ( State_diagram )<br />

Secţiunea State_diagram conţine descrierea logică a unui circuit sub forma unor<br />

diagrame de stare. În aceasta secţiune se utilizează instrucţiunile: "Goto", "Case" <strong>si</strong> "With".<br />

De obicei în secţiunea de declaraţii se declară (se utilizează) nume <strong>si</strong>mbolice pentru stări,<br />

programul fiind astfel mai uşor lizibil.<br />

Declararea se face cu următoarea <strong>si</strong>ntaxă (unde state_id – identificator stare):<br />

state_id [, state_id ...] STATE ;<br />

Ca un exemplu avem: SREG = [Q1, Q2]; care asociază numele <strong>si</strong>mbolic SREG cu starea<br />

definită prin intermediul bistabililor Q1 <strong>si</strong> Q2 (cei doi bistabili alcătuiesc practic un registru<br />

de stare).<br />

Sintaxa este următoarea:<br />

State_diagram registru_stare<br />

STATE valoare_stare : [ecuatie;]<br />

[ecuatie;]<br />

:<br />

:<br />

instructiune_tranzitie_stare ; ...<br />

Cuvântul cheie state_diagram indică începutul unei descrieri de maşină secvenţială.<br />

Cuvântul cheie STATE şi instrucţiunile următoare descriu o stare din diagrama de stări, ele<br />

incluzând o valoare a stării sau un nume <strong>si</strong>mbolic pentru stare, o instrucţiune care descrie<br />

tranziţia stării şi, opţional, o ecuaţie care descrie o ieşirile asociate stării.<br />

În descrierea de mai sus registru_stare este un identificator pentru semn<strong>ale</strong>le care<br />

definesc starea maşinii secvenţi<strong>ale</strong>. Se poate utiliza o notaţie <strong>si</strong>mbolică a registrului de stare,<br />

definită anterior în secţiunea declaraţii.<br />

valoare_stare: poate fi o expre<strong>si</strong>e , o valoare sau un nume <strong>si</strong>mbolic pentru starea curentă.<br />

ecuatie : opţional, o ecuaţie care descrie ieşirile asociate stării<br />

instructiune_tranzitie_stare: instrucţiunile "If-Then-Else", CASE sau GOTO utilizate pentru<br />

a descrie starea următoare; opţional sunt urmate de ecuaţiile de tranziţie descrise cu o<br />

instrucţiune WITH.<br />

Instrucţiunea If-Then-Else:<br />

Este utilizată pentru a descrie următoarea stare şi pentru a specifica condiţiile de<br />

tranziţie mutual exclu<strong>si</strong>ve. Sintaxa este următoarea:<br />

IF expre<strong>si</strong>e THEN expre<strong>si</strong>e _stare<br />

[ELSE expre<strong>si</strong>e _stare] ;<br />

Mai sus, expre<strong>si</strong>e_stare poate fi o expre<strong>si</strong>e logică sau un nume <strong>si</strong>mbolic al stării. Clauza<br />

ELSE este opţională. Instrucţiunile IF-Then-Else pot fi combinate cu instrucţiuni Goto, Case<br />

şi With.<br />

10


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

OBS. "IF-Then-Else" poate fi utilizată doar în secţiunea state_diagram; pentru descrierea unor<br />

funcţii logice combinaţion<strong>ale</strong> (secţiunea ecuaţii) se utilizează "When-If-Then".<br />

În următorul exemplu (o maşină cu 2 stări şi două ieşiri) se defineşte mai întâi registrul de<br />

stare, în secţiunea declaraţii:<br />

SREG = [Q1, Q0]; "definim registrul de stare<br />

S0 = [0, 1];<br />

S1 = [1, 1];<br />

state_diagram SREG<br />

state S0: OUT1 = 1;<br />

if A then S1<br />

else S0;<br />

state S1: OUT2 =1;<br />

if A then S0<br />

else S1;<br />

Instrucţiunile "If-Then-Else" pot fi de asemenea imbricate.<br />

Instrucţiunea "with":<br />

Sintaxa instrucţiunii este:<br />

instructiune_tranzitie_stare expre<strong>si</strong>e_stare WITH ecuatie<br />

[ecuatie ] ... ;<br />

Unde instructiune_tranzitie_stare poate fi o instrucţiune "If-then-else", 'Goto" sau "Case";<br />

expre<strong>si</strong>e_stare descrie starea următoare, iar ecuaţie este ecuaţia care descrie ieşirile asociate<br />

stării. În locul unei <strong>si</strong>mple expre<strong>si</strong>i de stare se pot utiliza tot instrucţiunile "If-Then-Else",<br />

"Goto" sau "Case".Instrucţiunea "With" permite ca ecuaţiile de ieşire să fie scrise în termeni<br />

de tranziţii. Exemplul 1:<br />

if ( X#Y==1 ) then S1 with Z=1 else S2;<br />

În exemplul de mai sus ieşirea Z va fi 1 în momentul în care expre<strong>si</strong>a este evaluată ca fiind<br />

adevărată (tranziţia făcându-se în starea S1). Expre<strong>si</strong>a care apare împreună cu WITH poate fi<br />

orice expre<strong>si</strong>e care va fi însă evaluată doar când condiţia anterioară este adevărată, ca în<br />

exemplul următor:<br />

if X&!Y then S3 with Z=X#Y else S2 with Z=Y;<br />

Instrucţiunea este utilă şi în descrierea ieşirilor de tip registru deoarece aceste ieşiri vor<br />

fi actualizate la următorul ciclu al semnalului de ceas. Este astfel po<strong>si</strong>bil să descriem că o<br />

anumită ieşire de tip registru va avea o valoare specifică după o anumită tranziţie, ca în<br />

următorul exemplu:<br />

state S1:<br />

if RST then S2 with { OUT1 : = 1;<br />

Error_Adrs : = ADDRESS; }<br />

else if (ADDRESS


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

Dimen<strong>si</strong>unea timp trebuie avută în vedere atunci când instrucţiunea WITH se foloseşte<br />

împreună cu ieşiri combinaţion<strong>ale</strong> sau a<strong>si</strong>ncrone (ca în cazul unei maşini Mealy). La o maşină<br />

Mealy ieşirile se modifică în momentul în care se modifică intrările, astfel că ieşirile vor fi<br />

stabile doar la sfârşitul unui timp de stare (înainte de tranziţia activă a semnalului de ceas).<br />

Din acest punct de vedere o maşină Moore (cu ieşiri <strong>si</strong>ncrone cu starea) este mai avantajoasă.<br />

Instrucţiunea Case :<br />

Sintaxa este următoarea:<br />

CASE expre<strong>si</strong>e : expre<strong>si</strong>e _stare;<br />

[ expre<strong>si</strong>e : expre<strong>si</strong>e _stare; ]<br />

:<br />

ENDCASE ;<br />

Unde expre<strong>si</strong>e este orice expre<strong>si</strong>e <strong>ABEL</strong> validă şi expre<strong>si</strong>e_stare descrie starea următoare<br />

(urmată opţional de instrucţiunea WITH). Exemplu:<br />

State S0:<br />

case ( A == 0) : S1;<br />

( A == 1) : S0;<br />

endcase;<br />

Instrucţiunea case este utilizată pentru a specifica o secvenţă de condiţii de tranziţie<br />

mutual exclu<strong>si</strong>ve, corespunzând următoarei stări. Condiţiile specificate trebuie să fie<br />

mutual exclu<strong>si</strong>ve (două tranziţii nu pot fi adevărate în acelaşi timp), în caz contrar rezultatele<br />

(tranzitia la starea următoare) sunt imprevizibile.<br />

d. Exten<strong>si</strong>i de tip .DOT<br />

Această categorie de facilităţi se pot utiliza pentru a descrie mai precis comportarea<br />

circuitului. Reprezintă o modalitate de a descrie semn<strong>ale</strong>le interne şi nodurile asociate cu un<br />

semnal primar. Sintaxa folo<strong>si</strong>tă este nume_semnal.exten<strong>si</strong>e. Numele exten<strong>si</strong>ei este<br />

independent de tipul de literă folo<strong>si</strong>t (mare sau mic).<br />

Unele din aceste exten<strong>si</strong>i sunt de uz general (numite şi independente de arhitectură sau<br />

pin-to-pin) putând fi folo<strong>si</strong>te pentru o mare varietate de circuite programabile (PAL, GAL,<br />

CPLD, etc). Altele pot fi folo<strong>si</strong>te doar pentru clase specifice de circuite, fiind numite şi<br />

dependente de arhitectură sau cu exten<strong>si</strong>i detailate. În general se pot utiliza ambele categorii<br />

de exten<strong>si</strong>i. O parte din aceste exten<strong>si</strong>i sunt descrise în tabelul următor.<br />

Exten<strong>si</strong>e<br />

Descriere<br />

Independente de arhitectură sau exten<strong>si</strong>i pin-to-pin (pin la pin)<br />

.ACLR<br />

Reset a<strong>si</strong>ncron<br />

.ASET<br />

Preset a<strong>si</strong>ncron<br />

.CLK<br />

Intrare de ceas într-un bistabil cu comutare pe front.<br />

.CLR<br />

Reset <strong>si</strong>ncron<br />

.COM<br />

Reacţie combinaţională provenind de la intrarea de date<br />

.FG<br />

Reacţie registru (bistabil)<br />

.OE<br />

Activare ieşire (de tip buffer tri-state)<br />

.PIN<br />

Reacţie pin<br />

.SET<br />

Preset <strong>si</strong>ncron<br />

Exten<strong>si</strong>i specifice circuitului (dependente de arhitectură)<br />

12


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

.D Intrare date într-un bistabil de tip D<br />

.J Intrare J într-un bistabil de tip<br />

.K Intrare K într-un bistabil de tip JK<br />

.S Intrare S într-un bistabil de tip SR<br />

.R Intrare R într-un bistabil de tip SR<br />

.T Intrare T într-un bistabil de tip T<br />

.Q Reacţie registru (bistabil)<br />

.AP<br />

Preset a<strong>si</strong>ncron<br />

.AR<br />

Reset a<strong>si</strong>ncron<br />

.SP<br />

Preset <strong>si</strong>ncron<br />

.SR<br />

Reset <strong>si</strong>ncron<br />

Figura următoare ilustrează câteva din aceste exten<strong>si</strong>i.<br />

(a) independent de arhitectură (b) dependent de arhitectura bistabilului (D sau T)<br />

Exemplul 1:<br />

[S7..S0].oe = ACTIV;<br />

unde semnalul ACTIV controlează bufferele tri-state <strong>ale</strong> celor 8 ieşiri S7..S0. Când ACTIV<br />

este în 1 ieşirile sunt active, în caz contrar(ACTIV=0) ieşirile respective sunt în starea de<br />

înaltă impedanţă (High-Z).<br />

Exemplul 2:<br />

Q.AR = reset;<br />

Y.AR = reset;<br />

[Z.ar, Y.ar] = reset;<br />

aici ieşirea bistabilelor Z <strong>si</strong> Y va fi adusă în 0 dacă intrarea reset este în 1.<br />

Pentru înţelegerea semnificaţiei acestui tip de exten<strong>si</strong>i vom exemplifica cu ajutorul<br />

unei ecuaţii care foloseşte operatorul de a<strong>si</strong>gnare tip registru(:=) şi unde Preset este o intrare :<br />

Q1 := !Q1 # Preset;<br />

Aici Q1 îşi va menţine starea (valoarea curentă) până în momentul în care elementul<br />

de memorie (circuitul bistabil) asociat cu acest semnal primeşte un semnal de ceas. Acesta<br />

ecuaţie reprezintă o descriere pin-to-pin a semnalului de ieşire Q1. Ea descrie comportarea<br />

semnalului în termeni de valori dorite pentru pinul de ieşire funcţie de intrare şi este complet<br />

independentă de arhitectura dispozitivului utilizat pentru implementare.<br />

Totuşi, în ecuaţia de mai sus există o condiţie ambiguă de reacţie pentru elementul de<br />

memorie. Semnalul Q1 apare în partea dreaptă a ecuaţiei, dar nu avem nici o informaţie de<br />

13


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

unde anume provine această reacţie: direct din logica combinaţională care formează intrarea<br />

bistabilului sau din pinul de ieşire asociat cu semnalul Q1. Nu există de asemenea nici o<br />

informaţie despre ce tip de bistabil se va utiliza (deşi algoritmii de <strong>si</strong>nteză pot , teoretic, plasa<br />

acesta ecuaţie în orice tip de bistabil po<strong>si</strong>bil). Ecuaţia poate fi mai concretă astfel:<br />

Q1.CLK = Clock; "Semnal de ceas provenind de la o intrare<br />

Q1 := !Q1.FB # Preset; " Reactie provenind din ie<strong>si</strong>rea bistabilului<br />

Acum setul de ecuaţii descrie complet circuitul, informaţia fiind suficientă pentru ca<br />

acest circuit să funcţioneze indiferent de dispozitivul în care va fi implementat. Reacţia<br />

provine direct din ieşirea negată a bistabilului , iar exten<strong>si</strong>a .CLK arată ca bistabilul este cu<br />

comutare pe front (şi nu unul de tip latch !).<br />

Spre deosebire de descrierea pin-to-pin acelaşi circuit poate fi descris şi într-o formă<br />

detailată astfel:<br />

Q1.CLK = Clock; "Semnal de ceas de la intrare<br />

Q1.D = !Q1.Q # Preset; "Se utilizeaza CBB de tip D<br />

În această formă în care este descrisă intrarea D a bistabilului şi specificată reacţia<br />

apar unele restricţii legate de arhitectura dispozitivului în care va fi implementat proiectul.<br />

Mai mult, ecuaţiile descriu doar intrarea şi reacţia ne existând nici o informaţie despre<br />

configuraţia pinului de ieşire. În consecinţă această descriere va funcţiona diferit când va fi<br />

implementată într-un dispozitiv cu ieşiri inversate (negate) sau într-unul cu ieşiri ne inversate.<br />

Pentru a menţine o comportare corectă a pinului , folo<strong>si</strong>nd descrierea detailată, este necesar<br />

un element suplimentar al limbajului: atributul `buffer` (sau complementul său, atributul<br />

`invert`).<br />

Atributul `buffer` ne a<strong>si</strong>gură ca în implementarea finală nu va exista inversare între ieşirea<br />

bistabilului şi pinul de ieşire asociat cu Q1. Astfel în secţiunea de declaraţii trebuie să apară:<br />

Q1 pin istype 'buffer';<br />

Observaţie Pentru un circuit CPLD, <strong>si</strong> nu numai, o modalitate de a înţelege diferenţa între<br />

descrierea pin-to-pin <strong>si</strong> descrierea detailată este de a vedea descrierea detailată ca o<br />

specificaţie a macrocelulei.<br />

În figură este prezentată o macrocelulă generică asociată semnalului q1.<br />

Se observă că există un nivel de<br />

inversare programabil între ie<strong>si</strong>rea bistabilului<br />

<strong>si</strong> pin, astfel că pinul q1 poate avea o<br />

comportare diferită de cea a ie<strong>si</strong>rii Q(q1.q).<br />

Ori de câte ori folo<strong>si</strong>m o descriere pin-<br />

to-pin in <strong>ABEL</strong>, va fi <strong>si</strong>ntetizată o „macrocelulă<br />

generică” <strong>si</strong>milară celei din figură, indiferent de<br />

tipul particular de macrocelulă existent în<br />

dispozitivul PLD.<br />

8. Vectori de test<br />

Vectorii de test sunt opţionali şi reprezintă o modalitate de a verifica funcţionarea<br />

co rectă a <strong>si</strong>stemului numeric proiectat. Ei sunt folo<strong>si</strong>ti pentru <strong>si</strong>mularea modelului intern al<br />

dispozitivului şi testarea funcţională a dispozitivului programat. Prin intermediul lor<br />

14


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

specificăm comportarea aşteptată a <strong>si</strong>stemului prin descrierea explicită a ieşirilor funcţie de<br />

intrări. Sintaxa este următoarea :<br />

Test_vectors<br />

(intrare [, intrare ].. -> ieşire [,ieşire] .. )<br />

[valori intrări -> valori ieşiri ; ]<br />

:<br />

Ca exemplu vom relua semisumatorul prezentat anterior pentru care vom avea:<br />

Test_vectors<br />

( [A, B] -> [Sum, Carry] )<br />

[ 0, 0 ] -> [0, 0];<br />

[ 0, 1 ] -> [1, 0];<br />

[ 1, 0 ] -> [1, 0];<br />

[ 1, 1 ] -> [1, 1];<br />

sau utilizând constantele <strong>numerice</strong> definite anterior:<br />

Test_vectors<br />

( [A, B] -> [Sum, Carry] )<br />

0 -> 0;<br />

1 -> 2;<br />

2 -> 2;<br />

3 -> 3;<br />

Este permisă folo<strong>si</strong>rea constantelor .X. , .C., .Z. ca şi a oricăror alte constante<br />

<strong>si</strong>mbolice definite anterior:<br />

test_vectors<br />

( [CLK, RESET, A, B ] -> [ Y0, Y1, Y3] )<br />

[.X., 1, .X.,.X.] -> [ S0, 0, 0];<br />

[.C., 0, 0, 1 ] -> [ S0, 0, 0];<br />

[.C., 1, 1, 0 ] -> [ S0, 0, 1];<br />

9. Instrucţiuni care descriu proprietăţi<br />

<strong>ABEL</strong> permite transmiterea (în momentul implementării) unor proprietăţi specifice<br />

dispozitivului PLD prin intermediul instrucţiunii property. Aceste proprietăţi sunt de fapt<br />

transmise programului care face implementarea (fitter). Pentru dispozitivele CPLD aceste<br />

proprietăţi includ: viteza de variaţie a ieşirilor (timpii de front -slew rate), , puterea<br />

consumată, valorile care vor fi preîncărcate în bistabili la power-up, utilizarea resurselor<br />

logice (plasare), optimizare sau protejarea la citire . Aceleaşi proprietăţi pot fi stabilite şi ca<br />

opţiuni <strong>ale</strong> diverselor componente <strong>ale</strong> mediului integrat de dezvoltare (compilator, fitter,<br />

programator), lucru care este de dorit deoarece oferă o mai mare independenţă de dispozitiv a<br />

proiectului .<br />

10. Diverse<br />

a. Declaraţii de tip active-low (în ”0”)<br />

Un semnal de tip activ în 0 este definit prin prefixarea cu operatorul ! :<br />

!OUT pin istype 'com' ;<br />

Când acest semnal va fi utilizat în descrierea logică, el va fi în mod automat complementat.<br />

Să con<strong>si</strong>derăm următorul exemplu:<br />

module EXEMPLU<br />

A, B pin ;<br />

!OUT pin istype 'com';<br />

15


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

equations<br />

OUT = A & !B # !A & B ;<br />

end<br />

În acest exemplu semnalul de ieşire OUT este XOR-ul între A <strong>si</strong> B , fiind în 1 (High)<br />

când doar una din intrări este în 1, altcumva fiind în 0. Deoarece semnalul de ieşire a fost însă<br />

declarat activ în 0 (!OUT), pinul de ieşire OUT va fi în 0 doar când numai una din intrări este<br />

în 1.<br />

Acelaşi rezultat se putea obţine inversând pe OUT la nivelul ecuaţiei şi declarându-l<br />

doar ca OUT (o descriere explicită pin la pin a semnalului activ în 0), aşa cum se vede în<br />

exemplul următor:<br />

module EXEMPLU<br />

A, B pin ;<br />

OUT pin istype 'com';<br />

equations<br />

!OUT = A & !B # !A & B ;<br />

end<br />

Declaraţiile de tip activ în 0 pot fi utilizate şi pentru mulţimi, ca în următorul exemplu:<br />

A = [A2,A1,A0]; " declaratie multime<br />

B = [B2,B1.B0]; " declaratie multime<br />

X = [X2,X1.X0]; " declaratie multime<br />

!X = A & !B # !A & B;<br />

Ultima ecuaţie este echiv<strong>ale</strong>ntă cu a scrie :<br />

!X0 = A0 & !B0 # !A0 & B0;<br />

!X1 = A1 & !B1 # !A1 & B1;<br />

!X2 = A2 & !B2 # !A2 & B2;<br />

b. Directive<br />

Utilizarea directivelor duce la anumite modificări <strong>ale</strong> fişierului sursă <strong>ABEL</strong>, în<br />

momentul prelucrarii acestora. Se pot include condiţional secţiuni de sursă <strong>ABEL</strong>, se pot<br />

include porţiuni din alte surse <strong>ABEL</strong>, se pot afişa diverse mesaje pe parcursul compilării, etc.<br />

Prin utilizarea şi de parametrii, unele din directive permit construirea şi manipularea unor<br />

structuri complexe.<br />

Sintaxa utilizată este: @directiva [parametrii]<br />

Un exemplu prezentat anterior este directiva @ALTERNATE. Alte directive mai utilizate ar<br />

fi: @CONST, @DCSET, @EXIT, @IF, @INCLUDE, @MESSAGE, @REPEAT,<br />

@RADIX, etc.<br />

Exemplu:<br />

@repeat 100 { [.C.]->[0,0] " insereaza de 100 de ori vectorul de test cuprins între acolade<br />

" in textul sursa, intr-o sectiune test_vectors<br />

}<br />

11. Exemple<br />

Familia de circuite destinată implementării acestor circuite este cea de circuite CPLD<br />

Xilinx(9500, 9500XL, 9500XV, Cool Runner) de<strong>si</strong> unele din ele pot fi implementate <strong>si</strong><br />

16


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

folo<strong>si</strong>nd circuite <strong>si</strong>mple PLD (PAL sau GAL). Compilatorul <strong>ABEL</strong> se presupune că este cel<br />

din mediul de programare Xilinx Webpack.<br />

În toate exemplele care urmează cuvintele cheie au fost reprezentate, pa cat po<strong>si</strong>bil, cu litere<br />

îngroşate(bold).<br />

11.1. Diverse circuite MSI din familiile logice standardizate<br />

11.1.1 Buffer tri-state, octal, bi-directional 74LS245(74HC245,etc)<br />

module SN74LS245<br />

title 'Octal Bidirectional Bus Transceiver'<br />

OE_, DIR pin;<br />

A1..A8 pin istype 'com';<br />

B1..B8 pin istype 'com';<br />

A = [A8..A1];<br />

B = [B8..B1];<br />

X =.X.; Z = .Z.;<br />

equations<br />

A = B;<br />

B = A;<br />

A.oe = !DIR & !OE_;<br />

B.oe = DIR & !OE_;<br />

test_vectors<br />

([OE_,DIR,A,B] -> [A,B])<br />

[1, 0, 0, 0] -> [Z,Z];<br />

[0,0,X,^h00] -> [^h00,X];<br />

[0,0,X,^h55] -> [^h55,X];<br />

[0,0,X,^hAA] -> [^hAA,X];<br />

[0,0,X,^hFF] -> [^hFF,X];<br />

[0,0,X,^hF0] -> [^hF0,X];<br />

[0,1,X,X] -> [Z,X];<br />

[0,1,^h00,X] -> [X,^h00];<br />

[0,1,^h55,X] -> [X,^h55];<br />

[0,1,^hAA,X] -> [X,^hAA];<br />

end<br />

17


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

11.1.2 Registru de deplasare serie, cu încărcare par<strong>ale</strong>lă, a<strong>si</strong>ncronă, 74LS165 (74HCT165,etc)<br />

Module SN74LS165<br />

Title 'Parallel-Load 8-bit Shift Register, async load'<br />

ShLd, ClkInh, Clk, SER pin;<br />

A,B,C,D,E,F,G,H<br />

pin;<br />

QA,QB,QC,QD,QE,QF,Q G node istype 'reg, buffer';<br />

QH<br />

pin istype 'reg, buffer';<br />

QH_<br />

pin istype 'com';<br />

Equations<br />

QH_ = !QH;<br />

[QH,QG,QF,QE,QD,QC,QB,QA] : = [QG,QF,QE,QD,QC,QB,QA,SER];<br />

[QH,QG,QF,QE,QD,QC,QB,QA].clk = Clk # ClkInh;<br />

when (!ShLd) then<br />

{ [QH,QG,QF,QE,QD,QC,QB,QA].ar = ![H,G,F,E,D,C,B,A];<br />

[QH,QG,QF,QE,QD,QC,QB,QA].ap = [H,G,F,E,D,C,B,A];<br />

}<br />

Test_Vectors<br />

([Clk,ClkInh,ShLd,SER,A,B,C,D,E,F,G,H]->[QA,QB,QC,QD,QE,QF,QG,QH,QH_])<br />

[.C., 1 , 0 , 0 ,1,0,1,0,1,0,1,1]->[ 1, 0, 1, 0, 1, 0, 1, 1, 0 ];<br />

[.C., 1 , 1 , 0 ,1,0,1,0,1,0,1,1]->[ 1, 0, 1, 0, 1, 0, 1, 1, 0 ];<br />

[.C., 0 , 1 , 0 ,0,0,0,0,0,0,0,0]->[ 0, 1, 0, 1, 0, 1, 0, 1, 0 ];<br />

[.C., 0 , 1 , 0 ,0,0,0,0,0,0,0,0]->[ 0, 0, 1, 0, 1, 0, 1, 0, 1 ];<br />

[.C., 0 , 1 , 1 ,0,0,0,0,0,0,0,0]->[ 1, 0, 0, 1, 0, 1, 0, 1, 0 ];<br />

[.C., 0 , 1 , 1 ,0,1,1,1,1,0,0,0]->[ 1, 1, 0, 0, 1, 0, 1, 0, 1 ];<br />

[.C., 0 , 1 , 0 ,0,1,1,1,1,1,0,0]->[ 0, 1, 1, 0, 0, 1, 0, 1, 0 ];<br />

[ 0 , 0 , 1 , 0 ,0,1,1,1,1,1,0,0]->[ 0, 1, 1, 0, 0, 1, 0, 1, 0 ];<br />

[ 0 , 1 , 1 , 0 ,0,1,1,1,1,1,0,0]->[ 0, 0, 1, 1, 0, 0, 1, 0, 1 ];<br />

[.C., 1 , 0 , 0 ,0,1,1,1,1,1,0,0]->[ 0, 1, 1, 1, 1, 1, 0, 0, 1 ];<br />

End<br />

18


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

11.1.3 Registru octal, de tip D-latch(transparent), cu ie<strong>si</strong>re tri-state 74LS373 (74HCT373,etc.)<br />

Registru octal, de tip D cu comutare pe front, cu ie<strong>si</strong>re tri-state 74LS374 (74HCT374, etc.)<br />

Module SN74LS373<br />

Title 'Octal D-type Transparent Latch'<br />

OC,C pin;<br />

D8..D1 pin;<br />

Q8..Q1 pin istype 'reg,buffer';<br />

Input = [D8..D1];<br />

Output = [Q8..Q1];<br />

Equations<br />

Output := Input;<br />

Output.lh = C; “asa se genereaza un latch transparent in high!!<br />

Output.oe = !OC;<br />

Test_Vectors<br />

([OC ,C ,Input] -> Output)<br />

[ 1 ,.X., .X. ] -> .Z.;<br />

[ 0 , 1 ,^h00 ] -> ^h00;<br />

[ 0 , 1 ,^h55 ] -> ^h55;<br />

[ 0 , 1 ,^hAA ] -> ^hAA;<br />

[ 0 , 1 ,^hFF ] -> ^hFF;<br />

[ 0 , 1 ,^hA5 ] -> ^hA5;<br />

[ 0 , 0 ,^hA5 ] -> ^hA5;<br />

[ 0 , 0 ,^h00 ] -> ^hA5;<br />

[ 0 , 1 ,^h22 ] -> ^h22;<br />

End<br />

Module SN74LS374<br />

Title 'Octal edge triggered D-type flip-flops'<br />

OC, CLK<br />

D8..D1<br />

Q8..Q1<br />

pin;<br />

pin;<br />

pin istype 'reg,buffer';<br />

19


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

Input = [D8..D1];<br />

Output = [Q8..Q1];<br />

.C.= c;<br />

Equations<br />

Output := Input;<br />

Output.clk = CLK;<br />

Output.oe = !OC;<br />

Test_Vectors<br />

([OC ,CLK ,Input] -> Output)<br />

[ 1 ,.X., .X. ] -> .Z.;<br />

[ 0 , c ,^h00 ] -> ^h00;<br />

[ 0 , c ,^h55 ] -> ^h55;<br />

[ 0 , c ,^hAA ] -> ^hAA;<br />

[ 0 , c ,^hFF ] -> ^hFF;<br />

[ 0 , c ,^hA5 ] -> ^hA5;<br />

[ 0 , 0 ,^hA5 ] -> ^hA5;<br />

[ 0 , 0 ,^h00 ] -> ^hA5;<br />

[ 0 , c ,^h22 ] -> ^h22;<br />

End<br />

11.2 Decodificator de adrese<br />

Exemplul prezintă una din aplicaţiile tipice <strong>ale</strong> logicii programabile şi anume<br />

realizarea unui decodificator pentru spaţiul de memorie al unui microprocesor de 8 biti.<br />

Pentru identificarea spaţiului specific de adresă se utilizează cei mai semnificativi biţi<br />

A15..A10, dintr-o magistrală de adrese de 16 biţi(A15..A0).<br />

Există 4 secţiuni de natură diferită în spaţiul de memorie de 64k, fiecare identificată<br />

printr-un semnal de ieşire al decodificatorului, şi anume:<br />

DRAM: 0000- DFFF H (RAM dinamic)<br />

I/O : E000 –E7FF H (porturi intrare /ieşire mapate în memorie)<br />

ROM2: F000-F7FF H (EPROM 2)<br />

ROM1 : F800-FFFF H (EPROM 1)<br />

Semn<strong>ale</strong>le de ieşire sunt active în 0 (se utilizează semnal definite explicit ca fiind<br />

active în 0). Utilizarea mulţimii Adresa şi a notaţiei pentru un domeniu (..) <strong>si</strong>mplifică<br />

substanţial programul.<br />

20


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

module dec_mem<br />

title ` decodificator memorie uP `<br />

A15..A0<br />

ROM1,IO,ROM2,DRAM<br />

H,L,X = 1, 0, .X. ;<br />

Adresa =[ A15..A0];<br />

pin;<br />

pin istype `com`;<br />

equations<br />

!DRAM = (Adresa = ^hE000) & (Adresa = ^hF000) & (Adresa = ^hF800);<br />

test_vectors<br />

(Adresa -> [ROM1,ROM2,IO,DRAM])<br />

^h0000 -> [ H,H, H, L ];<br />

^h4000 -> [ H, H, H, L ];<br />

^h8000 -> [ H, H, H, L ];<br />

^hC000 -> [ H, H, H, L ];<br />

^hE000 -> [ H, H, L, H ];<br />

^hE800 -> [ H, H, H, H ];<br />

^hF000 -> [ H, L, H, H ];<br />

^hF800 -> [ L, H, H, H ];<br />

end<br />

11.2 Multiplexor 12 : 4<br />

Exemplul prezintă de fapt un multiplexor 3 la 1, pentru 3 grupe de semn<strong>ale</strong>, fiecare<br />

grupă având 4 biţi: a3..a0, b3..b0 şi c3..c0. Se utilizează două semn<strong>ale</strong> de selecţie (s1,s0) ,<br />

combinaţia s1s0=11 (3) având acelaşi efect ca s1s0=10 (2). Ieşirea este reprezentată de<br />

y3..y0.<br />

Folo<strong>si</strong>rea instrucţiunii when .. then permite cea mai compactă descriere a unui multiplexor.<br />

Pentru toate grupele de semn<strong>ale</strong> relevante s-au<br />

utilizat mulţimi: select, a, b, c şi y.<br />

module Mux12to4<br />

title `multiplexor 12 la 4 `<br />

21


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

a0..a3 pin;<br />

b0..b3 pin;<br />

c0..c3 pin;<br />

s1,s0 pin; ``selectii<br />

y0..y3 pin; ``ie<strong>si</strong>ri<br />

H = [1,1,1,1];<br />

L = [0,0,0,0];<br />

X = .X. ;<br />

select = [s1,s0];<br />

y = [y3..y0];<br />

a = [a3..a0];<br />

b = [b3..b0];<br />

c = [c3..c0];<br />

equations<br />

when (select == 0) then y = a;<br />

when (select == 1) then y = b;<br />

when (select == 2) then y = c;<br />

when (select == 3) then y = c;<br />

test_vectors<br />

([ select, a, b, c] -> y)<br />

[ 0 , 1, X, X] -> 1;<br />

[ 0 ,10, H, L] -> 10;<br />

[ 0 , 5, H, L] -> 5;<br />

[ 1 , H, 3, H] -> 3;<br />

[ 1 ,10, 7, H] -> 7;<br />

[ 1 , L,15, L] -> 15;<br />

[ 2 , L, L, 8] -> 8;<br />

[ 2 , H, H, 9] -> 9;<br />

[ 2 , L, L, 1] -> 1;<br />

[ 3 , H, H, 0] -> 0;<br />

[ 3 , L, L, 9] -> 9;<br />

[ 3 , H, L, 0] -> 0;<br />

end<br />

11.3 Comparator de 4 biţi<br />

``select = 0<br />

``select = 1<br />

``select = 2<br />

``select = 3<br />

a->y<br />

b->y<br />

c->y<br />

c->y<br />

În acest exemplu este prezentat un comparator de 4 biţi cu două intrări generice de 4<br />

biţi A (A3..A0) şi B (B3..B0), oferind 4 ieşiri active în 1 (NE- diferit , EQ- egal, GT- mai<br />

m are şi LT- mai mic) .<br />

Temă Să se completeze corespunzător vectorii de test<br />

care să permită verificarea din punct de vedere<br />

funcţional a tuturor celor 4 ieşiri. Pentru vectorii de test<br />

se pot defini şi utiliza constante corespunzătoare, care să<br />

uşureze scrierea.<br />

22


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

module comp4<br />

title ` comparator 4 biti `<br />

A3..A0 pin;<br />

A = [A3..A0];<br />

B3..B0 pin;<br />

B = [B3..B0];<br />

NE,EQ,G T,LT pin istype `com`;<br />

``NE –diferit<br />

``EQ- egal<br />

``GT- mai mare<br />

``LT – mai mic<br />

equations<br />

EQ = (A = = B);<br />

NE = !(A = = B);<br />

GT = (A > B);<br />

LT = !((A > B) # ( A = = B));<br />

Test_vectors<br />

`` aici vectorii de test !!!<br />

end<br />

11.4 Decodificator pentru un afişor LED cu 7 segmente<br />

Astfel de decodificatoare există şi în diverse familii de circuite <strong>numerice</strong> (ex. 7446,<br />

7447, 4053, etc.) dar o implementare PLD oferă întotdeauna o flexibilitate suplimentară. El<br />

stabileşte o corespondenţă între mărimea de intrare de 4 biţi interpretată ca un cod BCD de 4<br />

biţi (cifre între 0 şi 9) <strong>si</strong> un <strong>si</strong>stem de afişare alfanumeric organizat sub forma a 7 segmente.<br />

Prin aprinderea diferită a segmentelor este po<strong>si</strong>bilă afişarea cel puţin a cifrelor de la 0 la 9.<br />

Cele 7 segmente sunt notate de la a la g poziţia lor fiind standard pentru toate afişoarele (vezi<br />

a<strong>si</strong>gnare în comentariu şi figura).<br />

Decodificatorul este realizat pentru un afişor cu anod comun, aprinderea segmentului<br />

(ON) presupunând că ieşirea respectivă este adusă în 0 logic. Pentru afişoarele cu catod<br />

comun ieşirea este activă în 1 <strong>si</strong> este suficient să modificăm doar definirea constantelor ON <strong>si</strong><br />

OFF. Mai există şi o intrare de activare Ena, activă în 0 logic. Când intrarea este inactivă (Ena<br />

23


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

=1 ), ieşirile sunt aduse în starea de înaltă impedanţă (High -Z) toate segmentele fiind stinse,<br />

indiferent de starea intrărilor.<br />

module bcd7<br />

title `dec afisor 7segmente `<br />

`` identificare segmente<br />

`` -a-<br />

`` f| |b<br />

`` -g-<br />

`` e| | c<br />

`` -d-<br />

D3,D2, D1,D0,Ena pin;<br />

a,b,c,d,e,f,g pin istype `com`;<br />

bcd = [D3,D2,D1,D0];<br />

led = [a,b,c,d,e,f,g];<br />

ON,OFF = 0,1; ``LED-uri cu anod comun<br />

L,H,X,Z = 0,1,.X.,.Z.;<br />

equations<br />

led.oe = !Ena;<br />

truth_table<br />

(bcd -> [ a, b, c, d, e, f, g ])<br />

0 -> [ ON, ON, ON, ON, ON, ON, OFF];<br />

1 -> [ OFF,ON, ON, OFF,OFF,OFF,OFF];<br />

2 -> [ ON, ON, OFF,ON, ON, OFF,ON ];<br />

3 -> [ ON, ON, ON, ON, OFF,OFF,ON ];<br />

4 -> [ OFF,ON, ON, OFF,OFF,ON, ON ];<br />

5 -> [ ON, OFF,ON, ON, OFF,ON, ON ];<br />

6 -> [ ON, OFF,ON, ON, ON, ON, ON ];<br />

7 -> [ ON, ON, ON, OFF,OFF,OFF,OFF];<br />

8 -> [ ON, ON, ON, ON, ON, ON, ON ];<br />

9 -> [ ON, ON, ON, ON, OFF,ON, ON ];<br />

end<br />

11.5 Numărător universal de 4 biţi<br />

Următorul exemplu ilustrează implementarea unui numărător binar <strong>si</strong>ncron de 4 biţi.<br />

Numărătorul este bidirecţional, sensul de numărare fiind controlat prin intermediul intrării<br />

u_d . De asemenea numărătorul poate fi încărcat par<strong>ale</strong>l, intrarea de încărcare fiind ld (activă<br />

în 1) şi intrările corespunzătoare de date fiind d3..d0. Este po<strong>si</strong>bilă şi oprirea/pornirea<br />

numărării cu ajutorul intrării cnten (1 numără, 0 - oprit). Ieşirile sunt q3 ..q0. Există şi o<br />

intrare a<strong>si</strong>ncronă de aducere în 0(reset) numită rst.<br />

Descrierea funcţionării se face cu ajutorul ecuaţiilor şi nu al diagramelor de stare, fiind mult<br />

mai compactă în acest caz.<br />

Există 4 moduri de operare <strong>ale</strong> numărătorului:<br />

- încărcare par<strong>ale</strong>lă (<strong>si</strong>ncronă) a datelor de pe intrările de date (LOAD)<br />

- numărare oprită (HOLD)<br />

- numără în sus (DOWN)<br />

- numără în jos (UP)<br />

24


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

Modul încărcare este prioritar, activarea intrării ld (în 1) făcând ca ieşirile q să ia<br />

valoarea intrărilor d , la următorul semnal de ceas (încărcare <strong>si</strong>ncronă).<br />

Modul numărare oprită este al doilea ca prioritate; pentru a număra este necesar ca<br />

in trarea cnten=1. În momentul în care cnten = 0 (dacă şi ld=0) numărarea se opreşte, ieşirile q<br />

păstrându-şi valoarea avută în acel moment.<br />

Numărătorul este resetat (q3..q0 = 0) în momentul în care intrarea rst =1 (a<strong>si</strong>ncron,<br />

independent de evolutia intrarii de ceas) .<br />

A<strong>si</strong>gnările pentru mulţimea count sunt a<strong>si</strong>gnări de tip registru (: =), toţi bistabilii au acelaşi<br />

semnal de ceas şi respectiv acelaşi semnal de reset a<strong>si</strong>ncron (se utilizează exten<strong>si</strong>ile .DOT de<br />

tip .clk şi .ar).<br />

module unicnt4<br />

title ` numarator binar de 4 biti bidirectional cu incarcare par<strong>ale</strong>la `;<br />

"constante<br />

X = .X.;<br />

"Intrari<br />

d3..d0 pin; "intrari date 4-biti<br />

clk pin; "intrare ceas<br />

rst pin; "reset a<strong>si</strong>ncron<br />

cnten<br />

ld<br />

pin; "activare numarare<br />

pin; "incarca date par<strong>ale</strong>l<br />

u_d pin; "Up/Down sens numarare – 1 =up(in sus), 0- down (in jos)<br />

"Ie<strong>si</strong>ri<br />

q3..q0 pin istype `reg`; "bistabili <strong>si</strong> ie<strong>si</strong>ri numarator<br />

"definire multimi<br />

data = [d3..d0];<br />

count = [q3..q0];<br />

"date intrare<br />

"numarator<br />

"definirea modurilor de lucru<br />

MODE = [cnten, ld, u_d] ; "Modul de lucru este definit<br />

LOAD = (MODE = = [ X , 1, X ]);<br />

HOLD = (MODE = = [ 0 , 0, X ]);<br />

"ca o multime de valori <strong>ale</strong><br />

" intrarilor de control.<br />

UP = (MODE = = [ 1 , 0, 1 ]); " Numele <strong>si</strong>mbolic este definit ca multimea MODE<br />

DOWN = ( MODE = = [ 1 , 0, 0 ] ); " careia i se a<strong>si</strong>gneaza o valoare<br />

equations<br />

when LOAD then count := data<br />

"incarca date par<strong>ale</strong>l<br />

else when UP then count := count + 1 "numara in sus<br />

else when DOWN then count := count - 1 " numara in jos<br />

else when HOLD then count := count;<br />

count.clk = clk;<br />

"opreste numararea<br />

"semnalul de ceas pentru toti bistabilii<br />

25


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

count.ar = rst;<br />

"<strong>si</strong> intrarea de reset a<strong>si</strong>ncrona<br />

test_vectors<br />

"aici vectori de test<br />

end<br />

11.6 Numărător zecimal (decimal) <strong>si</strong>ncron, bidirectional, cu semnal de reset <strong>si</strong>ncron<br />

Număratorul de patru biti va fi descris ca o ma<strong>si</strong>nă secventială cu 10 stări: S0 la S9.<br />

Semnalul de ceas este Clk, sensul de numărare este stabilit cu intrarea Dir (Dir=”1” numără in<br />

sus, iar cu Dir=”0” numără in jos), iar Clr este semnalul de reset activ in ”1”.<br />

Module counter10<br />

Title ’Numarator zecimal bidirectional cu reset <strong>si</strong>ncron’<br />

"intrari<br />

Clk pin; "semnalul de ceas<br />

Clr,Dir pin; " reset <strong>si</strong> directie de numarare Dir=1 up /Dir=0 down<br />

"ie<strong>si</strong>ri<br />

Q3..Q0 pin istype ’reg’; "registre <strong>si</strong> ie<strong>si</strong>ri numarator<br />

" Definim <strong>si</strong> a<strong>si</strong>gnam starile numaratorului<br />

S0 = ^b0000; S4 = ^b0100; S8 = ^b1000;<br />

S1 = ^b0001; S5 = ^b0101; S9 = ^b1001;<br />

S2 = ^b0010; S6 = ^b0110;<br />

S3 = ^b0011; S7 = ^b0111;<br />

"Numaratorul propriu-zis ca vector<br />

CNT = [Q3,Q2,Q1,Q0];<br />

Equations<br />

"ceasul pentru toate bistabilele<br />

CNT.CLK = Clk;<br />

State_diagram [Q3,Q2,Q1,Q0]<br />

State S0: if Clr then S0 "reset<br />

else if Dir then S1 " in sus<br />

else S9; "sau in jos<br />

State S1: if Clr then S0<br />

else if Dir then S2<br />

else S0;<br />

State S2: if Clr then S0<br />

else if Dir then S3<br />

else S1;<br />

State S3: if Clr then S0<br />

else if Dir then S4<br />

else S2;<br />

State S4: if Clr then S0<br />

26


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

else if Dir then S5<br />

else S3;<br />

State S5: if Clr then S0<br />

else if Dir then S6<br />

else S4;<br />

State S6: if Clr then S0<br />

else if Dir then S7<br />

else S5;<br />

State S7: if Clr then S0<br />

else if Dir then S8<br />

else S6;<br />

State S8: if Clr then S0<br />

else if Dir then S9<br />

else S7;<br />

State S9: if Clr then S0<br />

else if Dir then S0<br />

else S8;<br />

End counter10<br />

11.7 Maşină secvenţială <strong>si</strong>ncronă<br />

Maşina <strong>si</strong>ncronă are trei stări: A,B <strong>si</strong> C. Mai are trei intrări: start, hold <strong>si</strong> reset <strong>si</strong> trei<br />

ie<strong>si</strong>ri: halt(<strong>si</strong>ncronă-ca o ma<strong>si</strong>nă Moore), in_B <strong>si</strong> in_C (a<strong>si</strong>ncrone-ca o ma<strong>si</strong>nă Mealy). Mai<br />

există, evident, <strong>si</strong> o intrare de ceas(tact) clock precum şi o intrare de activare enab, pentru<br />

ieşiri, care sunt de tip tri-state.<br />

Următoarea diagramă de stare descrie tranziţiile de stare şi ie<strong>si</strong>rile maşinii. Maşina<br />

porneşte din starea A <strong>si</strong> rămane acolo până când intrarea start devine 1. Trece apoi în starea<br />

B, în starea C şi înapoi în starea A.<br />

27


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

Rămane în starea A pană cand start devine din nou activ în 1. Daca intrarea reset este<br />

activă, în 1, maşina se intoarce în starea A la următorul semnal de ceas(tact).<br />

Dacă acest reset apare în starea B, o ieşire <strong>si</strong>ncronă halt se activează (în 1) şi rămane activă<br />

până când start devine activ din nou.<br />

Pe durata stărilor B <strong>si</strong> C, ieşirile a<strong>si</strong>ncrone in_B <strong>si</strong> in_C trec în 1 pentru a indica starea<br />

curentă. Activarea intrării hold (in 1) face ca maşina să rămână în starea B sau C până când<br />

hold devine inactivă sau se activează reset.<br />

Valoarea vectorilor de stare este <strong>ale</strong>asă astfel ca la pornire (power-up), când toate<br />

registrele(bistabilele) sunt iniţializate implicit în 0, să se plece dintr-o stare cunoscută,<br />

starea A (registrul de stare este 00)!!.<br />

module Ma<strong>si</strong>na de paine<br />

title 'Exemplu de ma<strong>si</strong>na secventiala';<br />

q1,q0<br />

pin istype 'reg,buffer';<br />

clock,enab,start,hold,reset pin;<br />

halt<br />

pin istype 'reg, buffer ';<br />

in_B,in_C<br />

pin;<br />

''definim registrul de stare, avem nevoie de 2 registre(bistabile)<br />

sreg = [q1,q0];<br />

''Definim <strong>si</strong> valorile starilor ...<br />

A = 0; B = 1; C = 2;<br />

equations<br />

[q1, q0, halt].clk = clock;<br />

[q1, q0, halt].oe = !enab;<br />

state_diagram sreg;<br />

State A: ''Sta in starea A pana cand start devine activ.<br />

in_B = 0;<br />

in_C = 0;<br />

IF (start & !reset) THEN B WITH halt : = 0;<br />

ELSE A WITH halt : = halt;<br />

State B: ''trece in starea C daca reset nu este activ<br />

in_B = 1; ''sau hold este activ; halt devine activ daca avem reset<br />

in_C = 0;<br />

IF (reset) THEN A WITH halt : = 1;<br />

ELSE IF (hold) THEN B WITH halt : = 0;<br />

ELSE C WITH halt : = 0; ''<br />

State C: ''Se intoarce in A daca halt nu este activ.<br />

in_B = 0; ''Reset-ul este prioritar fata de hold.<br />

in_C = 1;<br />

IF (hold & !reset) THEN C WITH halt : = 0;<br />

ELSE A WITH halt : = 0;<br />

''aici vectorii de test...<br />

end<br />

28


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

11.8 Proiectarea ierarhică<br />

Proiectarea ierarhică reprezintă o modalitate de a dezvolta aplicaţii mai complexe ca<br />

un tot unitar. Mai reprezintă <strong>si</strong> un mod util de organiza <strong>si</strong> structura un proiect <strong>ABEL</strong>-HDL.<br />

Vor exista mai multe module, din care unul pe nivelul superior (numit <strong>si</strong> nivel top) <strong>si</strong><br />

cel puţin unul pe un nivel inferior. La rândul lor modulele de pe nivelele inferioare pot<br />

instanţia (apela) alte module aflate pe nivele inferioare faţă de ele.<br />

In modulul de pe nivelul superior interfaţa (intrări->ie<strong>si</strong>ri) este definită cu ajutorul<br />

cuvântului cheie INTERFACE, iar identificarea instanţei modulului este făcută cu<br />

FUNCTIONAL_BLOCK (pot exista mai multe instanţieri <strong>ale</strong> aceluia<strong>si</strong> modul).<br />

Vom prezenta un exemplu elementar, pur didactic, in care vom implementa, la nivelul<br />

top, o poartă NAND cu ajutorul unui modul AND definit pe un nivel inferior.<br />

Sursa pentru modulul top este următoarea:<br />

MODULE NAND1<br />

TITLE 'Poarta NAND ierarhica –instantiaza o poarta AND.'<br />

I1, I2, O1 pin;<br />

and1 INTERFACE(IN1, IN2 -> OUT1);<br />

my_and functional_block and1;<br />

EQUATIONS<br />

my_and.IN1 = I1;<br />

my_and.IN2 = I2;<br />

O1 = ! my_and.OUT1;<br />

END<br />

Modulul de pe nivelul inferior este descris de sursa următoare:<br />

MODULE and1<br />

TITLE 'Poarta and1 care va fi instantiata de NAND1'<br />

IN1, IN2, OUT1 pin;<br />

EQUATIONS<br />

OUT1 = IN1 & IN2;<br />

END<br />

Numele pinilor (<strong>si</strong>mbolul a<strong>si</strong>gnat) trebuie să fie acela<strong>si</strong> (atenţie la tipul de litera!) cu<br />

cel care apare in declaraţia interface din modulul top. Deasemenea numele modulului<br />

instanţiat (la noi and1) declarat in modulul top trebuie să fie acela<strong>si</strong> cu cel care apare in<br />

declaraţia MODULE din modulul de pe nivel inferior.<br />

Este bine ca mai intâi să fie create sursele pentru modulele inferioare <strong>si</strong> după aceea<br />

sursele pentru modulele de pe nivelele superioare.<br />

11.9 Alte descrieri <strong>ABEL</strong> utile, orientate pe arhitectura CPLD Xilinx<br />

11.9.1 Crearea semn<strong>ale</strong>lor bi-direction<strong>ale</strong><br />

Exemplul este util pentru implementarea unor registre de stare, la care biţii individuali<br />

din componenţa acestora pot fi scrişi sau citiţi, prin intermediul datelor vehiculate pe o<br />

magistrală tri-state. Avem doi bistabili (doua registre) out0 <strong>si</strong> out1. Semn<strong>ale</strong>le de ceas<br />

strobe0 <strong>si</strong> strobe1 precum şi cel de activare a bufferului de ie<strong>si</strong>re read se presupune ca au fost<br />

definite anterior.<br />

Data de pe pinul de pe intrare poate fi scrisă in registrul out0 astfel:<br />

29


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

out0:= out0.pin;<br />

out0.clk = strobe0;<br />

`` data de pe pin in registru<br />

`` pe frontul crescator al lui strobe0<br />

Data din out0 este citită înapoi pe pin(pe magistrală) astfel:<br />

out0.oe = read; `` read este activ in 1<br />

În out1 se va scrie un 1, pe frontul crescător al lui strobe1, numai cand starea lui out0<br />

<strong>si</strong> cea pinului este diferită (un XOR):<br />

out1 : = out0.q $ out0.pin;<br />

out1.clk = strobe1;<br />

11.9.2 Multiplexarea a două sau mai multe semn<strong>ale</strong> de ie<strong>si</strong>re<br />

O modalitate <strong>si</strong>mplă este de lega impreună pinii de ie<strong>si</strong>re corespunzători celor două<br />

semn<strong>ale</strong> multiplexate (dout1, dout2) <strong>si</strong> de a utiliza bufferele de ie<strong>si</strong>re tri-state(comandate cu<br />

select <strong>si</strong> !select). La un moment dat nu trebuie să fie activ (în 1) decât un <strong>si</strong>ngur semnal de<br />

control al bufferului, deci numai o ie<strong>si</strong>re poate fi activă, restul fiind in tri-state. Acesta este<br />

<strong>si</strong> motivul pentru care semn<strong>ale</strong>le de comandă pentru aceste buffere, in exemplul nostru, sunt<br />

complementare.<br />

Legate impreuna in<br />

afara circuitului<br />

dout0 : = data0;<br />

dout1 : = data1;<br />

dout0.oe = select;<br />

dout1.oe = !select;<br />

30


<strong>Circuite</strong> <strong>integrate</strong> <strong>numerice</strong> – <strong>Limbajul</strong> <strong>ABEL</strong> <strong>si</strong> <strong>aplicatii</strong> <strong>ale</strong> circuitelor CPLD<br />

Se poate utiliza multiplexorul dintr-o altă macrocelulă şi data să fie adusă la ieşire<br />

printr-un <strong>si</strong>ngur pin. Dezavantajul este că se foloseste o macrocelulă pentru fiecare bit al<br />

multiplexorului. În exemplul de mai jos s0 = = select.<br />

dout<br />

= data0 & select<br />

# data1 & !select;<br />

Se mai poate utiliza şi registrul(bistabilul) din macrocelula respectivă pentru a scurta<br />

timpul de propagare de la intrarea de ceas la ieşire (t CO ).<br />

dout := data0 & select<br />

# data1 & !select;<br />

Observatie<br />

La toate circuitele CPLD <strong>ale</strong> firmei Xilinx nu există po<strong>si</strong>bilitatea implementării<br />

unei magistr<strong>ale</strong> interne de tip tri-state.<br />

31

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!