User Tools

Site Tools


lab:cn1:lab06

= Laboratorul 6 - Sumatoare = == 1. Scopul laboratorului == Scopul acestui laborator este proiectarea unor module ce implementează operații aritmetice. În acest laborator vom implementa sumatoare simple, vom examina performanțele și vom face o interfață grafică pe LCD pentru operația de adunare. == 2. Mod de lucru == Cuvintele calculatoarelor sunt compuse din biți, deci o reprezentare facilă este în numere binare. Numărul de biți din care este compus un cuvânt determină gama de valori reprezentabilă în acel cuvânt. Spre exemplu, un cuvânt de 32 de biți poate conține valori între 0 și 2<sup>32</sup> - 1 = 4.294.967.295 (desigur, am considerat numărul ca fiind fără semn). De asemenea, pentru a reprezenta numere negative putem folosi primul bit dintr-un cuvânt ca bit de semn. Astfel un cuvânt cu primul bit 0 este considerat număr pozitiv, iar un cuvânt cu primul bit 1 este considerat negativ. Numerele negative sunt reprezentate în [[http://en.wikipedia.org/wiki/Two%27s_complement|cod complementar lui 2]]. == 3. Sumatoare == Un sumator este un circuit digital ce realizează suma a două numere. În calculatoarele moderne ele se găsesc nu numai în unitatea aritmetică-logică ([[http://en.wikipedia.org/wiki/Arithmetic_logic_unit|UAL]]) ci și în alte unități ale procesorului, fiind folosite pentru a calcula adrese, indici, etc. === 3.1. Half-adder === {{ :lab:cn1:half-adder.png?300 |}} Un half-adder este un circuit care realizează suma a doi operanzi pe un singur bit. Intrările sale sunt A și B, cei doi operanzi. El generează la ieșire două semnale: S (suma) si C (carry - transportul către următorul rang). Tabela de adevăr pentru un half-adder este prezentată în figura 3.1. ^ A ^ B ^ S ^ C ^ | 0 | 0 | 0 | 0 | | 0 | 1 | 1 | 0 | | 1 | 0 | 1 | 0 | | 1 | 1 | 0 | 1 | //Fig 3.1: Tabela de adevăr pentru un half-adder// === 3.2. Full-adder === {{ :lab:cn1:382_fa_diagram.gif?400 |}} Un full-adder este un circuit care realizează suma a doi operanzi ținând cont și de transportul din rangul inferior. Intrările sale sunt A, B (cei doi operanzi) și C<sub>in</sub> (transportul de la rangul inferior). El generează la ieșire doua semnale: S (suma) și C<sub>out</sub> (carry out - transportul către rangul următor). Tabela de adevăr pentru un full-adder este prezentată în figura 3.2. ^ A ^ B ^ C<sub>in</sub> ^ S ^ C<sub>out</sub> ^ | 0 | 0 | 0 | 0 | 0 | | 0 | 0 | 1 | 1 | 0 | | 0 | 1 | 0 | 1 | 0 | | 0 | 1 | 1 | 0 | 1 | | 1 | 0 | 0 | 1 | 0 | | 1 | 0 | 1 | 0 | 1 | | 1 | 1 | 0 | 0 | 1 | | 1 | 1 | 1 | 1 | 1 | // Figura 3.2: Tabela de adevăr pentru un full-adder// Un full-adder se poate implementa folosind 2 half-adder-e: {{ :lab:cn1:images.png?400 |}} === 3.3. Sumatorul ripple-carry === Cum în practică vom avea nevoie de numere mai mari decât 1, acestea vor fi reprezentate pe mai mulți biți. În acest caz avem o problemă: sumatoarele noastre nu pot aduna decât maxim un bit! Pentru a rezolva problema trebuie să creăm un circuit care să facă suma numerelor reprezentate pe mai mulți biți. Un astfel de circuit, și cel mai simplu, este sumatorul ripple-carry. Pentru a construi un astfel de sumator pe n biți avem nevoie de fie n sumatoare full-adder (dintre care primul va avea intrarea C<sub>in</sub> legată la 0 întotdeauna), fie de n-1 sumatoare full-adder și un half-adder (care va înlocui acel prim full-adder și **NUMAI** pe acela). Conectarea lor, prezentată în figura 3.3, este una foarte simplă: ieșirea C<sub>out</sub> a modulului de rang //i// va fi conectată la intrarea C<sub>in</sub> a modulului de rang //i+1//. Acest fapt ne bucură în faza de proiectare, fiindcă nu avem mult de lucru, însă un astfel de sumator este încetinit de faptul că modulul de rang //i// trebuie să aştepte modulul de rang //i-1// sa îşi termine executia pentru a afla cât este C<sub>in</sub>, iar cel de rang //i-1// la rândul său trebuie să îl aștepte pe cel de rang //i-2// s.a.m.d. {{:lab:cn1:ripple-carry4bit.png?400|Ripple-carry pe 4 biți}} //Figura 3.3: Un sumator ripple-carry pe 4 biți// == 4. TL;DR == * Cuvintele calculatorului sunt compuse din biți, prin urmare, cuvintele sunt de fapt niște valori. * Convenție ([[https://en.wikipedia.org/wiki/Two%27s_complement|Complement față de 2]]): * **pozitive** - primul bit este 0 * **negative** - primul bit este 1 * **Sumator** = circuit digital care realizează suma a două numere * **Half-adder** = realizează suma a doi operanzi pe un singur bit * **Full-adder** = realizează suma a doi operanzi pe un singur bit ținând cont și de transportul din rangul inferior * **Ripple-carry** = sumator pe **n** biți realizat din **n** sumatoare 'full-adder' cascadate * C<sub>in<sup>(i+1)</sup></sub> = C<sub>out<sup>(i)</sup></sub> * C<sub>in<sup>(0)</sup></sub> = 0 == 5. Exerciții == Pentru fiecare dintre exerciții va trebui să faceți atât **implementarea** cât și **simularea** cu seturi de date relevante. Urmăriţi **TODO**-urile din module pentru rezolvarea exerciţiilor. Modulele, fişierele de test şi fişierele de constrângeri sunt **deja create** în scheletul laboratorului. - (2p) Implementați un half-adder și un full-adder. __Simulați funcționarea lor.__ (**NU** aveți voie să folosiți operatorul '+' din Verilog). - Implementarea half-adder se va face: * la nivel structural * la nivel flux de date * la nivel procedural - Implementarea full-adder se va face utilizând două instante ale half-adder-ului implementat la subpunctul anterior. - (2p) Implementați un sumator ripple-carry pe 8 biți și creați un scenariu pentru __simularea modulului__. * !!! Pentru implementare folosiți modulele de la punctul precedent. - (2p) Implementați un scăzător pe 8 biti, pornind de la modulul de la punctul precedent. __Simulați modulul.__ - (4p) Implementați un sumator/scăzător pe 8 biți cu ajutorul [[http://www.digilentinc.com/Data/Products/NEXYS3/Nexys3_rm_V2.pdf|placii de laborator]]. - Caracteristici: - 2 operanzi pe 8 biţi - Afişare operanzi şi rezultat pe afişajul cu 7 segmente - Afişare progres pe cele 8 LED-uri - Mod de operare: - Preluare operand 1 -> prin apăsarea unui 'push-button' - Preluare operand 2 -> prin apăsarea aceluiaşi 'push-button' * !!! Până la apăsarea butonului, pe afişajul cu 7 segmente va fi afişată valoarea operandului - Afişare: * rezultat -> dacă este ţinut apăsat butonul corespunzător unei operaţii * 'APAS' -> dacă nu este apăsat niciun buton - La apăsarea butonului de reset, circuitul se întoarce la preluarea primului operand * **Citiţi comentariile din modul şi urmăriţi TODO-urile!** == 6. Resurse == * {{:lab:cn1:lab06:lab06_skel.zip|Scheletul de laborator}} <ifauth @user> </ifauth> == 7. Link-uri utile == * [[http://www.fpgadeveloper.com/2011/07/code-templates-generate-for-loop.html | Generate in verilog]] * [[http://www.ecs.umass.edu/ece/koren/arith/simulator/Add/ripple/ripple.html | Ripple Carry Adder Simulator]]

lab/cn1/lab06.txt · Last modified: 16.03.2020 by Iosif-Alexandru Selea