This shows you the differences between two versions of the page.
cn2:laboratoare:00 [2019/09/30 18:37] tudor.visan created |
— (current) | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== Laboratorul 0 - Recapitulare ===== | ||
- | == Obiective == | ||
- | |||
- | În acest laborator vom recapitula noțiuni învățate la CN1. | ||
- | |||
- | == 1. Verilog == | ||
- | |||
- | Verilog este un HDL (Hardware Description Language) folosit pentru specificarea formală a circuitelor electronice digitale. | ||
- | |||
- | **Modulul** este unitatea de bază a limbajului Verilog. Definește interfața (intrările și ieșirile) și comportamentul unui circuit electronic. Putem descrie comportamentul unui modul în trei moduri: | ||
- | * **Descriere structurală**: specificând structura internă a modulului folosind primitive și module | ||
- | * **Descriere la nivel flux de date**: specificând relațiile dintre intrări și ieșiri sub forma unor expresii | ||
- | * **Descriere procedurală**: specificând funcționarea în mod algoritmic | ||
- | |||
- | <code Verilog> | ||
- | module A(input in, output out); | ||
- | not(out, in); | ||
- | endmodule | ||
- | |||
- | module B(input in, output out); | ||
- | assign out = ~in; | ||
- | endmodule | ||
- | |||
- | module C(input in, output reg out); | ||
- | always @(*) | ||
- | begin | ||
- | out = ~in; | ||
- | end | ||
- | end | ||
- | </code> | ||
- | |||
- | În Verilog putem folosi două tipuri de date: | ||
- | * ''**wire**'': reprezintă conexiuni fizice între componentele, se folosesc pentru transmisia semnalelor și nu au capacitate de reținere a informației | ||
- | * ''**reg**'': folosite pentru a stoca date, care persistă chiar dacă registrul este deconectat | ||
- | |||
- | <code Verilog> | ||
- | wire a; | ||
- | wire [7:0] b; | ||
- | reg c; | ||
- | reg [0:7] d; | ||
- | </code> | ||
- | |||
- | Pentru a controla ce date se află pe fire sau în registre, avem la dispoziție mai multe tipuri de atribuiri: | ||
- | * Atribuiri continue (''**assign**''): reprezintă relații directe între semnalele, funcționează doar pe ''wire'' | ||
- | * Atribuiri blocante (''**=**''): sunt folosite pentru descrierea logicii combinaționale, executându-se secvențial, funcționează doar pe ''reg'' | ||
- | * Atribuiri non-blocante (''**<nowiki><=</nowiki>**''): sunt folosite pentru descrierea logicii secvențiale, executându-se în paralel, funcționează doar pe ''reg'' | ||
- | |||
- | <code Verilog> | ||
- | module A(input in); | ||
- | wire a; | ||
- | reg b; | ||
- | reg c; | ||
- | | ||
- | assign a = in; | ||
- | | ||
- | always @(*) | ||
- | begin | ||
- | b = in; | ||
- | end | ||
- | | ||
- | always @(*) | ||
- | begin | ||
- | c <= in; | ||
- | end | ||
- | endmodule | ||
- | </code> | ||
- | |||
- | Dacă alegem descrierea procedurală avem la dispoziție doua blocuri speciale: | ||
- | * ''**initial**'': va fi executat o singură dată și se folosește frecvent pentru inițializări sau resetarea circuitului | ||
- | * ''**always**'': va fi executat continuu, ca o buclă infinită. El poate fi executat încontinuu sau la apariția unui eveniment | ||
- | |||
- | == 2. Logică combinațională și secvențială == | ||
- | |||
- | Circuitele logice combinaționale sunt circuitele reprezentate prin porți logice ce aplică o funcție pe intrări. **Valorile de ieșire depind doar de valorile de intrare**, nu și de stări de reactie (feedback), iar cand starea unei intrări se schimbă, se reflectă imediat la ieșiri. | ||
- | |||
- | {{ :lab:cn2:lab00:circuit_combinational.png?500 |Circuit combinațional}} | ||
- | |||
- | Spre deosebire de circuitele logice combinaționale, la cele secvențiale **valorile de ieșire nu mai depind exclusiv de starea curentă a intrărilor, ci și de stările anterioare ale circuitului**. | ||
- | |||
- | {{ :lab:cn2:lab00:circuit_secvential.png?500 |Circuit Secvențial}} | ||
- | |||
- | == 3. Automate cu stări finite (FSM) == | ||
- | |||
- | Un automat finit este, în sensul cel mai abstract, un model de calculabilitate. Trăsătura fundamentală a automatelor finite este faptul că se află, la orice moment de timp, într-una dintr-un număr finit de stări posibile. De asemenea, în anumite condiţii, ele pot executa tranziţii între aceste stări. Astfel, un automat este descris de: **intrări**, **ieșiri**, **stări** și **tranziții**. | ||
- | |||
- | În funcție de relația dintre intrare, ieșire și starea curentă există două tipuri de automate: Mealy și Moore. La automatele **Mealy**, ieşirea depinde de starea curentă şi de input-ul curent. Astfel, o **ieșire corespunde unei tranziții**. | ||
- | |||
- | {{ :lab:cn2:lab00:diagrama_mealy.png?300 |Diagramă automat Mealy}} | ||
- | |||
- | La automatele **Moore**, pe de altă parte, **ieșirea este determinată exclusiv de starea în care se află**. | ||
- | |||
- | {{ :lab:cn2:lab00:diagrama_moore.png?300 |Diagramă automat Moore}} | ||
- | |||
- | == 4. TL;DR == | ||
- | |||
- | * Verilog | ||
- | * Modul | ||
- | * Descriere structurală | ||
- | * Descriere flux de date | ||
- | * Descriere procedurală | ||
- | * ''initial'' | ||
- | * ''always'' | ||
- | * ''wire'' vs ''reg'' | ||
- | * Atribuiri continue (''assign''), blocante (''='') și non-blocante (''<nowiki><=</nowiki>'') | ||
- | * Simulare | ||
- | * Circuite combinaționale | ||
- | * Ieșirile depind doar de intrările de la momentul respectiv | ||
- | * Circuite secvențiale | ||
- | * Ieșirile depind de intrările de la momentul respectiv, dar și de stările anterioare are modulului | ||
- | * Automate cu stări | ||
- | * Mealy (ieșirea depinde de starea curentă și intrarea curentă) | ||
- | * Moore (ieșirea depinde de starea curentă) | ||
- | |||
- | == 5. Exerciții == | ||
- | |||
- | **Task 01** (4p) Scrieți un modul cu 4 intrări pe 1 bit și o ieșire pe 1 bit care implementează următoarea funcție: //out = (in3 NAND (in1 OR in2)) AND (not in0 AND (in1 OR in3))//. Simulați comportamentul modulului. | ||
- | * (2p) Folosiți descriere structurală. | ||
- | * (2p) Folosiți descriere la nivel de flux de date. | ||
- | |||
- | **Task 02** (4p) Implementați un shift register pe 8 biți. Acesta are o intrare de date pe 1 bit, o intrare de ceas, o intrare de reset și o ieșire pe 1 bit. Ieșirea va reflecta intrarea, dar cu o întârziere de 8 cicli de ceas. Simulați comportamentul modulului. Folosiți descriere procedurală. | ||
- | |||
- | <note tip> | ||
- | Pentru a genera un semnal de ceas **în modulul de test** puteți folosi următoarea construcție: | ||
- | <code Verilog> | ||
- | reg clk; | ||
- | ... | ||
- | always | ||
- | begin | ||
- | #5 clk = ~clk; | ||
- | end | ||
- | ... | ||
- | initial begin | ||
- | ... | ||
- | clk = 0; | ||
- | ... | ||
- | end | ||
- | </code> | ||
- | </note> | ||
- | |||
- | **Task 03** (2p + 1p bonus) Implementați un automat cu o intrare de date pe 8 biți, o intrare de ceas, o intrare de reset și o ieșire pe 1 bit. Automatul va primi ca intrare litere ale alfabetului (a-zA-Z), câte o literă pe fiecare front al semnalului de ceas, iar ieșirea va fi 0 până în momentul în care este recunoscută secvența "DCBA", după care aceasta va trece pe 1. Pentru bonus, adaugati 4 intrari si folosindu-va de modulul creat la Task 01 faceți modificarile necesare astfel încat iesirea sa fie egală cu rezultatul aplicarii funcției de la Task 01 pe cele 4 intrări în momentul în care este recunoscută secvența "DCBA". | ||
- | |||
- | == Resurse == | ||
- | <hidden> | ||
- | * {{lab:cn2:lab00:sol:lab00_sol.zip|Solutie laborator}} | ||
- | </hidden> |