Laboratorul 07 - Sumatorul Carry-Lookahead

Obiective

Scopul acestui laborator este proiectarea unui sumator Carry-lookahead, care are performanțe mai bune decât sumatorul Ripple-Carry studiat în laboratorul trecut.

1. Recapitulare

a. Sumatoare multi-bit

Î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.

Sumatorul Ripple-Carry

Cel mai simplu circuit este sumatorul ripple-carry care folosind N sumatoare full-adder poate însuma numere pe N biți.

 Ripple-carry pe 4 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.

Limitări

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.

Îmbunătățiri

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
  • C1 = A0 * B0 * C0 + A0 * B0 * ~C0 + ~A0 * B0 * C0 + A0 * ~B0 * C0
  • C1 = A0 * B0 * (C0 + ~C0) + C0 * (~A0 * B0 + A0 * ~B0)
  • C1 = A0 * B0 + C0 * (A0 ⊕ B0)

Dacă generalizăm formula, pentru i = 0:

  • Ci+1 = Ai * Bi + Ci * (Ai ⊕ Bi)

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.

  • Cout = Generează_biții_carry? SAU Propagă_bitul_de_carry_de_la_rangul_inferior_dacă_nu_e_generat?

2. Prezentare generală

Pentru a reduce timpul necesar unui calcul, proiectanții folosesc sumatorul carry-lookahead.

 Sumator Carry-lookahead pe 4 biti

Î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.

  • G - reprezintă un semnal de generare a unui bit de carry.
  • P - reprezintă un semnal de propagare a unui bit de carry.

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ă:

  • Ai = 1 AND Bi = 1

sau

  • (Ai = 1 OR Bi = 1) AND ci = 1

am observat că putem calcula semnalul carry-out folosind doar semnalele rangului curent:

  • ci+1 = Ai & Bi | ci & (Ai | Bi) (1)

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)

  • Gi(Ai, Bi) = Ai & Bi

Si Pi(Ai, Bi) ca fiind predicatul logic care este adevărat atunci cand Ai + Bi propagă carry (al doilea caz)

  • Pi(Ai, Bi) = Ai | Bi

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:

  • P'i(Ai, Bi) = Ai ⊕ Bi

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ă:

  • ci+1 = Gi | Pi & ci

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):

3. Detalii de implementare

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:

  • c1 = G0 | P0 & c0
  • c2 = G1 | P1 & c1

Înlocuind c1 în expresia lui c2, vom obtine urmatoarele ecuații:

  • c1 = G0 | P0 & c0
  • c2 = G1 | P1 & G0 | P1 & P0 & c0

Similar, putem generaliza pentru un sumator de 4 biți:

  • c3 = G2 | P2 & G1 | P2 & P1 & G0 | P2 & P1 & P0 & c0

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.

 Ripple-Carry vs. Carry-Lookahead

TL;DR

- 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:

  • Gi(Ai, Bi) = Ai & Bi
  • Pi(Ai, Bi) = Ai | Bi
  • ci+1 = Gi | Pi & ci

Exerciții

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:

  • Intrari:
    • operandul A → 4 switch-uri
    • operandul B → 4 switch-uri
    • buton1 →buton pentru validarea operanzilor
    • buton2 → buton pentru operatia de adunare
    • buton3 → buton pentru operatia de scadere
    • buton reset
  • Iesiri:
    • cele 8 leduri → pentru afisarea operanzilor
    • afisajul cu 7 segmente → pentru afisarea rezultatului
  • Mod de operare:
    • trebuie intodusi operanzii cu ajutorul switch-urilor si afisari cu ajutorul led-urilor(cate 4 pentru fiecare operand
    • pentru a valida opernazii trebuie apasat butonul “buton1”
    • dupa validare:
      • la apasarea butonul “buton2” se va afisa cu ajutorul afisajului cu 7 segmente rezultatul adunarii celor doi operanzi
      • la apasarea butonul “buton3” se va afisa cu ajutorul afisajului cu 7 segmente rezultatul adunarii celor doi operanzi
      • dupa apasarea unui buton, va ramane afisata aceeasi valoare pana la apasarea urmatorului buton
    • pentru introducerea altor valori pentru operanzi se va apasa butonul de reset
  • pentru a realiza operațiile veți folosi modulele create la exercițiile anterioare

Resurse

cn1/laboratoare/07.txt · Last modified: 2021/04/04 21:06 by george_mircea.grosu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0