CID Aplicatii 7
1. Latch-ul
Latch-urile sunt dispozitive elementare de memorare, sensibile la nivelul semnalelor de intrare. Exemple de astfel de dispozitive sunt latch-urile de tip SR si latch-urile de tip D.
Latch-ul SR
Latch-ul de tip SR poate fi realizat cu doua porti SI NU sau SAU NU si este un dispozitiv asincron controlat de starile semnalelor S (set) si R (reset). Tabelul de adevar al acestui circuit este prezentat mai jos.
Atunci cand S este 1 si R este 0, iesirea Q va deveni 1, iar Qn va deveni 0. Atunci cand R este 1 si S este 0, iesirea Q se resteaza (devine 0), iar Qn devine 1. Starea de memorare apare atunci cand atat R cat si S sunt 0 in acelasi timp. Cazul in care R si S sunt 1 in acelasi timp duce la un comportament nedorit. (atat Q cat si Qn vor fi 0, ceea ce este incorect din punct de vedere al logicii dorite – Qn sa fie negatul lui Q). In plus, daca din aceasta stare se doreste trecerea in starea de memorare (R = 0, S = 0), poate aparea oscilatia. In realitate, cele doua porti nu vor avea acelasi timp de propagare datorita variatiilor de productie si circuitul va ajunge in cele din urma intr-o stare stabila, nepredictibila.
Descrierea structurala a latch-ului SR
`timescale 1ns/1ps
module latch_SR(
input R,
input S,
output Q,
output Qn
);
assign #1 Q = ~(Qn | R);
assign #1 Qn = ~(Q | S);
endmodule
Modul de test pentru latch-ul SR
`timescale 1ns/1ps
module latch_SR_TB();
reg S_t, R_t;
wire Q_t, Qn_t;
initial begin
R_t = 1;
S_t = 0;
#5 R_t = 0;
#5 S_t = 1;
#5 S_t = 0;
#5 R_t = 1;
S_t = 1;
#5 $stop();
end
latch_SR DUT(
.S(S_t),
.R(R_t),
.Q(Q_t),
.Qn(Qn_t)
);
endmodule
Latch-ul de tip D
Latch-ul de tip D elimina problema combinatiilor nedorite de la iesire. Acesta modifica iesire doar atunci cand semnalul de enable (E) este 1. Altfel, atunci cand E este 0, va memora starea anterioara (Qt-1).
Descrierea comportamentala a latch-ului D
module latch_D(
input D,
input E,
output Q
);
assign Q = (E == 1) ? D : Q;
endmodule
Modul de test pentru latch-ul D
`timescale 1ns/1ps
module latch_D_TB();
reg D_t, E_t;
wire Q_t;
initial begin
D_t = 0;
E_t = 1;
#1 D_t = 1;
#1 D_t = 0;
#1 E_t = 0;
#1 D_t = 1;
#1 D_t = 0;
#5 $stop();
end
latch_D DUT1(
.D(D_t),
.E(E_t),
.Q(Q_t)
);
endmodule
2. Bistabilul de tip D
Bistabilul de tip D este un dispozitiv de memorare ce salveaza valoarea intrarii pe unul din fronturile ceasului (in mod uzual, frontul crescator). El poate fi obtinut prin conectarea a doua latch-uri de tip D, conform schemei de mai jos. De obicei, singura iesire care ne intereseaza este Q.
Descrierea comportamentala a bistabilului D
module flipflop_D(
input data_in,
input clock,
output reg data_out
);
always@(posedge clock) begin
data_out <= data_in;
end
endmodule
Modulul de test pentru bistabilul de tip D
`timescale 1ns/1ps
module flipflop_D_TB();
reg data_in_t, clock_t;
wire data_out_t;
initial begin
data_in_t = 0;
#2 data_in_t = 1;
#4 data_in_t = 0;
#5 $stop();
end
initial begin
clock_t = 0;
forever #1 clock_t = ~ clock_t;
end
flipflop_D DUT(
.data_in(data_in_t),
.clock(clock_t),
.data_out(data_out_t)
);
endmodule
Observatie: Atunci cand avem un circuit secvential, se foloseste atribuirea non-blocanta ("<=”)
Bistabilul de tip D cu reset sincron
Resetarea unui bistabil inseamna aducerea valorii memorate la 0 sau la o alta valoare de reset definita de cel care proiecteaza circuitul. Vom considera in exemplul nostru ca resetarea va face 0 valoarea memorata. Un reset sincron inseamna ca acesta va actiona pe frontul crescator al ceasului. Asta inseamna ca reset-ul nu va fi prezent in lista de sensitivitati a circuitului, dar valoarea sa va fi interogata la fiecare front crescator de ceas si, daca acesta este activ, bistabilul va fi resetat. Vom considera ca activ palierul de 0 al semnalului de reset.
Descrierea comportamentala a bistabilului D cu reset sincron
module flipflop_D(
input data_in,
input reset,
input clock,
output reg data_out
);
always@(posedge clock) begin
if(reset == 0)
data_out <= 0;
else
data_out <= data_in;
end
endmodule
Modulul de test pentru bistabilul de tip D cu reset
`timescale 1ns/1ps
module flipflop_D_TB();
reg data_in_t;
reg reset_t;
reg clock_t;
wire data_out_t;
initial begin
data_in_t = 1;
reset_t = 1;
#2 reset_t = 0;
#2 reset_t = 1;
#2 data_in_t = 0;
#4 data_in_t = 1;
#5 $stop();
end
initial begin
clock_t = 0;
forever #1 clock_t = ~ clock_t;
end
flipflop_D DUT(
.data_in(data_in_t),
.reset(reset_t),
.clock(clock_t),
.data_out(data_out_t)
);
endmodule
Bistabilul de tip D cu reset asincron
Un reset asincron inseamna ca acesta va actiona asincron, fara a tine cont de ceas. Asta inseamna ca reset-ul va fi prezent in lista de sensitivitati a circuitului, trecerea sa in 0 (frontul cazator) cauzand imediat resetarea circuitului. De asemenea, orice eveniment de front crescator de ceas ce apare cat timp reset-ul este activ, va duce la mentinerea resetarii circuitului. Vom considera ca activ palierul de 0 al semnalului de reset si frontul cazator al acestuia ca declansator al resetarii asincrone.
Descrierea comportamentala a bistabilului D cu reset asincron
module flipflop_D(
input data_in,
input reset,
input clock,
output reg data_out
);
always@(posedge clock or negedge reset) begin
if(reset == 0)
data_out <= 0;
else
data_out <= data_in;
end
endmodule
3. Eliminarea hazardului folosind bistabile
Vom considera circuitul din ora anterioara de aplicatii si vom exemplifica eliminarea hazardului folosind elementele de sincronizare.
Implementarea circuitului cu iesiri sincronizate
`timescale 1ns/1ps
module Circuit(
input a,
input b,
input clock,
output c_sinc,
output d_sinc
);
wire c, d;
assign #1 c = ~(a | b);
assign #1 d = ~(c & b);
always@(posedge clock) begin
c_sinc <= c;
end
always@(posedge clock) begin
d_sinc <= d;
end
endmodule
Modulul de test pentru circuitul cu iesiri sincronizate
`timescale 1ns/1ps
module Circuit_TB();
reg a_t, b_t, clock_t;
wire c_sinc_t, d_sinc_t;
initial begin
a_t = 0;
b_t = 0;
#5 b_t = 1;
#30 $stop();
end
initial begin
clock_t = 0;
forever #5 clock_t = ~ clock_t;
end
Circuit DUT(
.a(a_t),
.b(b_t),
.clock(clock_t),
.c_sinc(c_sinc_t),
.d_sinc(d_sinc_t)
);
endmodule