Sunteți pe pagina 1din 7

Fundamentele Calculatoarelor 2018 - 2019 Laborator 12

Laborator 12
1. Operatorul de atribuire blocking vs non-blocking

În Verilog putem avea două tipuri de atribuiri: blocking și non-blocking. Pentru


a vedea mai bine ce înseamnă vom simula următorul cod:

module b_vs_nb;
integer nba,nbb,nbc;
integer ba,bb,bc;

initial begin
ba = 4;
bb = 5;
bc = 6;
#1 ba = 2;
bb = ba;
bc = bb;
ba = bc;
#1;
end
initial begin
nba <= 4;
nbb <= 5;
nbc <= 6;
#2 nba <= 2;
nbb <= nba;
nbc <= nbb;
nba <= nbc;
#1;
end
endmodule

Un bloc initial sau always poate conține fie doar atribuiri blocking, fie doar
atribuiri non-blocking, nu un mix al celor două.

Observați în simulare diferența dintre operatorii blocking și non-blocking.

Toate circuitele secvențiale sincrone utilizează numai operatori de atribuire


non-blocking.

Mai multe detalii puteți găsi accesând link-ul de mai jos:

http://www.asic-world.com/tidbits/blocking.html
Fundamentele Calculatoarelor 2018 - 2019 Laborator 12

2. Flip-flop-uri în Verilog
2.1. D flip-flop

Se dă implementarea de mai jos:

module d_ff(
input d,clk,rst_b,
output reg q
);
// Always secvential care se executa
// la aparitia unui front crescator
// al clock-ului activ la 1
// sau la aparitia unui front descrescator
// al reset-ului activ la 0
always @ (posedge clk, negedge rst_b ) begin

if (!rst_b) begin
// Daca avem reset activ, adica !rst_b==1
// q este resetat, adica ia valoarea 0
q <= 1'd0;

end else begin


// Daca nu avem reset, adica !rst_b==0
// q devine d
q <= d;
end
end
endmodule

a) Să creeze un fișier cu numele design-ului de mai sus și să se scrie implementarea


de mai sus.
Fundamentele Calculatoarelor 2018 - 2019 Laborator 12

b) Să se creeze un fișier d_ff_tb cu codul de mai jos și să se simuleze. De acum


înainte semnalele din testbench nu vor mai conține extensia _tb din motive
de simplitate a scrierii codului.

module d_ff_tb;
// Declarare variabile
reg d,clk,rst_b;
wire q;
// Instantiere DUT
d_ff ff(
.d(d),
.clk(clk),
.rst_b(rst_b),
.q(q)
);
// Clock-ul se genereaza folosind
// structuri repetitive
initial begin
clk = 1'b0;
repeat (12) begin
// Utilizam un clock
// cu perioada de 20
// unitati de timp
#10 clk = ~clk;
end
end
// Pentru claritate, fiecare semnal
// de intrare are blocul sau
// "initial" de generare de stimuli
initial begin
rst_b = 1'b0;
#5 rst_b = 1'b1;
//#30 rst_b = 1'b1;
//#1 rst_b = 1'b0;
//#2 rst_b = 1'b1;
end
// Se dau valori aleatoare lui d
initial begin
d = 1'b0;
#25 d = 1'b1;
#25 d = 1'b0;
#25 d = 1'b1;
#1 d = 1'b0;
#1 d = 1'b1;
end
endmodule

c) Simulați decomentând cele 3 linii de la generarea lui rst_b și explicați


diferența dintre simularea anterioară și această simulare.
Fundamentele Calculatoarelor 2018 - 2019 Laborator 12

3. Registre

Registrele nu sunt altceva decât mai multe flip-flop-uri de același tip puse
împreună. Registrele sunt de 4 tipuri general vorbind:
• PIPO - Paralel Input Paralel Output
• PISO - Paralel Input Serial Output
• SIPO - Serial Input Paralel Output
• SISO - Serial Input Serial Output

3.1. Registru de tip PIPO

a) Flip-Flop-ul de tip D implementat ca în secțiunea 2.1, implementare pe care


o vom folosi în continuare, are schema de mai sus. A se observa semnalul de
reset activ la 0 și triunghi-ul de lângă CLK care semnifică faptul că avem un
circuit care este activ pe front. Semnalul CLK nu este negat, deci circuitul își
modifică ieșirea în funcție de intrare pe frontul crescător/ pozitiv al clock-ului.

b) Se va implementa folosind descriere structurală schema de mai jos. Hint: Se


va folosi un modul parametrizabil cu parametru n ca în Laboratorul 6.
Fundamentele Calculatoarelor 2018 - 2019 Laborator 12

c) Să se scrie un testbench pentru pipo_reg fără monitor, cu instanțiere și


generarea de stimuli de mai jos. În testbench setați parametrul ca fiind 8.

initial begin
clk = 1'b1;
repeat (12) begin
#10 clk = ~clk;
end
end
initial begin
rst_b = 0;
#5 rst_b = 1;
end
initial begin
d = 'hAB;
#25 d = 'hEF;
#25 d = 'hCD;
#23 d = 'hBA;
#7 d = 'hBE;
#12 d = 'hCF;
end

d) În simulare, în fereastra Wave selectați toate semnalele, dați click dreapta pe


ele și mergeți la opțiunea Radix → Hexadecimal . Observați când se schimbă
ieșirile în funcție de intrări și clock.
Fundamentele Calculatoarelor 2018 - 2019 Laborator 12

e) În fișierul d_ff schimbați posedge clk cu negedge clk și simulați.


Observați diferențele dintre un registru activ la frontul crescător al clock-ului
și un registru activ la frontul descrescător al clock-ului.

f) În Verilog se scrie mult mai simplu codul comportamental pentru un astfel de


registru. Pur și simplu un registru se scrie ca un flip-flop care are la intrare
n biți și la ieșire tot n biți. Implementați în Verilog comportamental un
registrul de tip PIPO cu numele pipo_comp . Hint: Implementarea este exact
ca la D flip-flop doar cu n biți la intrarea d și n biți la ieșirea q.

g) Creați un testbench pentru registrul creat la punctul f) și simulați-l. Hint:


Testbench-ul va fi foarte asemănător cu cel creat la punctul c). A se observa
ca este mult mai ușor de descris din punct de vedere comportamental un
registru decât să fie descris structural. De acum înainte vom descrie doar
comportamental circuitele sincrone secvențiale.

3.2. Registru de tip SISO ( de deplasare)

a) Registrul cu intrare serială și ieșire serială este utilizat pentru a face deplasări
(shiftări) la stânga sau la dreapta, în funcție de necesități. Implementați folosind
descriere comportamentală un registru de deplasare la dreapta cu numele
siso_plus. Hint: Datele seriale intră în partea stângă și ies pe partea dreaptă,
direcția deplasării fiind de la stânga la dreapta.

b) Creați un testbench fără monitor, cu instanțiere și generarea de stimuli de mai


jos pentru registrul de deplasare anterior creat.Parametrul din testbench care
se va transmite și DUT-ului va fi 4.
Fundamentele Calculatoarelor 2018 - 2019 Laborator 12

initial begin
clk = 1'b1;
repeat (36) begin
#5 clk = ~clk;
end
end
initial begin
rst_b = 0;
#2 rst_b = 1;
end
initial begin
d_ser = 1;
#22 d_ser = 0;
#24 d_ser = 1;
#23 d_ser = 0;
#30;
end

c) După ce simulați testbench-ul anterior creat, în fereastra Sim dați click pe butonul
+ de la siso_plus_tb și apoi dați click pe numele instanței DUT-ului ( în cazul
nostru, instanța se numește SISO). În fereastra Objects apar semnalele din
instanță. Adăugați în fereastra Wave semnalul data din DUT selectându-l în
fereastra Objects și apăsând combinația de taste Ctrl+W sau dând click dreapta
și alegând opțiunea Add Wave .

Dați click pe butonul + din dreptul vectorului data adăugat în fereastra Wave
pentru a vedea fiecare componentă a vectorului ca mai jos.

d) Selectați toate semnalele din fereastra Wave și dați click dreapta pe ele și mergeți
la opțiunea Radix → Binary . Mutați semnalul q_ser sub vectorul data și
explicați ce se întâmplă cu valorile din fiecare flip-flop din registru. A se observa
cum se deplasează în interiorul vectorului data informația primită în mod serial
și după cât timp ajunge la ieșirea q_ser.

S-ar putea să vă placă și