Differences

This shows you the differences between two versions of the page.

Link to this comparison view

ac-is:lab:lab03 [2021/09/20 18:36]
127.0.0.1 external edit
ac-is:lab:lab03 [2023/10/27 15:15] (current)
teodor.dicu [Resurse]
Line 1: Line 1:
-= Laboratorul 3 - Sintetizarea modulelor Verilog = +====== Laboratorul 3 -  ​Circuite combinaționale ​descrierea comportamentală ======
-În laboratoarele anterioare au fost prezentate elementele principale ale limbajului Verilog și au fost descrise o serie de circuite digitale, folosind acest limbaj de descriere a hardware-ului. Verificarea comportamentului descris s-a făcut folosind simulatorul ISim, inclus în mediul de dezvoltare Xilinx ISE. +
  
-Scopul final pentru un cod Verilog este însă de a realiza implementări hardware care se comportă precum descrierea VerilogAcest lucru poate fi obținut în mod automat printr-un proces numit sintetizare (eng. //​synthesis//​). Un utilitar ​de sintetizare preia descrierea Verilog ​sau VHDL și poate genera fișiere ​de configurare pentru circuite integrate reconfigurabile (ex. PLA, CPLDFPGA) sau chiar măștile necesare pentru realizarea unui ASIC (//​Application-Specific Integrated Circuit//) prin diferite tehnologii *MOS.+În laboratoarele anterioare am studiat descrierea structurală, folosind primitive, precum și descrierea comportamentală,​ folosind atribuiri continue. Am remarcat faptul că generalizarea modulelor folosind parametri conduce la o capacitate ​de reutilizare mai mare, cu schimbări minimeCu toate acestea, soluțiile prezentate nu sunt pretabile funcțiilor complexe, întrucât ele devin complicat ​de implementat ​sau de urmăritîn momentul când este găsit un bug în cod.
  
-Există mai multe utilitare capabile de sintetizarea circuitelor digitale, de la diverși producătoricare sunt în principal axate pe anumite tehnologii specifice acestoraPentru programarea plăcilor ​de dezvoltare de la laboratorcare sunt dotate cu FPGA-uri ​de la Xilinxse folosește mediul de dezvoltare Xilinx ISE care, pe lângă simulatorul ISim, conține ​și un utilitar de sintetizare.+Laboratorul curent va prezenta elementele Verilog folosite pentru descrierea comportamentală la nivel proceduralce se vor axa în continuarea ​pe conceptul de “**ce face** circuitul” Se folosesc construcții ​de nivel înaltsimilare altor limbaje ​de programare întâlnite până în prezentprin care putem descrie mai facil algoritmul care calculează ieșirile circuitului.
  
-== FPGA-uri == 
-Un FPGA (Field-Programmable Gate Array) este un circuit integrat care poate fi programat pentru a se comporta ca orice alt circuit digital. Spre deosebire de un procesor, care stochează și execută instrucțiuni,​ programarea unui FPGA înseamnă reconfigurarea hardware a acestuia pentru a realiza funcționalitatea dorită. 
  
-Primele FPGA-uri au fost introduse în anii '80, iar utilizarea lor principală era în testarea prototipurilor pentru ASIC-uri. Avantajele aduse de FPGA-uri au făcut însă ca ele să fie folosite acum, atât pentru testare, cât și în multe alte domenii precum prelucrarea de semnale, criptografie și HPC (High Performance Computing).+===== Structura limbajului Verilog ​continuare =====
  
-FPGA-urile sunt construite dintr-un număr mare de blocuri logice configurabile (eng. //​configurable logic block - CLB//), identice, interconectate printr-o matrice de fire și switch-uri programabile (<imgref interconnect>​). 
  
-<​imgcaption interconnect | Structura unui FPGA>{{ .:​lab03:​fpga.png?​nolink | Structura unui FPGA}}</​imgcaption>​+==== Tipul reg ====
  
-În general, un CLB este compus dintr-un element combinațional reconfigurabil și un bistabil. De obicei elementul combinațional este un LUT (Look-Up Table), iar bistabilul este de tip D. Arhitectura unui bloc diferă însă de la producător la producător,​ motiv pentru care trebuie folosite utilitarele de sintetizare specifice producătorului. <imgref clb> prezintă un CLB tipic. 
  
-<​imgcaption clb | Configurable Logic Block>​{{ ​.:lab03:clb.png?nolink | Configurable Logic Block}}</imgcaption>​+În primele laboratoare a fost prezentat tipul //wire// pentru reprezentarea semnalelor din interiorul modulelorPorturile unui modul erau //wires//, la fel și semnalele de legătură dintre instanțele primitivelor și porțilorDeoarece acestea realizează conexiuni, nu au o stare și nu li se pot atribui valori. Pentru a putea reține stări/valori și a face atribuiri avem nevoie de tipul **reg**. ​
  
-Numărul ​de celule dintr-un FPGA variază ​de la model la modelputând ajunge până la câteva sute de mii și chiar milioane. Un exemplu este familia Virtex-7 de la Xilinx care conține peste 2 milioane de celule.+Declararea variabilelor ​de tip reg se poate face într-un mod similar variabilelor ​de tip wirecum este exemplificat ​și mai jos:
  
-În cadrul laboratorului se folosește placa de dezvoltare Spartan3E Starter Board de la Digilent, care este dotată cu un FPGA din familia Spartan-3E (XC3S500E) produs ​de către Xilinx. Acest FPGA oferă ~500.000 de porți logice organizate în ~10.000 de celule. Pe lângă cipul FPGA, placa de dezvoltare oferă și o serie de periferice conectate la acesta, cum ar fi: +== Exemplu declarare variabilă de tip reg ==
-  * o memorie volatilă DDR-SDRAM de 64MB +
-  * o memorie nevolatilă Flash paralelă de 16MB +
-  * o memorie nevolatilă Flash serială de 16MB +
-  * un display LCD cu 2 linii și 16 caractere +
-  * butoane, switch-uri și LED-uri +
-  * generator de ceas de 50MHz +
-Lista completă a perifericelor,​ precum și modul de interconectare și folosire a acestora împreună cu cipul FPGA pot fi consultate în [[http://​www.xilinx.com/​support/​documentation/​boards_and_kits/​ug230.pdf | manualul de utilizare a plăcii]].+
  
-== Sintetizarea folosind Xilinx ISE == +<code systemverilog>​ 
-Mediul de dezvoltare Xilinx ISE permite programarea cipurilor FPGA produse de către Xilinx. Versiunea WebPACK poate fi folosită pentru ​sintetiza circuite și programa cipurile FPGA din gama low-cost ale acestui producător,​ cum ar fi familia Spartan.+reg x; 
 +reg[7:0] m;  
 +reg[0:4] n; 
 +reg[7:​0] ​[3:0]; // array multidimensional cu 4 elemente de 8 biti 
 +</​code>​
  
-În Xilinx ISE sintetizarea unui circuit se face selectând modul //​Implementation//​ și este împărțită în două etape. În prima etapă, reprezentată ​de procesul //​Synthesize//,​ este generată ​descriere generică a circuitului ce urmează a fi implementat,​ sub forma unei liste de primitive și conexiunile dintre ele. În a doua etapă, reprezentată de procesul ​//Implement Design//, primitivele sunt mapate pe resursele oferite de cipul FPGA țintă, iar apoi conexiunile dintre ele sunt rutate prin matricea de interconectare din interiorul FPGA-ului.+<note important>​Declararea unei variabile ​de tip reg (deci variabilă de tip registru în Verilog) **nu** implică sinteza unui registru hardware!<​/note>
  
-<note tip> 
-Schema circuitului sintetizat de Xilinx ISE se poate vizualiza rulând procesul //​Synthesize - XST->​View RTL Schematic//​. Selectând opțiunea //Start with a schematic of the top-level block//, inițial schema va conține doar un //​black-box//​ pentru modulul //​top-level//​. Implementarea unui //​black-box//​ poate fi expandată prin //​dublu-click//​. 
  
-Nu toate modulele pot fi expandate până la nivel de porți logice. În procesul de sintetizare,​ Xilinx ISE va infera anumite funcționalități precum: sumatoare (eng: //​adders//​),​ comparatoare (eng: //​comparators//​),​ multiplicatoare (eng: //​multipliers//​),​ numărătoare (eng: //​counters//​) etc. care nu mai pot fi expandate. Lista tuturor funcționalităților inferate se găsește în //Synthesis Report// disponibil în //Design Summary/​Reports//​ din lista de procese. +==== Construcții de control ====
-</​note>​+
  
-<note important>​ 
-La crearea proiectului Xilinx, trebuie selectat cipul FPGA țintă pentru care vor fi sintetizate circuitele. Pentru a putea programa placa de dezvoltare acesta trebuie să corespundă cu cipul FPGA de pe placă. 
-</​note>​ 
  
-Pentru a putea testa un modul Verilog pe placa de dezvoltareintrările și ieșirile acestuia trebuie rutate la pinii cipului FPGA. Acest lucru se face cu un fișier de constrângeri care asignează fiecărui bit dintr-un port al modulului un anumit pin al cipului. Alegerea pinilor care se conectează la porturile modulului Verilog se face în funcție de perifericele care vrem să producă intările ​și să primească ieșirile modulului. Legăturile dintre pinii cipului FPGA și perifericele plăcii de dezvoltare se găsesc în [[http://​www.xilinx.com/​support/​documentation/​boards_and_kits/​ug230.pdf ​manualul de utilizare]].+În afară ​de folosirea atribuirilor continuecircuitele pot fi descrise comportamental ​și prin [[ac-is:lab:​lab03#​Blocul always@|blocuri always]]. În interiorul acestora se pot folosi construcții de limbaj similare celor din limbajele procedurale.
  
-<note important>​ 
-Fișierul de constrângeri trebuie creat înainte de sintetizarea circuitului. Urmăriți [[..:​tutoriale:​4-ise-constraints | tutorialul de asignare a pinilor de IO]] pentru a vedea cum se creează acest fișier.</​note>​ 
  
-În final, programarea cipului FPGA se face cu fișierul de configurare generat pentru acesta ​(extensia .bit). Urmăriți [[..:tutoriale:5-ise-programare ​tutorialul de programare ​FPGA-ului]] pentru ​vedea cum se realizează acest lucru.+^  Cod Verilog ​ ^  Cod C  ^  
 +| <code systemverilog>​ 
 +if (sig == 0begin 
 +    a = 2; 
 +end else if (sig == 1 ) begin 
 +    a = 1; 
 +end else begin 
 +    a = 0; 
 +end 
 +</​code>​ | <code c> 
 +if (sig == 0) { 
 +    a = 2; 
 +} else if (sig == 1 ) { 
 +    a = 1; 
 +} else { 
 +    a = 0; 
 +
 +</​code>​ | 
 +| <code systemverilog>​ 
 +case (sig) 
 +    'b0a = 2; 
 +    'b1a = 1; 
 +    default: a = 0;  
 +endcase 
 +</​code> ​<code c> 
 +switch (sig) { 
 +    case 0: = 2; break; 
 +    case 1: = 1; break; 
 +    default: a = 0; 
 +
 +</​code>​ | 
 +| <code systemverilog>​ 
 +for (i = 0; i < 10; i = i + 1) begin 
 +    a = a / 2; 
 +end 
 +</​code>​ | <code c> 
 +for(i = 0; i < 10; i = i + 1) { 
 +    a = a / 2; 
 +
 +</​code>​ | 
 +| <code systemverilog>​ 
 +i = 0; 
 +while (i < 10) begin 
 +   a = a / 2; 
 +   i = i + 1; 
 +end 
 +</​code>​ | <code c> 
 +i = 0; 
 +while(i < 10) { 
 +   a = a / 2; 
 +   i = i + 1; 
 +
 +</​code>​ | 
 +| <code systemverilog>​ 
 +repeat (10) begin 
 +   a = a / 2; 
 +end 
 +</​code>​ | |
  
-<​note ​tip> +<​note ​important>Construcțiile de repetiție sunt sintetizabile doar dacă ele au un număr **fix** de iterațiiTrebuie acordată o deosebită atenție în momentul în care se implementează structuri repetitive utilizând ​//while// sau //repeat//, acestea fiind mult mai susceptibile la greșeli de implementare care vor genera, în final, un cod simulabil dar nesintetizabil.</​note>​
-Un singur modul, și dependențele acestuia, poate fi sintetizat la un moment datAcest modul se numește modulul ​//top-level// și este marcat cu un simbol special în lista de module ale proiectului. Fișierul de constrângeri va referi porturile acestui modul.+
  
-Modulul //​top-level//​ poate fi modificat prin //​click-dreapta//​ pe un alt modul și selectarea opțiunii //Set as Top Level Module//. În această situație, fișierul de constrângeri trebuie actualizat pentru a folosi porturile noului modul //​top-level//​. 
-</​note>​ 
  
-== Exerciții ​== +==== Blocul always@ ====
-  - (**1p**) Urmăriți [[..:​tutoriale:​3-ise-debug | tutorialul de debugging]] și rezolvați bug-urile din sumator, apoi setați un //​breakpoint//​ la linia 35 și rulați simularea până la a 5-a iterație (bitul 4) a celei de-a treia perechi de numere testate. :!: Implementarea sumatorului este una didactică, Verilog permițând o descriere mult mai simplă pentru un sumator pe oricâți biți cu operatorul ''​+''​. :!: +
-  - (**2p**) Testați pe placa de dezvoltare modulul //comp1//. Generați și vizualizați schema circuitului. +
-    * Hint: Funcționalitatea modulului //comp1// este explicată în [[.:​lab01#​exercitii | exercițiul 5]] din laboratorul 1. +
-    * Hint: Scheletul de cod conține deja fișierul de constrângeri (//​comp1.ucf//​) și configurațiile necesare pentru programarea plăcii (//​comp1.ipf//​). +
-    * Hint: Rulați procesul //Configure Target Device// din modul //​Implementation//​ pentru programarea plăcii. Placa este programată în momentul în care se aprinde LED-ul portocaliu. +
-    * Hint: Studiați fișierul de constrângeri și manualul de utilizare a plăcii de dezvoltare pentru a descoperi corespondența dintre porturile modulului //comp1// și perifericele plăcii. +
-  - (**3p**) Testați pe placa de dezvoltare modulul //​simple_alu//​. Folosiți ca intrări pentru ''​a''​ switch-urile //​SW0//​-//​SW3//,​ pentru ''​b''​ butoanele //​BTN_NORTH//,​ //​BTN_EAST//,​ //​BTN_SOUTH//​ și //​BTN_WEST//,​ iar pentru ''​sel''​ butonul //​ROT_CENTER//​. Afișati ieșirea modulului pe LED-urile //​LED0//​-//​LED4//​. +
-    * Hint: Porniți de la scheletul de cod. +
-    * Hint: Funcționalitatea modulului //​simple_alu//​ este explicată în [[.:​lab02#​exercitii | exercițiul 4]] din laboratorul 2. +
-    * Hint: Urmăriți [[..:​tutoriale:​4-ise-constraints | tutorialul de asignare a pinilor de IO]] pentru generarea fișierului de constrângeri. :!: Nu uitați configurarea de tip //​PULLDOWN//​ a porturilor pentru butoane și switch-uri. +
-    * Hint: Urmăriți [[..:​tutoriale:​5-ise-programare | tutorialul de programare a FPGA-ului]] pentru configurațiile necesare programării plăcii. +
-  - (**4p**) Implementați și testați pe placa de dezvoltare un circuit care poate compara 2 numere pe câte 4 biți. Circuitul trebuie să aibă 3 ieșiri corespunzătoare situațiilor:​ //mai mic//, //egal//, //mai mare//. :!: Se va acorda punctajul integral în cazul în care implementarea va fi realizată utilizând instanțe ale modulului comp1, fără a invoca operatorii de comparație (< , == , >). Rezolvarea exercițiului prin metode care nu respectă această restricție va fi punctată cu maxim **2p**. +
-    * Hint: Urmăriți [[..:​tutoriale:​1-ise-proiect | tutorialul de creare a unui proiect]]. +
-    * Hint: Folosiți o descriere comportamentală a circuitului.+
  
-== Resurse ==  
-  * {{.:​lab02:​sol:​lab3_skel.zip|Schelet de cod}} 
-  * {{.:​lab03:​sol:​lab3_sol.zip|Soluție laborator}} (disponibilă începând cu 19.10.2019) 
-  * <​html><​a class="​media mediafile mf_pdf"​ href="/​ac/​wiki/​lab/​lab03?​do=export_pdf">​PDF laborator</​a></​html>​ 
-  * <​html><​a class="​media mediafile mf_pdf"​ href="​http://​www.xilinx.com/​support/​documentation/​boards_and_kits/​ug230.pdf">​Manualul plăcii de dezvoltare</​a></​html>​ 
  
 +Blocurile //always// descriu un comportament ciclic, codul acestora fiind executat în continuu. Prezența operatorului //@// face ca blocul să se “execute” doar la apariția unor evenimente. Evenimentele sunt reprezentate de modificarea unuia sau mai multor semnale.
  
-<​ifauth ​@user> +În cadrul acestui laborator ne axăm doar pe descrierea circuitelor combinaționale,​ și vom folosi doar blocuri ''​always ​@(*)'',​ unde (*) se numește **sensitivity list**. Folosirea wildcard-ului implică “execuția” blocului //always/la orice eveniment de modificare a oricărui semnal folosit în cadrul blocului.
----- +
-  ​[[:​internal:​synth|Ghid asistent]] +
-</ifauth>+
  
 +Instrucțiunile din blocul //always// sunt încadrate între cuvintele cheie ''​begin''​ și ''​end''​ și sunt “executate” secvențial atunci când blocul este activat. ​
  
 +<code systemverilog>​
 +always @(*) begin
 +   b = 0;     // registrul b este inițializat cu 0 la orice
 +              // modificare a unui semnal
 +   c = b ^ a; // registrul c va primi valoarea expresiei din dreapta
 +              // la orice modificare a unui semnal (nu doar a sau b)
 +end
 +</​code>​
 +
 +
 +În locul wildcard-ului,​ *, sensitivity list-ul poate conține o listă de semnale la modificarea cărora blocul //always// să fie activat. Acestea se declară prin numele lor, folosind or sau , pentru a le separa. ​
 +
 +Este foarte important ca lista de semnale dată unui bloc //always@// să fie **completă**,​ altfel nu toate combinațiile de intrări sunt acoperite și unele variabile pot rămâne neatribuite corespunzător. Pentru a evita astfel de erori se recomandă folosirea wildcard-ului *.
 +
 +== Exemplu declarare listă de senzitivitate ==
 +
 +<code systemverilog>​
 +always @(a or b or c) // sintaxa Verilog-1995
 +always @(a, b, c)     // sintaxa Verilog-2001,​ 2005
 +always @(a, b or c)   // permis dar nerecomandat,​ îngreunează
 +                      // lizibilitatea codului
 +always @(*)           // toate semnalele din modul (intrări +
 +                      // wires declarate în modul)
 +</​code>​
 +
 +În modulul următor care implementează o poartă xor, ieșirea out se va schimba doar când semnalul a se schimbă, ceea ce duce la un comportament incorect care nu ia în considerare și schimbarea lui b. În plus, modulul generat nu va fi unul combinațional,​ deoarece este nevoie de memorie pentru a menține starea ieșirii atunci când b se modifică.
 +
 +<code systemverilog>​
 +module my_xor(output reg out, input a, input b);
 +    always @(a) begin
 +        out = a ^ b;
 +    end
 +endmodule
 +</​code>​
 +
 +<note important>​**Nu** se pot instanția primitive și module în interiorul blocurilor //always// și //​initial//​. </​note>​
 +
 +În cadrul blocurilor //initial// și //always// atribuirile pot fi de două feluri, cu semantici diferite:
 +  * **Atribuiri blocante**: sunt folosite pentru descrierea logicii combinaționale (porți logice). Atribuirile blocante sunt interpretate ca executându-se secvențial,​ semantica fiind identică cu cea din limbajele de programare procedurale.
 +  * **Atribuiri non-blocante**:​ sunt folosite pentru descrierea logicii secvențiale (ne vom întâlni cu ele în laboratorul următor).
 +
 +În Verilog putem declara variabile de tipul //reg// și //wire// pentru a crea circuite combinaționale. Atunci când se fac atribuirile există totuși următoarele restricții:​
 +  * Pe o variabilă de tip **wire** nu putem face decât **atribuiri continue** (//​assign//​). Acestea trebuie să fie **în exteriorul blocurilor** always sau initial. Valoarea atribuită poate fi o constantă, o expresie, valoarea unui fir sau a unui registru.
 +  * Pe o variabilă de tip **reg** putem face doar **atribuiri blocante/​non-blocante**. Acestea trebuie să fie **în interiorul** unui bloc initial sau always. Valoarea atribuită poate fi o constantă, o expresie, valoarea unui fir sau a unui registru. ​
 +
 +== Exemplu sumator descris comportamental,​ folosind always@ ==
 +
 +<code systemverilog>​
 +module my_module(
 +    output reg[4:0] o, // o trebuie sa fie reg pentru a o putea atribui
 +                       // în blocul always
 +    input[3:0] a, b);
 +
 +    reg[2:0] i;        // poate fi maxim 7; noi avem nevoie de maxim 4
 +    reg c;             // ținem minte transportul
 +
 +    always @(*) begin
 +        i = 0; // la orice modificare a intrărilor,​ i va fi inițial 0
 +        c = 0; // transportul initial este 0
 +    ​
 +        // toți biții lui o sunt recalculati la modificarea intrărilor
 +        for (i = 0; i < 4; i = i + 1) begin
 +            {c, o[i]} = a[i] + b[i] + c;
 +        end
 +    end
 +endmodule
 +</​code>​
 +
 +<note important>​Pentru ca un bloc //always// să fie sintetizat într-un circuit combinațional este necesar ca orice “execuție” a blocului să atribuie cel puțin o valoare pentru fiecare ieșire a modulului. </​note>​
 +
 +Bineînțeles,​ acea valoare nu poate fi calculată pe baza ieșirilor sau valorilor anterioare ale variabilelor din interiorul modulului. Asta ar însemna că este necesară o memorie pentru a menține acele valori, transformând circuitul într-unul secvențial.
 +
 +<note important>​**Nu** este recomandată declararea variabilelor de tip reg în interiorul blocurilor de tip //always// sau //​initial//​. În Verilog ea este totuși posibilă, dacă blocul respectiv are un tag asociat. Variabila astfel declarată va avea vizibilitate doar în interiorul blocului.</​note>​
 +
 +== Exemplu declarare variabilă de tip reg în interiorul blocului always ==
 +
 +<code systemverilog>​
 +always @(*) begin :my_tag
 +    reg x;
 +    x = in1 ^ in2;
 +end
 +</​code>​
 +
 +
 +===== Exerciții =====
 +
 +
 +Pentru implementarea exercițiilor se vor utiliza scheletele de cod din arhiva laboratorului. Scheletele de cod conțin deja un proiect Xilinx ISE, iar unele din ele și un modul de testare. Urmăriți cerința și zonele marcate cu TODO.
 +
 +  - **(4p)** Implementați și simulați un **multiplicator pe 4 biți** fără a folosi operatorul * (înmulțire).
 +    * //Hint//: Folosiți convenția Verilog pentru interfața modulului. Câți biți are ieșirea? ​
 +    * //Hint//: Înmulțiți pe hârtie, în baza 2, numerele 1001 și 1011. Transpuneți în limbajul Verilog algoritmul folosit.
 +  - **(2p)** Implementați și simulați un modul de **afișaj cu 7 segmente** pentru numere în baza 10. Descrierea sumară a funcționalității acestuia se poate regăsi în [[lab03#​Anexă|Anexă]]. ​
 +    * //Hint//: Există o ieșire validă pentru fiecare intrare? Nu uitați de cazul ''​default''​. ​
 +    * //Hint//: Se vor testa doar cifrele de la 0 la 9.
 +  - **(4p)** Implementați o **unitate aritmetico-logică** simplă (UAL), pe **4** biți, cu 2 operații: adunare și înmulțire. Folosiți o intrare de selecție de 1 bit pentru a alege între cele două operații astfel: 0 - adunare, 1 - înmulțire.
 +    * //Hint//: Este necesar să creați un nou proiect. Se poate folosi [[ac-is:​tutoriale:​1-ise-proiect|tutorialul]]. ​
 +    * //Hint//: Câți biți au ieșirea sumatorului și a multiplicatorului?​ Dar a UAL-ului? ​
 +    * //Hint//: Pentru selecția dintre ieșirea sumatorului și cea a multiplicatorului se poate folosi atribuirea continuă sau se poate implementa un modul multiplexor 2:1 
 +    * //Hint//: Pentru testarea UAL trebuie creat un scenariu de test, folosind [[ac-is:​tutoriale:​2-ise-simulare|tutorialul]]. Presupunând că sumatorul și multiplicatorul sunt testate temeinic la exercițiile anterioare, creați un scenariu relevant funcționării UAL-ului ca un ansamblu.
 +  - **(3p)**: Pentru o utilizare mai generală, implementați un UAL cu operatori cu dimensiune variabilă. ​
 +    * //Hint//: Pentru a-l implementa, este necesară implementarea unui multiplicator parametrizat - atenție la dimensiunea semnalelor!  ​
 +
 +
 +===== Anexă =====
 +
 +
 +==== Seven-segment display ====
 +
 +
 +Acest tip de dispozitiv de afișare este alcătuit, așa cum vă puteți da seama și din numele acestuia, din 7 segmente controlabile individual. Așadar, putem aprinde (1 logic) sau stinge (0 logic) fiecare segment din componența acestuia.
 +
 +{{ :​ac-is:​lab:​lab03:​7seg.png | Reprezentarea numerelor în format hexazecimal considerând un afișaj cu 7 segmente}}
 +<​html><​p align="​center">​Reprezentarea numerelor în format hexazecimal considerând un afișaj cu 7 segmente</​p></​html>​
 +
 +De exemplu, dacă dorim să afișăm cifra 6, ieșirea noastră va avea valoarea ''​7’b111_1101''​.
 +
 +Pentru mai multe detalii asupra acestui tip de modul, consultați pagina de [[https://​en.wikipedia.org/​wiki/​Seven-segment_display|Wiki]].
 +
 +
 +===== Resurse =====
 +  * {{.:​lab03:​lab3_skel.zip|Schelet de cod}}  ​
 +  * <​html><​a class="​media mediafile mf_pdf"​ href="​https://​ocw.cs.pub.ro/​courses/​ac-is/​lab/​lab03?​do=export_pdf">​PDF laborator</​a></​html> ​
 +  * {{.:​lab03:​sol:​lab3_sol.zip|Soluție laborator}}
 +
 +<ifauth @ac-is>
 +----
 +  * {{.:​lab03:​sol:​lab3_sol.zip|Soluție laborator}}
 +  * [[ac-is:​internal:​guidelines|Ghid asistent]]
 +</​ifauth>​
  
-== Referințe == 
-  * [[http://​en.wikibooks.org/​wiki/​Programmable_Logic/​FPGAs]] 
-  * [[http://​www.xilinx.com/​support/​documentation/​data_sheets/​ds312.pdf | Datasheet-ul cipului XC3S500E (FPGA-ul folosit pe placa de laborator)]] 
ac-is/lab/lab03.1632152205.txt.gz · Last modified: 2021/09/26 19:46 (external edit)
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