Circuite integrate numerice â Limbajul ABEL si aplicatii ale ...
Circuite integrate numerice â Limbajul ABEL si aplicatii ale ...
Circuite integrate numerice â Limbajul ABEL si aplicatii ale ...
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