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 aduna 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 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 |
Scriem expresia logică corespunzătoare liniilor din tabel pentru care C1 are valoarea 1:
Dacă generalizăm formula:
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, 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)
Rescriind ecuația (1) cu Pi si Gi, rezultă:
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 calculează valoarea unui bit i din adunare doar după ce au avut loc calculele pentru toți biții de la 0 la i - 1, deci calculul pentru fiecare bit are loc secvențial.
- Sumatorul Carry-Lookahead calculează valoarea unui bit i independent de calculele pentru ceilalti biți (în 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) Implementați un sumator/scăzător carry-lookahead pe 4 biti cu ajutorul plăcii de laborator. Interacțiunea cu modulul se va face astfel: