Grund dafür ist, ich habe eine Statemachine in der verschiedene Timer us
- s Basis genutzt werden. Mit dieser Implementation kann ich aus dem
Prozess der Statemachine mittels setTimer und timer_newVal den Counter
innerhalb eines Clockzyklus neu setzten.
Oder kennt jemand eine bessere Lösung ohne, dass ich riesige Register
brauche um Sekunden zu zählen?
Wenn ein Timer z.B. mit einem Takt von 1ms getaktet wird und man mach
einen asynchronen Reset gibt es meiner Meinung nach zwei Möglichkeiten:
1. der Reset kommt z.B. bei 9,3ms dann kann der Timer beim nächsten
Tick, also bei 10ms auf 0 gesetzt werden. Dann braucht der Timer nur 1ms
Auflösung.
2. soll der Reset aber innerhalb eines FPGA-Systemclocks zurückgesetzt
werden, braucht man einen Timer mit der vollen Auflösung.
Kombinatorische Schleifen lassen sich eigentlich immer vermeiden. Wenn
du die clocks einsynchronisierst, warum dann die Zustandsabfrage nicht
einfach an den Anfang des Hauptprozesses. Damit sparst du dir sogar das
setTimer Signal und das newVal Register.
In der Statemachine kannst du dann einfach den Timer nach belieben
setzten.
Gestern habe ich mal in diesem Buch geblättert:
https://www.dpunkt.de/buecher/11821/9783864901737-fpgas-f%C3%BCr-maker.html
Dort empfehlen sie synchrone Designs.
Soweit ich gesehen habe, werden dort alle vorgestellten Funktionsblöcke
mit dem schnellen Systemclock versorgt.
Wenn man dann z.B einen Block braucht, der mit 1ms getaktet wird, wird
zusätzlich ein Pulssignal mit 1ms Periode und 20ns Dauer durchgeroutet.
Der langsame Takt ist also dann kein symmetrisches Rechtecksignal,
sondern nur ein Puls, der sich mit der langsamen Rate wiederholt.
Ich generiere mir für meine Designs meisst dedizierte counter clocks,
sprich ich hab z.B. 50MHz Systemtakt und dann jeweils einen Teiler für
1MHz, 1kHz und 1Hz. Diese Takte werden dann in die jeweiligen Blöcke
"gespiesen" und dort in ein 2-Bit Schieberegister gepackt für die
Flankenerkennung. Mit diesem Schieberegister kann man dann bequem
weiterarbeiten und muss nicht x-Mal einen Frequenzteiler implementieren
für ein und den selben Takt.
>Diese Takte werden dann in die jeweiligen Blöcke>"gespiesen" und dort in ein 2-Bit Schieberegister gepackt für die>Flankenerkennung.
Das jedes Modul extra noch mal ein Schieberegister zur Flankenerkennung
braucht, scheint mir etwas aufwendig.
Ich vermute, dass es mit dem Pulsprinzip besser geht.
Der entscheidende Punkt ist der:
1
process
2
begin
3
waituntilrising_edge(clk);
4
if(pulse_ms='1')then
5
speakerSignal<=notspeakerSignal;
6
endif;
7
endprocess;
Getaktet wird mit der vollen Systemfrequenz "clk", aber das
speakerSignal wird mit dem Puls gekippt.
Pope schrieb:> Mal eine Frage an die erfahrenen FPGA bändiger. Folgender Code generiert> mir combinatorische Latches das ist klar
Das ist mir eigentlich nicht klar. Die Latches passieren offenbar
ausserhalb des geposteten Codes. Du hast da nochmal irgendwo einen
gewaltigen Bock drin...
> Mit dieser Implementation kann ich aus dem Prozess der Statemachine> mittels setTimer und timer_newVal den Counter innerhalb eines> Clockzyklus neu setzten.
Such mal nach meinen "Postulaten" hier im Forum. Und lies dann gleich
die paar Zeilen drumrum. Dort haben andere Leute auch sowas
zusammengebastelt ud ihre Probleme damit.
> aber wie verboten ist es?
Sieh dir das Handbuch deines Synthesizers an. Wenn es dort nicht
ausdrücklich empfohlen wird, dann solltest du ganz, ganz genau wissen,
was du da tust. Das ist nicht der Fall.
> aber wie verboten ist es?
Ein solcher Code ist ein Kündigungsgrund.
Als ich neu im FPGA-Geschäft war, haben wir von einem Dienstleister mal
genau solchen Code bekommen, der asynchrone kombinatorische Resets und
Loads enthielt. Bei der Fehlersuche an diesem Code lernte ich, dass man
auch von "Profis" schlechten Code bekommen kann und dass man solche
Dinge wie asynchrone kombinatorische Resets besser nicht macht.
> Oder kennt jemand eine bessere Lösung ohne, dass ich riesige Register> brauche um Sekunden zu zählen?
Mach den ms-Timertic einfach zum synchronen Clock-Enable. So wie es der
Rest der Welt auch tut. Und so wie ich es hier im Lauflicht mit dem
Weiterschalttakt mache:
http://www.lothar-miller.de/s9y/archives/61-Lauflicht.html
Ich könnte mit dem dort erzeugten 3-Hz-Clock-Enable viele Lauflichter
mit der selben Frequenz ansteuern.
Wenn du also einen 1ms Clock-Enable machst (oder einen mit 100ms), ist
deine Zeitbasis fürderhin nur noch 1ms (oder 100ms) statt 20ns (bei
50MHz FPGA-Takt) und die ganzen Zähler werden wesentlich kürzer.
>Wenn du also einen 1ms Clock-Enable machst (oder einen mit 100ms), ist>deine Zeitbasis fürderhin nur noch 1ms (oder 100ms) statt 20ns (bei>50MHz FPGA-Takt) und die ganzen Zähler werden wesentlich kürzer.
100ms ... dort ist dann halt das Problem der "Granularität" die ich oben
versucht habe, zu beschreiben.
Die Frage ist: muss nach dem Reset der nächste Tick in genau 100ms
kommen, oder kann es eine Zeitspanne von 0..100ms sein.
Da ist die Frage an den "Pope": Was brauchst Du?
Aha, das ist ja quasi die gleiche Implementierung.
Mittlerweile meine ich aber ein Problem zu Erkennen: Der Puls aus aus
dem Clockdivider und der Clock selbst haben die steigende und fallende
Flanke quasi gleichzeitig, deshalb könnte es abhängig vom Routing im
FPGA in der nächsten Stufe zu einer Race-Condition kommen, d.h. die
Flanke des clk könnte leicht nach der vom Puls kommen.
chris schrieb:> Mittlerweile meine ich aber ein Problem zu Erkennen: ...Race-Condition...
Dass genau das nicht passiert, garantiert mir der FPGA-Hersteller. Ich
bezahle ihn dafür, dass er mir einen Baustein liefert, in dem der Takt
im gesamten FPGA gleichzeitig ist. Denn nur so funktioniert ein
synchrones Design:
1. Es kommt ein Takt, der die Daten an den Flipflopeingängen übernimmt.
2. Jetzt kommt Hektik ins FPGA, es werden neue Zustände oder
Zählerstände berechnet.
3. Kurz vor dem nächsten Takt muss alles fertig und stabil sein, damit
das ganze Spiel von vorn losgehen kann.
>Dass genau das nicht passiert, garantiert mir der FPGA-Hersteller. Ich>bezahle ihn dafür, dass er mir einen Baustein liefert, in dem der Takt>im gesamten FPGA gleichzeitig ist.
Signale ohne Laufzeit. Schade, dass das Einstein nicht mehr erleben
durfte ;-)
chris schrieb:> Signale ohne Laufzeit.
Deine Interpretation meiner Worte ist falsch, weil du "gleichzeitig" mit
"sofort" verwechselst.
Stichworte dazu sind "balanced clock tree" und "zero skew clock". Und da
geht es eben nicht darum, den Takt vom Pin sofort an die Flipflops zu
bekommen, sondern das Ziel ist, ihn gleichzeitig an den Flipflops
ankommen zu lassen.
chris schrieb:> Der Puls aus aus> dem Clockdivider und der Clock selbst haben die steigende und fallende> Flanke quasi gleichzeitig
Mitnichten:
1. Der Puls (sowas nennt man auch Tick) liegt eine volle Periodendauer
am Ausgang des FlipFlops an, die fallende Taktflanke kommt bereits nach
einer halben Periode.
2. Per Timing-Constraint wird sichergestellt, dass der Tick rechtzeitig
vor der Taktflanke (Setup-Time) anliegt und noch ausreichend lange
danach (Hold-Time).
N.B.: Der (Logik-)Simulator weiss nichts von Setup- und Hold-Time,
deswegen erscheinen dort Takt- und Signalflanke zum selben Zeitpunkt.
Werden in Deinem Design die Setup- und/oder Hold-Time eines Signals
aufgrund zu langer Wege nicht eingehalten, dann macht Deine Toolchain
die rote Ampel an: sie meldet eine Timing-Violation.
Burkhard K. schrieb:> N.B.: Der (Logik-)Simulator weiss nichts von Setup- und Hold-Time,> deswegen erscheinen dort Takt- und Signalflanke zum selben Zeitpunkt.
NB2: Nur falls jetzt einer auf eine gloriose Idee kommt: es ist keine
gute Idee, in Code, der für die Verhaltenssimulation bestimmt ist,
vorsorglich eine Laufzeit einzubauen. Sowas also:
Pope schrieb:> Mal eine Frage an die erfahrenen FPGA bändiger. Folgender Code generiert> mir combinatorische Latches das ist klar, aber wie verboten ist es?
Das ist einfach zu beantworten: "Only fools and Genius uses latches"
Meiner Meinung nach ist die fallende Flanke für das Timing unwichtig.
Wichtiger wäre, dass man in der Simulation den Unterschied zwischen A
und B sieht.
>2. Per Timing-Constraint wird sichergestellt, dass der Tick rechtzeitig>vor der Taktflanke (Setup-Time) anliegt und noch ausreichend lange>danach (Hold-Time).
Wo kann man das einstellen?
>----------------------------------------------------------------------- -
P.s.: Entschuldigt meine Übungen mit dem Wacom-Tablet.
Ich muss mich noch daran gewöhnen ...
chris schrieb:> Meiner Meinung nach ist die fallende Flanke für das Timing unwichtig.
Stimmt, wenn das Design nur auf die steigende Flanke reagiert.
> Wichtiger wäre, dass man in der Simulation den Unterschied zwischen A> und B sieht.
Du sehnst dich nach den symbolischen Verzögerungen, die ich als
verwirrend und unnötig bechrieben habe.
Denn der zeitliche Ablauf ist in der Verhaltenssimulation unwichtig,
weil es nur ein "vor dem Takt" und "den Takt" selber gibt: vor dem Takt
wurde ein bestimmter Zustand berechnet, der mit dem Takt übernommen und
daraus eine neuer Zustand berechnet wird, der wiederum beim nächsten
Takt übernommen wird. Und dann geht das Spiel immer wieder im Kreis:
Takt-Berechnen-Takt-Berechnen...
In der Praxis wird dann per Constraints (das wichtigste Constraint ist
die Taktfrequenz) angegeben, wie schnell diese Berechnung ablaufen muss,
dass sie rechtzeitig (um die Setupzeit einzuhalten) vor dem Takt fertig
ist.
chris schrieb:>> 2. Per Timing-Constraint wird sichergestellt, dass der Tick rechtzeitig>>>vor der Taktflanke (Setup-Time) anliegt und noch ausreichend lange>>>danach (Hold-Time).> Wo kann man das einstellen?
Wie gesagt: du gibst in den Contraits die gewünschte Taktfrequenz an.
Die Toolchain sorgt dann dafür, dass die eingehalten wird. Oder sie gibt
dir einen Fehler aus, wenn sie es nicht schafft.
chris schrieb:>>2. Per Timing-Constraint wird sichergestellt, dass der Tick rechtzeitig>>vor der Taktflanke (Setup-Time) anliegt und noch ausreichend lange>>danach (Hold-Time).>> Wo kann man das einstellen?
Hier lohnt sich u.U. ein Blick in die Literatur, Stichwort: "Statische
Timing-Analyse", z.B.:
- Kesel, Bartholomä: "Entwurf von Digitalen Schaltungen mit HDLs und
FPGA", 2. Auflage; Kapitel 4.1.3 bis 4.1.5
- Pong P. Chu: "RTL Hardware Design Using VHDL", Kapitel 16 "Clock and
Synchronization" (insbesondere 16.1 und 16.2)
- und last but not least: der passende "User Guide" Deines
FPGA-Herstellers