Stefan H. schrieb:
> Vielleicht liegt der Fehler hier!?
Wenn ich diese Abhängigkeit von der Taktfrequenz höre und sowas sehe,
dann weiß ich, was zu ändern ist:
1 | if reset = '0' or UhrZuruecksetzen = '1' then
|
2 | ZaehlerSekundenHundertstel <= 0;
|
3 | ZaehlerSekundenHundertstelUeberlauf <= '0';
|
4 | elsif rising_edge(takt) then
|
Das ist ein asynchroner kombinatorischer Reset. Der funktioniert in
Gedanken und in der Simulation tadellos. Aber in der Realität hast du da
beliebige Probleme mit irgendwelchen Spikes und Glitches, die jedesmal
entstehen, wenn irgendwas im Prozess FOLGEZUSTANDSBERECHNUNG_UHR
passiert. Sowas läuft in der Realität niemals zuverlässig. Du hast
Glück, dass du den Fehler dauernd hast, und nicht nur 1x pro Stunde...
;-)
Mach aus diesem asynchronen Reset einen synchronen Reset indem du ihn
ausschließlich im getakteten Teil deiner Prozesse abfrägst!
Das ist übrigens kein "könnte" oder "sollte", sondern ein "muss".
Insgesamt scheint die Beschreibung, naja, sagen wir mal auf maximale
"Lines of Code" optimiert nach dem Motto "Viel hilft viel". Aber das
kommt natürlich auch von der m.E. umständlichen 2-Prozess-Schreibweise.
Dazu das:
http://www.lothar-miller.de/s9y/archives/43-Ein-oder-Zwei-Prozess-Schreibweise-fuer-FSM.html
Aber das hängt natürlich leider auch vom Lehrer, dessen Bücher und
seinen Vorlieben ab...
Zudem reichen bei einem synchronen Prozess der Reset (wenn für die
Funktion überhaupt nötig!) und der Takt in der Sensitivliste. Denn der
Simulator (und nur der schert sich überhaupt um diese Liste, dem
Synthesizer ist die schnuppe) berechnet bei einer Änderung eines der
Signale darin den betroffenen Prozess neu.
Nachdem in diesem Prozess also das mit dem fehlerhaften asynchronen
UhrZuruecksetzen korrigiert ist, seht da nur noch:
1 | UHR_HUNDERTSTELSEKUNDEN: PROCESS (takt, reset)
|
2 | begin
|
3 | if reset = '0' then
|
4 | ZaehlerSekundenHundertstel <= 0;
|
5 | ZaehlerSekundenHundertstelUeberlauf <= '0';
|
6 | elsif rising_edge(takt) then
|
7 | if UhrStart = '1' and UhrUeberlauf = '0' and HundertstelTakt = '1' then
|
8 | if ZaehlerSekundenHundertstel < 9 then
|
9 | ZaehlerSekundenHundertstel <= ZaehlerSekundenHundertstel + 1;
|
10 | ZaehlerSekundenHundertstelUeberlauf <= '0';
|
11 | else
|
12 | ZaehlerSekundenHundertstel <= 0;
|
13 | ZaehlerSekundenHundertstelUeberlauf <= '1';
|
14 | end if;
|
15 | else
|
16 | ZaehlerSekundenHundertstel <= ZaehlerSekundenHundertstel;
|
17 | ZaehlerSekundenHundertstelUeberlauf <= '0';
|
18 | end if;
|
19 | if UhrZuruecksetzen = '1' then -- Reset: die letzte Zuweisung an ein Signal "gewinnt"
|
20 | ZaehlerSekundenHundertstel <= 0;
|
21 | ZaehlerSekundenHundertstelUeberlauf <= '0';
|
22 | end if;
|
23 | end if;
|
24 | end PROCESS UHR_HUNDERTSTELSEKUNDEN;
|
Und die Entprellung kannst du mitsamt der Flankenerkenn statt mit einer
FSM auch einfach mit einem Schieberegister machen:
http://www.lothar-miller.de/s9y/categories/5-Entprellung
http://www.lothar-miller.de/s9y/categories/18-Flankenerkennung
Sieh dir mal als Denkanstoß meine Stoppuhr an:
http://www.lothar-miller.de/s9y/archives/88-VHDL-vs.-Verilog-am-Beispiel-einer-Stoppuhr.html
Die kann mal schon starten und zählen. Die anderen Funktionen lassen
sich aber recht einfach integrieren. Für den Split (Rundenzeit) müsste
nur noch mit einem Registersatz als Zwischenspeicher die Anzeige vom
Zähler entkoppelt werden.
Mit zusätzlichen 30 Zeilen müsste das leicht zu schaffen sein.