Hallo, ich suche gerade ein Problem in einer State Machine (hängt) und mir fällt gerade folgendes auf (komme erst am Wochenende zum nächsten Test) habe so in etwa folgendes SIGNAL A : INTEGER RANGE 0 TO 8191; SIGNAL B : INTEGER RANGE 0 TO 255; .... WHEN XX => A <= A + B; B <= 0; ... wann wird hier was zugewiesen, wenn das gleichzeitig abläuft (was ich mal vermute) könnte B schon zugewiesen oder in einem undefinierten Zustand sein wenn B zu A addiert wird. Liege ich hier richtig ? (Dann kann ich mir zumindest vorstellen wo mein Problem liegt)
Du solltest den Code für den gesamten Prozess posten. Da dein Programm-Teil mit dem WHEN in einen Prozess vorkommt, bekommen A und B die neuen Werte immer erst am Schluß und GEMEINSAM. Die Reihenfolge spielt in deinem Beispiel keine Rolle. Klaus
Nö, A kommt aus einem Register und wird zur Taktflanke gesetzt. Benutzt wird dabei der "alte" Wert von B, da das Ergebnis von A+B bereits am "neuen" A anliegt.
Ok, sorry, war zu wenig aber der gesamte code ist wirklich zu lang: SIGNAL VRamCursAddr : STD_LOGIC_VECTOR(SRAM_ADDRWIDTH-1 downto 0); SIGNAL currX : INTEGER RANGE 0 TO VIDEO_NUMCHARS-1; begin ProcessChar:PROCESS (Reset,clk) BEGIN IF Reset = HI THEN -- do some init ... ELSIF Rising_Edge(Clk) THEN CASE State IS ... WHEN S_CursorX0 => VRamCursAddr <= VRamCursAddr - currX; currX <= 0; State <= S_WaitCharGone; ... das klappt auch meistens aber manchmal nimmt VRamCursAddr unsinnige Werte an, daher vermutete ich das Problem mit der Reihenfolge.
Du subtrahierst einen Integer (currX) von einem einem std_logic_vector (VRanCursAddr) ohne Typumwandlung? Da meckert nix?
nein, das funkioniert. Nur manchmal wird da mist gerechnet, VRamCursAddr mimmt unsinnige Werte an. Daher vermutete ich ein Problem mit der Reihenfolge.
schreib doch mal die unsinnigen werte, so müssen wir raten, wie Überlauf etc..
Hi! >nein, das funkioniert. Nur manchmal wird da mist gerechnet, >VRamCursAddr mimmt unsinnige Werte an. Zufälligerweise wenn currX > VRamCursAddr ist ? Bye, Simon
> fpgakuechle wenn ich die Werte kennen würde ;-) Ich sehe nur das der Wert ausserhalb der gültigen Werte ist weil ich keinen Cursor mehr sehen kann. VRamCursAddr wird in einem anderen Modul verwendet um den Cursor anzuzeigen. >Zufälligerweise wenn currX > VRamCursAddr ist ? bestimmt nicht, VRamCursAddr kann nur >= currX sein. Ist auch nichts logisches im Code. Tritt nur manchmal auf, gleiche Daten, dann teilweise Fehler nach 10 Sekunden oder auch erst nach 10 Minuten. Wird die Optomierung im ISE geändert, ändert sich auch die Zeit wann der Fehler auftritt.
@Armin Diehl >Ist auch nichts logisches im Code. Tritt nur manchmal auf, gleiche >Daten, dann teilweise Fehler nach 10 Sekunden oder auch erst nach 10 >Minuten. Wird die Optomierung im ISE geändert, ändert sich auch die Zeit >wann der Fehler auftritt. Asynchrone Sauereien? Timing zu knapp? MFG Falk
>Asynchrone Sauereien? Nein, alles läuft auf clock >Timing zu knapp? gleiches Problem mit 50Mhz, 25MHz und 12 MHz und auch egal wie schnell die Daten reinkommen
Armin Diehl wrote: >>Asynchrone Sauereien? > Nein, alles läuft auf clock Alles auf dieselbe clock ? Wo kommt clk her ? Direkt vom Oszillator ? Bye, Simon
>Alles auf dieselbe clock ? innerhalb von dem Teil der hängt, ja. Zum testen läuft momentan alles auf einem 25MHz clock, der 50MHz clock (für einen anderen Teil) ist momentan abgeklemmt. >Wo kommt clk her ? Direkt vom Oszillator ? von einem 100MHz Oszi, intern an einer Stelle geteilt auf 50,25 und 12.5. Wie gesagt momentan nur die 25MHz verwendet.
nein, kein DCM, etwa so: -- generate 50 and 25 MHz clocks genclks:PROCESS (reset,clk) BEGIN IF Rising_Edge(clk) THEN IF Reset = '1' THEN cnt <= "00"; ELSE cnt <= cnt + 1; END IF; clk50Mi <= cnt(0); clk25Mi <= cnt(1); END IF; END PROCESS; clk50M <= clk50Mi; clk25M <= clk25Mi;
So einen Frequenzteiler hatte ich auch öfters implementiert. Das Synthesewerkzeug meckerte aber darüber, dass es einen ripple-clock erkannt hat. Funktioniert hats dann, sobald man Constraints einfügte und definierte, wo die clks herkommen und welchen zeitlichen Bezug sie zum Eingangsclock usw haben sollen. Muss nicht sein, dass du damit Probleme hast - kann aber sein ... Mfg Thomas Pototschnig
@Thomas Pototschnig >So einen Frequenzteiler hatte ich auch öfters implementiert. Das >Synthesewerkzeug meckerte aber darüber, dass es einen ripple-clock >erkannt hat. Funktioniert hats dann, sobald man Constraints einfügte und Ist ja formal auch korret (deas Meckern). >definierte, wo die clks herkommen und welchen zeitlichen Bezug sie zum >Eingangsclock usw haben sollen. DAS ist schon was anderes. Aber wenn die oben generierten Takte als einzige Taktquelle fungieren, also keinerlei Daten von aussen mit den 100 MHz hereinkommen und wenn ein globaler Taktpuffer verwendet wird, dann sollt es wasserdicht sein. MfG Falk
@Thomas >sobald man Constraints einfügte und >definierte, wo die clks herkommen und welchen zeitlichen Bezug sie zum >Eingangsclock usw haben sollen. Wie machst Du das? Also das Problem wird ja sein, dass 2 Taktdomains (incl. Clockbuffer) erstellt werden, die ein unterschiedliches Clock-Delay besitzen können. Damit Laufen die Taktflanken der beiden Takte nicht mehr synchron zueinander, was den Datenaustausch zwischen den Taktdomains erschwert. Mein Workaround für das Problem war bisher das direkte Taktteilen zu vermeiden und mit Ticks zum rechten Zeitpunkt zu arbeiten. Leider erhöht das die Logiktiefe durch ein zusätzliches Enable Signal in den Clock-Prozessen. Wenn Du passende Contrains hast, um den Taktteiler benutzen zu können und trotzdem zueinander synchrone Taktflanken zwischen unterschiedlichen Taktdomains sicherzustellen, dann her damit ;). Gruß DaMicha.
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.