Guten Tag ich habe das folgende Problem und mich würde interessiren wie ihr das angehen würdet. Im Anhang habe ich versucht das ganze darzustellen. Am FPGA (Spartan6) hängt ein LTC2379 1.6MSPS ADC. Die SPI Signale werden über ein Isolatorbaustein durchgeschleift. Man kann annehmen dass der unidirektionale Delay gleich ist bzw. nicht stört. Der ADC SPI Takt ist mit 100 MHz festgelegt was auch den Systemtakt vom FPGA entspricht. Der Takt wird über den Isolator zurückgeschlifen und wird verwendet um die SDO Daten einzutakten. Leider ist dieser Takt (CLK_100_OUT bzw. CLK_100_IN) nicht durchgehend weil sonst die ADC Wandlung gestört werden kann. Und jetzt ensteht im FPGA das Problem dass ich nicht weiss wie ich die Daten wieder auf dem Systemtakt sauber rübersynchronisiere. Der CLK_100_IN hat nur 18 Takten pro ADC Auslesung und somit ist eigentlich ziemlich schwer ein FIFO anzusteuern. Ich dachte dass ich den Schieberegister mittels den UCF Constraint "FROM...TO..." abfange aber weiss nicht ob das ausreichend ist um den Datenbus danach "einfach" mit dem Systemtakt zu übernehmen. FPGA:Spartan6 Tool: ISE 14v7 Bin für jede Vorschlag offen :) Gruss
:
Bearbeitet durch User
Erzeuge dir aus den internen 100MHz einen verschobenen Takt mit dem DCM, den du für das Einsammeln der Daten nimmst. Das Delay sollte ja relativ konstant sein.
Hallo Christian danke für dein Antwort. Wie meinst du das eigentlich? Das Problem ist dass durch den Isolatorrückführung CLK_SYS und CLK_100_IN phasen-technisch nichts miteinander zu tun haben. Oder meinst du was ganz anderes? Gruss
Doch das meine ich. Klar ist das verschoben das musst du halt mit der Phasenverschiebung des DCM ausgleichen. Die Verschiebung ist doch konstant, der Takt ist immer noch der gleiche, also kein Problem, musst halt mit dem zusätzlichen internen Takt dann am besten auf einen Dual Clock Fifo. Den Rückführungstakt brauchst du nicht, vor allem da der nicht dauernd läuft.
erstmal danke für das hilfreiche Bild. hast du es schon mal mit einem asynchronen bzw. pseudo-asynchronen FIFO probiert? Die Daten werden mit CLK_IN_100 reingeschoben und mit CLK_SYS ausgelesen? Inwiefern siehst du die 18 Takte als Problem, landet doch erst mal im FIFO.
Servus @Christian Ob die Phase konstant ist kann glaube ich nicht garantiert werden. Die Toleranz vom Isolator kann an dieser Stelle stören oder nicht? Ausserdem bedeutet nicht dass sobald ich eine Flanke ausgebe gleich mit den nächsten abtasten kann. Der Roundtrip Delay, nenne ich das mal, ist mehr als einen Takt. @Klarkx Ich befürchte dass wenn der Takt nicht dauerhaft anliegt dann werden die FIFO Flags nicht korrekt aktualisiert. Meine Idee wäre die Daten mit der steigende Flanke von CLK_100_IN abzutasten und mit der letze fallende Flanke in ein dual-ported RAM reinzuschreiben immer an der gleiche Adresse, 0 oder so. Somit kann ich auch ein Flag setzen der ich dann auch abtakten kann und somit in dem CLK_SYS Domain erkennen kann dass was neues ist. Der Flag wird dann bei der nächsten Wandlung zurückgesetzt. Ich will es halt so elegant wie möglich lösen und vor allem alle asynchrone Übergänge zu 100% abdecken. Danke nochmal für die Empfehlungen und Vorschläge. Gruss
ich sehe nicht, wieso du in diesem Fall ein FIFO brauchen solltest. Takte wie geplant in der CLK_100_IN Domäne ein Schieberegister sowie einen Zähler, der die 18 Bits runterzählt und beim letzten Bit das Schieberegister in ein Halteregister kopiert. Das Halteregister liegt zwar in der CLK_100_in Domäne, aber es ändert seinen Wert nur alle 18 Zyklen. Du kannst also in der CLK_SYS Domäne einen zweiten Zähler betreiben, der die Takte auf CLK_100_Out zählt. Der hat zwar keine definierte Phasenbeziehung zu CLK_100_in, aber wenn du z.B. das Halteregister im 16. Takt ausliest und in ein Register der CLK_SYS Domäne kopierst kannst du trotzdem sicher sein, dass der Wert im Halteregister stabil ist. FIFO ginge natürlich auch - du musst beim letzten der 18 CLK_IN_100 Pulse das WE aktiv setzen (so wie du in meinem Vorschlag beim letzten der 18 Pulse das Halteregister laden müsstest). Ich seh nur nicht den Vorteil, ein FIFO für nur einen Wert einzusetzen.
Valko Z. schrieb: > Der ADC SPI Takt ist mit 100 MHz festgelegt. Mal nachgefragt: Wenn die "time between conversions" 625 ns beträgt und davon 200 ns auf "acquisition time" entfallen, sollte für die Übertragung der 18 bit doch eine deutlich langsamere SCLK (<= 50 MHz) ausreichen? Laut Datenblatt sind die 100 MHz SCLK Frequenz das Maximum - aber kein Requirement.
Valko Z. schrieb: > Ich befürchte dass wenn der Takt nicht dauerhaft anliegt dann werden die > FIFO Flags nicht korrekt aktualisiert. Doch das klappt, denn das Full Flag brauchst du ja nicht, das würde mit dem Write Clock aktualisiert. Das Empty Flag wird mit dem Read Clock betrieben, sollte also klappen. Aber du musst das Enable Signal ja auch sauber in die 2. Taktdomäne bringen. Was sagt denn das Datenblatt des Isolators wie die Delays aussehen? Irgendwie sieht die Lösung bissl kompliziert aus, ist sicher gar nicht nötig mit dem Takt zurück führen. Ob das Delay mehr als ein Takt ist, ist doch egal, dann muss halt noch ein FF in das Enable Signal für das Schieberegister.
Burkhard K. schrieb: > Valko Z. schrieb: >> Der ADC SPI Takt ist mit 100 MHz festgelegt. > > Mal nachgefragt: > > Wenn die "time between conversions" 625 ns beträgt und davon 200 ns auf > "acquisition time" entfallen, sollte für die Übertragung der 18 bit doch > eine deutlich langsamere SCLK (<= 50 MHz) ausreichen? Laut Datenblatt > sind die 100 MHz SCLK Frequenz das Maximum - aber kein Requirement. Nee, denn SPI Transfer geht nur während der kurzen acquisition time. Die Datenblätter sind da immer ganz trügerisch, und zeichnen die acquisition time viel länger als die conversion time ein. Aber es ist in Wirklichkeit genau andersrum. Und 200ns/18Bit sind nur 11.1ns also muss man schon mit 100MHz ran. Das nervt uns an den PULSAR Wandlern auch immer.
Um solche asyncen Probleme mit ADC Daten eintakten zu vereinfachen wurde mir damals geraten "einfach" BRAMs als Shadow zu missbrauchen. Hat auch super funktioniert, allerdings habe ich 50MHz ADC Clock mit 100MHz FPGA Clock verwurstet.
Hallo @Achim S. Das war die Lösung bis jetzt. Leider hatten wir Probleme wie "Stucking Bits" gehabt die nicht erklärbar waren. Und fürs Redesign wollte ich mir was anderes überlegen. @Christian R. Das ich den FULL Flag nicht brauche hast du vollkommen Recht. Muss eigentlich das ganze einmal simulieren dann sehe ich was dabei rauskommt. @Burkhard K. Wie von Christian erklärt darf NUR während die "Acquisition Phase" gelesen werden. Und dann wird es recht schnell knapp mit der SPI Frequenz. Danke an alle für die Antworten. Gruss
Valko Z. schrieb: > Das war die Lösung bis jetzt. Leider hatten wir Probleme wie "Stucking > Bits" gehabt die nicht erklärbar waren. das Raustakten der Daten dauert 180ns, die Zeit zwischen zwei Wandlungen ca. 600ns. Auch wenn es durch den Turnaround-Delay ne Timing-Unsicherheit von einigen 10ns besteht muss es in den verbleibenden (600ns-180ns-x*10ns) locker möglich sein, die Daten stabil von der CLK_100_in Domäne in die CLK_Sys Domäne zu übernehmen - das Register hat rund 400ns lang einen konstanten Wert am Ausgang. 400ns sind lang genug, um die Daten richtig zu übernehmen. Wenn es Probleme mit falschen Bits gibt, würde ich mir eher das Eintakten von SDO mit CLK_100_in anschauen. Das Datenauge am Ausgang des LTC2379 ist verdammt klein. Garantiert sind (bei 10ns Takt) gerade mal 1,5ns (tDSDO und THSDO). Das wird nochmal dadurch angeknabbert, dass die Delays durch den Isolator zwar ganz gut matchen, aber eben doch mal ein paar 100ps variieren können. Am Eingang des Spartan 6 bleibt dir also noch ein (garantiertes) Setup-Hold Fenster von gut 1ns. Das ist für den Spartan 6 einfach zu wenig. In der Praxis mag es trotzdem häufig funktionieren (weil der LTC2379 ein besseres Datenauge liefert als in seiner Spec garantiert). Habt ihr das Setup-Hold Fenster für SDO bezogen auf CLK_100_in in den constraints? (Ich denke immer noch, dass der Spartan 6 ein solches Constraint gar nicht erfüllen kann). Habt ihr mal am SDO-Eingang einen IODelay platziert um den Abtastzeitpunkt von SDO zu optimieren? Ihr könntet auch mal entweder SDO oder CLK_100_in am FPGA mit ein paar pF belasten (aktive Scope-Probe) und so das Signal etwas verzögern. Wenn euer Fehler auf einem Setup-Hold Problem beruht, dann müsste es mal schlimmer, mal besser werden (je nachdem, welches der beiden Signale Ihr belastet). Eine Aufnahme des Datenauges am FPGA wäre sicher auch mal nicht uninteressant.
Hi wir haben damals ein andere ADC gehabt aber das Interface war gleich - CNV anlegen und mit 100 MHz auslesen. Wir haben damals zweimal den gleichen Wert nacheinander ausgelesen und das "gefühlt" relativ oft. Wir hatten keine Bitwechsel sondern der Wert blieb gleich für zwei Wandlungen (als würde der CNV nicht ankommen). Damals ziemlich viel rumgemessen aber ohne Erfolg. IODELAY war und ist vorgesehen. Dass der Register konstant bleibt ist richtig und ich denke das ist ausreichend für das was ich vorhabe. Eigentlich kann ja ein metabstalie Zustand auftreten wenn bei der aktive Taktflanke der FF wechselt. Und das wäre da nicht der Fall. CLK_100_IN zu CLK_SYS sowie OFFSE_IN constraints sind auch im UCF vorgesehen.
Valko Z. schrieb: > Wir haben damals zweimal den > gleichen Wert nacheinander ausgelesen und das "gefühlt" relativ oft. Also nicht der Fehler eines Bits im Datenwort, sondern mehrfach das identische Datenwort: das hat dann natürlich nichts mit setup/hold-Problemen am SDO zu tun. Zwei mal der identsiche Analogwert muss nicht per se ein Fehler sein (aber man kann dem Spannungverlauf natürlich ansehen, wenn die zwei identischen Werte nicht richtig sein können). Ein Synch-Problem zwischen den Clock-Domänen ist eine denkbare Ursache, wobei - wie schon geschrieben - die mehrere hundert ns lange Phase mit stabilem Registerausgang sicher ausreichend sein muss, um die Daten korrekt zu übernehmen. Ein andere denkbare Ursache hast du selbst schon beschrieben: bist du sicher, dass der CNV-Puls lang genug ist, um vom ADC erkannt zu werden? 20ns ist laut Datenblatt Minimum, ich würde mindestens 3 Zyklen deines 10ns Takts vorsehen. Je nachdem, wie ihr die bisherige Lösung implementiert habt, kämen auch Problem innerhalb der CLK_100_in Domäne in Frage. Nutzt Ihr hinter dem Schieberegister noch so was wie ein Halteregister, in das der Wert des Schieberegisters übernommen wird? Da wäre denkbar, dass der "Übernahmepuls" Probleme macht. (Bei der Nutzung eines FIFOs wäre das prinzipielle Problem aber das selbe: dort muss ein entsprechender WE-Puls erzeugt werden). Ich würde bei deinem ADC-Timing sowohl auf ein "Halteregister" als auch auf ein FIFO verzichten und direkt die Werte des Schieberegisters dann in CLK_SYS übernehmen, wenn ich weiß, dass sie seit sehr langer Zeit stabil sind (je nachdem, wie die Druchlaufzeiten durch euren Isolator sind z.B. 200ns nach dem Absenden des 18. CLK_100_OUT Pulses). Wenn man den Delay zwischen CLK_100_Out und CLK_100_in wenigstens halbwegs kennt muss es damit klappen, Synch-Probleme zwischen den CLK-Domänen zu vermeiden. Und wenn man beim Delay grob daneben liegt, erhält man als Fehler nicht zwei mal den identischen Analogwert sondern z.B. Messwerte, die um eine oder mehrere Bitpositionen verschoben sind. Valko Z. schrieb: > Damals ziemlich viel > rumgemessen aber ohne Erfolg. Vielleicht habt ihr alles das eh schon gemacht, aber was mir als erstes in den Sinn kommen würde wäre: - Oszi an Busy-Flag hängen und schauen, ob dessen Puls zwischendurch mal ausbleibt (sofern der ADC regelmäßig abgefragt wird sollte sich eine ausfallende Wandlung recht gut triggern lassen) - FPGA den letzten Analogwert mit dem vorletzten vergleichen lassen und bei identischen Werten einen Trigger fürs Oszi erzeugen. Mit dem Oszi den Datentransfer anschauen (Pretrigger von einigen µs) und analysieren, wie der tatsächliche Datentransfer aussah wenn das FPGA meint, zwei mal die identischen Daten emfpangen zu haben.
Hi @Achim S. das ganze mit Trigger ausgeben und Chipscope einbauen um zu schauen dass alles passt habe ich mehrmals gemacht. Am Ende konnte erstmal kein FPGA Fehler festgestellt werden. Das Redesign beinhaltet jetzt ein gleichwertiges Bauteil aber von ein anderen Hersteller. Mal schauen wie da sich das ganze verhält :) Gruss
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.