Skip to content

Commit

Permalink
fix: typos lab 2 (#14)
Browse files Browse the repository at this point in the history
* Centered circuit_tb.png in the 'Testare' section of Lab2

* Fixed the typos from Lab1, Lab2 and Lab3

---------

Co-authored-by: sdcioc <[email protected]>
  • Loading branch information
aidanozo and sdcioc authored Oct 14, 2024
1 parent 0e68c6b commit 09f99ca
Show file tree
Hide file tree
Showing 10 changed files with 34 additions and 33 deletions.
9 changes: 5 additions & 4 deletions chapters/verilog/basic/drills/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Practică:

## 1. **Sumator elementar complet**, utilizând sumatoare elementare parțiale.
Soluția se află în repo-ul materiei [GitHub](https://github.com/cs-pub-ro/computer-architecture/tree/main/chapters/verilog/basic/drills/tasks/fulladder). Implementarea unui sumatoar elementar parțial se poate găsi în fișierul `halfadder.v`, iar sumator elementar complet în `fulladder.v`. Observați modul în care sunt declarate sumatoarele elementare partțiale.
Soluția se află în repo-ul materiei [GitHub](https://github.com/cs-pub-ro/computer-architecture/tree/main/chapters/verilog/basic/drills/tasks/fulladder). Implementarea unui sumator elementar parțial se poate găsi în fișierul `halfadder.v`, iar sumatorul elementar complet în `fulladder.v`. Observați modul în care sunt declarate sumatoarele elementare parțiale.
```verilog
halfadder l_m_halfadder_0( .o_w_s(l_w_s0), .o_w_cout(l_w_c0), .i_w_a(i_w_a), .i_w_b(i_w_b) );
halfadder l_m_halfadder_1( .o_w_s(o_w_s), .o_w_cout(l_w_c1), .i_w_a(i_w_cin), .i_w_b(l_w_s0) );
```
Pentru a crea proiectul putem folosi comanda ```make build```. Pentru simulare ```make simluation``` și pentru a deschide întreg proiectul în vivado și a avea posibilitatea de a încărca pe FPGA ```make vivado```.
Pentru a crea proiectul putem folosi comanda ```make build```. Pentru simulare ```make simluation``` și pentru a deschide întreg proiectul în Vivado și a avea posibilitatea de a încărca pe FPGA ```make vivado```.

## 2. **Sumator pe 4 biți**, cu două intrări și două ieșiri.
Soluția se află în repo-ul materiei [GitHub](https://github.com/cs-pub-ro/computer-architecture/tree/main/chapters/verilog/basic/drills/tasks/adder_4bits). Rulați simulare (```make simluation```) și verificați corectitudinea sumatorului vizualizând semnalele în baza 10.
Expand All @@ -15,7 +15,8 @@
Soluția se află în repo-ul materiei [GitHub](https://github.com/cs-pub-ro/computer-architecture/tree/main/chapters/verilog/basic/drills/tasks/adder_6bits). Încărcați programul pe FPGA (```make vivado```), urmărind ghidul.

## 4. **Comparator** pe un bit.
Acesta are două intrări și 3 ieșiri (pentru mai mic, egal și mai mare). Soluția se află în repo-ul materiei [GitHub](https://github.com/cs-pub-ro/computer-architecture/tree/main/chapters/verilog/basic/drills/tasks/comparator). Simulați și încărcați pe FPGA.
Acesta are două intrări și trei ieșiri (pentru mai mic, egal și mai mare). Soluția se află în repo-ul materiei [GitHub](https://github.com/cs-pub-ro/computer-architecture/tree/main/chapters/verilog/basic/drills/tasks/comparator). Simulați și încărcați pe FPGA.


## Test
Aveți următorul tabel de adevăr:
Expand All @@ -31,4 +32,4 @@
| 1 | 1 | 0 | 1 |
| 1 | 1 | 1 | 0 |

Intrările sunt `a`, `b`, `c` iar ieșirea este `f`. Implementați modulul verilog este definit de acest tabel de adevăr.
Intrările sunt: `a`, `b`, `c`, iar ieșirea este `f`. Implementați modulul Verilog definit de acest tabel de adevăr.
6 changes: 3 additions & 3 deletions chapters/verilog/basic/reading/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,17 @@ Un singur modul sau o singură primitivă nu poate îndeplini singură funcția
|---------------------------------------|---------------------------------------------------------------------|
| ![Gates](../media/gates.png) | ```wire y1, y2; xor(out, y1, y2); and(y1, in1, in2); nand(y2, in3, in4, in5);``` |

_Table: Exemplu de fromare a unei porti complexe din primitive_
_Table: Exemplu de formare a unei porti complexe din primitive_


În exemplul anterior y1 și y2 sunt semnale de câte 1 bit care leagă ieșirile porților and (y1) și nand (y2) la intrările porții xor.

Pentru a declara semnale pe mai mulți biți se pot folosi vectori precum în declarațiile următoare: m reprezintă un semnal de 8 biți, iar n reprezintă un semnal de 5 biți. Bitul cel mai semnificativ (eng. most significant bit - MSB) este situat întotdeauna în stânga, iar bitul cel mai puțin semnificativ (eng. least significant bit - LSB) în dreapta.

În mod implicit semnalele care nu sunt declarate sunt considerate ca fiind de tip wire și având 1 bit (ex. in1, in2, … din codul de mai sus). Putem accesa individual biții dintr-un wire sau putem accesa un grup consecutiv de biți specificând intervalul (ex. m[0], m[3:1], m[7:2]).
În mod implicit porturile care nu sunt declarate sunt considerate ca fiind de tip wire și având 1 bit (ex. in1, in2, … din codul de mai sus). Putem accesa individual biții dintr-un wire sau putem accesa un grup consecutiv de biți specificând intervalul (ex. m[0], m[3:1], m[7:2]).

```verilog
wire[7:0] m; _ 8 biti, MSB este bitul 7, LSB bitul 0
wire[0:4] n; _ 5 biti, MSB este bitul 0, LSB bitul 4
wire[7:0] a [9:0]; _ array multidimensional cu 10 elemente de 8 biti
```
```
2 changes: 1 addition & 1 deletion chapters/verilog/behavioral/drills/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ De exemplu, dacă dorim să afișăm cifra 6, ieșirea noastră va avea valoarea

Pentru mai multe detalii asupra acestui tip de modul, consultați pagina de [Wiki](https://en.wikipedia.org/wiki/Seven-segment_display).

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.
Pentru implementarea exercițiilor se vor utiliza scheletele de cod din arhiva laboratorului. Scheletele de cod conține 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?
Expand Down
8 changes: 4 additions & 4 deletions chapters/verilog/behavioral/reading/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

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

In continuare vom trece prin elementele Verilog folosite pentru descrierea comportamentală la nivel procedural, ce se vor axa în continuarea pe conceptul de “**ce face** circuitul”. Se folosesc construcții de nivel înalt, similare altor limbaje de programare întâlnite până în prezent, prin care putem descrie mai facil algoritmul care calculează ieșirile circuitului.
In continuare vom trece prin elementele Verilog folosite pentru descrierea comportamentală la nivel procedural, ce se vor axa în continuare pe conceptul de “**ce face** circuitul”. Se folosesc construcții de nivel înalt, similare altor limbaje de programare întâlnite până în prezent, prin care putem descrie mai facil algoritmul care calculează ieșirile circuitului.


## Tipul reg
Expand Down Expand Up @@ -30,7 +30,7 @@ Declararea unei variabile de tip reg (deci o variabilă de tip registru în Veri
În afară de folosirea atribuirilor continue, circuitele pot fi descrise comportamental și prin blocuri always. În interiorul acestora se pot folosi construcții de limbaj similare celor din limbajele procedurale.


Construcțiile de repetiție sunt sintetizabile doar dacă ele au un număr **fix** de iterații. Trebuie 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.
Construcțiile de repetiție sunt sintetizabile doar dacă ele au un număr **fix** de iterații. Trebuie 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.

| Cod Verilog | Cod C |
|-------------|-------|
Expand All @@ -45,7 +45,7 @@ Construcțiile de repetiție sunt sintetizabile doar dacă ele au un număr **fi

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.

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

Instrucțiunile din blocul _always_ sunt încadrate între cuvintele cheie ''begin'' și ''end'' și sunt “executate” secvențial atunci când blocul este activat.

Expand All @@ -59,7 +59,7 @@ end
```


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

Expand Down
4 changes: 2 additions & 2 deletions chapters/verilog/intro/reading/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Un limbaj de descriere hardware conține o serie de abstractizări sau moduri de
## Ce tipuri de circuite putem construi?


**Circuitele logice combinaționale** aplică funcții logice pe intrări pentru a obține ieșirile. Valorile de ieșire depind astfel doar de valorile curente de intrare, iar când starea unei intrări se schimbă, se reflectă imediat asupra ieșiri.
**Circuitele logice combinaționale** aplică funcții logice pe intrări pentru a obține ieșirile. Valorile de ieșire depind astfel doar de valorile curente de intrare, iar când starea unei intrări se schimbă, se reflectă imediat asupra ieșirii.

<div align="center">

Expand All @@ -48,4 +48,4 @@ _Figure: Schema bloc a unui circuit secvențial sincron_

</div>

În primul caz, cel cu care vom lucra și la laborator, este folosit un semnal de ceas care comandă elementul/elementele de memorare, acestea schimbându-și starea doar la impulsurile de ceas. În al doilea caz, ieșirile se modifică atunci când se modifică și intrările, neexistând un semnal de ceas pentru elementele de memorare. Circuitele secvențiale asincrone sunt mai greu de proiectat, pot apărea probleme de sincronizare și sunt folosite mai rar. În continuare ne vom referi doar la circuitele secvențiale sincrone.
În primul caz, cel cu care vom lucra și la laborator, este folosit un semnal de ceas care comandă elementul/elementele de memorare, acestea schimbându-și starea doar la impulsurile de ceas. În al doilea caz, ieșirile se modifică atunci când se modifică și intrările, neexistând un semnal de ceas pentru elementele de memorare. Circuitele secvențiale asincrone sunt mai greu de proiectat, pot apărea probleme de sincronizare și sunt folosite mai rar. În continuare ne vom referi doar la circuitele secvențiale sincrone.
12 changes: 6 additions & 6 deletions chapters/verilog/operators/reading/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Laboratorul curent va prezenta elementele Verilog folosite pentru descrierea com
## Assign


Deși partiționarea circuitelor în cadrul unei arhitecturii duce la simplificarea implementării unui modul, implementarea acestuia la nivel de porți logice este rareori folosită, întrucât aceasta devine complicată și dificil de înțeles.
Deși partiționarea circuitelor în cadrul unei arhitecturi duce la simplificarea implementării unui modul, implementarea acestuia la nivel de porți logice este rareori folosită, întrucât aceasta devine complicată și dificil de înțeles.

Primul pas este reprezentat de ușurarea modalității de scriere a unei funcții logice. Pentru aceasta, Verilog oferă o instrucțiune numită **atribuire continuă**. Aceasta folosește cuvântul cheie ''assign'' și “atribuie” unei variabile de tip ''wire'', valoarea expresiei aflată în partea dreaptă a semnului egal. Atribuirea are loc la fiecare moment de timp, deci orice schimbare a valorii expresiei din partea dreaptă se va propaga imediat.
În partea stângă a unei atribuiri continue se poate afla orice variabilă declarată de tip wire sau orice ieșire a modulului care nu are altă declarație (ex. reg). Expresiile din partea dreaptă pot fi formate din orice variabile sau porturi de intrare și de ieșire și orice operatori suportați de Verilog.
Expand Down Expand Up @@ -60,7 +60,7 @@ Pentru specificarea valorilor întregi este folosită următoarea sintaxă:
- pentru a ușura citirea, se poate folosi caracterul '_' ca delimitator
- caracterul '?' specifică impedanță mare (z)
- caracterul 'x' specifică valoare necunoscută
- se poate specifica dimensiunea numărului în biți dar și baza acestuia (b,B,d,D,h,H,o,O - binar, zecimal, hexa, octal)
- se poate specifica dimensiunea numărului în biți, dar și baza acestuia (b,B,d,D,h,H,o,O - binar, zecimal, hexa, octal)

```verilog
8'b1; //binar, pe 8 biti, echivalent cu 1 sau 8'b00000001
Expand All @@ -76,7 +76,7 @@ Pentru specificarea valorilor întregi este folosită următoarea sintaxă:

Descrierea comportamentală la nivelul fluxului de date, descrisă anterior, presupune în continuare cunoașterea schemei hardware la nivelul porților logice sau, măcar, expresia logică. Deși reprezintă o variantă mai simplă decât utilizarea primitivelor, nu este cea mai facilă.

Pentru a ușura implementarea, Verilog pune la dispoziție mai multe tipuri de operatori. Unii dintre aceștia sunt cunoscuți din limbajele de programare precum C, C++, Java, și au aceeași funcționalitate. Alții sunt specifici limbajului Verilog și sunt folosiți în special pentru a descrie ușor circuite logice. Cu ajutorul acestora putem simplifica implementarea, apelând la construcții folosind limbajul de nivel înalt.
Pentru a ușura implementarea, Verilog pune la dispoziție mai multe tipuri de operatori. Unii dintre aceștia sunt cunoscuți din limbajele de programare precum C, C++, Java și au aceeași funcționalitate. Alții sunt specifici limbajului Verilog și sunt folosiți în special pentru a descrie ușor circuite logice. Cu ajutorul acestora putem simplifica implementarea, apelând la construcții folosind limbajul de nivel înalt.

Tabelul de mai jos conține operatorii suportați de Verilog, împreună cu nivelul lor de precedență.

Expand All @@ -98,9 +98,9 @@ Tabelul de mai jos conține operatorii suportați de Verilog, împreună cu nive
- Operatorii de shiftare aritmetică; realizează shiftarea cu păstrarea bitului de semn, pentru variabilele declarate ca fiind cu semn.
```verilog
wire signed[7:0] a, x, y;
assign x = a >>> 1; // dacă bitul de semn al lui a este 0 bitul nou
assign x = a >>> 1; // dacă bitul de semn al lui a este 0, bitul nou
//introdus este 0
// dacă bitul de semn al lui a este 1 bitul nou
// dacă bitul de semn al lui a este 1, bitul nou
// introdus este 1
assign y = a <<< 1; // bitul nou introdus este tot timpul 0,
//asemănător cu operatorul <<
Expand All @@ -126,4 +126,4 @@ Tabelul de mai jos conține operatorii suportați de Verilog, împreună cu nive
// biții 3:2 din x vor fi egali cu biții 2:1 ai lui a
// biții 1:0 din x vor fi egali cu 00
assign x = {b, 2'b01, a[2:1], 2'b00};
```
```
2 changes: 1 addition & 1 deletion chapters/verilog/parameters/drills/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Practice: Parameters

- Implementați și simulați un sumator parametrizat pe n biți, cu două intrări și o ieșire. Parametrizarea se va efectua asupra dimensiunii variabilelor.
Hint: De câți parametri este nevoie? Observați dependența între dimensiunea variabilelor de între și cea de ieșire.
Hint: De câți parametri este nevoie? Observați dependența între dimensiunea variabilelor de intrare și cea de ieșire.
Hint: Luând exemplul modulului de test implementat la exercițiul 1, instanțiați un sumator pe 6 biți și adăugați stimuli corespunzători pentru a-i testa întreaga plajă de valori.
6 changes: 3 additions & 3 deletions chapters/verilog/parameters/reading/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Parameter

Cuvântul rezervat ''parameter'' este o construcție de limbaj în verilog care permite unui modul să fie reutilizat cu specificații diferite. Spre exemplu, un sumator poate fi parametrizat să accepte o valoare pentru numărul de biți care poate să fie configurată diferit de la o simulare la alta. Comportamentul lor este similar cu cel al argumentelor unor funcții în alte limbaje de programare cunoscute. Folosind ''parameter'' este declarată o valoare constantă, prin urmare este ilegală modificarea valorii acesteia în timpul simulării. De asemenea, este ilegal ca un alt tip de dată să aibă același nume ca unul dintre parametri.
Cuvântul rezervat ''parameter'' este o construcție de limbaj în Verilog care permite unui modul să fie reutilizat cu specificații diferite. Spre exemplu, un sumator poate fi parametrizat să accepte o valoare pentru numărul de biți care poate să fie configurată diferit de la o simulare la alta. Comportamentul lor este similar cu cel al argumentelor unor funcții în alte limbaje de programare cunoscute. Folosind ''parameter'', este declarată o valoare constantă, prin urmare, este ilegală modificarea valorii acesteia în timpul simulării. De asemenea, este ilegal ca un alt tip de dată să aibă același nume ca unul dintre parametri.

```verilog
parameter MSB = 7; // MSB este un parametru cu valoarea constantă 7
Expand All @@ -16,7 +16,7 @@ O variabilă de tip parametru este vizibilă local, în modulul ce a fost declar
## Construirea și instanțierea modulelor parametrizabile


Instanțierea modulelor a fost folosită și în laboratorul anterior pentru a invoca logica implementată într-un alt modul. În acel context, era necesar să cunoaștem dimensiunea semnalelor din interfață pentru a le potrivi cu variabilele conectate la instanță. În cazul în care un modul are dimensiunile porturilor parametrizate, acesta poate fi instanțiat cu valori particulare ale parametrilor (diferite de cele predefinite). Să considerăm ca exemplu un modul de mai jos:
Instanțierea modulelor a fost folosită și în laboratorul anterior pentru a invoca logica implementată într-un alt modul. În acel context, era necesar să cunoaștem dimensiunea semnalelor din interfață pentru a le potrivi cu variabilele conectate la instanță. În cazul în care un modul are dimensiunile porturilor parametrizate, acesta poate fi instanțiat cu valori particulare ale parametrilor (diferite de cele predefinite). Să considerăm drept exemplu modulul de mai jos:

```verilog
module my_beautiful_module (out, a, b);
Expand Down Expand Up @@ -62,7 +62,7 @@ my_beautiful_parameterized_module #(.a_width(3),
.b_width(2),
.out_width(5)) inst2(out, a, b);
// Sau, menținându-se ordinea parametrilor, doar prin specificarea noilor // dimensiuni:
// Sau, menținându-se ordinea parametrilor, doar prin specificarea noilor dimensiuni:
my_beautiful_parameterized_module #(3, 2, 5) inst3(out, a, b);
```
Expand Down
Loading

0 comments on commit 09f99ca

Please sign in to comment.