CATEGORII DOCUMENTE |
REGISTRE, MEMORII, NUMARATOARE
implementate In verilog
Scopul lucrarii
Descrierea unor structuri de memorare realizate cu latch-uri sau bistabile (registru, memoria statica RAM), precum si descrierea automatelor bistabile (bistabilele JK si T) si a structurilor de numarare realizate cu acestea. Intelegerea functionarii acestor structuri prin testarea lor prin simulare cu ajutorul programului Veriwell.
2. Aparate necesare
- calculator compatibil Pentium
- sistem de operare Windows 95 sau superior
- programul VeriWell 2.0, produs de Wellspring Solutions, versiunea freeware, disponibila pe Internet
3. Consideratii teoretice
Folosind descrierea comportamentala a bistabilului de tip D, discutata data trecuta si disponibila in fisierul bistabil_D.v, sa incercam sa realizam o descriere structurala a registrului paralel pe 4 biti, reprezentat in figura 3.1. Descrierea poate fi urmatoarea:
module register_4(out, in, clock, reset);
input clock, reset;
input[3:0] in;
output[3:0] out;
D_flipflop bistabil3(out[3], q_negat, in[3], 0, reset, clock),
bistabil2(out[2], q_negat, in[2], 0, reset, clock),
bistabil1(out[1], q_negat, in[1], 0, reset, clock),
bistabil0(out[0], q_negat, in[0], 0, reset, clock);
endmodule
Se foloseste modelul D_flipflop din fisierul bistabil_D.v, cu intrarea asincrona SET dezactivata, iar fisierul de testare poate fi urmatorul:
Fig. 3.1 Reprezentarea registrului paralel de 4 biti si structura sa interna
module test_reg_4;
reg clock, reset;
reg[3:0] counter;
wire[3:0] out;
initial begin clock = 0;
counter = 0;
forever #5 clock = ~clock;
end
always @(negedge clock) counter = counter + 1;
initial begin reset = 0;
#42 reset = 1;
#48 reset = 0;
#12 reset = 1;
#30 reset = 0;
#100 $stop;
end
register_4 reg_under_test(out, counter, clock, reset);
initial $vw_dumpvars;
endmodule
Un circuit destinat memorarii unui volum mare de date in sistemele numerice este memoria RAM (Random Access Memory). Circuitul stocheaza bitii de date intr-o matrice de memorie, la fel ca memoria ROM. Diferenta consta in faptul ca informatia utila memorata in RAM trebuie mai intai sa fie "scrisa" acolo, inainte de a fi citita. Termenul RAM se traduce prin "memorie cu acces aleator", care sugereaza faptul ca timpul pentru citirea/scrierea unui bit nu depinde de pozitia bitului in matricea de memorie. Exista doua tipuri constructive de memorie RAM: RAM static sau SRAM, in care bitii de date, odata ce au fost inscrisi, sunt memorati atat timp cat circuitul integrat este alimentat cu tensiune, fara aplicarea altor semnale periodice din exterior, si RAM dinamic sau DRAM, in care datele memorate trebuie sa fie mereu reimprospatate prin citirea si apoi rescrierea lor periodica in locatiile respective de memorie, in caz contrar ele pierzandu-se definitiv.
Daca admitem ca semnalul de scriere a datelor in memorie, WRITE, este activ pe 1 logic, atunci configuratia simplificata a unei memorii SRAM de 8 cuvinte a cate 4 biti este reprezentata in figura 3.2. Modelul Verilog al unei memorii SRAM de 256 cuvinte a cate 16 biti este dat in continuare (8 linii de adresa si 16 linii de date):
Fig. 3.2 Structura unei memorii SRAM de 8 cuvinte de 4 biti
module mem(dout, din, address, write);
parameter word_dim = 16, // numarul de biti pe cuvant
add_dim = 8; // numarul de linii de adresa
input write;
input[word_dim - 1:0] din; // datele de intrare
input[add_dim - 1:0] address; // liniile de adresa
output[word_dim - 1:0] dout; // iesirea de date
reg[word_dim - 1:0] memory[0:(1'b1 << add_dim) - 1]; // memoria se
// defineste ca un sir de 256 registre pe 16 biti, iar inmultirea cu 2
// se face prin deplasare spre stanga
assign dout = memory[address];
always @(address or din or write)
if (write) memory[address] = din;
endmodule
Testarea functionarii modulului de memorie se poate face cu urmatorul program:
module test_mem;
parameter word_dim = 16,
add_dim = 8;
reg write;
reg[word_dim - 1:0] din;
reg[add_dim - 1:0] address;
wire[word_dim - 1:0] dout;
initial begin address = 0;
write = 0;
din = 16'b0100111110100001;
// memory_content.v este un fisier care contine datele memorate
$readmemb('memory_content.v', under_test_memory.memory);
#1 address = address + 1;
#1 address = address + 1;
#1 address = address + 1;
#1 address = address + 1;
#1 write = 1;
#1 write = 0;
#1 din = 16'b1111111110100001;
#1 write = 1;
#1 din = 16'b10100001;
#1 write = 0;
#4 $stop;
end
mem under_test_memory(dout, din, address, write);
initial $monitor('time=%0d add=%b din=%b write=%b dout=%b',
$time, address, din, write, under_test_memory.dout);
initial $vw_dumpvars;
endmodule
Bistabilul JK este cel mai complex bistabil si cel mai simplu automat cu stari finite, numit si automatul finit elementar. Daca consideram reprezentarea din figura 3.3, adica un circuit cu basculare pe front pozitiv, cu intrari asincrone de SET si RESET, active pe 1 logic (cazul circuitului CMOS 4027), atunci un model Verilog al circuitului este prezentat in continuare:
Fig. 3.3 Bistabilul JK cu basculare pe front pozitiv si tabelul tranzitiilor
module JK_flipflop(q, q_negat, j, k, set, reset, clock);
input j, k, set, reset, clock;
output q, q_negat;
reg q;
always @(posedge clock or posedge set or posedge reset)
if (set) #1 q = 1;
else if (reset) #1 q = 0;
else if(clock) case ()
2'b00: #2 q = q;
2'b01: #2 q = 0;
2'b10: #2 q = 1;
2'b11: #2 q = ~q;
endcase
assign #1 q_negat = ~q;
endmodule
In fisierul test_bistabil_JK.v s-a dat un exemplu de modul de testare a functionarii bistabilului JK. Cu acest circuit se pot construi diverse automate simple cu functie de numarator. Un exemplu de numarator asincron (sau divizor de frecventa) cu 3 bistabile JK este prezentat in figura 3.4. Modelul circuitului este urmatorul:
module async_counter(q2, q1, q0, count, clock, reset);
input count, clock, reset;
output q2, q1, q0;
wire q1_negat, q0_negat;
JK_flipflop ff_2(q2, q2_negat, count, count, 0, reset, q1_negat),
ff_1(q1, q1_negat, count, count, 0, reset, q0_negat),
ff_0(q0, q0_negat, count, count, 0, reset, clock);
endmodule
Fig. 3.4 Numarator asincron pe 3 biti realizat cu bistabile JK
Pentru testare se poate folosi urmatorul modul:
module test_async_counter;
reg count, clock, reset;
wire q2, q1, q0;
initial begin clock = 0;
forever #10 clock = ~clock;
end
initial begin count = 1;
reset = 1;
#35 reset = 0;
#200 count = 0;
#40 $stop;
end
async_counter our_counter(q2, q1, q0, count, clock, reset);
initial $vw_dumpvars;
endmodule
Schema unui numarator sincron modulo 5 care numara crescator este data in figura 3.5. Daca folosim din nou modelul bistabilului JK descris anterior, atunci modelul Verilog al circuitului este urmatorul:
module sync_counter(q4, q2, q1, clock, reset);
input clock, reset;
output q4, q2, q1;
wire w1, q4_negat;
and #1 poarta_SI(w1, q1, q2);
JK_flipflop ff_4(q4, q4_negat, w1, 1, 0, reset, clock),
ff_2(q2, q2_negat, q1, q1, 0, reset, clock),
ff_1(q1, q1_negat, q4_negat, 1, 0, reset, clock);
endmodule
iar modulul de testare care verifica functionarea circuitului poate fi urmatorul:
module test_sync_counter;
reg clock, reset;
initial begin clock = 0;
forever #10 clock = ~clock;
end
Fig. 3.5 Numarator sincron modulo 5, realizat cu bistabile JK
initial begin
reset = 0;
#15 reset = 1;
#10 reset = 0;
#140 $stop;
end
sync_counter our_counter(q4, q2, q1, clock, reset);
initial $vw_dumpvars;
endmodule
4. Modul de lucru
Se lanseaza in executie VeriWell 2.0 si se vizualizeaza fisierele bistabil_D.v si registru_4biti.v. Se vizualizeaza si fisierul test_registru_4biti.v, care este fisierul de generare a testului pentru registrul paralel de 4 biti. Se deschide un proiect care contine cele 3 fisiere si se ruleaza, verificand ca nu exista erori de compilare. Vizualizati formele de unda si explicati functionarea circuitului. Realizati modelul unui registru serie de 4 biti si verificati functionarea circuitului. Reconstruiti modelul registrului paralel, introducand o intrare suplimentara (ENABLE), care sa permita memorarea datelor in registru, numai atunci cand este activata pe 1 logic. Verificati functionarea circuitului.
Se vizualizeaza fisierele memorie_SRAM.v si test_memorie_SRAM.v si se deschide proiectul care contine cele doua fisiere. Faceti simularea circuitului si verificati functionarea corecta a circuitului urmarind formele de unda. Observati ca nu exista fisierul memory_content.v care contine date din memorie. In aceasta situatie, datele memorate au implicit valoarea necunoscuta (X) pana cand capata prin atribuire noi valori in cadrul programului.
Vizualizati fisierele bistabil_JK.v si test_bistabil_JK.v si deschideti proiectul care contine cele doua fisiere. Faceti simularea circuitului si verificati functionarea corecta a circuitului urmarind formele de unda. Modificati modelul bistabilului de tip JK, introducand si posibilitatea ca ambele intrari asincrone de set si reset sa fie activate simultan, caz in care iesirile bistabilului se pozitioneaza pe 1 logic. Modificati si fisierul test_bistabil_JK.v pentru a pune in evidenta acest eveniment si repetati simularea circuitului, in toate situatiile posibile. Concepeti si un model de bistabil T si verificati functionarea lui cu ajutorul unui modul de test.
Vizualizati cele doua fisiere numarator_asincron.v si test_numarator_asincron.v si deschideti proiectul corespunzator, care contine inca un fisier suplimentar care descrie bistabilul folosit: bistabil_JK.v. Faceti simularea circuitului si verificati functionarea corecta a circuitului urmarind formele de unda. Observati ca resetarea numaratorului (sau resetarea bistabilelor din structura) se face de la inceput, altfel starea lui initiala ar fi necunoscuta (X).
Vizualizati cele doua fisiere numarator_sincron.v si test_numarator_sincron.v si deschideti proiectul corespunzator. Faceti simularea circuitului si verificati functionarea lui corecta urmarind formele de unda. Refaceti sinteza circuitului, folosind bistabile de tip T in locul bistabilelor JK. Construiti modelul unui numarator sincron cu incarcare paralela a datelor de intrare.
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 4123
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved