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