Scopul acestui laborator este proiectarea unui sumator Carry-lookahead, care are performanțe mai bune decât sumatorul Ripple-Carry studiat în laboratorul trecut. De asemenea, vom vedea ce este registrul SREG din cadrul unui UAL.
Î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.
În urma calculelor făcute de UAL pot apărea anumite situații, precum overflow la adunare/scădere, care este util să fie semnalate în cadrul sistemului. În acest scop procesoarele au un registru de status în care prin setarea unui bit anume este semnalat un anumit eveniment. Cel mai adesea, informațiile din registrul de status (sau Status Register) sunt folosite pentru a modifica fluxul de execuție al programului pe baza instrucțiunilor condiționale.
Spre exemplu, procesorul calculează A + B și dorește să sară la o anumită etichetă dacă rezultatul este 0. UAL va calcula rezultatul lui A + B și va seta bitul Z (Zero) din Status Register dacă rezultatul adunării este 0. Instrucțiunea de salt JZ (jump zero) verifică bitul Z din Status Register și sare la eticheta data dacă bitul este 1, altfel execută instrucțiunea imediat următoare.
În cadrul x86 Status Register se numește FLAGS și are 16 biți. El are o extensie de 32 de biți numită EFLAGS. Biții din cele două registre au următoarea semnificație:
Un exemplu mai simplu este registrul de status pentru Atmega324 (AVR în general), care se numește SREG și are 8 biți:
În ambele registre de status prezentate mai sus se regăsesc o serie de biți de interes pentru UAL:
CF
sau C
(carry flag) este setat pe 1 când operația executată pe UAL are carry. ZF
sau Z
(zero flag) este setat pe 1 când rezultatul operației de pe UAL este 0. N
(negative) este setat pe 1 când rezultatul operației de pe UAL este un număr negativ (bitul de semn al rezultatului este 1). OF
sau V
(overflow flag) este setat pe 1 când operația executată pe UAL produce overflow, mai exact există 2 cazuri: ZF
/Z
- Zero, CF
/C
- Carry, N
- Negative, OF
/V
- OverflowPentru 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 00 (4p) Implementați un sumator carry-lookahead pe 4 biți.
Task 01 (2p) Implementați un scăzător carry-lookahead pe 4 biți, pornind de la punctul precedent.
Task 02 (4p) Implementați un sumator pe 16 de biți folosind modulul carry-lookahead deja implementat și logica sumatorului ripple-carry.
Task 03 (bonus - 2p) 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: