Diferență între revizuiri ale paginii „CID aplicatii 10 : Aplicatii cu numaratoare”
(Nu s-au afișat 7 versiuni intermediare efectuate de același utilizator) | |||
Linia 7: | Linia 7: | ||
==Exemplu: Numaratul apasarilor unui buton== | ==Exemplu: Numaratul apasarilor unui buton== | ||
− | Un prim sistem simplu cu numarator poate fi cel care contorizeaza de cate ori a fost apasat un buton, | + | Un prim sistem simplu cu numarator poate fi cel care contorizeaza de cate ori a fost apasat un buton sau, echivalent, cate persoane/masini au trecut printr-un senzor, de cate ori a fost deschisa o usa etc. Acest sistem se poate apoi dezvolta cu usurinta pentru a numara si oamenii care trec invers prin respectivul set de senzori prin adaugarea functionalitatii de up/down la numarator. |
Un astfel de sistem simplu (varianta doar cu numarat intrari) ar arata in felul urmator: | Un astfel de sistem simplu (varianta doar cu numarat intrari) ar arata in felul urmator: | ||
− | [[Fișier:Aplicatii_numarator_exemplu_contor_senzor.png | | + | [[Fișier:Aplicatii_numarator_exemplu_contor_senzor.png | 800px]] |
Circuitul de debounce are rolul de a "curata" semnalul de intrare, astfel incat chiar si in prezenta zgomotului sau a unei activari indelungate a senzorului/butonului, sa se contorizeze un singur eveniment. O explicatie mai detaliata puteti gasi [[Circuitul_de_debounce|aici]]. | Circuitul de debounce are rolul de a "curata" semnalul de intrare, astfel incat chiar si in prezenta zgomotului sau a unei activari indelungate a senzorului/butonului, sa se contorizeze un singur eveniment. O explicatie mai detaliata puteti gasi [[Circuitul_de_debounce|aici]]. | ||
Linia 19: | Linia 19: | ||
Transcodorul pentru display cu 7 segmente este apoi folosit pentru o mai usoara vizualizare a numarului curent. | Transcodorul pentru display cu 7 segmente este apoi folosit pentru o mai usoara vizualizare a numarului curent. | ||
− | '''Observatie:''' transcodorul | + | '''Observatie:''' transcodorul pentru 7seg din exemplul de mai jos este in logica negativa. Daca circuitul fizic este in logica pozitiva trebuie adaugat un inversor la iesirea din acesta. De asemnea consider segmentul "a" pe bitul "0" si segmentul "h" pe bitul "6". |
− | '''Descrierea debouncer-ului (fisierul debounce. | + | '''Descrierea debouncer-ului (fisierul debounce.sv):''' |
<syntaxhighlight lang="Verilog"> | <syntaxhighlight lang="Verilog"> | ||
module debounce | module debounce | ||
Linia 28: | Linia 28: | ||
parameter limit = 20'd650000 | parameter limit = 20'd650000 | ||
) ( | ) ( | ||
− | input | + | input logic clock, |
− | input | + | input logic in, |
− | output | + | output logic out |
); | ); | ||
− | + | logic [19:0] counter; // observatie: si circuitul de debounce foloseste un numarator | |
− | + | logic hit; | |
assign out = (counter == limit); | assign out = (counter == limit); | ||
− | + | always_ff @(posedge clock) | |
begin | begin | ||
if(in == 0) | if(in == 0) | ||
Linia 66: | Linia 66: | ||
− | '''Descrierea numaratorului pe 4b(fisierul counter_4b. | + | '''Descrierea numaratorului pe 4b(fisierul counter_4b.sv):''' |
<syntaxhighlight lang="Verilog"> | <syntaxhighlight lang="Verilog"> | ||
module counter_4b | module counter_4b | ||
( | ( | ||
− | input | + | input logic clock, |
− | input | + | input logic reset, |
− | input | + | input logic en, |
− | output | + | output logic [3:0] out |
); | ); | ||
− | + | always_ff @(posedge clock) | |
begin | begin | ||
if(reset == 1) | if(reset == 1) | ||
Linia 99: | Linia 99: | ||
− | '''Descrierea transcodorului pentru afisaj cu 7seg(fisierul transcodor_7seg. | + | '''Descrierea transcodorului pentru afisaj cu 7seg(fisierul transcodor_7seg.sv):''' |
<syntaxhighlight lang="Verilog"> | <syntaxhighlight lang="Verilog"> | ||
module transcodor_7seg // logica negativa | module transcodor_7seg // logica negativa | ||
( | ( | ||
− | input [3:0] in, | + | input logic [3:0] in, |
− | output | + | output logic [6:0] out |
); | ); | ||
− | + | always_comb | |
begin | begin | ||
case(in) | case(in) | ||
Linia 134: | Linia 134: | ||
− | '''Descrierea sistemului, modulul de top (fisierul top. | + | '''Descrierea sistemului, modulul de top (fisierul top.sv):''' |
<syntaxhighlight lang="Verilog"> | <syntaxhighlight lang="Verilog"> | ||
module top | module top | ||
( | ( | ||
− | input | + | input logic clock, |
− | input | + | input logic reset, |
− | input | + | input logic button, |
− | output | + | output logic [6:0] out // logica negativa |
); | ); | ||
− | + | logic debounce_0_X_out; | |
− | + | logic [3:0] counter_4b_0_X_out; | |
debounce | debounce | ||
Linia 175: | Linia 175: | ||
− | '''Descrierea test bench-ului(fisierul tb. | + | '''Descrierea test bench-ului(fisierul tb.sv):''' |
<syntaxhighlight lang="Verilog"> | <syntaxhighlight lang="Verilog"> | ||
`timescale 1ns / 1ps | `timescale 1ns / 1ps | ||
Linia 181: | Linia 181: | ||
module tb(); | module tb(); | ||
− | + | logic clock_tb; | |
− | + | logic reset_tb; | |
− | + | logic button_tb; | |
− | + | logic [6:0] out_tb; | |
top dut | top dut | ||
Linia 233: | Linia 233: | ||
endmodule | endmodule | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | |||
− | |||
==Exercitii== | ==Exercitii== | ||
Linia 243: | Linia 241: | ||
El este alcatuit doar dintr-un numarator, iar fiecare bit al acestuia va fi practic un semnal de ceas cu frecventa din ce in ce mai mica astfel (la jumate): | El este alcatuit doar dintr-un numarator, iar fiecare bit al acestuia va fi practic un semnal de ceas cu frecventa din ce in ce mai mica astfel (la jumate): | ||
− | bit[0] - frecventa de 2 ori mai mica decat semnalul de ceas | + | bit[0] - frecventa de 2 ori mai mica decat semnalul de ceas |
+ | |||
bit[1] - frecventa de 2 ori mai mica decat bit[0], deci de 4 ori mai mica decat semnalul de ceas | bit[1] - frecventa de 2 ori mai mica decat bit[0], deci de 4 ori mai mica decat semnalul de ceas | ||
+ | |||
bit[2] - frecventa de 2 ori mai mica decat bit[1], deci de 8 ori mai mica decat semnalul de ceas | bit[2] - frecventa de 2 ori mai mica decat bit[1], deci de 8 ori mai mica decat semnalul de ceas | ||
+ | |||
Acest lucru se poate observa si in poza ce urmeaza: | Acest lucru se poate observa si in poza ce urmeaza: | ||
− | [[Fișier:Freq_divider_output.png| | + | [[Fișier:Freq_divider_output.png| 800px]] |
− | Implementati acest circuit si folosind ledurile prezente pe placa, incercati sa conectati bitul corespunzator la leduri astfel incat cel mai din dreapta led sa clipeasca cu o frecventa cat mai apropiata de 1s. | + | Implementati acest circuit, si folosind ledurile prezente pe placa, incercati sa conectati bitul corespunzator la leduri astfel incat cel mai din dreapta led sa clipeasca cu o frecventa cat mai apropiata de 1s. |
− | '''Observatie:''' Printr-un astfel de divizor de frecventa minimal, un numar | + | '''Observatie:''' Printr-un astfel de divizor de frecventa minimal, un numar foarte mic de frecvente poate fi generat. Daca se doreste generarea unui semnal periodic cu o perioada exacta, diferita de cele posibile prin acest mecanism, se poate construi urmatorul circuit: |
Linia 260: | Linia 261: | ||
Un astfel de divizor de frecventa este construit ca in figura de mai jos: | Un astfel de divizor de frecventa este construit ca in figura de mai jos: | ||
− | [[Fișier: | + | [[Fișier:Freq_div_orice_freq.png | 800px]] |
Prin adaugarea constantei "limit", perioada semnalului de iesire poate sa fie orice multiplu a perioadei semnalului de ceas. | Prin adaugarea constantei "limit", perioada semnalului de iesire poate sa fie orice multiplu a perioadei semnalului de ceas. | ||
− | Bistabilul de tip t, se modifica atunci cand limita este atinsa si practic iesirea lui este semnalul periodic. | + | Bistabilul de tip t, se modifica atunci cand limita este atinsa si practic iesirea lui este semnalul periodic dorit (cu observatia ca o perioada a semnalului de iesire necesita 2 numarari pana la limita). |
− | Sa se calculeze valoarea necesara pentru "limit" astfel incat pe | + | Sa se calculeze valoarea necesara pentru "limit" astfel incat pe leduri sa se genereze semnal cu perioada exact 1s. |
+ | |||
+ | '''Observatie:''' In FPGA exista fizic trasee speciale pentru reset si ca sinteza sa le foloseasca pe acestea in mod optim nu este recomandat sa se puna logica (cum e aici poarta sau) pe acestea. Modificati schema de mai sus astfel incat sa eliminati respectiva poarta de pe reset. (Sfat: numaratorul va avea acum si intrari de load: semnalul de comanda si data propriu zisa) | ||
===Exercitiul 3: PWM (Pulse Width Modulation)=== | ===Exercitiul 3: PWM (Pulse Width Modulation)=== | ||
Linia 273: | Linia 276: | ||
PWM este un concept folosit foarte des in multiple ramuri ale ingineriei, de la transmisiunea informatiei pana la controlul motoarelor sau al intensitatii ledurilor din instalatii de Craciun. El se refera la a avea un semnal periodic cu factor de umplere variabil, asa cum este aratat in poza de mai jos : | PWM este un concept folosit foarte des in multiple ramuri ale ingineriei, de la transmisiunea informatiei pana la controlul motoarelor sau al intensitatii ledurilor din instalatii de Craciun. El se refera la a avea un semnal periodic cu factor de umplere variabil, asa cum este aratat in poza de mai jos : | ||
− | [[Fișier:Pwm.png| | + | [[Fișier:Pwm.png| 800px]] |
+ | |||
Generarea unui astfel de semnal periodic se face printr-un numarator si un comparator, ca in figura de mai jos: | Generarea unui astfel de semnal periodic se face printr-un numarator si un comparator, ca in figura de mai jos: | ||
− | [[Fișier:Pwm_schematic.png | | + | [[Fișier:Pwm_schematic.png | 800px]] |
+ | |||
Raportul dintre limita pusa si valoarea la care numaratorul se reseteaza este practic factorul de umplere selectat. | Raportul dintre limita pusa si valoarea la care numaratorul se reseteaza este practic factorul de umplere selectat. | ||
Pentru testare pe placa, cei 6b ai limitei provin de la switch-uri si butoane. Afisarea se face pe led[0]. | Pentru testare pe placa, cei 6b ai limitei provin de la switch-uri si butoane. Afisarea se face pe led[0]. | ||
+ | |||
+ | Testati acest circuit in simulare si apoi implementati pe placa pentru o valoare fixa a limitei. Implementati in paralel mai multe generatoare de semnal PWM cu limite diferite, astfel incat sa observati diferentele de intentistate dintre ledurile comandate de acestea. | ||
Linia 290: | Linia 297: | ||
Un astfel de circuit se realizeaza punand inca un numarator in locul limitei, ca in poza de mai jos: | Un astfel de circuit se realizeaza punand inca un numarator in locul limitei, ca in poza de mai jos: | ||
− | [[Fișier:Pwm_duty_cycle_up_schematic.png | | + | [[Fișier:Pwm_duty_cycle_up_schematic.png | 800px]] |
+ | |||
− | Pentru o functionalitate suplimentara, a pastra un anumit factor de umplere mai multe perioade, am adaugat inca un numarator. | + | Pentru o functionalitate suplimentara, anume a pastra un anumit factor de umplere mai multe perioade, am adaugat inca un numarator. |
Pentru claritatea desenului, nu am mai tras efectiv firul de ceas catre intrarile unde acesta se duce. | Pentru claritatea desenului, nu am mai tras efectiv firul de ceas catre intrarile unde acesta se duce. | ||
Linia 299: | Linia 307: | ||
Rezultatul este: | Rezultatul este: | ||
− | [[Fișier:Pwm_duty_cycle_up_output.png | | + | [[Fișier:Pwm_duty_cycle_up_output.png | 800px]] |
+ | |||
+ | |||
+ | Testati circuitul propus prin simulare si apoi vizualizati implementarea sa pe placa. Alegeti limite potrivite astfel incat sa puteti observa usor rezultatul. | ||
+ | |||
− | '''Bonus:''' Incercati sa adaugati si parametri pentru LIMIT_DUTY_CYCLE_LOW si LIMIT_DUTY_CYCLE_HIGH, care sa permita factorului de umplere sa varieze doar intre ele | + | '''Bonus:''' Incercati sa adaugati si parametri pentru LIMIT_DUTY_CYCLE_LOW si LIMIT_DUTY_CYCLE_HIGH, care sa permita factorului de umplere sa varieze doar intre ele (numaratorul va avea nevoie de intrari pentru comanda de load si data load, ca sa poata incepe de la orice valoare). |
+ | '''Bonus:''' Modificati circuitul astfel incat semnalul de iesire sa isi schimbe sensul de variatie al factorului de umplere cand ajunge cu acesta la capat. In forma curenta factorul de umplere creste de la 0% la 100% si apoi se reseteaza brusc la 0%, repetand acest ciclu. Se vrea ca la ajungerea la 100% sa inceapa o scadere treptata catre 0%, urmata apoi de o urcare s.a.m.d. | ||
===Exercitiul 5: Ceas=== | ===Exercitiul 5: Ceas=== | ||
− | Un ceas poate fi construit cifra cu cifra, folosind numaratoare si comparatoare (si transcodoare pentru display cu 7seg ca sa se vada totul mai bine pe placa) | + | Un ceas poate fi construit cifra cu cifra, folosind numaratoare si comparatoare (si transcodoare pentru display cu 7seg ca sa se vada totul mai bine pe placa). |
Incercati sa implementati un ceas cu milisecunde, secunde si minute in varianta comportamentala. | Incercati sa implementati un ceas cu milisecunde, secunde si minute in varianta comportamentala. | ||
Linia 315: | Linia 328: | ||
− | Incercati si o implementare structurala a ceasului, mergand pe | + | Incercati si o implementare structurala a ceasului, mergand pe aceeasi idee. Fiecare cifra va contine numaratorul ei. Cand numaratorul unei cifre ajunge ajunge la limita sa, va da enable pentru numaratorul cifrei urmatoare. Daca este nevoie se pot folosi si porti aditionale (ex: ca sa creasca minutul cifra zecilor secundelor trebuie sa fie 5 si cifra unitatilor secundelor trebuie sa fie 9). |
'''Observatie:''' Va fi nevoie de un numarator cu frecventa rezolutiei dorite (aici 1 ms sau 1s). | '''Observatie:''' Va fi nevoie de un numarator cu frecventa rezolutiei dorite (aici 1 ms sau 1s). | ||
− | '''Observatie:''' Pentru a scrie mai putin puteti face un numarator doar cu secunde si minute. Principiul de baza este acelasi si daca aveati | + | '''Observatie:''' Pentru a scrie mai putin puteti face un numarator doar cu secunde si minute. Principiul de baza este acelasi si daca aveati milisecunde. |
− | '''Observatie:''' Simularea a cateva milisecunde sau chiar secunde este un proces indelungat (dureaza minute-ore fizice) | + | '''Observatie:''' Simularea a cateva milisecunde sau chiar secunde este un proces indelungat (dureaza minute-ore fizice), astfel strict pentru simulari se recomanda ceasul sa functioneze cu microsecunde sau milisecunde maxim. |
Versiunea curentă din 22 octombrie 2024 13:56
Teorie
Numaratoarele au extrem de multe aplicatii in lumea reala, cateva dintre acestea fiind descrise mai jos.
Exemplu: Numaratul apasarilor unui buton
Un prim sistem simplu cu numarator poate fi cel care contorizeaza de cate ori a fost apasat un buton sau, echivalent, cate persoane/masini au trecut printr-un senzor, de cate ori a fost deschisa o usa etc. Acest sistem se poate apoi dezvolta cu usurinta pentru a numara si oamenii care trec invers prin respectivul set de senzori prin adaugarea functionalitatii de up/down la numarator.
Un astfel de sistem simplu (varianta doar cu numarat intrari) ar arata in felul urmator:
Circuitul de debounce are rolul de a "curata" semnalul de intrare, astfel incat chiar si in prezenta zgomotului sau a unei activari indelungate a senzorului/butonului, sa se contorizeze un singur eveniment. O explicatie mai detaliata puteti gasi aici.
Numaratorul numara evenimentele.
Transcodorul pentru display cu 7 segmente este apoi folosit pentru o mai usoara vizualizare a numarului curent.
Observatie: transcodorul pentru 7seg din exemplul de mai jos este in logica negativa. Daca circuitul fizic este in logica pozitiva trebuie adaugat un inversor la iesirea din acesta. De asemnea consider segmentul "a" pe bitul "0" si segmentul "h" pe bitul "6".
Descrierea debouncer-ului (fisierul debounce.sv):
module debounce
#(
parameter limit = 20'd650000
) (
input logic clock,
input logic in,
output logic out
);
logic [19:0] counter; // observatie: si circuitul de debounce foloseste un numarator
logic hit;
assign out = (counter == limit);
always_ff @(posedge clock)
begin
if(in == 0)
begin
counter <= 0;
hit <= 0;
end
else
begin
if(counter == limit)
begin
hit <= 1;
counter <= counter + 1;
end
else
begin
if(in == 1 & hit == 0)
begin
counter <= counter + 1;
end
end
end
end
endmodule
Descrierea numaratorului pe 4b(fisierul counter_4b.sv):
module counter_4b
(
input logic clock,
input logic reset,
input logic en,
output logic [3:0] out
);
always_ff @(posedge clock)
begin
if(reset == 1)
begin
out <=0;
end
else
begin
if(en == 1)
begin
out <= out + 1;
end
else
begin
out <= out;
end
end
end
endmodule
Descrierea transcodorului pentru afisaj cu 7seg(fisierul transcodor_7seg.sv):
module transcodor_7seg // logica negativa
(
input logic [3:0] in,
output logic [6:0] out
);
always_comb
begin
case(in)
4'd0: out = 7'b1000000;// h....a
4'd1: out = 7'b1111001;
4'd2: out = 7'b0100100;
4'd3: out = 7'b0110000;
4'd4: out = 7'b0011001;
4'd5: out = 7'b0010010;
4'd6: out = 7'b0000010;
4'd7: out = 7'b1111000;
4'd8: out = 7'b0000000;
4'd9: out = 7'b0010000;
4'd10: out = 7'b0001000;
4'd11: out = 7'b0000011;
4'd12: out = 7'b1000110;
4'd13: out = 7'b0100001;
4'd14: out = 7'b0000110;
4'd15: out = 7'b0001110;
default: out = 7'b1111111;//tot stins
endcase
end
endmodule
Descrierea sistemului, modulul de top (fisierul top.sv):
module top
(
input logic clock,
input logic reset,
input logic button,
output logic [6:0] out // logica negativa
);
logic debounce_0_X_out;
logic [3:0] counter_4b_0_X_out;
debounce
#(
.limit(20'd50_000)
) debounce_0 (
.clock(clock),
.in(button),
.out(debounce_0_X_out)
);
counter_4b counter_4b_0
(
.clock(clock),
.reset(reset),
.en(debounce_0_X_out),
.out(counter_4b_0_X_out)
);
transcodor_7seg transcodor_7seg_0 // logica negativa
(
.in(counter_4b_0_X_out),
.out(out)
);
endmodule
Descrierea test bench-ului(fisierul tb.sv):
`timescale 1ns / 1ps
module tb();
logic clock_tb;
logic reset_tb;
logic button_tb;
logic [6:0] out_tb;
top dut
(
.clock(clock_tb),
.reset(reset_tb),
.button(button_tb),
.out(out_tb) // logica negativa
);
initial
begin
clock_tb = 0;
forever
begin
#5 clock_tb = ~clock_tb;
end
end
initial
begin
reset_tb = 0;
button_tb = 0;
#50;
reset_tb = 1;
#50;
reset_tb = 0;
#100;
repeat(5) // vreau 5 apasari de buton
begin
button_tb = 1;
repeat(70_000)
begin
@(posedge clock_tb);
end
button_tb = 0;
repeat(70_000)
begin
@(posedge clock_tb);
end
end
#1000 $stop();
end
endmodule
Exercitii
Exercitiul 1: Divizor de frecventa cu puteri ale lui 2
Divizorul de frecventa are rolul de a genera un semnal de ceas mai lent din semnalul de ceas principal. El este alcatuit doar dintr-un numarator, iar fiecare bit al acestuia va fi practic un semnal de ceas cu frecventa din ce in ce mai mica astfel (la jumate):
bit[0] - frecventa de 2 ori mai mica decat semnalul de ceas
bit[1] - frecventa de 2 ori mai mica decat bit[0], deci de 4 ori mai mica decat semnalul de ceas
bit[2] - frecventa de 2 ori mai mica decat bit[1], deci de 8 ori mai mica decat semnalul de ceas
Acest lucru se poate observa si in poza ce urmeaza:
Implementati acest circuit, si folosind ledurile prezente pe placa, incercati sa conectati bitul corespunzator la leduri astfel incat cel mai din dreapta led sa clipeasca cu o frecventa cat mai apropiata de 1s.
Observatie: Printr-un astfel de divizor de frecventa minimal, un numar foarte mic de frecvente poate fi generat. Daca se doreste generarea unui semnal periodic cu o perioada exacta, diferita de cele posibile prin acest mecanism, se poate construi urmatorul circuit:
Exercitiul 2: Divizor de frecventa ce poate genera orice perioada
Un astfel de divizor de frecventa este construit ca in figura de mai jos:
Prin adaugarea constantei "limit", perioada semnalului de iesire poate sa fie orice multiplu a perioadei semnalului de ceas.
Bistabilul de tip t, se modifica atunci cand limita este atinsa si practic iesirea lui este semnalul periodic dorit (cu observatia ca o perioada a semnalului de iesire necesita 2 numarari pana la limita).
Sa se calculeze valoarea necesara pentru "limit" astfel incat pe leduri sa se genereze semnal cu perioada exact 1s.
Observatie: In FPGA exista fizic trasee speciale pentru reset si ca sinteza sa le foloseasca pe acestea in mod optim nu este recomandat sa se puna logica (cum e aici poarta sau) pe acestea. Modificati schema de mai sus astfel incat sa eliminati respectiva poarta de pe reset. (Sfat: numaratorul va avea acum si intrari de load: semnalul de comanda si data propriu zisa)
Exercitiul 3: PWM (Pulse Width Modulation)
PWM este un concept folosit foarte des in multiple ramuri ale ingineriei, de la transmisiunea informatiei pana la controlul motoarelor sau al intensitatii ledurilor din instalatii de Craciun. El se refera la a avea un semnal periodic cu factor de umplere variabil, asa cum este aratat in poza de mai jos :
Generarea unui astfel de semnal periodic se face printr-un numarator si un comparator, ca in figura de mai jos:
Raportul dintre limita pusa si valoarea la care numaratorul se reseteaza este practic factorul de umplere selectat.
Pentru testare pe placa, cei 6b ai limitei provin de la switch-uri si butoane. Afisarea se face pe led[0].
Testati acest circuit in simulare si apoi implementati pe placa pentru o valoare fixa a limitei. Implementati in paralel mai multe generatoare de semnal PWM cu limite diferite, astfel incat sa observati diferentele de intentistate dintre ledurile comandate de acestea.
Exercitiul 4: PWM cu limita variabila
Un exemplu foarte uzual de folosire a PWM este aprinderea ledurilor cu diverse pattern-uri. Factorul de umplere determina intensitatea cu care ledul este aprins. Un PWM cu o limita variabila automata va face ledul sa para din ce in ce mai stins sau din ce in ce mai luminos (exemplu: instalatii de Craciun). Combinand asta cu leduri RGB se obtin efecte de schimbare a culorii ledului aparent la intamplare.
Un astfel de circuit se realizeaza punand inca un numarator in locul limitei, ca in poza de mai jos:
Pentru o functionalitate suplimentara, anume a pastra un anumit factor de umplere mai multe perioade, am adaugat inca un numarator.
Pentru claritatea desenului, nu am mai tras efectiv firul de ceas catre intrarile unde acesta se duce.
Rezultatul este:
Testati circuitul propus prin simulare si apoi vizualizati implementarea sa pe placa. Alegeti limite potrivite astfel incat sa puteti observa usor rezultatul.
Bonus: Incercati sa adaugati si parametri pentru LIMIT_DUTY_CYCLE_LOW si LIMIT_DUTY_CYCLE_HIGH, care sa permita factorului de umplere sa varieze doar intre ele (numaratorul va avea nevoie de intrari pentru comanda de load si data load, ca sa poata incepe de la orice valoare).
Bonus: Modificati circuitul astfel incat semnalul de iesire sa isi schimbe sensul de variatie al factorului de umplere cand ajunge cu acesta la capat. In forma curenta factorul de umplere creste de la 0% la 100% si apoi se reseteaza brusc la 0%, repetand acest ciclu. Se vrea ca la ajungerea la 100% sa inceapa o scadere treptata catre 0%, urmata apoi de o urcare s.a.m.d.
Exercitiul 5: Ceas
Un ceas poate fi construit cifra cu cifra, folosind numaratoare si comparatoare (si transcodoare pentru display cu 7seg ca sa se vada totul mai bine pe placa).
Incercati sa implementati un ceas cu milisecunde, secunde si minute in varianta comportamentala.
Observatie: Va fi nevoie fie separat, fie in modul de un numarator cu frecventa rezolutiei dorite (aici 1 ms).
Observatie: Codul va contine multe "if" de tipul "daca cifra unitatilor secundelor a ajuns la 10, se face 0 si cresc cifra zecilor", repetate pentru fiecare cifra.
Incercati si o implementare structurala a ceasului, mergand pe aceeasi idee. Fiecare cifra va contine numaratorul ei. Cand numaratorul unei cifre ajunge ajunge la limita sa, va da enable pentru numaratorul cifrei urmatoare. Daca este nevoie se pot folosi si porti aditionale (ex: ca sa creasca minutul cifra zecilor secundelor trebuie sa fie 5 si cifra unitatilor secundelor trebuie sa fie 9).
Observatie: Va fi nevoie de un numarator cu frecventa rezolutiei dorite (aici 1 ms sau 1s).
Observatie: Pentru a scrie mai putin puteti face un numarator doar cu secunde si minute. Principiul de baza este acelasi si daca aveati milisecunde.
Observatie: Simularea a cateva milisecunde sau chiar secunde este un proces indelungat (dureaza minute-ore fizice), astfel strict pentru simulari se recomanda ceasul sa functioneze cu microsecunde sau milisecunde maxim.