Guten Tag. Ich arbeite auf dem Virtex 6 (XC6VLX75T) und nutze die Beschreibungssprache VHDL. Ich bin dabei Daten von einem AD-Wandler (AD9249) mittels des gesagten FPGAs einzulesen, und in ChipScope darzustellen (vgl. Beitrag: Beitrag "ChipScope limitierende Größe beim Systemtakt?" ). In dem Beitrag wurde bereits erwähnt, dass es bei den auftretenden Takten zu Schwierigkeiten kommen kann -> deshalb wurde im Weiteren der Dividend N eingeführt). Folgende Spezifikationen seien genannt: - DCO1 = 390/N MHz (65/N MSps * (12 Bit/2)) - DCO2 = 390/N MHz (65/N MSps * (12 Bit/2)) - FCO1 = 65/N MHz (65/N MSps) - FCO2 = 65/N MHz (65/N MSps) mit N = [1,2,...,8]. Bei der Wahl von N = 2 erwartet man einen max. Takt von 195 MHz. Dieser sollte zu handhaben sein. Ich speise ein Sinussignal passender Frequenz (N = 2) in Kanal A1..H1 sowie A2..H2 ein. Dieses betrachte ich in ChipScope. Im Anhang ist dieses für zwei Kanäle exemplarisch dargestellt. Man sieht zum Teil "Ausreißer". Diese scheinen sehr zufällig aufzutreten (ab N = 2 sichtbar). In einer Testbench fällt mir kein solcher Fehler auf (sowohl vor der Synthese, als auch nach dieser). Bemerkung: Über einen externen LogicAnalyzer sehe ich die Ausreißer ebenso. (ChipScope auskommentiert!) Ich hänge einmal den Timing Report sowie die relevanten Timing Constrains für N = 2 an. Vielleicht hat ja wer Vorschläge bzw. kann aus dem Report mögliche Probleme ableiten. Vielen Dank
ChipScopeUser schrieb: > In einer Testbench fällt mir kein solcher Fehler auf (sowohl vor der > Synthese, als auch nach dieser). Dann ist es also mit sehr hoher Wahrscheinlichkeit das altbekannte Problem: zwei asynchrone Taktdomänen und nicht synchronisierte Datenpfade... > Diese scheinen sehr zufällig aufzutreten (ab N = 2 sichtbar). Man könnte aber auch eine Regelmäßigkeit erkennen: zumindest die kleine "Zacke" wiederholt sich. Und die anderen Fehler treten alle im Nulldurchgang auf und sehen gar nicht so arg zufällig aus... > Bemerkung: Über einen externen LogicAnalyzer sehe ich die Ausreißer > ebenso. (ChipScope auskommentiert!) An welchen Leitungen misst du da?
ChipScopeUser schrieb: > Man sieht zum Teil > "Ausreißer". Diese scheinen sehr zufällig aufzutreten (ab N = 2 > sichtbar). Ganz so zufällig sehen die mir nicht aus. Der 'Abstand' zwischen den Ausreißern sieht 'konstant' aus. Woher kommt der Takt für Deinen ADC? Woher kommt der Takt für Deinen FPGA? Duke
Danke euch erstmal. Lothar Miller: 1) Werde ich nochmals überprüfen. 2) Die Zacken treten nicht nur im Nulldurchgang auf. Ich habe dazu einmal ein Screenshot angehängt, welcher das Verhalten ohne die Einspeisung eines Signals zeigt. 3) Ich habe mir den Kanal A1 auf 12 externe IO Pins (P201, P202) am FPGA gelegt. War mit der Auswahl der Pins vom EV Kit (https://wiki.analog.com/resources/eval/ad9249-65ebz) eingeschränkt. Duke: 1) Betrachtet man den Zeitverlauf (im Angang ist ja nur ein Screenshot enthalten), sieht man, dass die Abstände nicht konstant sind. 2) Der ADC wird von einem externen Quarz mit 65 MHz getaktet. Dieser wird intern (im ADC) um den Faktor N herabgesetzt (je nach Konfiguration). 3) Der Datenclock (vom ADC erzeugt) wird im FPGA eingelesen (über einen Clk Buffer).
ChipScopeUser schrieb: > welcher das Verhalten ohne die Einspeisung eines Signals zeigt. Also wenn wegen des Rauschens ständig irgendein Nulldurchgang auftritt... :-/ Was bekommst du, wenn du ein Gleichspannung anlegst und aus dieser Nullzone herausgehst?
Lothar Miller: 1) So kann man es auch sehen, stimmt. 2) Gleichspannung anlegen ist aufgrund der werksseitigen Eingangsbeschaltung nicht möglich.
ChipScopeUser schrieb: > 2) Gleichspannung anlegen ist aufgrund der werksseitigen > Eingangsbeschaltung nicht möglich. Aber eine niedrigere/andere Frequenz müsste doch möglich sein...
Lothar Miller: 1) Hab ich soeben ausprobiert. Die Ausreißer werden weniger (so scheint es). Allerdings ist die Eingangsbeschaltung für niedrige Frequenzen nicht wirklich ausgelegt. Ich sehe "Ausreißer" auch außerhalb des Nulldurchganges. Würden Teile des VHDL-"Codes" hilfreich sein? Das Projekt ist leider zu groß, um es hochzuladen.
ChipScopeUser schrieb: > Würden Teile des VHDL-"Codes" hilfreich sein? Wie sehen Deine Timing-Constraints aus (OFFSET_IN)? Werdesn diese eingehalten? Was sagt der Timing-Report? Duke
Lothar Miller: Ich habe mir auf deiner Homepage den Artikel zur Einsynchronisierung durchgelesen (falls du Soetwas meintest). Die Signale DCO, FCO und Data_in sind nicht speziell als CLk Signale ausgeführt. Es wird in den angehängten VHDL-Dateien die Flanke vom DCO Detektiert, um die Daten bei fallender und steigender zu übernehmen. Anschließend wird anhand des FCO Signals das Wort eingefasst. Fallen bisher gravierende Fehler in den entsprechenden Dateien auf, die besagtes Verhalten hervorrufen? Vielen Dank.
ChipScopeUser schrieb: > Anbei das ucf-File. Sieht ja erstmal gar nicht so schlecht aus. Unsicher bin ich mir, ob die Zuordungen mit den INST richtig funktionieren:
1 | INST "bank1_diff_ch_matrix<0><1>" TNM = din1_timegroup; |
Ich habe bei mir die timings direkt an die input-Netze genagelt:
1 | TIMEGRP "ADC_DATA" OFFSET = IN 500 ps VALID 2500 ps BEFORE "ADC_DCO" RISING; |
2 | |
3 | NET ADC_OUTA_P LOC = A6 | TNM = "ADC_DATA"; |
4 | NET ADC_OUTA_N LOC = B6 | TNM = "ADC_DATA"; |
Das Constraint auf FALLING wurde immer ignoriert, obwohl ich DDR verwende. FCO würde ich nicht als Taktsignal verwenden, sondern nur als ein weiteres Datensignal, um die Bits richtig zu sortieren. Wie funktioniert das eigentlich mit den Bänken? Gibt der ADC alles doppelt aus? Hast Du ein schnelles Scope mit aktiven Tastköpfen zur Verfügung? Wenn ja, würde ich mir mal die Datenleitungen darauf anschauen. Duke P.S.: Hier nochmal der Link zum Datenblatt: http://www.analog.com/static/imported-files/data_sheets/AD9249.pdf
ChipScopeUser schrieb: > Es wird in den angehängten VHDL-Dateien die Flanke vom DCO > Detektiert, um die Daten bei fallender und steigender zu übernehmen. > Anschließend wird anhand des FCO Signals das Wort eingefasst. Koennte das das Problem sein? Ich dachte, mit den OFFSET contraints schiebst du die Datenbits in der Laufzeit so hin, dass ein mit DCO getaktetes FF (bzw. 2FFs wg. rising/falling) genau in der Mitte des Datenbits sampled. Die OFFSET contraints sollen ja nur dafuer sorgen, dass die Laufzeiten DCO vs. Datenbit richtig von der Toolchain angepasst werden. Ich wuerde mir an deiner Stelle mal die Leitungen nach post-place&route anschauen. Die muessen alle irgendwie "Laengenbalanciert" sein. Und mit der FCO musst du dann natuerlich den Uebergang in deine eigentliche Clockdomain sauber hinkriegen
Duke: 1) Hat nichts am Verhalten geändert. 2) Genau. Verwende FCO demnach auch als "normales" Signal. 3) Auf Seiten des ADCs sind jeweils acht Kanäle einem Takt (DCO_1 bzw DCO_2) zugeordnet. Ich denke, dass dieses an der vom Hersteller verwendeten Technologie liegt. D.h. beim vorliegenden ADC hat man 2 x 8 Kanäle. Jeder Kanal ist gleich ausgeführt. Im VHDL Design dementsprechend auch. 4) Ja habe ich zur Verfügung. Sieht alles brauchbar aus. (Anzahl der Bits, welche in einen Frame passen, DCO-Frequenz, FCO-Frequenz etc.)
berndl schrieb: > Ich dachte, mit den OFFSET contraints > schiebst du die Datenbits in der Laufzeit so hin Nene. Die Constraints schieben nichts. Die Timinganalyse schaut nur, ob die Constraints nach dem P&R eingehalten wurden. Wenn man schieben will, muß man das selber machen (z.B. mit IDELAY). ChipScopeUser schrieb: > Ja habe ich zur Verfügung. Sieht alles brauchbar aus. Auch das Augendiagramm auf den Daten- und Taktleitungen (Datenblatt Seite 22)? Per SPI kann man sich Testmuster (Checkerboard, PN sequence, diverse Toggle) generieren lassen. Gibt es da auch Ausreißer im Chipscope? Wenn ja, bei welchen Mustern? Duke
Duke: 1) Das Augendiagramm habe ich nicht ermittelt. Das würde mir - falls ich an den Pins des AD-Wandlers direkt messe - ja auch nur zeigen, ob die Werte korrekt ausgegeben werden. AD liefert eine zum Kit passende Software mit (AnalogStudio). Mit dieser gegehen alle Kanäle. Demnach liegt der Fehler noch in meinem VHDL Code. (Das Problem, weshalb ich die original Software nicht nutze, ist die fehlende Synchronität der Kanäle seitens des Herstellers. 2) Habe ich noch nicht versucht.
ChipScopeUser schrieb: > Das Augendiagramm habe ich nicht ermittelt. Das würde mir - falls ich an > den Pins des AD-Wandlers direkt messe - ja auch nur zeigen, ob die Werte > korrekt ausgegeben werden. Flasch. Man sieht auch die Reflexionen, die von der Verbindung zum FPGA zurückkommen. Außerdem kannst Du mal verschiedene Einstellungen für Output Termination am ADC (bzw. Input Termination am FPGA) testen. Im Anhang mal ein Beispiel, wie das bei mir aussieht. Ich mußte die Timing-Constraints enger setzen, damit die Übertragung fehlerfrei funktioniert. Duke
Ok. Dann werde ich das Augendiagramm aufnehmen. Zusammenfassend bisher: (1) Der gepostete VHDL-Code weisst keine groben Fehler auf, welche das Verhalten erklären? (2) Nach (1) ist es ein Problem, welches über Timing Constrains zu lösen ist? Hattest du ähnliche Probleme (Ausreißer bei deinem Design) Duke?
ChipScopeUser schrieb: > (1) Der gepostete VHDL-Code weisst keine groben Fehler auf, welche das > Verhalten erklären? Ich hab ihn mir nicht angeschaut. Aber bei groben Fehlern würdest Du gar keinen Sinus sehen ;-) > (2) Nach (1) ist es ein Problem, welches über Timing Constrains zu lösen > ist? Möglicherweise. > Hattest du ähnliche Probleme (Ausreißer bei deinem Design) Duke? Im Prinzip ja. Viele Geräte funktionierten und einige nicht so recht. Wenn Du ausreichend viele Samples verwendest, kannst Du eine FFT machen und siehst, wie gut der ADC ist (SNR). Da fallen solche (und andere) Ausreißer sofort auf. Duke
Ok. In wie weit kann ich das Timing "enger" setzen? Welches Constrains meinst du? Es ist ja ersichtlich, dass es ab etwa N = 3 funktioniert. N = 2 bzw N = 1 ist kritisch.
Vlt nochmal ein Beitrag von mir. Ich hatte einen aehnlichen ADC an einem FPGA Design 'geerbt', das FPGA lief mit 10MHz, der ADC (4-Kanal) hat mit 60MHz zurueck gefeuert. Timing contraints gab es nicht, es hat sich nur jeder gewundert, dass manchmal nach der Synthese nix mehr ging (Timing violations halt, wenn halt auch nix spezifiziert ist...). Das war auf einem Altera Cyclon III. Wir haben uns dann mal hingesetzt, die Timings auf dem Board (worst-case) analysiert. Und dann passende Timing Constraints im .sdf (synopsis design constraints) spezifiziert. (Uebrigens, unter Vivado sollte ein .xdf genau das gleiche sein, unter ISE ist's ein bisschen anders). Und was wir damit herausgefunden haben: Vorher waren die Daten und Clockleitungen komplett unterschiedlich in der Laenge (und damit der Laufzeit). Danach sah das 'sehr harmonisch' aus, die Daten und Clockleitungen hatten nach dem Place&Route ziemlich aehnliche Laengen (bzw. Laengenverhaeltnisse). Seitdem gibt's auch keine Probleme mehr mit Aenderungen, der Design funktioniert bzgl. ADCs einfach. Und ich vermute, genau da liegt dein Problem...
aargh, bullshit, ersetze .xdf mit ".xdc" und .sdf mit ".sdc"... War gerade in Gedanken woanderst...
berndl: Vielen Dank für deinen Hinweis. In Sachen Timing Constrains ist bei mir wohl einiges aufzuarbeiten. Wie analysiere ich soetwas denn in meinem Fall? Ich "erhalte" ja keine Fehlermeldung im Timing Report etc.. Das mit den unterschiedlichen Längen der Pfade hört sich nach dem Problem an. Es wäre super, wenn ihr mich bei der Fehlersuche anleiten könntet. Was ein Timing Constrain macht ist mir denke ich klar. Wie ich die Zeiten analysiere, die ich benötige, scheinbar (in der Praxis) nicht. Also ein Schritt für Schritt Vorgehen wäre hilfreich. Sagt mir, was ich dazu ausprobieren bzw. posten soll. Duke: Arbeite am Augendiagramm ;)
Du könntest ja statt:
1 | TIMEGRP din1_timegroup OFFSET = IN 1ns VALID 2ns BEFORE "DCO1_p" RISING ; |
mal auf 500 ps und 1 ns gehen:
1 | TIMEGRP din1_timegroup OFFSET = IN 500ps VALID 1ns BEFORE "DCO1_p" RISING ; |
(natürlich auch bei all den anderen Constraints) Duke
ChipScopeUser schrieb: > Ich "erhalte" ja keine Fehlermeldung im Timing Report etc.. Naja, was du spezifizierst und was die Toolchain 'frisst', das ist das was du im Timing Report siehst. Wenn da auch nur irgendwas schiefgeht, dann kriegst du halt Fahrkarten gemeldet... Duke's Vorschlag scheint mir ziemlich praktikabel zu sein. Und vor allem, schau dir die Pfade mal im Chipeditor an. Da muss CLK und DATA eng begrenzt immer gleich aussehen. Wenn's dann noch nicht funzt, dann musst du halt die Daten ggue. der Clock im Timing verschieben... Du musst der Toolchain schon genau sagen, was du eigentlich haben willst...
ChipScopeUser schrieb: > Wie analysiere ich soetwas denn in meinem > Fall? Klassische Worst-Case Analyse. Was halt so am Eingang deines FPGAs besten- oder schlimmstenfalls anliegen kann. Ist aufwendig und tut weh, aber so ist halt das Leben...
Hm, ich hab auf die Schnelle in deinem Code nirgendwo die ISEDES des Virtex gefunden. Machst du das etwa zu Fuß? Schau die mal die XAPP1064 an, das klappt wunderbar für solche ADCs. Ich benutze das angepasst an den Artix 7 für den LTM9011-14 ADC. Da muss man sich überhaupt keine Verrenkungen mit den DDR usw machen. Und das FCO nimmst du als Referenz für die BitSlip Logik, dann synchronisiert sich die Kiste selber korrekt.
Duke: Das habe ich natürlich schon versucht. Werde ich dort zu "klein", dann gibt es im Timing Report "Verletzungen". Habe mich auch schon herangetastet. Hab nur noch folgende Constrains im ucf-file. TIMEGRP din1_timegroup OFFSET = IN 800ps VALID 1ns BEFORE "DCO1_p" RISING ; TIMEGRP din2_timegroup OFFSET = IN 800ps VALID 1ns BEFORE "DCO2_p" RISING ; NET bank2_diff_ch_matrix<0><1> LOC = "J11" |IOSTANDARD = "LVDS_25" |DIFF_TERM = TRUE | TNM = "din2_timegroup"; usw. Der Offset gibt mir doch in diesem Fall den maximal zulässigen Zeitversatz zum DCO_1 bzw DCO_2 an, korrekt? berndl: Mit dem "ChipEditor" habe ich bisher noch nicht gearbeitet. Meinst du "View/Edit Routed Design (FPGA Editor)?
ChipScopeUser schrieb: > Der Offset gibt mir doch in diesem Fall den maximal zulässigen > Zeitversatz zum DCO_1 bzw DCO_2 an, korrekt? Die 800 ps sind die Setup-Time, ja. Die 1 ns ist Setup-Time + Hold-Time. Diese Werte sind aus dem Datenblatt von AD etwas schwierig herauszuholen, weil dort die Samplerate (bzw. das Vielfache davon) mit eingeht. Bei all diesen Betrachtungen wird oft von einem idealen Takt ausgegangen. Vielleicht kannst Du Dir den nochmal getrennt anschauen und auf Jitter bzw. Phasenrauschen untersuchen (Scope -> Spekki -> phase noise analysator). Duke
Danke euch. Duke: Das Datenblatt gibt in der Tat nur schwer die Zeiten preis. Ich versuche momentan Durchblick in PlanAhead zu bekommen, um zu schauen, ob die Leitungen eng beieinander liegen. Ist es möglich eine Datei hochzuladen, damit ihr mal drüber schauen könnt? Christian: Hab es bisher "zu Fuss" gemacht, da mir die andere Option nicht bekannt war. Dieses nun zu ändern, würde ein komplettes redesign bedeuten. Da die Funktionalität generell gegeben ist (bei geringen Abtastraten), ist es wohl sinnvoller den Fehler/Timingproblem zu beheben. Ich nehme den Hinweis jedoch für ein zukünftiges Projekt gerne auf. Danke dir.
ChipScopeUser schrieb: > Ist es möglich eine Datei hochzuladen, damit ihr mal drüber schauen > könnt? Ich werde wohl dieses Jahr kein FPGA-Design mehr anfassen :-)
ChipScopeUser schrieb: > Hab es bisher "zu Fuss" gemacht, da mir die andere Option nicht bekannt > war. Dieses nun zu ändern, würde ein komplettes redesign bedeuten. Da > die Funktionalität generell gegeben ist (bei geringen Abtastraten), ist > es wohl sinnvoller den Fehler/Timingproblem zu beheben. Ich nehme den > Hinweis jedoch für ein zukünftiges Projekt gerne auf. Danke dir. Naja, ich denke, du wirst das nur sehr schwer in den Griff bekommen und damit viel mehr Arbeit haben, als wenn du das austauschst. Das ist dank der XAPP1064 und dem ISERDES Core Generator schnell gemacht. Ich würde es dir dringend empfehlen. Das ist alles fix und fertig, ich kann dir auch Quelltext-Schnipsel reinstellen bei Bedarf, ist aber eigentlich nicht nötig, das erzeugt der Coregen alles für dich, sogar als VHDL. Außerdem macht man das mit der Abtastrate anders, man lässt den ADC mit voller Geschwindigkeit laufen und benutzt dann im FPGA nur jedes x. Sample. Dann bekommst du weitaus weniger Stress mit den Taktdomänen, weil du immer den gleichen Takt hast.
Christian R.: Dann bin ich aber mit meinem VHDL-Teil an einen FPGA Typ gebunden, richtig? Steht der IPCore auf dem Virtex6 eigentlich zur Verfügung?
Freilich hat der Virtex 6 auch die ISERDES integriert. Lass dir einfach mal einen Core generieren, zusammen mit der xapp siehste dann sehr schnell durch. Die Dinger gehen problemlos bis über 1GBit/s pro Leitungspaar.
Da musst du sicherlich erst mal in den Projektoptionen den passenden FPGA einstellen, dann wirds aktiv. Bei supported families auf der rechten Seite ist ja der V6 dabei.
Habs ;) Werde mich morgen mal dran setzen. Vielleicht komme ich damit ja weiter, wenn ich das Projekt von vorn aufarbeite. Ich habe ja zwei FCOs (zwei Bänke). Da müsste ich dann quasi zwei Cores einfügen? Die Option eine variable Anzahl von Kanälen (z.B. 4 von 16) zu nutzen (platz auf dem FPGA zu sparen, bleibt mir wahrscheinlich mit der Nutzung des Cores nicht erhalten, oder? Bzw. muss ich für jeden Kanal einen eigenen Core anlegen/ einbinden? Hast du für meinen Fall Beispieleinstellungen (du sagtest du hattest ein ähnliches Projekt)?
Doch, das geht. Du brauchst für jedes Leitungspaar so einen ISERDES, außer für den DCO. Da die sowieso alle einzeln sind, kannst du die auch nach Bedarf instanziieren. Mit dem Ausgang des FCO steuerst du die Bitslip Logik, die die Daten gerade rückt. Bei zwei Bänken brauchst du halt alles doppelt, hab ich ja auch am LTM9011. Code suche ich mal im Laufe des Tages, ist aber 1:1 aus der Xapp1064.
:
Bearbeitet durch User
Hm, anscheinend geht das mit den ISERDES am V6 doch nicht so mit dem speziellen ADC zusammen. Denn die können erst mal keine 14:1 Parallelisierung (Nur 2-4-6-8-10). Da müsste man mal schauen, ob der Trick aus der XAPP104 für höhere Serialisations-Faktoren mit dem Master/Slave Teil beim Virtex auch klappt...das ist ja ein blöder ADC, die mit den 2 Lanes pro Kanal sind da viel sinnvoller. Vielleicht musste dann doch zu Fuß implementieren...
Christian R. schrieb: > Hm, anscheinend geht das mit den ISERDES am V6 doch nicht so mit dem > speziellen ADC zusammen. Denn die können erst mal keine 14:1 > Parallelisierung (Nur 2-4-6-8-10). Da müsste man mal schauen, ob der > Trick aus der XAPP104 für höhere Serialisations-Faktoren mit dem > Master/Slave Teil beim Virtex auch klappt...das ist ja ein blöder ADC, > die mit den 2 Lanes pro Kanal sind da viel sinnvoller. Vielleicht musste > dann doch zu Fuß implementieren... Allerdings nur das Framing. Es ist trotzdem sinnvoll die ISERDES im 1:4 bzw 1:6 Mode zu verwenden. 1:4 ist portabler auf FPGA's anderer Hersteller, einen IDDR mit x2 Mode (d.h. 1:4) dürfte jeder moderne FPGA haben.
Danke für die zahlreichen Hinweise. Ich lese aus den letzten Beiträgen heraus, dass das Verwenden des ISERDES nicht die einfachste/idealste Lösung für den speziellen ADC ist. Mein Versuch wäre es jetzt, dass "Programm" noch einmal Schritt für Schritt aufzubauen (eigentlich ist es ja nicht viel "Code"). Vielleicht wäre dieses am besten, um den Fehler zu entdecken. Also werde ich meinen Ansatz und dessen Umsetzung zur "Kontrolle" posten, wenn es ok ist. Variante (a): - Zu Fuss Variante (b): - 4 x 4 ISERDES (benötigt wohl mehr Fläche auf dem FPGA, deswegen von mir nicht so bevorzugt. Sehe auch in meinem Fall mit dem speziellen ADC nicht unbedingt den Vorteil) Es muss doch auch für einen Anfänger wie mich möglich sein, den ADC zum Laufen zu bekommen. ;)
ChipScopeUser schrieb: > Danke für die zahlreichen Hinweise. Ich lese aus den letzten Beiträgen > heraus, dass das Verwenden des ISERDES nicht die einfachste/idealste > Lösung für den speziellen ADC ist. Das siehst du falsch. > Variante (a): > - Zu Fuss Nur mit Constraints und ohne in den IO Zellen vorhande Funktionalität, ist das Wahnsinn. > > Variante (b): > - 4 x 4 ISERDES (benötigt wohl mehr Fläche auf dem FPGA, deswegen von > mir nicht so bevorzugt. Sehe auch in meinem Fall mit dem speziellen ADC > nicht unbedingt den Vorteil) Der ISERDES ist eine in IO Zellen vorhandene Funktion, d.h. die braucht eben gar keine Fläche. Und um von 1:4 ode 1:6 auf 1:12 zu kommen braucht es nur wenig nachgeschaltete Logik/Register. > > Es muss doch auch für einen Anfänger wie mich möglich sein, den ADC zum > Laufen zu bekommen. ;) 1. Schritt, mal sich die Datenblätter wirklich genau anzuschauen, ein FPGA ist mehr als nur Clocktree, LUTs und Flipflops, und nicht einfach los schreiben.
Lattice User: Danke dir. Ich werde mir auf Grund deines Beitrages das Datenblatt zum ISERDES noch einmal genau durchlesen, und gegebenfalls nachfragen.
Lattice User: Hab mir nun ein Konzept erstellt. (1) Einbinden des IPCores ISERDES jeweils einmal pro Kanal (zu Beginn beschränke ich mich auf einen Kanal). (2) Figure 4 der von Euch angesprochenen Note 1064 zeigt, wie ich einen seriellen Stream der Wortlänge 12 einlese und parallelisiere. (Allerdings wäre dieses für 14 Bits nicht ohne Aufwand später zu ändern, was nicht schlimm ist in diesem Fall) (3) Testbench erstellen und testen :) Meine aufgetretenen Fragen: (a) Ich orientiere mich beim Einlesen des Datenstreams am DCO-Takt, so wie ich das verstehe. Sind zwölf Werte eingelesen (DDR), dann liegt ein Wort am Ausgang des Cores an. Da ich für eine Bank im ADC den selben DCO nehme, müssten die Daten vollkommen synchron an acht möglichen Ausgängen anliegen, richtig? Das Framesignal benötige ich sozusagen vom ADC her nicht! (b) Für die zweite Bank am ADC mache ich das Selbe, nur, dass ich DCO2 statt DCO1 verwende. Nun muss ich die Daten von Bank 1 und Bank 2 wieder synchronisieren. In dieser Variante fällt der ärger mit Timing Constrains weg.
Naja, Frame brauchst du schon, musst ja den Anfang finden. Der DCO Clock ist ja ein vielfaches des Sample Taktes und wir zum Einlesen gebraucht. Deine interne Logik sieht den durch 7 geteilten Takt und das ist ja gerade das entspannte an der Geschichte, die 500MHz interessieren dich gar nicht so recht.
ChipScopeUser schrieb: > Lattice User: > Hab mir nun ein Konzept erstellt. > > (1) Einbinden des IPCores ISERDES jeweils einmal pro Kanal (zu Beginn > beschränke ich mich auf einen Kanal). > (2) Figure 4 der von Euch angesprochenen Note 1064 zeigt, wie ich einen > seriellen Stream der Wortlänge 12 einlese und parallelisiere. > (Allerdings wäre dieses für 14 Bits nicht ohne Aufwand später zu ändern, > was nicht schlimm ist in diesem Fall) > (3) Testbench erstellen und testen :) > In etwa, nur ein kleines Problem, der ISERDES kann keine 1:12 auf dem Virtex6. D.h. wenn du 1:6 verwendest, bekommst du die 12 Bits des ADC in 2 Takten. FC liest du genau so ein, damit du weisst wann die Daten anfangen. Um auf FC zu synchronisieren, kannst du entweder das Bitslip Module des ISERDES verwenden und solange schieben lassen bis es passt, oder eine FSM nachschalten. Letzteres ist dann mit etwas nachdenken auch auf 14 Bit erweiterbar.
Noch einen kleinen Tipp: wenn du den ISERDES mit 1:2 verwendest, bekommst du mit jedem takt 2 Bit, und kannst eventuell das meiste von deinem bisherigen Code weiterverwenden. Nachteil: Teiler N=1 wird schwierig.
Eine kurze Nachfrage: Für das Design nach Abb. 4 sollte ich schon die App-Note verwenden, richtig? Also nicht "direkt" den IPCore einbinden und dann das Blockschaltbild einzeln nachbilden.
Ich habe das ganze noch nicht ganz verstanden. Was der IPCore ISERDES macht, dass ist denke ich klar. Je nach Einstellung deserialisiert dieser eine Eingangsfolge. Jetzt bildet so wie ich das verstanden habe das Design "serdes_1_to_n_clk_pll_s16_diff.vhd" den oberen und das Design "serdes_1_to_n_data_s16_diff.vhd" den unteren Teil des Blockschaltbildes aus Fig. 4 ab. Lattice User: Es ist wohl (wegen N = 1) sinnvoll den Stream in 4 x 3 zu unterteilen (12 bit). Was genau macht der obere und der untere Block? Ich habe es so verstanden, dass der obere Block zunächst vier Bit jeweils zusammenfassen soll, und einen CLK bereit stellt, welcher dem unteren Block übergeben wird. Dieser fasst dann jeweils 3 der vier-Bit-Blöcke zu einem 12 Bit Block zusammen. Nun weiß ich nicht, wie ich D und S einzustellen habe in der App. Ich möchte ja 12 Bit Ausgangswortbreite erhalten. Demnach muss das Produkt S*D = 12 sein => S = 4, D = 3? Wo speise ich nun meinen Datastream vom ADC ein? Dieser ist ja stets 1 Bit breit? Entschuldigung, dass ich so verwirrt frage. Irgendwie wurde ich aus der Doku nicht schlau.
1. Frage :) Ist Abbildung 4 aus der App-Note 1064 überhaupt die korrekte Wahl (dort steht ja etwas von dem höheren Faktor). Meint ihr das die ganze Zeit? 2. Frage: Wenn ja, wo lege ich den seriellen Datastream an?
Also Bild 4 ist schon das richtige. Da der S6 vom Virtex 5 abgeleitet ist, sollte das auf dem Virtex 6 ähnlich klappen. Solche Spezialfälle werden vom Coregen aber nicht abgedeckt, das muss man nach der Appnote machen. Wenn ich heut noch zeit hab, schau ich mal, ob der Virtex diese Master/Slave Geschichte hat, oder ob da ein ISERDES im 1:7 Modus reicht (falls überhaupt möglich). Auf jeden Fall muss an den oberen Block der DCO Takt dran, an den unteren eine Datenleitung mit dem seriellen Datenstrom vom ADC. Den unteren Block brauchst du dann halt mehrfach. D wäre bei dir 1, S wäre 14.
Danke dir. Ich habe gestern noch diese App-Note gefunden. http://www.xilinx.com/support/documentation/application_notes/xapp1071_V6_ADC_DAC_LVDS.pdf Da ist genau der Fall beschrieben, der hier vorliegt. Ich denke mal, dass es ähnlich zu der oben genannten App-Note ist.
Hm, ich weiß nicht. Auch da laufen die 14 Bit ADCs im 16 Bit Modus. Der blöde 14 Bit auf 1 Leitung Modus wie ihn dein ADC hat. Ich hab aber im Datenblatt auch nix gefunden, wie man den in einen sinnvollen modus schalten kann.
Christian R.: Irgendwie sehe ich das wohl falsch. Die APP-Note deckt doch genau meinen Fall ab. (siehe zB. Tabelle 1 Seite 5: 12 Bit bei 80 MSp/s (ich wäre mit 64 MSp/s sogar drunter) Außerdem stimmt das Datenformat des AD9249 mit dem aus Abbildung 2/Seite 2 überein (also bei mir 12 Bit Mode). Außerdem ist das ganze Dokument auf den Virtex6 zugeschnitten.
Auch die XAPP1071 schaut etwas schlampig gemacht aus. Aus der UG361 (IOSelecr userguide für den Virtex&) geht klar hervor, dass der ISERDES1 nur 6 bit kann. Also nicht mit 14 bit, auch nicht mit dem Trick die beiden ISERDES an den 2 LVDS Pins im SDR Mode zu benutzen. Ich würde einfach nur einen einzigen ISERDES1 (pro Datenleiting) im DDR Mode nutzen, und die Erweiterung auf auf viele Bits und das Framing mit einer kleinen FSM dahinter machen. Als Lattice ECP3/MachXO2 User habe ich ohnehin keine Wahl, das es da nichts zu kaskadieren gibt, und auch Bitslipper.
Achso, ich dachte du willst den 14 Bit Modus des ADC nehmen, der ist nämlich echt blöde. Beim 12 Bit Modus sollte das relativ einfach mit der Kaskadierung klappen....so richtig schön ist dsas aber erst mit der 7er Serie geworden, am Artix ist der LTM9011 ein Kinderspiel.
Lattice User: Gerade für noch nicht so Erfahrende auf dem Gebiet des FPGA Designs ist es schwer solche App.-Notes richtig zu lesen/deuten. Den Userguide (IOSelecr userguide für den Virtex) habe ich auch grad auf. Christian R.: Ich möchte den 12 Bit Mode nutzen. Auf diesen kann ich per SPI bereits wechseln. Tut mir leid für die Verwirrung. Es stehen meiner Meinung nach viele Ansätze im Raum. Jetzt muss ich einen konsequent umsetzen. Kann mir noch einmal einer von euch zusammenfassend sagen, welche App. Note/Lösung für einen noch nicht so erfahrenden Entwickler umzusetzen ist ? (mit eurer Unterstützung). Bin ja mit meinem ursprünglichen Design auf dem Holzweg gewesen.
probier mal deinen existierenden Code mit SAME_EDGE_PIPELINED auf dem IDDR.
Lattice User: Ich versteh nicht recht. "SAME_EDGE_PIPELINED" ist die ganze Zeit gesetzt in meinem Code. Ihr meintet doch, dass ich von "meinem" existierenden Code weg soll (auf Grund vom Timing: das sagten ja auch die ganzen App-Notes, dass bei meinen Taktraten ein ISERDES zu nutzen ist). Korregiere mich ruhig;)
Ich versuche die ganze Zeit schon den ISERDES1 zu verstehen. Funktion: - mit dem ISERDES1 kann ich die Eingangsdatenfolge D in einen parallelen Ausgangsdatenstream Q umsetzen. Eingänge: D : Eingangsdaten z.B. 1 0 1 0 0 1 1 0 0 0 1 1 1 ... DDLY CLK : DCO_p CLKB : DCO_n CE1 CE2 RST : Reset CLKDIV : OCLK BITSLIP : wird benötigt, falls man die Position der Daten ermitteln möchte SHIFTIN1 SHIFTIN2 OFB DYNCLKDIVSEL DYNCLKSEL Ausgänge: Q : paralleler Datenstream z.B für Wortbreite 4 1010 0110 0011 1 ... O SHIFTOUT1 SHIFTOUT2 Keine Funktion in der Testbench
ChipScopeUser schrieb: > Lattice User: > Ich versteh nicht recht. "SAME_EDGE_PIPELINED" ist die ganze Zeit > gesetzt in meinem Code. habe mich wohl verguckt. Eigentlich sollte IDDR mit "SAME_EDGE_PIPELINED" unkritisch sein, zumindestens bei deinen bisher genutzten 200 MHz. Sind DC0/DC1 an einem Clock Input des FPGA's angeschlossen? Wenn nein geht es auch mit dem ISERDES nicht.
Lattice User: 1) Bei 32.5 MS/s (d.h. 195 MHz DCO) funktioniert es ja nach Setzen der Timing Constrains auch. Bei 65 MS/s (d.h. 390 MHz) funktioniert es nicht. Deshalb w wird ja hier gerade das mit dem ISERDES angesprochen ;) 2) DCO1, DCO2 (beim Virtex6 XC6VLX75T-2FFG784C) liegen auf F7(IO_L9P_MRCC_36), G7(IO_L9N_MRCC_36), H11(IO_L10P_MRCC_36) und H10(IO_L10N_MRCC_36). Also CLK Pins. NET DCO1_p LOC = "F7" |DIFF_TERM = "TRUE" |IOSTANDARD = "LVDS_25"; NET DCO1_n LOC = "G7" |DIFF_TERM = "TRUE" |IOSTANDARD = "LVDS_25"; NET DCO2_p LOC = "H11" |DIFF_TERM = "TRUE" |IOSTANDARD = "LVDS_25"; NET DCO2_n LOC = "H10" |DIFF_TERM = "TRUE" |IOSTANDARD = "LVDS_25";
ich selbst kann dir kein Beispiel generieren, mangels Xilinx SW. Eventuell findet Christan etwas Zeit. In diesem Thread findest du eines in Verilog (Kaskadiert mit Master Slaver, max 10 bit) http://forums.xilinx.com/t5/Virtex-Family-FPGAs/V6-iserdes1-expansion/td-p/242272 Versuche als Einsteig in deinem Code das IDDR durch ISERDES1 in 2 bit Mode zu ersetzen. Schafft dann zwar auch nicht die 65 MS/s aber du bekommst ein Gefühl dafür was am an einer einzelen ISERDES1 alles angeschlossen werden muss. Wenn das geht, auf 4 oder 6 bit Mode upgraden.
Wird schwierig, 2 Kinder, Weihnachten, Omi und Opi kommen morgen....obwohl das dann ein guter Ausgleich wäre.... Ich schau mal.
Dann dir schöne Feiertage. Wäre hilfreich ein Beispiel für das serielle Einlesen eines Kanals zu haben, ja :) Ich bin mit dem ISERDES1 nicht viel weiter gekommen (siehe Anhang). Ich wollte zunächst einen 1:4 seriell zu parallel umsetzer testen. Das Resultat in der Testbench stimmt nicht.
Wann wird beim ISERDES1 ein Datenwert übernommen? Fall 1: SDR Am CLK-Eingang (CLK) liegt der DCO-Takt an. Jetzt sollte doch bei jeder steigenden Flanke des DCO-Taktes ein Datenwert des Signals an D übernommen werden. Am CLKDIV liegt der Frameclock. Ist z.B. die Wortbreite 4 eingestellt, ist dieser ein vierfaches vom DCO. Fall 2: DDR Am CLK-Eingang (CLK) liegt der DCO-Takt an. Jetzt sollte doch bei jeder steigenden und bei jeder fallenden Flanke des DCO-Taktes ein Datenwert des Signals an D übernommen werden. Am CLKDIV liegt der Frameclock. Ist z.B. die Wortbreite 4 eingestellt, ist dieser ein zweifaches vom DCO. Meine TestBench zeigt anderes Verhalten.
ChipScopeUser schrieb: > Wann wird beim ISERDES1 ein Datenwert übernommen? > > Fall 1: SDR > > Am CLK-Eingang (CLK) liegt der DCO-Takt an. Jetzt sollte doch bei jeder > steigenden Flanke des DCO-Taktes ein Datenwert des Signals an D > übernommen werden. > Am CLKDIV liegt der Frameclock. Ist z.B. die Wortbreite 4 eingestellt, > ist dieser ein vierfaches vom DCO. Nicht ein vierfaches, sondern ein Viertel. > > Fall 2: DDR > > Am CLK-Eingang (CLK) liegt der DCO-Takt an. Jetzt sollte doch bei jeder > steigenden und bei jeder fallenden Flanke des DCO-Taktes ein Datenwert > des Signals an D übernommen werden. > Am CLKDIV liegt der Frameclock. Ist z.B. die Wortbreite 4 eingestellt, > ist dieser ein zweifaches vom DCO. Und hier die Hälfte
ChipScopeUser schrieb: > Dann dir schöne Feiertage. Wäre hilfreich ein Beispiel für das serielle > Einlesen eines Kanals zu haben, ja :) Danke dir. Leider hab ich hier zu Hause nur die aktuellen Files mit dem Artix 7, die Sachen für den Spartan 6 hab ich auf Arbeit, da komm ich von hier aus nicht ran, erst am 5.1. wieder. Ich hoffe, das versaut dir nicht Weihnachten :) Aber da gibts schließlich auch wichtigeres als FPGA Design.
Lattice User: Sorry meinte ich auch. Doch in der testbench (siehe Anhang Foto) scheint es nicht das zu machen was es soll.
Das hier ist auch Quatsch
1 | CLK => FCO, -- for testing 3xDCO (3 x 4 bit blocks = 12 bit) |
2 | CLKB => Low, |
3 | CLKDIV => DCO, -- adc data clock (max. 390 MHz) |
4 | OCLK => Low, |
DC0 ist deine Inputclock, und gehört auf CLK An CLKDIV gehört eine aus DC0 im richtigen Verhältnis Clock (1/2 für 4bit). Das ist dann auch die Clock mit der du deine Weiterverarbeitung treibst. In der Testbench kannst du sie einfach mal teilen, auf dem FPGA muss sie mit PLL,DCM etc erzeugt werden.
1 | Divided Clock Input - CLKDIV |
2 | The divided clock input (CLKDIV) is typically a divided version of CLK (depending on the |
3 | width of the implemented deserialization). It drives the output of the serial-to-parallel |
4 | converter, the Bitslip submodule, and the CE module. |
FC0 hat hier nichts zu suchen. FCO gehört auf einen zweiten ISERDES1 als Dateninput, lass es erstmal aussen vor. Noch etwas, FC0 ist eigentlich keine Clock, sondern ein Datensignal um zu erkennen wo deine Framegrenzen sind.
Genau, den CLKDIV musst du über DCM/PLL oder solche Clock Buffer mit Teilerfunktion erzeugen, das ist dann auch dein interner Takt, muss dann noch über einen Bufg. An CLK und CLKB muss der schnelle Takt, also vom ADC der DCO.
Lattice User: Du schriebst, dass ich das IDDR durch ein ISERDES im 2 Bit Modus zunächst zum Test ersetzen sollte. Das funktioniert nicht. Im DDR Mode darf das N (1:N) nur 4 und größer betragen. Versuche morgen eure Ratschläge umzusetzen
Hab es mit N = 4 und N = 6 ausprobiert. Anbei das Simulationsresultat und der Ausschnitt aus dem VHDL-Code. Irgendwie passt das nicht. Was mache ich hier falsch?
Da stimmt doch einiges nicht. Wieso ist der CLKB nicht angeschlossen? Normal muss der auf den negierten schnellen Takt. Dann betreibst du den ISERDES im Slave Modus. Wo ist der Master? Und außerdem muss doch beim Slave so ein SHIFTIN dann genutzt werden, der vom SHIFTOUT des Masters kommt, wenn ich mich recht erinnere...und sollten nicht beide Clock Enables aktiv sein?
Danke. ISERDES funktioniert. Außerdem habe ich das gefunden https://ez.analog.com/message/145116. Exakt mein Problem ;). Also mit der Verwendung der ISERDES fahre ich gut, denke ich. Ich habe nun meine Daten DIN 1:4 gewandelt. Nun muss ich diese 1:3 wandeln, um auf 12 Bit zu kommen, richtig? Also DOUT als neuer DIN verwenden von einem zweiten ISERDES mit N = 3. (Master-Slave funktioniert leider nur bis 10 Bit) Was ich genau mit dem Frame machen soll, ist mir noch nicht klar.
Naja, die Frage ist, ob die ISERDES sich einfach so hin Reihe schalten lassen. Die hängen ja schon direkt am IO Pin dran. Da musst du wahrscheinlich dahinter "einfach" noch vier 3 Bit Schieberegister machen, um die Daten noch weiter zu parallelisieren. Allerdings musst du dich dann um BitSlip und Einsynchronisieren selber kümmern. Das Frame Signal behandelst du wie ein 6 Bit breites Datensignal direkt mit einem ISERDES und nimmst das Ausgangssignal für die Bitslip Logik aus der XAPP1064, um die ISERDES auszurichten. Das Sync-Pattern muss dann halt "000111" oder halt "111000" sein....dann richtet sich deine erste Stufe schon mal selber aus.
Christian R.: Danke versuche es gleich umzusetzen. Habe dazu noch die Variante gefunden: http://forums.xilinx.com/t5/image/serverpage/image-id/2627i4C8B842D69FAF7DC/image-size/original?v=mpbl-1&px=-1 Wäre es nicht so einfacher? Also 6 Bits SDR auf dem clk_p und clk_n "einzusammeln" und anschließend zu ordnen?
Wenn das funktioniert ist das natürlich auch eine elegante Möglichkeit...
Zusammenfassung bisher: 1. ISERDES_ODD liest die Daten bei steigender Flanke ein. CLK => ADC_CLK_net, CLKB => not ADC_CLK_net, CLKDIV => ADC_CLK_DIV_net, 2. ISERDES_EVEN liest die Daten bei fallender Flanke ein. CLK => not ADC_CLK_net, CLKB => ADC_CLK_net, CLKDIV => ADC_CLK_DIV_net, 3. DOUT <= q_even_net(5) & q_odd_net(5) & q_even_net(4) & q_odd_net(4) ... 4. ISERDES_FRAME liest die Daten (FCO) bei steigender und fallender Flanke (DDR) ein. DOUT sieht dann in der ART aus "11111100000011111100000011111100..." Nun muss ich die Bits noch "schieben", bzw. den Anfang finden. Du sagtest, dass ich es über Bitslip mache. Ganz klar ist mir die Sache nicht. Ich habe die "Bits" zur Zeit ja mittels eines Delays in der TestBench passend "hingeschoben". Dieses "Hinschieben" soll nun mittels des FCO geschehen.
Schau noch mal in die Xapp 1064 rein, da ist eine kleine FSM, die immer, wenn das Datenwort nach dem Iserdes für das FCO nicht passt, einen Impuls am BitSlip eingang aller ISERDES auslöst. Dann wird wieder eine Weile gewartet, und dann wieder geschaut, ob es passt. Irgendwann hat der FCO dann den Wert den paasenden Wert und somit alle anderen auch. Ob das bei der Mogelschaltung mit den zwei ISERDES dann auch richtig aligned ist, Küste man nochmal genau durchdenken, notfalls musst du die selbe Sache für FCO machen, dass das auch völlig zueinander passt.
Achso, du musst natürlich auch das FCO parallelisieren, also die Q Ausgänge benutzen, nicht den DOUT.
Meinte auch das parallelisierte ;). Habe in der APP keine Funktionsbeschriebung entdeckt. Hier http://www.xilinx.com/support/documentation/application_notes/xapp1071_V6_ADC_DAC_LVDS.pdf ist eine aufgeführt (abbildung 9). Zum Verständnis: 1. Parallelisieren des FCO (DIN) in 6 Bit Blöcken bei 12 Bit ADC 2. Der FCO ist in Phase zum DCO. 3. Nun gilt es den "Anfang" des FCOs zu ermitteln 4. Man muss nun das parallelisierte Wort aus 1. mit einem Pattern vergleichen (in diesem Fall mit "111111000000" 5. Falls dieses nicht stimmt, wird BitSlip high gesetzt, bis der Comperator eine Übereinstimmung feststellt 6. Stimmen FRAME und Pattern überein, dann erhält man eine "Konstante" ( z.B. 3 BitSlip-Vorgänge) 7. Demnach müssen die Datenbits um diese "Konstante geschoben werden Sehe ich das Grundkonzept richtig?
FC0 wird genauso wie die Daten mit einem eigenen ISERDESE1 parallelisiert. Im Falle der Odd/Even Methode reicht der Odd. Danach ist es einfach, wenn FC0ParOdd != "111000", Bitslip für alle ISERDESE1 der Gruppe triggern sollte reichen. Eine komplierte FSM ist nur nötig wenn die Syncpattern im Nutzdatenstrom enthalten, und womöglich auch falsche Syncs auftreten können. Das ist hoer nicht der Fall.
Eine Nachfrage: mit dem BitSlip sortiert man die Bits - welche vorher zu einem Wort zusammengefasst wurden - um. Ich muss nun doch eher den Beginn der parallelisierung verschieben am FCO ausrichten). Was hat das mit nem BitSlip zu tun?
ChipScopeUser schrieb: > Eine Nachfrage: mit dem BitSlip sortiert man die Bits - welche vorher zu > einem Wort zusammengefasst wurden - um. Nein > Ich muss nun doch eher den > Beginn der parallelisierung verschieben am FCO ausrichten). Genau das macht Bitslip, es verschiebt den Beginn in Relation deinem CLKDIV. Ein Puls am Bitslip => einmal verschieben.
Nachtrag:
> Ein Puls am Bitslip => einmal verschieben.
Es bleibt dann für alle zukünftigen Daten verschoben bis zum Reset.
Genau, und das BitSlip darf immer nur ein Takt des DIVCLK auf High sein, dann eine Weile warten, dann erst bei Bedarf wieder genau einen Takt setzen. Einfach gesetzt lassen klappt nicht. Daher die FSM in der XAPP.
Ok. Danke. In der XAPP1064 finde ich die StateMachine nicht. Hast du da eine Seitenzahl für mich? Ich setze mich einmal dran, die selber zu schreiben bis dahin.
Die ist meines Wissens in den Code Beispielen, die als zip File in dem PDF verlinkt sind. Ich kann es aber auch posten wenn ich zu Hause bin.
So, hier mal die Files aus dem Artix 7 Design. Das ist eigentlich direkt aus der XAPP1064 abgeleitet, nur die Xilinx Primitiven halt getauscht. Bei mir hab ich am DCO noch ein IDELAY Element, damit kann ich den Abtastzeitpunkt genau in die Mitte des Datenauges schieben. Hab ich mit einem kleinen Testdesign einmalig rausgesucht, könnte man auch automatisieren, aber die Leiterplatte ändert sich ja nicht. Wir haben auch alle Datenleitungen gleich lang gemacht, so dass es ausreicht, den Takt zu verschieben.
:
Bearbeitet durch User
Eine Unstimmigkeit ist aufgetreten. VHDL-Datei zum Test der Frame State Maschine (Bspw. 6 Bit Wortbreite): a) Ohne State Maschine: BITSLIP <= BITSLIP im VHDL-Code (gelber Kasten). BITSLIP wird in der TestBench wie folgt belegt. stim_proc: process begin wait for 75 ns; BITSLIP <= '1'; wait for 10 ns; BITSLIP <= '0'; wait; end process; Resultat: Bitslip Operation funktioniert. b) Mit State Maschine (1 BitSlip zum Test): BITSLIP <= BITSLIP_net im VHDL-Code (gelber Kasten). In der TestBench sieht alles wie im Fall a) aus. Resultat: Bitslip funktioniert nicht. Verstehe nicht wieso. Ist die State Maschine von der Tendenz her korrekt aufgebaut?
ChipScopeUser schrieb: > Resultat: Bitslip funktioniert nicht. Verstehe nicht wieso. > > Ist die State Maschine von der Tendenz her korrekt aufgebaut? Falsche Verwendung von VHDL Variablen. Falscher Aufbau eines getakteten Prozesses. @Christian Du machst zwischen 2 Bitslip pulsen eine Pasue von 7 Frames. Ein Frame kann ich verstehen, aber warum so lang?
Christian R. schrieb: > Wie gesagt, aus der XAPP kopiert... ;) Ich hinterfrage so etwas immer, bei solchen Appnotes ist immer viel C&P im Spiel. Wenn es mit einem Frame Pause geht, sollte dieser Einzeiler reichen
1 | bitslip <= '1' when bitslip = '0' AND frame = "111000" and rising_edge(clkdiv) else '0' when rising_edge(clkdiv); |
Hm, müsste man noch mal in den User Guide schauen, ich glaube da war schon etwas mehr Pause nötig um das Bit weiter zu springen....steht ja detailliert da beschrieben. Ich glaube "ChipScopeUser" sollte das auch mal tun, dann würden sich einige Fragen erübrigen. Aber einen blutigen Anfänger (sieht man an seinem Code) mit sowas zu betrauen ist eh grenzwertig, das macht man nicht mal nebenbei. Wahrscheinlich wieder so eine völlig über-ambitionierte Diplomarbeit, oder noch wahrscheinlicher was von einer HTL....die überschätzen sich ja generell. Scheint Teil des Lehrplanes zu sein.
Christian R. schrieb: > Hm, müsste man noch mal in den User Guide schauen, ich glaube da war > schon etwas mehr Pause nötig um das Bit weiter zu springen....steht ja > detailliert da beschrieben. Habe es mir angeschaut, Im SDR Mode reicht zum eigentlichen Weiterspringen ein Frame Pause, aber der Slip wird erst wahrend dem Pauseframe ausgeführt was zur Folge dass die Framedaten ungültig sind. D.h. man braucht ein weiteres Frame Pause. Im DDR Mode ist keine Pause nötig. PS:Irrtum vorbehalten. PSS: Geht immer noch in einem Einzeiler.
Danke. Simulation klappt soweit für den vorliegenden adc. Eine Frage zum IDELAYE Element. Es hat die Aufgabe das Signal "clk_in_int", um ein festes Delay zu verschieben => clk_in_int_delay. Beim mapping tritt folgender Fehler auf: IDELAYCTRL not found for clock region CLOCKREGION_X1Y2. The IODELAYE1 block ADC_INTERFACE/DATA_CLOCK_1/IODELAY1_VIRTEX6_clk has an IDELAY_TYPE attribute of FIXED, VARIABLE, or VAR_LOADABLE. This programming requires that there be an IDELAYCTRL block programmed within the same clock region. Wollte nun einfach mal das IDELAYE Element ersetzen durch clk_in_int_delay => clk_in_int; Dann funktioniert die Simulation nicht mehr wie sie sollte. (BitSlip etc. rastet nicht mehr auf die Bitmaske ein). Daher: Übersehe ich etwas bei der Aufgabe des Blockes IDELAYE?
Du musst mal lernen, die User Guides zu lesen, da siehst du dass wenn du die IDELAY Elemente verwenden willst, du noch zusätzlich pro Clock Region ein IDELAYCTRL benötigst. Das hab ich global, deswegen im Modul nicht drin. Als Eingangstakt braucht das aber noch 200MHz im Normalfall.
Du hast Recht. Den hatte ich auch eingefügt nach der Fehlermeldung. Dann ist sie verschwunden. Aber ich muss die User Guides genauer lesen. Das Design ist nun funktionsfähig in der Simulation. UCF-File ist angelegt. Jetzt bekomme ich diese Fehlermeldung beim Routen: "This design is unrouteable. Router will not continue. To evaluate the problem please use fpga_editor. The nets listed below can not be routed:" Mehr steht da nicht. Im FPGA Editor sehe ich nur, dass alle Netze nicht geroutet sind.
Ich vermute, du hast noch nicht die passenden Clock Buffer an den ISERDES dran, da muss man je nach FPGA Familie verschiedene nehmen, schau mal, was der Core Generator da benutzt. Oder diese Verschaltung mit den zwei ISERDES klappt doch auf dem V6 nicht...User Guide...
Christian R. 1) CLOCK BUFFER: Habe die geforderten Buffer aus dem User Guide verwendet (S. 141 http://www.xilinx.com/support/documentation/user_guides/ug361.pdf). 2) Verschaltung: In meinem Fall habe ich keine Master-Slave Verschaltung (siehe Anhang).
Nachtrag zu 2): Lasse ich beim zweiten ISERDES testweise die Ausgänge "open", dann wird ein Bitfile generiert. Q1=> open,--q_odd_net(0), Q2=> open,-- q_odd_net(1), Q3=>open,-- q_odd_net(2), Q4=>open,-- q_odd_net(3), Q5=>open,--q_odd_net(4), Q6=>open,-- q_odd_net(5),
Kann es demnach möglich sein, dass auf Grund der äußeren Pinbelegung ein Routen unmöglich ist?
ChipScopeUser schrieb: > Kann es demnach möglich sein, dass auf Grund der äußeren Pinbelegung ein > Routen unmöglich ist? Am Routen scheidert es sicher nicht. Nur wenn du die Ausgänge des ISERDESE1 nicht verbindest, wird der Synthesizer das ganze Modul wegoptimieren. Wenn das Vorraussetzung ist, damit du eine Bitfile bekommst, könnte es sein, dass du Pins verwendest bei denen keine ISERDESE1 zur Verfügung stehen (oder nur einer). Da heisst es Datenblatt und Userguides konsultieren. Wenn du falsche Pins verwendest, hilft nur ein Redesign der Platine.
Das kann bei solchen speziellen FPGA Sachen schhon mal vorkommen, gerade die SERDES sind da zickig, vor allem was die Taktung angeht. Schau mal im Clocking User Guide, ob deine Clocks überhaupt bis ans Ziel kommen können. Und hat der Virtex überhaupt 2 ISERDES pro Pin, oder ist das da wieder diese komische Einschränkung mit LVDS oder nicht LVDS? Beim Spartan 6 war es ein Krampf...
Danke. Ich muss nocheinmal so doof fragen. In welchem Guide finde ich heraus, wo und wieviele ISERDES vorhanden an den pins sind? Zb beim virtex 6 in meinem fall? Bin wie gesagt neu auf dem Gebiet.
Im User Guide, aber ich hab eben mal geschaut, laut der XAPP1071 sollte das so in etwa klappen. Hast du mal den Code direkt aus der xapp1071 versucht? Da gibts ja auch ein Zip File mit Beispielprojekt... Was ich mir noch vorstellen kann, dass der Clock vom ADC ungünstig zu den Daten liegt, und somit vom Bufr nicht genutzt werden kann.....
:
Bearbeitet durch User
Hab mir das ISE Projekt (XAPP1071) angeschaut. Unterschied zu dem von mir verwendeten Modul zum Einlesen der Daten: In adcData sind lediglich Q1 - Q4 belegt (Q5,Q6 open) (hat was mit deren "Bitauswertung" zu tun). Demnach sollte es gehen mit zwei ISERDES (even, odd). Die Pinbelegung für den dort verwendeten FPGA Virtex 6 XC6VLX240T (ML605 EV Board) müsste doch identisch sein mit meinem Virtex6 XC6VLX75T (Analog EV Board). Der Unterschied besteht doch lediglich in der Anzahl der Logicelemente etc. Das sollte nicht den Ausschalg geben.
Naja nicht ganz. Wenn du die XAPP1071 auf deinen ADC anpassen wölltest, müsstest du jeweils 3 Bit des ISERDES nehmen, und die entstehenden 6 Bit dann wie in der XAPP in Abhängigkeit des Frame Sync zum 12 Bit Wort zusammen bauen.
Ja ok. Aber es ändert nichts an der Tatsache, dass die in der APP1071 sowie ich zwei ISERDES verwenden, um ein Wort zusammenzufügen. Demnach muss das vom Prinzip her bei mir auch generierbar (bit file) sein.
Wenn alle Randbedingungen stimmen, dann ja. Ich weiß da jetzt per Ferndiagnose auch nicht mehr weiter...
Kannst du mal die gesamten ReportFiles posten? Also syr, mrp, par usw...
Ich denke, ich habe eine Idee, wieso das Routing nicht funktioniert. In dem Beispiel aus der APP1071 habe ich in Bezug auf den BUFR folgende Zeile gefunden: -- Attributes attribute LOC : string; attribute LOC of AdcClock_I_Bufio : label is C_BufioLoc; -- The BUFR is generated through a generate statement and therefore the LOC attribute -- must be place into the generate statement. -- See the BUFR generation down in the source code. Außerdem sind im ucf. folgende Zeilen dazu eingefügt: # ADC Interface. INST "Apps_I_AdcToplevel" AREA_GROUP = "AdcToplevel"; AREA_GROUP "AdcToplevel" RANGE=SLICE_X0Y120:SLICE_X11Y159; Das könnte deine Vermutung mit dem Clock untermauern. Wie ich dieses korrekt verwende, muss ich mir erst anlesen.
Also, laut Report kann er die Dateneingäng der ISERDES nicht geroutet werden. Vielleicht musst du doch diesen komischen IBUFDS mit den zwei Ausgängen nehmen, wie in der ersten Variante da in der 1071.
Welche Variante meinst du da genau? Abb. 6? So ähnlich mach ich das doch. Gebe dataIn_p und DataIn_n auf eine solchen buffer. Den Ausgang reiche ich an den dateneingang des iserdes weiter. Komisch. Für einen Anfänger echt keine angenehme aufgabe :(. Probiere es morgen nochmal aus.
Nee, diesen komischen Buffer mit den zwei Ausgängen aus Bild 15, das ist der Eingangsteil von der Gesamtschaltung Bild 14 in der XAPP1071. Ja, sowas ist in der Tat nix für einen Anfänger...ich hab da auch am Spartan 6 eine ganze Weile gebraucht und viel lesen müssen.
:
Bearbeitet durch User
Chrinstian R. Das einfügen der Buffer hat leider nichts gebracht. Simulation funktioniert noch gut. Design nicht routbar.
Hast du mal versucht, nur den Teil mit den ISERDES reinzunehmen, sonst gar nix anderes? Also die Ausgänge nach der ISERDES Logik direkt auf I/O Pins geben. Ansonsten hilft wohl nur noch eine Anfrage im Xilinx Forum oder einen Webcase aufmachen.
Christian R.: Das Design funktiniert. Bzw. ich habe nun das Bitfile. Habe beim ODD ISERDES das selbe Signal als Eingang wie beim EVEN ISERDES verwendet. Da pro Pad nur ein ISERDES vorhanden ist, wurde der Fehler beim generieren des Bit Files ausgegeben. Das habe ich übersehen. Gebe mir nun wieder (wie im ersten Beitrag) das parallelisierte Eingangssignal in ChipScope auf. Ich könnte wieder exakt das selbe Bild posten. Die "Ausreißer" sind wieder da :(. Dachte, dass ich dieses mit der Verwendung des ISERDES ausschließe. Durch die Variation des Delays (0 - 31) kann ich das Resultat verbessern (im Bereich 3-4. Jedoch nicht vollständig beseitigen. Stehe ich nun wieder am Anfang?
Hm, dann muss irgendwo anders ein Fehler sein, vielleicht erzeugt derADC ja schon den Mist? Kann man den nicht auch auf ein festes Muster einstellen? Damit könntest du ja verschiedene Pattern probieren, und schauen ob der Fehler immer noch auftritt.
Wir verarbeitest du die Daten weiter? Findet das mit einer vom ADC abgeleiteten Clock statt, z.B. Clockdiv? Wenn nein wie hast du di Übergabe an die andere Clock gelöst?
Lattice User: Meinst du die parallelisierten Daten (z.B. bei 65 Msps mit 65 MHz FCO)? Diese gebe ich direkt in ChipScope aus. ChipScope wird mit dem Ref. Takt von 100 MHz getaktet. Ich versuche gerad mal die parallelisierten Daten in einen eigenen FIFO mit unabhängigen Takten zu schreiben (wr_clk = FCO, rd_clk = sys_clk). Dann werde ich die Daten am FIFO Ausgang mit ChipScope im Systemtakt einlesen. Dann darf es garantiert zu keinem Bitfehler durch ChipScope kommen. Erscheinen dann Ausreißer, muss es am Design und nicht an ChipScope liegen.
ChipScopeUser schrieb: > Lattice User: > Meinst du die parallelisierten Daten (z.B. bei 65 Msps mit 65 MHz FCO)? > Diese gebe ich direkt in ChipScope aus. ChipScope wird mit dem Ref. Takt > von 100 MHz getaktet. Was meinst du mit Ref Takt? Ist dieser vomADC Takt abgeleitet? Wenn nein, dann hast hier das Problem, da es dann vorkommen kann dass ChipScope die Daten genau dann übernimmt wenn sie sich ändern. Und da wegen Routingvariationen sich nicht alle Bits gleichszeitig ändern wird Schrott übernommen. Ein asynchroner dual clock FIFO ist ein möglicher Ansatz um das zu lösen.
Referenztakt : 100 MHz (von einem vom ADC unabhängigen Quarz auf dem FPGA EV Board bereitgestellt) Referenzdelaytakt: 200 MHz (leite ich vom Referenztakt über eine DCM ab) FCO : 65 MHz (vom ADC bereitgestellt) DCO : 390 MHz (vom ADC bereitgestellt) Ich arbeite am FIFO :)
Achja dazu: Gibt es beim ISERDES einen Ausgang Valid( wenn daten gültig sind) als Eingang für den FIFO (wr_clk)? Habe keinen gefunden. Wollt ungern mich am FCO orientieren.
ChipScopeUser schrieb: > Achja dazu: Gibt es beim ISERDES einen Ausgang Valid( wenn daten gültig > sind) als Eingang für den FIFO (wr_clk)? Habe keinen gefunden. Wollt > ungern mich am FCO orientieren. Braucht es auch keinen, der ISERDES gibt mit jedem CLKDIV gültige Daten aus. Wenn du ein Valid haben möchtest um Daten zu unterdrücken wenn der ISERDES no0ch nicht im Sync mit dem FC ist, kannst du ein Valid in der Bitslip FSM erzeugen. Auf keinen Fall aber direkt mit dem FC eingang etwas veranstalten zu wollen. Im einfachsten Falle entspricht (FC SERDES Out = "111111000000").
Ohje, na dann kann das ja nix werden, du musst für die weitere Verarbeitung, zumindest zur zu einem FIFO den geteilten Takt nehmen, den der BUFR für den CLKDIV am ISERDES zur Verfügung stellt. Denn nur der ist synchron zu den Daten am Ausgang des ISERDES. Valid braucht man nicht, denn mit jedem Takt des CLKDIV kommt ein gültiger Wert.
Ok. Muss zwei clk_out_buf_div_out abwarten (Datenwort setzt sich aus Even (6 Bit) und Odd (6 Bit) zusammen). Klar. Ich weiß gerade nur nicht, wie ich mit der Latenz zwischen clk_buf_div_out und den Daten umgehe.
ChipScopeUser schrieb: > Ok. Muss zwei clk_out_buf_div_out abwarten (Datenwort setzt sich aus > Even (6 Bit) und Odd (6 Bit) zusammen). Die kommen aber parallel! Sieht man auch in deiner Simulation! > Ich weiß gerade nur nicht, > wie ich mit der Latenz zwischen clk_buf_div_out und den Daten umgehe. Gar nicht. Die Daten sind bei der steigenden Flanke von clk_buf_div_out gültig. Um Dinge wie Setup/Hold kümmert sich P&R, vorrausgesetzt deine Timingonstraints (Frqeuenz bzw Periode) sind richtig. Es ist dringend anzuraten, dass du dir nochmal die Grundlagen von synchronen digatalen Designs anschaust.
- FIFO eingefügt: Schreibtakt (DIV CLK), Lesetakt (SYS CLK) - Simulation passt. - Datenausgang des FIFOs in ChipScope dargestellt - Umstellung auf internes Testpattern (wie vorgeschlagen). Passt momentan bei 65/8 MSps, 65/4 MSps, 65/2 MSps (ab und zu). Funktioniert bei Testpattern "101010101010","010101010101", ... Scheint jedoch abhängig von der Generierung des Bitfiles zu sein. Ich habe bisher nur folgende Timing Constrains erstellt: NET "DCO_1_N" TNM_NET = DCO_1_N; TIMESPEC TS_DCO_1_N = PERIOD "DCO_1_N" 390 MHz LOW 50%; NET "DCO_1_P" TNM_NET = DCO_1_P; TIMESPEC TS_DCO_1_P = PERIOD "DCO_1_P" 390 MHz HIGH 50%; # 65 MSps, 12 Bit, DDR NET "EVB_REF_CLK_N" TNM_NET = EVB_REF_CLK_N; TIMESPEC TS_EVB_REF_CLK_N = PERIOD "EVB_REF_CLK_N" 100 MHz LOW 50%; NET "EVB_REF_CLK_P" TNM_NET = EVB_REF_CLK_P; TIMESPEC TS_EVB_REF_CLK_P = PERIOD "EVB_REF_CLK_P" 100 MHz HIGH 50%; Steh wohl echt wieder ganz am Anfang.
ChipScopeUser schrieb: > Scheint jedoch > abhängig von der Generierung des Bitfiles zu sein. Dann fehlen wohl noch ein paar Constraints. Wo sind die "OFFSET IN"-Constraints hin? Duke
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.