CID Aplicatii 7

De la WikiLabs
Jump to navigationJump to search

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