Forum: FPGA, VHDL & Co. selbst resetender Counter


von vhdl-anfänger (Gast)


Lesenswert?

Hallo.
Ich hab mir folgendes für einen Counter(umzusetzen in VHDL und auch auf 
ein FPGA zu bringen) überlegt:
Ich hab einen synchronen Reset Eingang. Jetzt will ich aber, das wenn 
ich den reset setze, das der counter auf 0 zurückspringt und dann, 
obwohl der reset noch auf 1 ist, ganz normal weiterzählt. Erst bei der 
nächsten steigenden Flanke vom reset soll wieder auf 0 zurückgesetzt 
werden, und nicht, das der Counter die ganze Zeit auf 0 bleibt solange 
rst = 1.
Macht man sowas? Führt das zu einer "unglücklichen"(sprich 
ineffizienten) HW?
Grüße

von Werktätiger (Gast)


Lesenswert?

vhdl-anfänger schrieb:
> Hallo.
> Ich hab mir folgendes für einen Counter(umzusetzen in VHDL und auch auf
> ein FPGA zu bringen) überlegt:
> Ich hab einen synchronen Reset Eingang. Jetzt will ich aber, das wenn
> ich den reset setze, das der counter auf 0 zurückspringt und dann,
> obwohl der reset noch auf 1 ist, ganz normal weiterzählt. Erst bei der
> nächsten steigenden Flanke vom reset soll wieder auf 0 zurückgesetzt
> werden, und nicht, das der Counter die ganze Zeit auf 0 bleibt solange
> rst = 1.
> Macht man sowas? Führt das zu einer "unglücklichen"(sprich
> ineffizienten) HW?
> Grüße

in etwa so?

process(clk)
if rising_edge(clk) then
 reset_delayed <= reset;
 if reset = '1' and reset_delayed = '0' then
  count_q <= 0;
 else
  count_q <= count_q + 1;
 end if;
end if;
end process;

Sollte kein problem sein.

von vhdl-anfänger (Gast)


Lesenswert?

ok. scheint zu funktionieren.^^
Danke

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

vhdl-anfänger schrieb:
> scheint zu funktionieren.^^
Das Speichern des vorigen Zustands und der Vergleich mit dem aktuellen 
zustand nennt sich "Flankenerkennung". Die braucht man öfter mal...

von vhdl-anfänger (Gast)


Lesenswert?

ich weiß... ich wusste nur nicht wie ich das hier so formulieren kann... 
Hehe manchmal gehts nicht besser

von Joe F. (easylife)


Lesenswert?

Werktätiger schrieb:
1
(1)  if rising_edge(clk) then
2
(2)    reset_delayed <= reset;
3
(3)    if reset = '1' and reset_delayed = '0' then
4
(4)      count_q <= 0;

Entsteht hier nicht eine Racecondition?

Die Zuweisung (2) passiert ja quasi gleichzeitig mit dem Vergleich (3), 
also würde (4) eigentlich eher selten ausgeführt.

Besser wäre glaube ich soetwas hier:
1
if falling_edge(clk) then
2
 reset_delayed <= reset;
3
end if;
4
5
if rising_edge(clk) then
6
 if reset = '1' and reset_delayed = '0' then
7
  count_q <= 0;
8
 else
9
  count_q <= count_q + 1;
10
 end if;
11
end if;


oder vielleicht auch so:
1
process(clk)
2
if rising_edge(clk) then
3
 if reset = '1' and reset_delayed = '0' then
4
  count_q <= 0;
5
  reset_delayed <= 1;
6
 else
7
  count_q <= count_q + 1;
8
  reset_delayed <= reset;
9
 end if;
10
end if;
11
end process;

: Bearbeitet durch User
von mhm (Gast)


Lesenswert?

Joe F. schrieb:
> Werktätiger schrieb:
> (1)  if rising_edge(clk) then
> (2)    reset_delayed <= reset;
> (3)    if reset = '1' and reset_delayed = '0' then
> (4)      count_q <= 0;
>
> Entsteht hier nicht eine Racecondition?
>
> Die Zuweisung (2) passiert ja quasi gleichzeitig mit dem Vergleich (3),
> also würde (4) eigentlich eher selten ausgeführt.

Nochmal ansehen, wie sich Signale (erkennbar an <= in Zeile 2) in einem 
(synchronen) Prozess verhalten ;)

von Joe F. (easylife)


Lesenswert?

Alright, sorry. Hab wohl zu lange mit Verilog gearbeitet und 
zugegebenermaßen keine Ahnung von VHDL.
In Verilog ist "<=" ein non-blocking assignment, würde also 
'gleichzeitig' mit dem if ausgeführt werden.

Wer es auch wie ich nicht wusste, hier mehr Infos:
http://www.gmvhdl.com/signals.htm

: Bearbeitet durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Joe F. schrieb:
> In Verilog ist "<=" ein non-blocking assignment, würde also
> 'gleichzeitig' mit dem if ausgeführt werden.
Und trotzdem wäre da weit&breit keine Gefahr, weil das Design vollkommen 
synchron ist. Du hättest schlimmstenfalls einen Takt Latency.

von Joe F. (easylife)


Lesenswert?

Lothar M. schrieb:
> weil das Design vollkommen
> synchron ist.

Darin liegt ja genau das Problem.
'reset_delayed' würde seinen Zustand ändern,
während 'gleichzeitig' der Vergleich mit 'reset' stattfindet (in 
Verilog).
Je nachdem, wie viele ps dazwischen liegen, geht das gut, oder auch 
nicht.

Nicht, dass "asynchron" die Lösung wäre, da weiss man erst recht nicht, 
wie viel Zeit zwischen den Zustandsänderungen liegt...

> Du hättest schlimmstenfalls einen Takt Latency.

Was heisst "schlimmstenfalls"? Hat man, oder hat man nicht?
Und genau da fängt es an eklig zu werden.

Darum ist meiner Meinung nach die beste Lösung 'reset_delayed' zu einem 
definierten Zeitpunkt (eine halbe Clock vorher) seinen Zustand ändern zu 
lassen, bevor der Vergleich stattfindet.

: Bearbeitet durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Joe F. schrieb:
> 'reset_delayed' würde seinen Zustand ändern,
> während 'gleichzeitig' der Vergleich mit 'reset' stattfindet (in
> Verilog).
> Je nachdem, wie viele ps dazwischen liegen, geht das gut, oder auch
> nicht.
Weil alle Signale synchron sind (reset und reset_delayed) ändern sich 
ihre Pegel immer nur nach einer Taktflanke. Dann bricht Hektik aus, denn 
die Kombinatorik berechnet neue Zustände. Und die müssen nur rechtzeitig 
zur nächsten Taktflanke stabil sein. Und es ist klar, dass ein 
synchroner Zähler erst mit der nächsten Taktflanke auf einen Reset 
reagiert.
Das hat mit Verilog oder VHDL nichts zu tun. Hier geht es nur um die 
Hardware, und die ist beide Male die selbe.

Joe F. schrieb:
> 'reset_delayed' zu einem definierten Zeitpunkt (eine halbe Clock vorher)
> seinen Zustand ändern zu lassen, bevor der Vergleich stattfindet.
Auf diese Weise halbiert man sich die zur Verfügung stehende Zeit (bzw 
man verdoppelt die Taktfrequenz in diesem Pfad) und macht das Timing 
unnötigerwrise knapper.

Konkret ist es so, dass man durch die Verwendung des verzögerten Signals 
den Reset selbst nicht verzögert, sondern nur einen wiederholten Reset 
in nächsten Takt verhindert.

: Bearbeitet durch Moderator
von Fpgakuechle K. (Gast)


Angehängte Dateien:

Lesenswert?

Ich hab mal die Logik skiziert ->  da kommt kein delay dazu. Selbst die 
Gatterlaufzeit durch das AND entschwindet wahrscheinlich in der 
LUT-Logikwolke die den nächsten Zählerstand ermittelt.


Vielleicht wird es sichtbarere wenn man logik und D-FF getrennt 
beschreibt.
1
--kombinatorischer process für Logik
2
process(counter_q,reset,reset_delayed_q)
3
begin
4
 if reset = '1' and reset_delayed_q = '0' then
5
   counter_next <= 0;
6
 else
7
   counter_next <= counter_q + 1;
8
  end if;
9
end process;
10
11
--getakter prozess für FF
12
process(clk)
13
begin
14
 if rising_edge(clk) then
15
  reset_delayed_q <= reset;
16
  counter_q       <= counter_next;
17
 end if;
18
end process;

MfG,

von Sigi (Gast)


Lesenswert?

Fpga K. schrieb:
> Ich hab mal die Logik skiziert ->  da kommt kein delay dazu. Selbst die
> Gatterlaufzeit durch das AND entschwindet wahrscheinlich in der
> LUT-Logikwolke die den nächsten Zählerstand ermittelt.

Ja, denn selbst Uralt-FPGAs bauen auf LUT4 (16Bit LUT) auf,
für den Counter wird nur ein LUT-Eingang verwendet, bleiben
2 Eingänge für Reset und Reset-Delay. Damit hat man zum
einen nur eine LUT-Stufe (kein Baum) und zum Anderen keine
höhere Laufzeit. Nimmt man an, das Reset synchron ist,
kommt es durch Delay-Reset bei der Flankenerkennung zu
keiner Latenz.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.