View Full Version : [VHDL] cronometro
ciao a tutti, sto cercando un cronometro in VHDL che conti da 0 a 60 secondi... qualcuno sa dirmi dove ne posso trovare uno per prendere spunto?
Grazie mille
Ma questo timer deve essere regolato su un clock esterno ? Se sai la frequenza del clock esterno è semplice realizzare il timer è semplicemente un contatore su uno o più registri.
Usare Time ha poco senso perché misura solo il tempo di simulazione, quindi non è sintetizzabile in hardware.
non sono molto pratico di vhdl... i nteoria io devo solo saper fare un cronometro che vada da 0 a 60...
Ripeto, senza un clock esterno non ha molto senso (come fai a temporizzare il conteggio ?). Le specifiche del progetto ti devono dire la frequenza del clock, in alternativa dovresti presentare in ingresso il numero di cicli di clock corrispondenti alla durata di un secondo (direi che su un numero a 32 bit va bene), quindi anche un segnale di write/enable che fa in modo di abilitare la scrittura del valore in un registro e di inizializzare il conteggio.
Input: start/restart, stop, reset.
Output: num_sec, num_centsec.
La gestione del sistema deve garantire una reattività agli
ingressi pari a 10 microsec.
queste sono le uniche specifiche che ho..
Allora includi un generatore di clock nel modulo VHDL...
Questo è un generatore di clock:
process
begin
loop
CLK <= not CLK;
wait for 5 us;
end loop;
end process;
Permette una reattività di 10 microsecondi agli ingressi, come richiesto dal testo. Infatti lo puoi usare anche per sincronizzare la lettura dei segnali in ingresso. Dopo è semplice, basta usare un contatore che conta i colpi di clock.
Una curiosità studi a Pisa ?
nu a genova... ok quello mi serve per il clock... ora come ci costruisco attorno il cronometro ?_?
nu a genova... ok quello mi serve per il clock... ora come ci costruisco attorno il cronometro ?_?
Bastano due contatori, dopo 100 colpi di clock incrementi i millisecondi, quando i millisecondi arrivano a 1000 incrementi i secondi.
ehm... ho qualche lacuna di vhdl :eek:
ehm... ho qualche lacuna di vhdl :eek:
Basta studiare, non ci vuole molto :D
In una giornata le cose basilari (e queste sono basilari) le impari.
mi sai indicare una sorta di tutorial inerente al caso ? :o
Prova questo: http://xoomer.alice.it/nitorqua/vhdl/vhdl.html
sto cercando di smanettare con il link che mi hai passato, una curiosità:
ora io devo fare due contatori ok? Pero' poi come realizzo i due output? cioè mi è richiesto in output solo il numero di sec e il numero dei centesimi di sec...
Definirai un'entity con gli input e gli ouptput richiesti. Ovviamente visto che l'output dovrà essere un numero binario dovranno essere due numeri binari dovrai usare un vettore di bit per rappresentarlo nella entity:
MSEC_OUT : out std_logic_vector(9 downto 0);
SEC_OUT : out std_logic_vector(5 downto 0);
Ho usato quel numero di bit perché i millisecondi dovranno avere un range da 0 a 1000 (2^10 = 1024) mentre i secondi solo fino a 60 (2^6 = 64).
Quando hai definito la entity e la sua implementazione, puoi passare alla simulazione del funzionamento, ovviamente dipende dall'ambiente che usi per simulare il tutto, ma in teoria basta realizzare un processo quantizzato ogni tot secondi (sempre con la tecnica del wait). Puoi settare reset e start/stop ai valori che vuoi testare (ad esempio potresti esaurire tutti i vari input come una tavola di verità) e vedere l'ouput del contatore dopo 1 ms (+ 10 ns) verificando che abbia effettua un conteggio sui ms e dopo 1 secondo verificando che abbia conteggiato anche il secondo. E così via per verificare che l'output sia quello desiderato ad ogni istante (in realtà non importa verificare ogni istante, l'importante è verificare che i ms arrivati a 999 poi tornino a 0 e i secondi vengano incrementati e che arrivato a 60 secondi l'aggeggio si fermi).
Ovviamente dovrai verificare anche la funzionalità di start/stop e del reset.
sei enorme :cool:
comunque dev'essere perforza un binario in uscita ?
comunque dev'essere perforza un binario in uscita ?
Sai...nel mondo digitale :D
ora cerco di capire come fare il contatore... in caso ti richiedo :D
ora cerco di capire come fare il contatore... in caso ti richiedo :D
Intanto prova a fare qualcosa temporizzato dal clock, non direttamente l'intero problema. Fai ad esempio un contatore infinito. Incrementi di 1 un registro e lo assegni in output. Aggiungici anche un reset in modo da resettare il valore del registro (il reset solitamente è attivo basso).
A quel punto diventa semplice generalizzare il tutto ;)
Intanto prova a fare qualcosa temporizzato dal clock, non direttamente l'intero problema. Fai ad esempio un contatore infinito. Incrementi di 1 un registro e lo assegni in output. Aggiungici anche un reset in modo da resettare il valore del registro (il reset solitamente è attivo basso).
A quel punto diventa semplice generalizzare il tutto ;)
eh ma considera che anche quello che hai appena detto per me è totalemente nuovo :P
eh ma considera che anche quello che hai appena detto per me è totalemente nuovo :P
Lo è per tutti la prima volta che lo si usa ;)
ciao, innanzitutto colgo l'occasione per farti gli auguri :cool:
poi... dici che cosi funziona ?
ENTITY dff_cnt IS
PORT (CLK : IN std_logic;
RST_N : IN std_logic;
EN : IN std_logic;
Q : OUT std_logic_vector(3 DOWNTO 0));
END dff_cnt;
ARCHITECTURE rtl OF dff_cnt IS
SIGNAL i_q : std_logic_vector(3 DOWNTO 0);
BEGIN -- rtl
Q <= i_q;
p_ff: PROCESS (CLK, RST_N)
BEGIN -- PROCESS p_ff
IF RST_N = '0' THEN
i_q <= (OTHERS => '0');
ELSIF CLK'event AND CLK = '1' THEN
IF (EN = '1') THEN
i_q <= i_q + 1;
END IF;
END IF;
END PROCESS p_ff;
END rtl;
Questo è un contatore sincronizzato da 0 a 15...dovrebbe funzionare. Quando arriva a 15 però al clock successivo ritorna a zero.
scusa ma dove lo vedi che arriva a 15?
al posto dell'azzeramento dovrei incrementare le due uscite che pero' non ho messo :
MSEC_OUT : out std_logic_vector(9 downto 0);
SEC_OUT : out std_logic_vector(5 downto 0);
come mi avevi suggerito... ma basta fare ad esempio MSEC_OUT +1; ?
Q : OUT std_logic_vector(3 DOWNTO 0)
Sono 4 bit, quindi va da 0 a 15. Se il clock è a 10us conta solo fino a 160 us. A te serve che arrivi a 1000us. Il contatore deve arrivare a 100 e quando arriva a 100 devi incrementare i msec.
ENTITY dff_cnt IS
PORT (CLK : IN std_logic;
RST_N : IN std_logic;
EN : IN std_logic;
Q : OUT std_logic_vector(24 DOWNTO 0));
MSEC_OUT : out std_logic_vector(9 downto 0);
SEC_OUT : out std_logic_vector(5 downto 0);
END dff_cnt;
ARCHITECTURE rtl OF dff_cnt IS
SIGNAL i_q : std_logic_vector(24 DOWNTO 0);
BEGIN -- rtl
Q <= i_q;
p_ff: PROCESS (CLK, RST_N)
BEGIN -- PROCESS p_ff
IF RST_N = '0' THEN
i_q <= (OTHERS => '0');
ELSIF CLK'event AND CLK = '1' THEN
IF (EN = '1') THEN
i_q <= i_q + 1;
ELSIF (Q = i_q) THEN
MSEC_OUT +1;
END IF
END IF;
END IF;
END PROCESS p_ff;
END rtl;
così, parzialmente dici che ci siamo ?
Q è sempre uguale a i_q ;)
Q non ti serve più come uscita, devi memorizzare il valore interno del contatore di MSEC.
si ma a me interessa incrementare MSEC_OUT (si incrementa come ho fatto io?) solo dopo che ha fatto un giro completo...
l'unica cosa che mi viene in mente è mettere l'incremento dell'uscita fuori dal processo rtl ma mi sembra una cosa un po improvvisata..
si ma a me interessa incrementare MSEC_OUT (si incrementa come ho fatto io?) solo dopo che ha fatto un giro completo...
Non dopo un giro completo, ma quando arriva a 100 (ti servono 7 bit, non 24), quindi se i_q = 100 incrementi MSEC e azzeri i_q.
Non si fa come hai fatto te, deve esserci un registro interno che contiene il valore dato in uscita MSEC_OUT, quindi assegnare il registro interno all'uscita (così come avviene per Q nel sorgente ora). Tu devi lavorare sul registro interno incrementandolo di uno nella situazione descritta sopra.
Per incrementarlo si fa allo stesso modo in cui hai incrementato i_q.
ok forse ci sono quasi :D intanto ti chiedo, l'output richiesto era centsec non millisec... i bit cambiano quindi giusto ?
MSEC_OUT : out std_logic_vector(9 downto 0); questi diventano 7 giusto ???
Certo, bastano 7, ovviamente devi verificare che il contatore arrivi a 1000 e non a 100.
ENTITY dff_cnt IS
PORT (CLK : IN std_logic;
RST_N : IN std_logic;
EN : IN std_logic;
Q : OUT std_logic_vector(9 DOWNTO 0));
CSEC_OUT : out std_logic_vector(7 downto 0);
SEC_OUT : out std_logic_vector(5 downto 0);
END dff_cnt;
ARCHITECTURE rtl OF dff_cnt IS
SIGNAL i_q : std_logic_vector(9 DOWNTO 0);
SIGNAL i_CS : std_logic_vector(7 DOWNTO 0);
SIGNAL i_S : std_logic_vector(5 DOWNTO 0);
BEGIN -- rtl
process
begin
loop
CLK <= not CLK;
wait for 5 us;
end loop;
end process;
Q <= i_q;
CSEC_OUT <= i_CS;
SEC_OUT <= i_S;
p_ff: PROCESS (CLK, RST_N)
BEGIN -- PROCESS p_ff
IF RST_N = '0' THEN
i_q <= (OTHERS => '0');
ELSIF CLK'event AND CLK = '1' THEN
IF (EN = '1') THEN
i_q <= i_q + 1;
ELSIF (i_q = 1000) THEN
i_q = 0; i_CS <= i_CS +1;
ELSIF (i_CS = 100) THEN
i_S <= i_S + 1; i_CS = 0;
END IF;
END IF;
END PROCESS p_ff;
END rtl;
a logica mi sto avvicinando:D
xke se non sbaglio ora i bit di Q devono essere 9...
gli errori che mi da sono : il wait non me lo fa sintetizzare
mi dice che non posso fare = 0, se metto <= mi dice che sono di tipo diverso e non posso farlo.. se metto <= "0" mi dice che la dimensione è sbagliata
pensavo, ma se nell'architecture mettessi, anziche i tre vettori, una cosa simile :
ARCHITECTURE rtl OF dff_cnt IS
SIGNAL i_q : natural;
SIGNAL i_CS : natural;
SIGNAL i_S : natural;
cosi da azzerare piu facilmente? in uscita puo andare un natural no ?
ok ho editato il messaggio precedente cosi è tutto piu chiaro :stordita:
cionci non mi abbadonare proprio ora che sono ad un passo:cry:
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.