Forum: FPGA, VHDL & Co. Reihenfolge Signalzuweisungen VHDL


von Armin D. (ardiehl)


Lesenswert?

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)

von Klaus Falser (Gast)


Lesenswert?

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

von Fred (Gast)


Lesenswert?

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.

von Armin D. (ardiehl)


Lesenswert?

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.

von FPGA-Küchle (Gast)


Lesenswert?

Du subtrahierst einen Integer (currX) von einem einem std_logic_vector 
(VRanCursAddr) ohne Typumwandlung? Da meckert nix?

von Armin D. (ardiehl)


Lesenswert?

nein, das funkioniert. Nur manchmal wird da mist gerechnet, VRamCursAddr 
mimmt unsinnige Werte an. Daher vermutete ich ein Problem mit der 
Reihenfolge.

von fpgakuechle (Gast)


Lesenswert?

schreib doch mal die unsinnigen werte, so müssen wir raten, wie Überlauf 
etc..

von Ssss S. (sssssss)


Lesenswert?

Hi!

>nein, das funkioniert. Nur manchmal wird da mist gerechnet,
>VRamCursAddr mimmt unsinnige Werte an.
Zufälligerweise wenn currX > VRamCursAddr ist ?

Bye, Simon

von Armin D. (ardiehl)


Lesenswert?

> 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.

von Falk (Gast)


Lesenswert?

@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

von Armin D. (ardiehl)


Lesenswert?

>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

von Ssss S. (sssssss)


Lesenswert?

Armin Diehl wrote:
>>Asynchrone Sauereien?
> Nein, alles läuft auf clock
Alles auf dieselbe clock ?
Wo kommt clk her ? Direkt vom Oszillator ?

Bye, Simon

von Armin D. (ardiehl)


Lesenswert?

>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.

von Ssss S. (sssssss)


Lesenswert?

ah ok. wie wird geteilt ? DCM oder was eigenes ?

Bye, Simon

von Armin D. (ardiehl)


Lesenswert?

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;

von Thomas Pototschnig (Gast)


Lesenswert?

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

von Falk (Gast)


Lesenswert?

@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

von Da M. (damicha)


Lesenswert?

@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
Noch kein Account? Hier anmelden.