Scopul acestui laborator este proiectarea unui sumator Carry-lookahead, care are performanțe mai bune decât sumatorul Ripple-Carry studiat în laboratorul trecut.
În viața reală noi lucrăm cu numere reprezentabile pe mai mulți biți. Totuși, sumatoarele de tip Half-Adder și Full-Adder pot aduca cel mult un bit. Pentru depășirea acestei limitări, laboratorul trecut am implementat un circuit capabil să facă suma numerelor reprezentate pe mai mulți biți.
Cel mai simplu circuit este sumatorul ripple-carry care folosind N sumatoare full-adder poate însuma numere pe N biți.
Conectarea lor, prezentată în figura de mai sus, este una foarte simplă: ieșirea Cout a modulului de rang i va fi conectată la intrarea Cin a modulului de rang i+1.
Implementarea acestuia este facilă, însă performanța acestuia este scăzută. De ce? Deoarece transportul de intrare pentru fiecare sumator complet este dependent de semnalul carry-out din full-adder-ul anterior. Prin structura sa internă: modulul de rang i trebuie să aştepte modulul de rang i-1 sa îşi termine execuția pentru a afla cât este Cin_i.
Cum putem implementa un circuit mai rapid? Eliminând dependența între rang-uri în ceea ce privește bitul de carry. Pentru început aflăm expresia în logică booleană pornind de la tabelul de adevăr al bitului de carry C1.
A0 | B0 | C0 | C1 |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 0 | 1 | 0 |
0 | 1 | 0 | 0 |
0 | 1 | 1 | 1 |
1 | 0 | 0 | 0 |
1 | 0 | 1 | 1 |
1 | 1 | 0 | 1 |
1 | 1 | 1 | 1 |
Dacă generalizăm formula, pentru i = 0:
Prin urmare, pentru fiecare modul de full-adder, am putea calcula bitul carry de intrare cu cost constant egal cu 1, fără să mai așteptăm propagarea acestuia prin toate celelalte full-adder-e de rang mai mic.
Pentru a reduce timpul necesar unui calcul, proiectanții folosesc sumatorul carry-lookahead.
În sumatorul cu transport anticipat, fiecare adunare pe bit elimină dependenţa de semnalul carry-out anterior şi impune în schimb utilizarea valorilor celor doi operanzi de intrare. El functioneaza prin generarea a două noi semnale (P si G) pentru fiecare rang binar în funcție de starea intrărilor.
Deci pentru suma a două numere A și B, dacă bitul n din A, împreună cu bitul n din B generează un semnal G, înseamnă că acești biți generează un bit de carry, iar în cazul unui semnal P, bitul de carry de la n-1 (dacă există) este propagat de către biții n pe poziția n+1.
Pornind de la un sumator ripple-carry, unde pentru fiecare full-adder (i), semnalul carry-out, c(i+1), este setat la 1 dacă una dintre următoarele condiții este adevărată:
sau
am observat că putem calcula semnalul carry-out folosind doar semnalele rangului curent:
Pentru un sumator carry-lookahead definim Gi(Ai, Bi) ca fiind predicatul logic care este adevărat atunci când Ai * Bi generează carry (primul caz)
Si Pi(Ai, Bi) ca fiind predicatul logic care este adevărat atunci cand Ai + Bi propagă carry (al doilea caz)
Uneori (dar nu și in laboratorul de față) se folosește și o altă definiție a propagării. Conform acesteia, Ai + Bi va propaga dacă există carry anterior, dar nu va propaga dacă nu există acest carry. Astfel, propagagarea o putem exprima:
Desi OR(prima variantă) e mai rapid decât XOR(a doua variantă), pentru un sumator carry-lookahead pe mai multe nivele e mai avantajos să folosim P'i(Ai, Bi).
Rescriind ecuația (1) cu Pi si Gi, rezultă:
Pentru o comparație mai tangibilă a întârzierilor celor 2 sumatoare (ripple-carry și carry-lookahead), puteți folosi aceste 2 simulatoare cu întârziere setabilă pentru porțile folosite (se pot observa întârzieri semnificative ale lui ripple-carry față de carry-lookahead pentru numere reprezentabile pe 32 de biți):
Pentru fiecare rang dintr-o secvență binară, sumatorul va determina dacă perechea de biți care trebuie adunată poate genera sau propaga carry. Acest lucru permite circuitului sa “pre-proceseze” cei doi termeni ai adunării pentru a determina transportul înainte de a efectua adunarea propriu-zisă. Apoi, când aceasta are loc, nu va exista nici o întârziere de propagare a carry-ului, ca în cazul unui Ripple Adder. Mai jos aveți un exemplu de calcul al termenilor de propagare și, generare pentru un sumator de 2 biți:
Înlocuind c1 în expresia lui c2, vom obtine urmatoarele ecuații:
Similar, putem generaliza pentru un sumator de 4 biți:
Putem observa că pentru un sumator carry-lookahead cu 4 biți (cel de mai sus), propagarea semnalului de carry până la ieșirea ultimului nivel de adunare necesită trecerea prin 3 porți logice, pe când un sumator ripple-carry necesită trecerea prin 6 porți.
- Sumatorul Ripple-Carry calculeaza valoarea unui bit i din adunare doar dupa ce au avut loc calculele pentru toti bitii de la 0 la i - 1, deci calculul pentru fiecare bit are loc secvential.
- Sumatorul Carry-Lookahead calculeaza valoarea unui bit i independent de calculele pentru ceilalti biti (in paralel) folosind formulele:
Pentru fiecare dintre exerciții va trebui să faceți atât implementarea cât și simularea cu seturi de date relevante. (minim 3 cazuri de test)
Task 01 (3p) Implementați un sumator carry-lookahead pe 4 biți.
Task 02 (1p) Implementați un scăzător carry-lookahead pe 4 biți, pornind de la punctul precedent.
Task 03 (2p) Implementați un sumator pe 16 de biți folosind modulul carry-lookahead deja implementat și logica sumatorului ripple-carry.
Task 04 (4p) Implementati un sumator/scazator carry-lookahead pe 4 biti cu ajutorul placii de laborator. Interactiunea cu modulul se va face astfel: