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.
Versuche mal, alle outputs auf einer Zeitebene auszugeben und über Flipflops laufen zu lassen, so das die Kombinatorik einschwingen kann, bevor ein Takt kommt.
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)
@ 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
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.
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.
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 ?
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 ?
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
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.
@ 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.