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.

Latch SR.png

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

Latch D.png

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.

Bistabil D.png

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.

FFD Reset Sincron.svg

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.

FFD Reset Asincron.svg

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.

Eliminare hazard.png

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