Forum: FPGA, VHDL & Co. Spikes, Designproblem ?


von Armin D. (ardiehl)


Angehängte Dateien:

Lesenswert?

Ich versuche mit einem XC9572 ein IDE Interface für ein altes 8 Bit 
System zu basteln. Im Xilinx Simulator sieht alles gut aus nur am 
Zielsystem läuft es nur manchmal. Der CPLD soll den 16 Bit-Datenzugriff 
auf die Platte in 2 8 Bit Zugriffe vom Host umsetzen. Prinzipiell klappt 
das auch nur bekomme ich manchmal Spikes auf meinem Signal IDE_RD was 
dazu führt das Daten verloren gehen.
Ich suche jetzt schon länger und habe langsam keine idee mehr. Bin für 
Tipps dankbar.

Normaler Read läuft so:
IORQ und RD gehen vom Host auf low
...
IDE_RW geht auf low
...
alles auf High

Teilweise passtiert aber
IORQ und RD gehen vom Host auf low
...
IDE_RW geht auf low
IDE_RW geht auf high
IDE_RW geht auf low
...
alles auf High

und das unterschiedlich, nach 2 oder auch nach bis zu 10 erfolgreichen 
Zugriffen.

von Cheffe (Gast)


Lesenswert?

Versuche mal, alle outputs auf einer Zeitebene auszugeben und über 
Flipflops laufen zu lassen, so das die Kombinatorik einschwingen kann, 
bevor ein Takt kommt.

von Armin D. (ardiehl)


Lesenswert?

Sorry, aber keine Ahnung wie das gehen soll. Die Platte benötigt 
/CS0,/CS1,A0,A1,A2 bevor /RD aktiviert wird, daher muß ich diese vorher 
ausgeben sonst klappt das nicht. Das ist auch der Grund warum ich /RD 
erst später setze. Danach wird auch noch etwas Zeit benötigt bevor die 
Daten der Platte gültig sind und ich diese übernehmen (und die oberen 8 
bit speichern) kann. Den Clock vom Host kann ich auch nicht nehmen da IO 
im extremfall nur 2 Takte lang ist.
Ich bräuchte folgende Zeitebenen für die Ausgabe:
1) Ax,/Cx der Platte setzen
2) /RD setzen
3) Daten lesen und an Host ausgeben
4) /RD,Ax,/Cx rücksetzen
Ich müsste dann eine State Machine haben die den State auf der 
steigenden und fallenden Flanke von Clk incrementiert, keine Ahnung wie 
ich das in VHDL schreiben soll. (zumindest so das es auch 
synthetisierbar ist)

von Falk (Gast)


Lesenswert?

@ Armin Diehl

Cheffe hat Recht. Takte uund Strobes (wie das RD) müssen absolut 
glitchfrei sein. Das erreicht man

a) durch Decoder die mit Gray-code angesteuert werden
b) Signalgenerierung direkt aus einem Flip-Flop

b)ist meist einfacher und praktikabler. Ja, du brauchst eine State 
Machine. Die kann natürlich nur entweder auf der fallenden oder 
steigenden Flanke arbeiten. Aber es hindert dich niemand, weitere 
Flipflops in den Signalweg von RD einzufügen die auf der anderen Flanke 
arbeiten und somit RD um einen halben Takt verzögern.

MfG
Falk



von Jolli (Gast)


Lesenswert?

FFs verhindern, daß das dynamische Schalten der Kombinatorik am Ausgang 
zu sehen ist. Nur das Ergebnis ist sichtbar. Diese erzeugt einer 
zeiltiche Rasterung Deiner Signale im Systemtakt. Der Ist aber auf z.B. 
50Mhz genau und reicht 100x, um IDE zu takten.

von Falk (Gast)


Lesenswert?


von Armin D. (ardiehl)


Angehängte Dateien:

Lesenswert?

Ok, vielen vielen dank für eure Hinweise. Ich habe jetzt folgendes 
gemacht:
CS0,C1,A0..A2 jetzt über Latches bei steigender Flanke von IORQ
/RD wird bei fallendem CLK generiert.
Daten werden bei nächstem steigenden CLK gelesen
nächster fallende CLK setzt /RD zurück
das klappte dann zu 80-90%. (aber das /RD Signal war jetzt sauber)

Nach ewigem suchen habe ich mir einige interne Signale nach draussen 
gelegt und siehe da, die Umschaltung von ACCESS_HIGH hat machmal nicht 
funktioniert (hat geschaltet aber dann sofort zurückgesetzt). Ich habe 
das dann auf die steigende Flanke von CLK gelegt damit das garantiert 
nach dem IO passiert und, es klappt.

von Armin D. (ardiehl)


Lesenswert?

leider zu früh gefreut, habe immer noch das Problem mit /RD. Wird zum 
ruchtigen Zeitpunkt auf 0 gesetzt, geht aber dann fast sofort auf 1 und 
nocheinmal auf 0, danach zurück auf 1 bei fallender Flanke von CLK.
Noch irgendjemand eine idee ?

von Armin D. (ardiehl)


Lesenswert?

langsam verstehe ich das nicht mehr. Nachdem ich IDE_RD über ein Latch 
gesetzt hatte, waren die Spikes weg aber manchmal war das Signal viel zu 
kurz (so alle 3000 bis 10.000 Zugriffe), das FF sah so aus:

  LatchIdeRd:PROCESS(IDE_RD_INT,CS)
  BEGIN
    IF CS = '0' THEN
      IDE_RD <= '1';
    ELSIF Falling_Edge(IDE_RD_INT) THEN
      IDE_RD <= '0';
    END IF;
  END PROCESS;

CS wird aus den Adressen des Host gebildet und war im LA absolut suber 
und immer gleich lang:
  ADDRESSOK <= '1' WHEN A (7 downto 4) = JUMPER_A ELSE '0';
  CS <= '1' WHEN (IORQ = '0') AND (ADDRESSOK = '1') ELSE '0';

Wenn ich den CPLD in den low power mode und alle Leitungen auf Slow 
setze, brauche ich schon etwa 100.000 Zugriffe um den Fehler zu 
bekommen.

Nachdem ich das CS rausgenommen und stattdessen das RD signal vom Host 
genommen habe, funktioniert es (Test läuft jetzt zumindest seit einer 
Stunde ohne Fehler) (und jetzt kein low power und fast ports)

  LatchIdeRd:PROCESS(IDE_RD_INT,RD)
  BEGIN
    IF RD = '1' THEN
      IDE_RD <= '1';
    ELSIF Falling_Edge(IDE_RD_INT) THEN
      IDE_RD <= '0';
    END IF;
  END PROCESS;

Ich möchte gerne verstehen was hier passiert, die erste Lösung müsste 
doch auch funktionieren ?

von DerInder (Gast)


Lesenswert?

Moin Moin,

ich kann dir zwar nicht direkt bei deinem Problem helfen, aber ich habe 
das gleiche als Schematik gemacht und das Teil läuft ganz ohne Probleme.

Keine Ahnung ob dir das hilft, aber hier kannst du dir das Teil 
anschauen: http://schuetz.thtec.org/NKC/hardware/GIDE.html

Gruß
Jens

von T.M. (Gast)


Lesenswert?

Bei einem synchronen Prozess gehören NUR der (etweige) asynchrone 
(Re)sets und der Clock in die Snesitivitätsliste. Genau wie du im 
zweiten Beispiel geschrieben hast:
1
  LatchIdeRd:PROCESS(IDE_RD_INT,RD)
2
  BEGIN
3
    IF RD = '1' THEN
4
      IDE_RD <= '1';
5
    ELSIF Falling_Edge(IDE_RD_INT) THEN
6
      IDE_RD <= '0';
7
    END IF;
8
  END PROCESS;
bei kombinatorischen Prozessen müssen ALLE gelesenen Signale in die 
Liste.

T.M.

von Falk (Gast)


Lesenswert?

@ Armin Diehl

VORSICHT FALLE!!!

> langsam verstehe ich das nicht mehr. Nachdem ich IDE_RD über ein Latch
> gesetzt hatte, waren die Spikes weg aber manchmal war das Signal viel zu
> kurz (so alle 3000 bis 10.000 Zugriffe), das FF sah so aus:

>  LatchIdeRd:PROCESS(IDE_RD_INT,CS)
>  BEGIN
>    IF CS = '0' THEN
>      IDE_RD <= '1';
>    ELSIF Falling_Edge(IDE_RD_INT) THEN
>      IDE_RD <= '0';
>    END IF;
>  END PROCESS;

> CS wird aus den Adressen des Host gebildet und war im LA absolut suber
> und immer gleich lang:
>   ADDRESSOK <= '1' WHEN A (7 downto 4) = JUMPER_A ELSE '0';
>   CS <= '1' WHEN (IORQ = '0') AND (ADDRESSOK = '1') ELSE '0';

Cs ist ein kombinatorisches Signal. Da der Eingang (A(7 downto 4) sowie 
IORQ nicht als Gray-Code arbeiten, WIRD CS glitches enthalten 
(ultrakurze Störpulse). In deinem Porzess oben ist CA aber asynchrones 
Reset, da.h sobla CS auch nur gaaaanz kurz auf null geht (Glitch) wird 
IDE_RD gesetzt.
-> Fehler!!!!

Asynchrone Resets sowie Takte müssen ABSOLUT sauber sein und dürfen 
KEINESFALLS aus kombinatorischer Logik erzeugt werden (Ausnahme - 
GrayCode).

> Wenn ich den CPLD in den low power mode und alle Leitungen auf Slow
> setze, brauche ich schon etwa 100.000 Zugriffe um den Fehler zu
> bekommen.

Die Logik wird langsamer und reagiert nur noch auf etwas längere 
Glitches, das Problem ist nach wie vor vorhanden.

> Nachdem ich das CS rausgenommen und stattdessen das RD signal vom Host
> genommen habe, funktioniert es (Test läuft jetzt zumindest seit einer
> Stunde ohne Fehler) (und jetzt kein low power und fast ports)

>   LatchIdeRd:PROCESS(IDE_RD_INT,RD)
>   BEGIN
    IF RD = '1' THEN
>       IDE_RD <= '1';
>     ELSIF Falling_Edge(IDE_RD_INT) THEN
>       IDE_RD <= '0';
>     END IF;
>   END PROCESS;

Das RD vom Host ist glitch-frei.

> Ich möchte gerne verstehen was hier passiert, die erste Lösung müsste
> doch auch funktionieren ?

Nein, siehe oben.

MfG
Falk

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.