Hallo, ich habe folgendes Problem mit einem VHDL-Code (Spartan XC3S500E, ISE 9.2.04i): Es soll unter anderem ein langsames Clocksignal (ca. 40kHz) mit einem 8MHz-Takt ausgemessen werden. Grundsätzlich funktioniert es so wie geplant, nur habe ich festgestellt, daß einer der Zähler nicht immer korrekt zählt und Sprünge macht, weil beim Zählen ein oder mehrere Bits (ausschliesslich die Bits 0, 1, 4 des Zählers) nicht richtig gesetzt bzw. gelöscht werden. Zählvorgang z.B. 44, 45, 46, 47, 35, 36, 37... Bei dem Wechsel auf 47 folgend sollte Bit4 nach High gehen und Bit0 und Bit1 nach Low. Das tun sie aber nicht. Vermutlich ist in diesem Moment eine Setup/Hold-Bedingung in den betreffenden Registern 0, 1, 4 verletzt, so daß nicht richtig gezählt wird, in den anderen Registern (2, 3, ...) scheint die Bedingung wohl ok zu sein, sonst würden diese nicht korrekterweise auf 0 gehen. Scheint wohl mit Laufzeiten zu tun haben. Kann mir jemand einen Tipp geben wie ich das Problem lösen kann. Wie gesagt, es passiert nur hin und wieder und danach wird korrekt weitergezählt. Die Zählertiefe ist übrigens 16 Bit. Vielen Dank für Antworten. Gruß, Armin
Tritt der Fehler in Hardware oder in der Simulation auf? Wenn ersteres, ist es ein timing-Fehler, wenn zweiteres stimmt wahrscheinlich eine sensitivity list nicht. In jedem Fall wuerde der Quellcode sehr viel dabei helfen, dir zu helfen...
Kommt das zu messende Signal von außen ? Vielleicht sind die Flanken zu wenig steil. Du mußt das Signal sicher auch einsynchronisieren, sonst kommt es, wenn die Zeitdifferenz Flanke des Signals zum Meß-Takt zu klein ist, zu Hold-Time und Setup Verletzungen.
Danke für die Antwort. Der Fehler tritt in der Simulation nicht auf sondern nur in der realen Hardware, zumindest sporadisch. Wie meinst Du das genau mit der sensitivity list ? Ich habe den Code im Moment nicht hier, werde das aber nachholen wenn ich zu Hause bin.
Wenn der Fehler in Hardware auftritt ist es sicher ein Timing-Problem. Signale von aussen erst durch zwei Ebenen Flipflops leiten, bevor sie verwendet werden. An der sensitvity list kann es in diesem Fall nicht liegen, da diese ja nur in der Simulation eine Rolle spielt.
@Klaus Falser Vielen Dank für Deine Antwort. Das zu messende Signal kommt von aussen. Sowohl die Rise- als auch die Fall-Time sind in der Größenordnung von 15 ns. Vermutlich ist das zusätzliche Einsynchronisieren mein Problem. Das leuchtet ein. Das heißt, ich brauche zusätzlich einen Takt, der deutlich größer ist als mein Messtakt von 8Mhz. So was habe ich aber von außen nicht zur Verfügung. Gibt es sowas bereits auf dem XILINX und falls ja, wie kann ich das benutzen ?
> ... langsames Clocksignal (ca. 40kHz) > mit einem 8MHz-Takt ausgemessen werden. : > Das heißt, ich brauche zusätzlich einen Takt, > der deutlich größer ist als mein Messtakt von 8Mhz. Nein, du brauchst nur 2 FFs, die mit den 8MHz getaktet werden, und durch diese beiden muß dein Signal durch. Erst dann darfst du es innerhalb des FPGAs verwenden.
@Lothar, danke für den Hinweis, ich denke jetzt wird es klar. Ich muß lediglich die zum Zählen invertierte Flanke für das Eintakten des zu messenden Signals nehmen. Habe ich früher ja auch so gemacht als man noch Schematics gezeichnet hat, nur bei HDLs habe ich es vergessen. Ich werde es heute abend mal ausprobieren.
> Ich muß lediglich die zum Zählen invertierte Flanke > für das Eintakten des zu messenden Signals nehmen. ??? Einfach das Signal durch 2 FFs durch, so als wolltest du es um 2 Takte verzögern. Nach dem Einsynchronisieren musst du das Signal evtl. entprellen. Dazu verzögerst du das Signal um 1 (System-)Takt und vergleichst den verzögerten mit dem unverzögerten Wert. Nebenher zählt ein Zähler mit, der resettet wird wenn die beiden Werte verschieden sind. Am Ausgang des Entprellers sitzt ein weiteres Register, welches den Signalwert erst dann lädt, wenn der Zähler einen bestimmten Wert erreicht hat (der sich nach der zu erwartenden Prelldauer ergibt). Vorher wird das Ausgangsregister nicht geladen, d.h. der alte Wert wird behalten, so dass das Prellen nach innen nicht sichtbar ist.
> danke für den Hinweis, ich denke jetzt wird es klar. > Ich muß lediglich die zum Zählen invertierte Flanke > für das Eintakten des zu messenden Signals nehmen. Nein, ich glaube du hast es noch nicht soooo ganz richtig verstanden ;-) Du hast einen FPGA-Takt von 8 MHz. Und du hast ein zweites Signal mit 40kHz, von dem du die Zeit zwischen zwei steigenden (oder auch fallenden) Flanken basierend auf diesen 8 MHz zählen willst. Also mußt du 1. das externe Signal auf den Takt synchronisieren 2. die Flanken in dem synchronisierten Signal erkennen 3. die Zeit zwischen zwei dieser Flanken messen und 4. diesen ermittelten Wert abspeichern Machs z.B. so:
1 | library IEEE; |
2 | use IEEE.STD_LOGIC_1164.ALL; |
3 | use IEEE.NUMERIC_STD.ALL; |
4 | |
5 | entity Frequenzmesser is |
6 | Port ( clk8M : in STD_LOGIC; |
7 | sig : in STD_LOGIC; |
8 | cnt : out STD_LOGIC_VECTOR (15 downto 0)); |
9 | end Frequenzmesser; |
10 | |
11 | architecture Behavioral of Frequenzmesser is |
12 | signal counter : integer range 0 to 65535 := 0; |
13 | signal countmerk : integer range 0 to 65535 := 0; |
14 | signal sigsr : std_logic_vector(2 downto 0) := "000"; |
15 | begin
|
16 | -- Einsynchronisieren
|
17 | process begin |
18 | wait until rising_edge(clk8M); |
19 | sigsr <= sigsr(1 downto 0) & sig; |
20 | end process; |
21 | |
22 | -- Flankenerkennung und Zähler
|
23 | process begin |
24 | wait until rising_edge(clk8M); |
25 | counter <= counter+1; |
26 | if (sigsr(2 downto 1)="01") then -- steigende Flanke |
27 | countmerk <= counter; |
28 | counter <= 0; |
29 | end if; |
30 | end process; |
31 | |
32 | -- Zählerwert zurückgeben
|
33 | cnt <= std_logic_vector(to_unsigned(countmerk,16)); |
34 | end Behavioral; |
Im Anhang die (recht kompakte) Testbench zum Projekt.
@Morin, Lothar Miller Vermutlich habe ich mich sehr mißverständlich ausgedrückt, ich meinte zwei FFs. Ich synchronisiere den auszuwertenden Takt indem ich ihn durch 2 FFs durchschicke, diese FFs clocke ich mit der invertierten Flanke des 8MHz-Taktes, also invertiert zum darauf folgenden Zähler. So wird immer gewährleistet daß die S/H-Zeiten für die Register des Zählers eingehalten werden. Damit ist das Zählerproblem behoben. @Lothar Miller Danke für den geposteten Code.
> Ich synchronisiere den auszuwertenden Takt indem ich ihn durch > 2 FFs durchschicke, diese FFs clocke ich mit der invertierten > Flanke des 8MHz-Taktes, also invertiert zum darauf folgenden Zähler. > So wird immer gewährleistet daß die S/H-Zeiten für die Register des > Zählers eingehalten werden. Die 2 FFs sind so okay. Für die invertierte Flanke sehe ich aber den Grund noch nicht... soweit ich weiß nimmt man dafür die selbe Flanke wie für alle anderen FFs auch. Wenn z.B. das zweite Synchro-FF tatsächlich beim Laden mal metastabil wird, dann hat es bei deiner Lösung (invertierte Clock für die Synchro-FFs) nur eine halbe Taktperiode Zeit zum "Umkippen", beim nichtinvertierten Takt eine ganze.
@Morin Du hast natürlich recht, aber die Chance, dass bei einem 8 MHz Takt der Ausgang des 1. FF nach 125 ns noch metastabil ist, dürfte jenseits unserer aller Lebenserwartungen liegen :-)
> dürfte jenseits unserer aller Lebenserwartungen liegen :-)
Also, ich nehme auch immer eine Bombe mit ins Flugzeug, denn die
Wahrscheinlichkeit, dass zwei Bomben in einem Flugzeug sind.... ;-)
Es ist ganz einfach so, dass das Design an dieser Stelle
(unnötigerweise) doppelt so schnell sein muß. Und wenn man das bei 8 MHz
lernt, dann könnte es sein, dass man es auch bei 200 MHz noch so
macht.
Hallo, ich bin zufällig hier vorbeigestolpert. Ich empfehle auch, die 2 synchronisierungs Flipflops auf der selben Taktflanke laufen zu lassen, wie der Rest der Schaltung, wenn auch aus anderen Gründen. Ich setze mal voraus, dass es sich um eine komplett synchrone Schaltung handelt. Vorteile sind (zum Teil schon erwähnt und manches bei FPGA unnötig): * die kombinatorische Logic des Zählers hat eine ganze Taktperiode anstatt nur einer halben lang Zeit (kann bei hoher Temperatur schon mal wichtig werden) * Scanpfad einfügen ist einfacher * nur ein Clock-Tree Desweiteren sollte man über einen Signal-Debouncer nachdenken, wenn ein externes Steuersignal genutzt wird. Vielleicht kann man ja mal den Code sehen? @Lothar Miller Dein Code ist zwar "behavioral", aber mal 3 Fragen * auf einen Reset wird absichtlich verzichtet? * ist das synthetisierbar? Wenn ja mit welchem Tool? (Ich frage wegen der waits) * ein Überlauf des Counters wird absichtlich in Kauf genommen? Aber das ist rein interessehalber. Der Besucher
Der Besucher wrote: > @Lothar Miller > Dein Code ist zwar "behavioral", aber mal 3 Fragen > * auf einen Reset wird absichtlich verzichtet? Ja, Reset nur dort, wo unbedingt nötig. Und dann auch nur synchron. Dazu gibt es ein schönes Whitepaper von Xilinx. Siehe dazu den Beitrag "Xilinx und die Resets" > * ist das synthetisierbar? Wenn ja mit welchem Tool? (Ich frage wegen > der waits) Xilinx XST (Ausprobiert ab ISE 8, vorher hab ich das auch noch als if-Abfrage geschrieben). Damit wird dann auch (fast zwingend) das ganze Design synchron. > * ein Überlauf des Counters wird absichtlich in Kauf genommen? Es ist übersichtlicher, wenn ich davon ausgehe, dass vorher wieder eine Flanke kommt. Besser ist es natürlich, den Zähler einfach zu sättigen:
1 | :
|
2 | :
|
3 | -- Flankenerkennung und Zähler
|
4 | process begin |
5 | wait until rising_edge(clk8M); |
6 | if (counter/=65535) then |
7 | counter <= counter+1; |
8 | end if; |
9 | if (sigsr(2 downto 1)="01") then -- steigende Flanke |
10 | :
|
11 | :
|
EDIT: Zum Thema "Reset" Beitrag "Re: Reset für mehrere Komponenten" Und Beitrag "Hardware mit VHDL "richtig" beschreiben."
@Lothar Miller Danke für die antworten. Das Paper lese ich mir mal durch. Ich nutze normalerweise Resets, die asynchron ausgelöst werden und synchron freigegeben werden. Das mit den synthetisierbaren waits ist neu für mich. Und wird leider nicht von den Tools unterstützt, die ich nutze. Auch die initiale Zuweisungen in der Signaldeklaration kenne ich als Fehlerfall. Kleiner Verbesserungsvorschlag: zum sparen von Gatter einfach defaultmässig 0 auf den counter addieren (kann natürlich auch in einen else Zweig. Da spart man sich so manchen Multiplexer. Aber keine Ahnung, ob das bei FPGAs was bringt. : : -- Flankenerkennung und Zähler process begin wait until rising_edge(clk8M); -- default counter <= counter+0; if (counter/=65535) then counter <= counter+1; end if; if (sigsr(2 downto 1)="01") then -- steigende Flanke : : Der Besucher
> Da spart man sich so manchen Multiplexer
Kaum, am Ende kommt bei der Synthese und Optimierung sicher dasselbe
heraus, weil es ja keine Multiplexer gibt, sondern die kombinatorische
Funktion minimiert wird und in ein oder mehrere LUTs gepresst wird.
Kombinatorisch sind die Beschreibungen ja identisch.
> Aber keine Ahnung, ob das bei FPGAs was bringt.
Ich habs kurz ausprobiert: es ändert sich nichts am Syntheseergebnis.
Die Beschreibung ist auch funktionsgleich mit
1 | -- Flankenerkennung und Zähler
|
2 | process begin |
3 | wait until rising_edge(clk8M); |
4 | if (counter/=65535) then |
5 | counter <= counter+1; |
6 | else
|
7 | counter <= counter+0; |
8 | end if; |
9 | if (sigsr(2 downto 1)="01") then -- steigende Flanke |
10 | :
|
11 | :
|
--> die Addition der 0 wird rausoptimiert. Sinn macht diese Defaultzuweisung in kombinatorischen Prozessen, denn sonst hat man schnell ein Latch an der Backe ;-)
> Sinn macht diese Defaultzuweisung in kombinatorischen Prozessen, denn > sonst hat man schnell ein Latch an der Backe ;-) Eine Default-Zuweisung schon, aber eine Addition mit 0 ???
>> Sinn macht diese Defaultzuweisung in kombinatorischen Prozessen, denn >> sonst hat man schnell ein Latch an der Backe ;-) Hier wird ohne die default Anweisung aber kein Latch eingebaut. Das ist also nicht der Grund. Na ich versuche es mal zu erklären, was ohne die +0 gebaut wird: Bei nichtausführung der Incrementierung werden die Ausgänge der FFs auf ihre Eingänge zurückgekoppelt. Das macht pro FF einen Multiplexer. (Entweder Ergebnis der Incrementierung oder alter Wert) >Eine Default-Zuweisung schon, aber eine Addition mit 0 ??? Zum sparen der Multiplexer. Jetzt wird nur noch ein einziger Multiplexer verwendet, der entscheidet, ob eine 1 oder eine 0 addiert wird. Aber die Eingänge der FFs sehen nur noch den Ausgang des Addierers. Bei 16 Bit sparrt man so mal auf die schnelle 15 Muxe. Der Besucher
Wie gesagt, bei einem FGPA gibt es keine Multiplexer. Alle Funktionen werden in LUTs realisiert, und die Funktion dieser LUTs ist identisch mit oder ohne Addition.
> Bei 16 Bit spart man so mal auf die schnelle 15 Muxe. Das ist bei einem (Spartan3-)FPGA aber so, dass für Incerement (+1) oder kein Increment (+0) nur der Carry-In des Addierers mal auf 1 oder 0 gesetzt wird. Wie gesagt: >> Ich habs kurz ausprobiert: es ändert sich nichts am Syntheseergebnis.
Nunja, bei FPGAs bringt es dann wohl nichts. Aber da keine LE mehr verwendet wird und funktional identisch ist, ist es auch sicherlich kein Fehler. Im Standardzellenentwurf sparen solche Tricks jedenfalls wertvolle Fläche. Aber hier wird wohl nur über HDL in programmierbare Logik diskutiert? Der Besucher
> Aber hier wird wohl nur über HDL in programmierbare Logik diskutiert?
ASICs können sich die meisten nicht leisten ...
Klaus Falser wrote: > Wie gesagt, bei einem FGPA gibt es keine Multiplexer. Alle Funktionen > werden in LUTs realisiert, und die Funktion dieser LUTs ist identisch > mit oder ohne Addition. Und wie werden dann die Verbindungen zwischen den LUTs und FFs geroutet, ohne Multiplexer?
Auch auf die Gefahr gesteinigt zu werden weil ich die Sync-FFs mit der negativen Flanke ansteuere möchte ich erklären warum ich das tue. Vielleicht habe ich ja ein grundsätzliches Verständnisproblem welches ausgeräumt werden sollte. Das ursprüngliche Problem war dass ein Zähler, der mit der steigenden Flanke des 8Mhz-Taktes abhängig von einem externen Takt hin und wieder falsch zählt. Da dieser externe Takt nicht auf den 8Mhz-Takt synchronisiert war, konnte er sich also zeitlich beliebig zum 8MHz-Takt verändern. Deswegen kam es hin und wieder zu Verletzungen von Setup/Hold-Zeiten der Zählerregister, abhängig von internen Laufzeiten zu den Zählerregistern und natürlich der Phasenlage des externen Taktes. Also mußte ich natürlich das externe Signal auf den 8Mhz-Takt synchronisieren. Warum ? Damit der Wert des externen Taktes sich um die steigende Flanke des 8MHz-Taktes herum nicht ändert, damit weder die Setup-Zeit (also vor der steigenden Flanke des 8MHz-Taktes) als auch die Holdzeit (nach der steigenden Flanke des 8MHz-Taktes) nicht verletzt werden. Also muß man doch logischerweise mit der invertierten Flanke des 8MHz-Taktes synchronisieren, damit der Wert des externen Taktes, der in das Zähler-Schaltwerk geht, sowohl vor als auch nach der steigenden Flanke des 8MHz-Taktes stabil bleibt. Also insgesamt jeweils eine 8Mhz-Periode, eine halbe vor, eine halbe nach der steigenden Flanke. Wenn ich die steigende Flanke zum Synchronisieren nehmen würde, dann hätte ich doch genau die gleichen unsicheren Verhältnisse wie ohne Synchronisation: das externe Signal, jetzt zwar einsynchronisiert, kann sich zeitlich um die steigende Flanke des 8Mhz-Taktes herum verändern. Abhängig von Laufzeiten zu den einzelnen Registern kommt es also hin und wieder zu Zeitverletzungen und somit zu falschen Zählergebnissen. Mit Synchronisation durch fallende Flanke ist das Fehlverhalten auf alle Fälle weg, mit steigender werde ich es noch testen. Wo bitte liegt denn mein Denkfehler wenn jeder hier behauptet die Richtung der Flanke zum Einsynchronisieren wäre egal ?
OK, statisch konfigurierte Multiplexer zum Routen der Signale im CLB gibt es schon. Aber es gibt keine dedizierten, umschaltbare Multiplexer als logische Funktion. Alle Funktionen werden in LUTs als Funktion von 4 oder 5 Eingangssignalen erzeugt.
> Wenn ich die steigende Flanke zum Synchronisieren nehmen würde, dann > hätte ich doch genau die gleichen unsicheren Verhältnisse wie ohne > Synchronisation: das externe Signal, jetzt zwar einsynchronisiert, kann > sich zeitlich um die steigende Flanke des 8Mhz-Taktes herum verändern. > Abhängig von Laufzeiten zu den einzelnen Registern kommt es also hin und > wieder zu Zeitverletzungen und somit zu falschen Zählergebnissen. Wenn dem so wäre, dann würde kein synchrones Design funktionieren, da ja immer irgendwelche kombinatorische Logik zwischen 2 FFs steckt. Bei einem synchronen Design werden alle FFs zur gleichen Zeit getaktet (+- einiger hundert ps clock skew). Wenn Setup und Hold Time berücksichtigt werden, tritt kein Problem auf. Nur das erste Synchronisations-FF kann eine Timing-Violation haben. das kann zu Metastabilität führen. Deswegen auch das 2. FF, da man i.d.R annehmen kann, dass sich innerhalb einer Taktperiode das erste FF eingeschwungen hat (entweder auf den neuen, oder den alten Wert). Der Besucher
Klaus Falser wrote: > OK, statisch konfigurierte Multiplexer zum Routen der Signale im CLB > gibt es schon. > Aber es gibt keine dedizierten, umschaltbare Multiplexer als logische > Funktion. Alle Funktionen werden in LUTs als Funktion von 4 oder 5 > Eingangssignalen erzeugt. Und wie ist es bei diesen FPGAs von Actel, welche die Logik ausschliesslich mit Multiplexern erzeugen und gar nicht über SRAM verfügen?
> Nunja, bei FPGAs bringt es dann wohl nichts. Aber da keine LE mehr > verwendet wird und funktional identisch ist, ist es auch sicherlich kein > Fehler. Das hat nichts mit FPGAs zu tun: > Im Standardzellenentwurf sparen solche Tricks jedenfalls > wertvolle Fläche. Dito bei FPGAs, aber die Tools machen solche Umformungen im Hintergrund ohne dass du dich drum kümmern musst. Und das schon seit Jahren. > Aber hier wird wohl nur über HDL in programmierbare Logik diskutiert? Da scheinst du der einzige zu sein, der das so sieht.
> Deswegen kam es hin und wieder zu Verletzungen von > Setup/Hold-Zeiten der Zählerregister, abhängig von internen Laufzeiten > zu den Zählerregistern und natürlich der Phasenlage des externen Taktes. Richtig. (genauer: Das ist eine begründete Vermutung für die Ursache des Problems. Für andere Vermutungen siehe z.B. meinen Kommentar über das Entprellen) > Also mußte ich natürlich das externe Signal auf den 8Mhz-Takt > synchronisieren. Warum ? Damit der Wert des externen Taktes sich um die > steigende Flanke des 8MHz-Taktes herum nicht ändert, damit weder die > Setup-Zeit (also vor der steigenden Flanke des 8MHz-Taktes) als auch die > Holdzeit (nach der steigenden Flanke des 8MHz-Taktes) nicht verletzt > werden. Auch richtig. > Also muß man doch logischerweise mit der invertierten Flanke des > 8MHz-Taktes synchronisieren, damit der Wert des externen Taktes, der in > das Zähler-Schaltwerk geht, sowohl vor als auch nach der steigenden > Flanke des 8MHz-Taktes stabil bleibt. Also insgesamt jeweils eine > 8Mhz-Periode, eine halbe vor, eine halbe nach der steigenden Flanke. Das ist zwar keine falsche Lösung, aber auch nicht die beste. Zwei hintereinandergeschaltete FFs können ein Datensignal durchreichen, ohne dass Setup- / Hold-Zeiten verletzt werden. Auch die 2 Synchro-FFs können, wenn sie einfach vor den Zähler gehängt werden und mit dem nichtinvertierten Takt betrieben werden, das Datensignal richtig durchgeben. Setup-/Hold-Zeiten sind bei gleichphasig angesteuerten Registerketten keim Problem (passiert ja im FPGA drinnen auch die ganze Zeit). Der einzig kritische Fall ist nur, wenn das Eingabesignal die Setup-/Hold-Zeit des ersten FFs verletzt. Dass das ein vorgeschaltetes Synchro-FF sein sollte ist klar, damit der Zähler nicht durcheinanderkommt. Aber auch so kann das Synchro-FF metastabil werden, d.h. einen Zwischenwert zwischen 0 und 1 speichern und weitergeben. Einen Takt später kann dann prinzipiell das zweite Synchro-FF den Zwischenwert übernehmen, und noch einen Takt später kommt es beim Zähler an -> Sense. Der Zwischenwert ist aber nicht stabil, sondern tendiert dazu, "umzukippen", d.h. das Register "fällt" in den 0- oder 1-Zustand. Die Wahrscheinlichkeit für das Umkippen steigt radikal mit der Vergangenen Zeit. Schaltet man mehrere Synchro-FFs hintereinander, so sinkt die Wahrscheinlichkeit, dass der Zwischenzustand das Ende der Kette erreicht exponentiell mit der Kettenlänge. Deshalb 2 Synchro-FFs statt nur 1. Kippen die Synchro-FFs rechtzeitig um, so macht das gleichphasige Ansteuern von Synchro-FFs und Zähler kein Problem. Kippen sie nicht rechtzeitig um, hilft gegenphasiges Ansteuern auch nicht. ABER: Das gegenphasige ansteuern reduziert die Zeit zum Umkippen auf 1/2 Taktperiode statt einer ganzen.
> Also insgesamt jeweils eine 8Mhz-Periode, eine halbe vor, > eine halbe nach der steigenden Flanke. Innerhalb des FPGAs hat jedes einzelne FF das Problem, dass sich kurz nach dem Takt die Daten an seinem Eingang ändern (angeschlossen über z.B. nur einen Draht, ohne Logik, an den Ausgang des vorhergehenden FFs). D.h. die FFs benötigen nur eine sehr kurze Hold-Zeit. Dann bleibt für das ganze FPGA wieder ein ganzer Takt Zeit, bis sich die Logik mit den neuen Werte z.B. für SM und Zähler beruhigt hat. Dann kommt wieder ein Takt. Wenn du die Hold-Zeit auf Kosten der Setup-Zeit für die Eingangs-FFs änderst, bleibt es innerhalb des FPGAs trotzdem gleich. > Also insgesamt jeweils eine 8Mhz-Periode, eine halbe vor, > eine halbe nach der steigenden Flanke. Das müsstest du ja dann auch innerhalb des FPGAs für jede FF-Stufe alternierend machen. Nein, für den Anfang einfach: Ein (1) Takt mit einer (1) aktiven Flanke und kein (globaler und/oder asynchroner) Reset.
Der Vollständigkeit halber: die Schaltung funktioniert mit Sync über die positive Flanke. Nochmals Danke für die Erklärungen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.