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