Hallo zusammen, ich habe jetzt den HMCAD1511 https://www.analog.com/media/en/technical-documentation/data-sheets/hmcad1511.pdf auf meine Platine gebraten und siehe da, ich kann auch Daten entgegennehmen. Ich habe aber ein Problem: Ich habe in Register 46 x0008 geschrieben damit die Daten MSB first rauskommen. Ich kann jetzt problemlos das Sync Pattern "11110000" empfangen. Das sieht gut aus. Danach wollte ich benutzerdefinierte Muster ausgeben. Also habe ich in Register 25 die x0010 geschrieben und nacheinander die einzelnen 8 Bits gesetzt in Register 26 von x0100 bis x8000. Und da habe ich gesehen, dass einige Bits vertauscht sind, warum auch immer. Im Folgenden die Tabelle welches Bit welchen Wert liefert: x8000 => 16 x4000 => 32 x2000 => 64 x1000 => 128 x0800 => 1 x0400 => 2 x0200 => 4 x0100 => 8 Man sieht also, dass das nach LSB first aussieht und die Nibbels vertauscht sind. Aber wenn das so wäre, könnte ich dann das Sync Pattern korrekt empfangen? Das müsste doch dann statt "11110000" aussehen wie "00001111"? Jedenfalls habe ich die Bits jetzt mal umsortiert: DATA <= HMCAD1511(4) & HMCAD1511(5) & HMCAD1511(6) & HMCAD1511(7) & HMCAD1511(0) & HMCAD1511(1) & HMCAD1511(2) & HMCAD1511(3); Und dann habe ich in Register 25 eine x0040 geschrieben, der ADC sollte mir also eine Rampe ausgeben. Passiert auch, die sieht jedoch kaputt aus. Jetzt ist meine Frage: Was wie wird das Sync Pattern ausgegeben wenn der ADC MSB first ausgibt? Im Datenblatt steht nur, das Sync Pattern sei "11110000" aber nicht wo das MSB ist. Sprich ich weiß nicht ob das das Pattern ist oder nur das was man auf den Leitungen sieht. Denn wenn das das Pattern auf den Leitungen im Defaultmodus (LSB first) ist und ich genau das Muster aber bei MSB first erkenne, dann habe ich einen Fehler und muss um ein Nibbel verschieben. Es steht leider auch nicht im Datenblatt ob die Einstellung MSB/LSB first einen Einfluss auf das Sync Pattern hat. Ich finde das müsste einen Einfluss haben. Bei den Daten im Anhang ist jeder Wert acht Mal hintereinander weil das acht Datenleistungen sind. Über Tips bin ich dankbar! Noch ein Nachtrag/Hinweis: Zuerst hatte ich einen Fehler in meinem SPI und habe statt 16 nur 15 Datenbits gesendet. Als Resultat wurde der ADC ziemlich heiß und hat nichts ausgegeben, also auch nicht LCLK und FCLK.
:
Bearbeitet durch User
So ... geschafft. Ich musste noch die LCLK Phase ändern und den Takt um 1 nach vorne schieben. Insgesamt gebe ich als SPI diese 6 24 Bit Worte aus: x"310101" -- clk_div = 1, single channel x"3A0202" -- input 1 for all ADC2,1 x"3B0202" -- input 1 for all ADC4,3 x"420000" -- phase LCLK = 270° x"530010" -- no delay, advance 1 Clock, no slow clock x"560004" -- startup single channel 640MHz - 1GHz Jo, sieht gut aus, im Anhang auch das VHDL dazu und noch ein paar Bildchen. Der Ausgang sind nur: Data_CLK: out std_logic; Data: out std_logic_vector(63 downto 0)); Wobei Data natürlich synchron zur Data_CLK ist. Dabei sind Data jeweils 8 8 Bit Werte aneinandergereiht. Die kann man schön in einen FIFO reinfüttern der unterschiedliche Breiten für Lesen und Schreiben und auch getrennte Takte hat. Damit bekommt man dann auch den Taktübergang geschenkt. Edit: Warum die 10 MHz in der FFT wie 20 MHz aussehen weiß ich noch nicht. Ich kann aber sagen, dass garantiert keine Werte ausgelassen werden bei der Übertragung zum PC. Sampleclock ist auch bei 1 GHz, aber ... Tatsache ich bekomme je Periode nur halb so viele Werte wie ich haben möchte. Fehler gefunden: Register 31 darf nicht x0101 sondern muss x0001 enthalten. Tja, zu früh gefreut.
:
Bearbeitet durch User
So, letztes Update für heute: Ich lass mir jetzt wieder die Rampe geben, nur jetzt eben bei 1 GHz. Fehler war dass ich im ADC den Taktteiler auf 2 gestellt hatte ... jedenfalls bekomme ich jetzt keine schöne Rampe, kann mir aber nicht erklären wodurch genau der Fehler kommt. Die Rampe hat zwei Stellen, einmal in der Mitte und einmal am unteren Ende, an denen Bits nicht gesetzt sind. Am unteren Ende: ... 254 255 128 129 2 3 4 ... In der Mitte: ... 125 126 127 0 1 130 131 132 ... Ich kann mir das nicht erklären weil ja sonst die Werte korrekt sind. Sprich es werden die meiste Zeit wunderbar die 8 Bits in den SerDes geschoben nur zu zwei Zeitpunkten irgendwie nicht. Aber warum ist das so? Das Problem betrifft auch alle 8 Datenleitungen. Dass das zwei Werte betrifft finde ich logisch, ist ja DDR.
:
Bearbeitet durch User
Je mehr ich darüber nachdenke, desto weniger verstehe ich das. Ich bekomme eine Frame Clock FCLK und die 8 Datenleitungen auf denen jeweils eine Rampe mit lsb first ausgegeben wird. Während der vier LSBs ist FCLK high, während der vier MSBs ist FCLK low. Ich behandele FCLK genau wie einen der 8 Datenports und empfange da Daten. Wenn ich also MSB "00001111" LSB empfange auf dem Eingang an dem FCLK liegt, dann sollte ich davon ausgehen können, dass alle anderen Eingänge einen korrekten Wert empfangen haben. Natürlich muss ich einen "Verschiebewert" erzeugen weil ein empfangenes Byte nur selten direkt den gewünschten Wert hat. Ist ein empfangenes Byte "00001111" dann passt der Wert ohne Verschiebung. Bei "00011110" muss um 1 verschoben werden, ... Die Idee ist jetzt die Daten der Datenkanäle mit der Frame Clock in ein 16 Bit Schieberegister zu schieben. Also immer wenn ein neuer 8 Bit Wert empfangen wird, dann wird der hineingeschoben. Aus diesem Schieberegister wird jetzt über den oben erzeugten Verschiebungswert das korrekte Byte herausgenommen. Daten <= Schieberegister(Verschiebungswert+7 downto Verschiebungswert); Beispiel: Die korrekten Daten wären wiederholend "11100010". Im Schieberegister habe ich aber "1000101110001011" und das empfangene Byte der Frame Clock ist "00111100". Dann weiß ich, dass der Verschiebungswert 2 ist. Daten <= Schieberegister(9 downto 2), also "11100010", passt. Das funktioniert auch wunderprächtig, aber an wenigen Stellen der Rampe gibt es diese Fehler. Ich kann mir das nur dadurch erklären, dass manchmal entweder a) keine korrekten Werte ausgegeben werden vom ADC b) die Frame Clock gegenüber den Daten verschoben ist. Aber beides kann ich im FPGA nicht korrigieren. Fällt euch noch eine andere Ursache ein? Die Hardware möchte ich eigentlich ausschließen, denn ich empfange immer auf allen 8 Datenleitungen die gleichen Bytes und da wackelt auch kein Bit das mal 1 und mal 0 ist. Die Rampen haben immer an den gleichen Stellen die gleichen Fehler.
Ich hatte mal was, das ähnlich ausgesehen hat. - FFFF ergibt im Zweierkomplement wieder FFFF , das war dann ein einzelner outlier. Hier sind aber 2 Werte kaputt. Der Fehler ist aber verdächtig nahe beim Kippen des MSB. Ist da eine Vorzeichenkorrektur/signed-unsigned mit falscher Latenz? Das ist sicher keine Erklärung, das Bild triggert aber ein Déja-vue. Mir gefällt eigentlich der ganze AD-Wandler nicht wirklich. Er sieht irgendwie nach einer Fingerübung für einen ernsthaften Versuch aus. Weder richtig ordentliche Auflösung noch richtig schnell. Und Kanäle gegen Abtastrate zur Laufzeit abzuwägen wird wohl auch nicht oft gebraucht. Ich würde das Thema mal auf der AD-Website in der Engineer's Zone zur Sprache bringen. Obwohl das bei meinem LTC??57 sine-square converter auch nix gebracht hat.
:
Bearbeitet durch User
Gerhard H. schrieb: > Ist da eine > Vorzeichenkorrektur/signed-unsigned mit falscher Latenz? Also ich mache da nix sondern betrachte die Werte eben so wie auch alle anderen Werte. Dass zwei Werte nicht passen dachte ich sei verständlich weil ja DDR, aber die kommen ja nacheinander seriell. Also durchaus komisch. Gerhard H. schrieb: > Weder richtig ordentliche Auflösung noch richtig schnell. Und Kanäle > gegen Abtastrate zur Laufzeit abzuwägen > wird wohl auch nicht oft gebraucht. Naja aber eben super für günstige Oszis. Gerhard H. schrieb: > Ich würde das Thema mal auf der AD-Website in der Engineer's Zone > zur Sprache bringen. Werde ich machen wenn ich das nicht selber schaffe.
Seltsam finde ich, dss es etwas hilft wenn ich Daten und FCLK im ADC verschiebe. Wenn ich da nix verschiebe dann habe ich Fehler an 8 Stellen der Rampe. Wenn ich lvds_advance = 1 einstelle, dann werden FCLK und Daten um ein Bit verschoben. Und dann habe ich nur noch 4 Stellen mit Fahlern in der Rampe. Wenn ich dann noch die LCLK mit der Phase ändere komme ich eben auf die minimal zwei Stellen mit Fehlern. Aber das sollte eben egal sein wie die Bits verschoben sind, weil ich ja auch FCLK einlese und das so verschiebe, dass es zu FCLK passt.
Neue Erkenntnis: Der Fehler hängt nicht vom Sampletakt zusammen. Auch bei 500 MHz ist der Fehler da. Ich habe mal den Bereich zwischen 500 MHz und 1 GHz getestet. Dann kann man Testmuster ausgeben lassen. Das funktioniert wunderbar für alle konstanten Werte. Man kann auch zwischen zwei Werten toggeln lassen. Das funktioniert ebenfalls und ich konnte keinen Fehler provozieren. Aber die Rampe hat eben Fehler an ein paar Stellen und wenn ich tatsächlich echte Messwerte ausgeben lasse, dann sind die Fehler auch da. Aber so wie auch bei der Rampe sind die Fehler nur manchmal da, also ein Großteil der übertragenen Werte ist korrekt. Aber gut, dann frage ich mal bei AD nach.
Es geht weiter. Ich kann mir in dem Wizard den SerDes auch mit IDELAY bauen lassen. Dann bekomme ich:
1 | component HMCAD_SerDes is |
2 | generic( |
3 | SYS_W: integer := 9; |
4 | DEV_W: integer := 72); |
5 | port( |
6 | data_in_from_pins_p: in std_logic_vector(SYS_W-1 downto 0); |
7 | data_in_from_pins_n: in std_logic_vector(SYS_W-1 downto 0); |
8 | data_in_to_device: out std_logic_vector(DEV_W-1 downto 0); |
9 | -- Input, Output delay control signals
|
10 | in_delay_reset: in std_logic; -- Active high synchronous reset for input delay |
11 | in_delay_data_ce: in std_logic_vector(SYS_W -1 downto 0); -- Enable signal for delay |
12 | in_delay_data_inc: in std_logic_vector(SYS_W -1 downto 0); -- Delay increment (high), decrement (low) signal |
13 | in_delay_tap_in: in std_logic_vector(5*SYS_W -1 downto 0); -- Dynamically loadable delay tap value for input delay |
14 | in_delay_tap_out: out std_logic_vector(5*SYS_W -1 downto 0); -- Delay tap value for monitoring input delay |
15 | delay_locked: out std_logic; |
16 | ref_clock: in std_logic; |
17 | bitslip: in std_logic_vector(SYS_W -1 downto 0); |
18 | -- Clock and reset signals
|
19 | clk_in_p: in std_logic; |
20 | clk_in_n : in std_logic; |
21 | clk_div_out: out std_logic; |
22 | clk_reset: in std_logic; |
23 | io_reset: in std_logic); |
24 | end component; |
Mit in_delay_tap_in kann ich eine Verzögerung von ausßen vorgeben. Das funktioniert auch, aber nicht zuverlässig. Bisher dachte ich, dass ich neue Daten an in_delay_tap_in anlege und in_delay_data_ce für einen Takt auf '1' ziehe. Dabei habe ich aber beobachtet, dass ich bei exakt gleichem in_delay_tap unterschiedliche Verzögerungen bekomme. Die Fragen sind: in_delay_data_inc hat ja auch einen Einfluss wenn in_delay_data_ce '1' ist. Wie wird entschieden ob bei in_delay_data_ce = '1' die neuen Daten von in_delay_tap_in geladen werden oder mit in_delay_data_inc = '0' um eins verringert wird? Dann weiß ich nicht wie das mit dem Reset ist, sollte ich den Reset immer nach dem Laden eines neuen Tap Wertes kurz aktivieren? Auf welchen Takt bezieht sich das in_delay_data_ce? Ist das die 200 MHz ref_clock?
Gustl B. schrieb: > Natürlich muss ich einen "Verschiebewert" erzeugen weil ein empfangenes > Byte nur selten direkt den gewünschten Wert hat. > > Ist ein empfangenes Byte "00001111" dann passt der Wert ohne > Verschiebung. > Bei "00011110" muss um 1 verschoben werden, ... Du nutzt doch die ISERSES. Genau für dieses Problem haben die den Bitslip Eingang. Ich mache sowas auch, am LTM9011-14 und da nutze ich das Frame Sync auch als Daten Eingang und mache immer wenn das nicht passt mit 00001111 einen Bitslip per FSM bis es passt. Das kann man in der Appnote auch nachlesen....ich glaube in der XAPP1064... Vielleicht ist das Problem dann gelöst? Mit dem Delay am CLK über den Wizzard kann man auch in Grenzen Skew zwischen Clock und allen Daten ausgleichen. Wenn es durch Layout usw zwischen den Daten Skew gibt, muss man die Daten auch durch die IDELAY schicken. Das macht es noch aufwendiger...da braucht man dann eine FSM oder einen Prozessor Core der die Delays auf die Hälfte des sicheren Bereiches stellt. Trainingsdaten anlegen, messen, obere und untere Grenze raus finden....
Christian R. schrieb: > Du nutzt doch die ISERSES. Genau für dieses Problem haben die den > Bitslip Eingang. Naja, das stimmt, aber wenn Bitslip um 1 Bit verschieben soll, dann darf das nur für einen Takt von der 500 MHz LCLK anliegen? Und das schafft das Timing nicht. Christian R. schrieb: > 00001111 > einen Bitslip per FSM bis es passt. Naja, dafür füttere ich ja FCLK als 9ten Dateneingang rein. Wenn FCLK also synchron zu den Daten ist, bekomme ich als SerDes Wert für FCLK die 00011110 oder so. Die schiebe ich dann hin bis es 00001111 ist. Und genauso schiebe ich auch alle 8 Datenbytes. Und dann passt das. Normalerweise bis eben auf diese paar Ausnahmen an denen die Daten nicht stimmen. Woran das liegt weiß ich nicht. Ich kann mir beliebige statische Testmuster ausgeben alssen und empfange die alle korrekt. Nur in der Rampe und den echten Messdaten sind dann die Fehler. Ja und jetzt wollte ich die Daten gegenüber FCLK etwas verschieben oder FCLK gegenüber den Daten weil es ja sein könnte, dass die nicht immer schön synchron sind. Aber wenn ich mir den SerDes mit dem Wizard bauen lasse und da ein ladbares Delay hinzufüge bei den Daten, dann bekomme ich keinen LD Eingang, den ich ja zum Laden bräuchte, sondern nur den CE für increment/decrement. Jetzt baue ich mir das eben zu Fuß mit den einzelnen Bausteinen IBUFDS, IDELAYCTRL, IDELAY2 und die verzägerten Daten gehen dann in einen mit dem Wizard erzeugten SerDes. Edit: Statt Bitslip verwende ich eben das hier:
1 | process begin |
2 | wait until rising_edge(CLK125); |
3 | TwoByte_Serdes_0 <= TwoByte_Serdes_0(7 downto 0) & Byte_Serdes_0; |
4 | TwoByte_Serdes_1 <= TwoByte_Serdes_1(7 downto 0) & Byte_Serdes_1; |
5 | TwoByte_Serdes_2 <= TwoByte_Serdes_2(7 downto 0) & Byte_Serdes_2; |
6 | TwoByte_Serdes_3 <= TwoByte_Serdes_3(7 downto 0) & Byte_Serdes_3; |
7 | TwoByte_Serdes_4 <= TwoByte_Serdes_4(7 downto 0) & Byte_Serdes_4; |
8 | TwoByte_Serdes_5 <= TwoByte_Serdes_5(7 downto 0) & Byte_Serdes_5; |
9 | TwoByte_Serdes_6 <= TwoByte_Serdes_6(7 downto 0) & Byte_Serdes_6; |
10 | TwoByte_Serdes_7 <= TwoByte_Serdes_7(7 downto 0) & Byte_Serdes_7; |
11 | TwoByte_Serdes_FCLK <= TwoByte_Serdes_FCLK(7 downto 0) & Byte_Serdes_FCLK; |
12 | end process; |
13 | |
14 | with TwoByte_Serdes_FCLK(7 downto 0) select Shift_val <= |
15 | 0 when "00001111", |
16 | 1 when "00011110", |
17 | 2 when "00111100", |
18 | 3 when "01111000", |
19 | 4 when "11110000", |
20 | 5 when "11100001", |
21 | 6 when "11000011", |
22 | 7 when others; |
23 | |
24 | Data_shift_0 <= TwoByte_Serdes_0(Shift_val+7 downto Shift_val); |
25 | Data_shift_1 <= TwoByte_Serdes_1(Shift_val+7 downto Shift_val); |
26 | Data_shift_2 <= TwoByte_Serdes_2(Shift_val+7 downto Shift_val); |
27 | Data_shift_3 <= TwoByte_Serdes_3(Shift_val+7 downto Shift_val); |
28 | Data_shift_4 <= TwoByte_Serdes_4(Shift_val+7 downto Shift_val); |
29 | Data_shift_5 <= TwoByte_Serdes_5(Shift_val+7 downto Shift_val); |
30 | Data_shift_6 <= TwoByte_Serdes_6(Shift_val+7 downto Shift_val); |
31 | Data_shift_7 <= TwoByte_Serdes_7(Shift_val+7 downto Shift_val); |
Da werden also mit dem Ausgangstakt des SerDes immer zwei Bytes/deserialisierte Worte aneinandergehängt. Beim Kanal das die Frame Clock deserialisiert hat bestimme ich die Verschiebung und in Abhängigkeit der Verschiebung hole ich bei den Datenkanälen die passenden Datenbits raus. Funktioniert wunderbar, nur eben manchmal nicht und ich habe keine Ahnung wieso das nur manchmal, also zu einzelnen Zeitpunkten nicht klappt.
:
Bearbeitet durch User
Gustl B. schrieb: > Naja, das stimmt, aber wenn Bitslip um 1 Bit verschieben soll, dann darf > das nur für einen Takt von der 500 MHz LCLK anliegen? Und das schafft > das Timing nicht. Bitslip arbeitet mit der DIVCLK. Lies dir das mal im Userguide durch. ISERDES ohne das Bitslip Submodule zu verwenden ist einfach nur Verschwendung von Lebenszeit. ;-)
Tobias B. schrieb: > Bitslip arbeitet mit der DIVCLK. Lies dir das mal im Userguide durch. Gut, aber was bringt mir in meinem Fall denn Bitslip? Wenn ich das sync pattern vom ADC ausgeben lasse, dann kann ich das mit meiner Methode wunderschön empfangen. Ich kann auch jedes andere statische Testpattern wunderbar empfangen ohne irgendwelche Wackler. Wenn ich also als Testpattern z. B. 123 ins Register des ADCs schreibe, dann kann ich dauerhaft und ohne Fehler 123 empfangen. Aber wenn ich eine Rampe ausgeben lasse, dann hat die an ein paar Stellen Fehler. Warum das ist weiß ich nicht. Meine Erklärung ist eigentlich nur, dass der ADC zu manchen Zeitpunkten irgendwie FCLK gegenüber den Daten verschiebt oder LCLK verschiebt. Ich mag eigentlich meine Methode lieber wie Bitslip weil die schneller auf Verschiebungen reagiert. Quasi sofort und nicht erst mehrere empfangene Worte später.
Gustl B. schrieb: > Funktioniert wunderbar, nur eben manchmal > nicht Na dann ist ja alles gut ;) Gustl B. schrieb: > dafür füttere ich ja FCLK als 9ten Dateneingang rein. Wenn FCLK > also synchron zu den Daten ist, bekomme ich als SerDes Wert für FCLK die > 00011110 oder so. Die schiebe ich dann hin bis es 00001111 ist. Ich habe jetzt immer noch nicht verstanden, warum du es nicht einfach richtig machen willst. Gustl B. schrieb: > Ich mag eigentlich meine Methode lieber wie Bitslip weil die schneller > auf Verschiebungen reagiert. Quasi sofort und nicht erst mehrere > empfangene Worte später. Wenn die Fehler anfangen sich dynamisch einzustellen, sodass du ständig korrigieren musst, hast du eh schon verloren
Jan schrieb: > Ich habe jetzt immer noch nicht verstanden, warum du es nicht einfach > richtig machen willst. Riecht leider nach dem "not invented here" Syndrom. Schade. :-(
Jan schrieb: > Ich habe jetzt immer noch nicht verstanden, warum du es nicht einfach > richtig machen willst. Klar, werde ich gerne machen, aber dann erkläre mir doch was Bitslip anderes bezweckt als mein Code oben. Das verschiebt doch auch nur die Bits bis das Vergleichmuster passt. Und das macht meine Beschreibung ebenfalls. Aber gut, ich werde das auch mit Bitslip bauen ... jetzt versuche ich das aber erstmal mit IDELAY weil ich da schon gute Ergebnisse hatte, die aber nicht reproduzieren konnte. Also ich konnte mit einem Tap Wert dauerhaft gute Werte lesen, also korrekte Rampen, aber wenn ich den gleich Tap Wert neu laden wollte war das Ergebnis anders. Vermutlich lade ich die noch nicht korrekt.
Gustl B. schrieb: > Aber gut, ich werde das auch mit Bitslip bauen ... jetzt versuche ich > das aber erstmal mit IDELAY weil ich da schon gute Ergebnisse hatte, die > aber nicht reproduzieren konnte. Also ich konnte mit einem Tap Wert > dauerhaft gute Werte lesen, also korrekte Rampen, aber wenn ich den > gleich Tap Wert neu laden wollte war das Ergebnis anders. Vermutlich > lade ich die noch nicht korrekt. Aha, jetzt wird es interessant. Du musst dein Training antuerlich nicht nur auf Wort Ebene sondenr auch auf Bit Ebene ueber IDEALYs betreiben. Dazu eignet sich allerdings das 00001111 Pattern nicht. Besser ist 01001011. Dann Tapst du zu jedem Bitslip die komplette Delay Sequence durch. Fuer ein Bitslip erhaeltst du dann (sofern ein komplettes Datenauge durchgetapt werden kann) praktisch einen min udn einen max Tap Wert. Beim min Wert fangen die Daten an korrekt zu sein und beim max hoehren sie auf. Und dort setzt du dich dann genau in die Mitte. Wenn du dazu Info Material moechtest kann ich dir meine Diplomarbeit zusenden. Das war praktisch das Kernthema.
Ja genau das habe ich vor. Wobei ich nicht weiß ob das sinnvoll ist, denn ich jann ja jedes Testmuster das ich ausgeben lasse dauerhaft ohne Bitfehler empfangen. Ich tappe da also noch im Nebel weil ich eben keine wackelnden Bits habe. Das ist irgendwie seltsam. Tobias B. schrieb: > Wenn du dazu Info Material moechtest kann ich dir meine Diplomarbeit > zusenden. Das war praktisch das Kernthema. Vielen Dank! Ich werde das jetzt erstmal bauen und melde mich wenn ich nicht weiter komme. Edit: Der ADC hat natürlich ein deskew pattern. Aber auch das kann ich wunderbar empfangen ohne Fehler. Die Fehler in der Rampe kann ich mir auch anders erklären: Und zwar würden die passieren wenn manchmal LCLK nicht vom FPGA erkannt wird, also ein LCLK Takt fehlt. Dann fehlen zwei Bits im Wort. Wenn das der LCLK Takt ist zwischen zwei Datenworten, dann sind wie bei mir zwei Datenworte defekt. Aber wieso das so seien könnte weiß ich nicht. Wobei ... meine Fehler sind an so Grenzen an denen viele Bits gleichzeitig umschalten. 11111111 nach 00000000 oder 01111111 nach 10000000. Das könnte schon irgendwie in die Taktleitung einkoppeln vielleicht? Ich kann mir das leider nicht angucken weil ich kein schnell genuges Oszi habe. Aber ich werde jetzt mal den LVDS Strom der Datenleitungen reduzieren.
:
Bearbeitet durch User
Hm, wenn es an der Grenze von alles 1 zu alles 0 oder umgekehrt passiert, dann könnte es auch Ground Bouncing sein. Kann man den ADC einstellen dass er den Ausgang scrambelt? Das könnte dann helfen. Ansonsten muss man mit dem Bit Slip nur einmal beim Start den Sny suchen und dann ist der so. Da muss nix dauernd korrigiert werden. Die FSM läuft mit dem DIV CLK, alles entspannt und vom Timing her bestimmt besser als der Mega Mux bei dir. Ist das ein Demo Board oder hast du das selbst geroutet? Sind alle Paare gleich lang? Hast du die Terminierung aktiviert?
Christian R. schrieb: > Ground Bouncing sein. Kann man den ADC einstellen dass er den Ausgang > scrambelt? Nein, kann man nicht einstellen. Ich glaube aber nicht, dass es an der Signalintegrität liegt. Denn wenn ich mit den Delays spiele schaffe ich es eine fehlerfreie Rampe zu bekommen. Nur schaffe ich es nicht ein und den selben Tap Wert zuverlässig erneut zu laden. Christian R. schrieb: > Ansonsten muss man mit dem Bit Slip nur einmal beim Start den Sny suchen > und dann ist der so. Genau. Und in meinem Code müsste sich der Verschiebungsoffset auch nur am Start mal ändern. Christian R. schrieb: > Die FSM läuft mit dem DIV CLK, alles entspannt und vom Timing her > bestimmt besser als der Mega Mux bei dir. Kann gut sein, aber der MUX läuft bei mir ebenfalls mit der Div CLK. Der schafft das Timing locker. Christian R. schrieb: > Ist das ein Demo Board oder hast du das selbst geroutet? Sind alle Paare > gleich lang? Hast du die Terminierung aktiviert? Selbst geroutet. Ja annähernd gleich lang. Im FPGA habe ich die Terminierung an. Extern habe ich keine Terminierungswiderstände und bisher habe ich im ADC keine Ausgangsterminierung verwendet. Vielleicht sollte ich das machen.
Gustl B. schrieb: > Nur schaffe ich es nicht ein und den selben Tap Wert zuverlässig erneut > zu laden. Das kann durchaus sein. Du wirst mit deinen Taps immer noch am Rande des Datenauges stehen. Die Tap Breite der IDELAYs sind nicht konstant und veraendern leicht ihre Werte. Setz dich mal richtig ins Datenauge, dann sollte das nachladen auch funktionieren. Generell ist es jedoch zu empfehlen bei jedem Start eine automatische Kalibrierroutine durchzufuehren, aehnlich wie es bei den DDR Interfaces gemacht wird. Kleiner Nachtrag: Wenn die Leitungen in etwa alle gleich lang sind, kannst du dir das Leben vll. auch einfacher machen indem du nur die Clock durchtapst. Dann sollten aber die Datenleitungen auch wirklich einigermassen synchron sein (am besten mit dem Oszi verifizieren).
:
Bearbeitet durch User
Tobias B. schrieb: > Setz dich mal richtig ins Datenauge, dann > sollte das nachladen auch funktionieren. Das würde ich gerne machen, aber wenn ich im Betrieb ein und den selben Tap Wert erneut lade sieht das Signal wieder anders aus. So kann ich schlecht Anfang und Ende bestimmen. In der Simulation funktioniert das mit dem LD Pin wunderbar. Tobias B. schrieb: > Generell ist es jedoch zu empfehlen bei jedem Start eine automatische > Kalibrierroutine durchzufuehren, aehnlich wie es bei den DDR Interfaces > gemacht wird. Genau. Tobias B. schrieb: > Wenn die Leitungen in etwa alle gleich lang sind, > kannst du dir das Leben vll. auch einfacher machen indem du nur die > Clock durchtapst. Ich wollte eigentlich nur die FCLK oder LCLK verschieben. Und wenn, dann schiebe ich alle Daten gleichzeitig. Da habe ich jetzt auch IDELAYs drinnen aber die bekommen alle den gleichen Wert. Jetzt muss ich es erstmal schaffen, dass die Werte zuverlässig gelasen werden. Sehe ich das denn richtig, dass ich da nur LD pulsen muss und meinen Verzögerungswert an CNTVALUEIN anlege? Was mich irrirtiert ist, dass da von einem Counter gesprochen wird. Ich will da aber eine fixe Verzögerung einstellen ohne dass da irgendwas gezählt wird. Also das was ich da rein lade sollte nicht der Startwert eines Zählers sein der automatisch hochzählt oder so, sondern der Wert soll unverändert bleiben nachdem ich den reingeladen habe.
Gustl B. schrieb: > Sehe ich das denn richtig, dass ich da nur LD pulsen muss und meinen > Verzögerungswert an CNTVALUEIN anlege? > > Was mich irrirtiert ist, dass da von einem Counter gesprochen wird. Ich > will da aber eine fixe Verzögerung einstellen ohne dass da irgendwas > gezählt wird. Meinst du jetzt Zähler wegen CNT valuein? Das ist die Anzahl der Elemente in der Delay line. Und ich weiß nicht wie das bei deinem FPGA ist, aber eine "fixe" Verzögerung kriegst du nur, wenn die Delay line auf einen Takt synchronisiert ist. Ansonsten ist das eher ein Schätzeisen. Darf ich mal fragen, was du eigentlich machst? Ich sehe gefühlt jede Woche einen Thread von dir, wo du irgendwelche Sachen an ein FPGA zimmerst. Hast du 10 Projekte gleichzeitig oder steckt da mehr dahinter?
Hättest du den SelectIO Resources User Guide gelesen, wüsstest du wie das IDELAY funktioniert. Wichtig ist erst mal der 200,000MHz REF Clock. Intern arbeitet das Ding mit einem Zähler, richtig, aber im Modus VAR_LOAD kannst du über CNTVALUEIN direkt den Wert eingeben, wenn du C = 1 und LED = 1 setzt. Siehe Tabelle 2-7 im UG471 und die Beschreibung in dem Kapitel. Das klappt auch und ergibt immer das gleiche Delay. Irgendwo muss ja auch das IDELAYCTRL im Design sein, das kalibibriert im Hintergrund die Delays. Ich hab das ähnlich gemacht. Da bei uns zwischen FPGA und LTM9011 alle Leitungen gleich lang sind, hab ich nur ein Delay am schnellen CLK. Mit einem Test Design hab ich die Breite des Datenauges bei 3 verschiedenen Temperaturen ermittelt, und benutze seitdem die Mitte als Delay-Wert im Modus FIXED. Klappt einwandfrei. Sync erfolgt wie schon gesagt auf das FRAME Signal mit Bit Slip Logik aus der XAPP1064. Der Wizzard ist an manchen Stellen etwas unflexibel, daher hab ich nur initial die VHDL Files erzeugen lassen und hab die dann selbst entsprechend angepasst. Terminierung ist bei uns auf beiden Seiten, also FPGA und ADC Ausgang. Erst damit lief das zuverlässig. Bei der Terminierung muss man aufpassen, die interne geht ausschließlich mit 2,5V VCCO. Die gesamte Arbeitsweise erinnert mich an einen Kollegen der in Rente ist. Eigentlich sehr intelligent, aber anstatt Datenblätter oder user Guides zu lesen hat er erst mal so implementiert, wie er dachte dass der Chip funktionieren müsste bzw wie er ihn gebaut hätte. Das Ergebnis kann man sich ja vorstellen. Das "not invented here" Problem war da täglich. Bau erst mal die Bit Slip Logik ein, so wie sie dafür gedacht ist, terminierung auf beiden Seiten an und dann mit dem IDELAY nur den schnellen Takt verzögern.
Jan schrieb: > Meinst du jetzt Zähler wegen CNT valuein? Ja genau. Jan schrieb: > Das ist die Anzahl der > Elemente in der Delay line. OK. Also ist es so, dass der Wert den ich da reinlade die Anzahl der Elemente und somit die Länge der Delay Line festlegt? So hatte ich Verzögerungen auch verstanden. Was ich nicht verstehe ist wieso das Counter genannt wird ... Jan schrieb: > aber eine "fixe" Verzögerung kriegst du nur, wenn die Delay line > auf einen Takt synchronisiert ist. Ansonsten ist das eher ein > Schätzeisen. Naja, klar bleibt das mit Unsicherheit, aber wenn ich die Delayline immer gleich lang mache, dann sollte das schon grob die selbe Verzögerung sein. Ich brauche ja nicht auf die ps genau. Ich würde aber um feiner als einen halben Takt von LCLK verzögern können. Also feinere Schrittweite, und auch reproduzierbar, also <<1 ns wäre schon was. So 250 ps wäre wünschenswert und genau das sollte IDELAY ja können. Die halbe Breite von LCLK kann ich auch im ADC verzögern indem ich LCLK mit einer anderen Phase gegenüber FCLK und Daten ausgeben lasse. Jan schrieb: > Darf ich mal fragen, was du eigentlich machst? Lernen*. Ich mache gerne Bastelprojekte auf an denen ich Dinge ausprobieren kann die ich noch nie gemacht habe. Auf der aktuellen Platine geht es um schnelles LVDS, Analogbeschaltung mit hoher Bandbreite und gleichzeitig habe ich auch einen hochauflösenden mittelschnellen ADC mit Beschaltung drauf und bespaßt. Einen AD7960 mit 18 Bits und 5 MSample/s. Bin zufrieden und bekomme 15 rauschfreie Bits. Jan schrieb: > Hast du 10 Projekte gleichzeitig Fast. Ich habe noch zwei Weitere. Quasi den Vorgänger. Der ist zwar fertig, hatte aber einen Fehler und ist jetzt in Rev. B. Da hatte ich erstmals USB3 gemacht und einen HyperRAM mit schnellerem Takt (200MHz DDR) verbaut und auch HDMI über USB-C gemacht. Das andere ist mein Bodenfeuchtigkeitssensor. Ja. Also funktioniert, aber ich kann mich nicht so recht zwischen Solar und Akku oder Betterie entscheiden. Ich würde gerne einen ESP verwenden weil das mit WLAN sehr bequem ist, aber da hält eine Batterie nicht lange. Das liegt also gerade etwas auf Eis. Aber: Wenn die Projekte fertig sind, dann gibt es hier im Forum Schaltplan und Layout. *Ich will mich vielleicht mal als Quereinsteiger bewerben. Aber da werden wohl lieber Leute von der Uni und vom Fach angestellt. Was ich machen kann und eben mache ich mir Erfahrung zu holen bei Bastelprojekten. Ich denke das wirkt schon gut wenn man sagen kann das und das und das, das haben ich alles gemacht und funktioniert.
Gustl B. schrieb: > Ich würde aber um feiner als einen halben Takt von LCLK verzögern > können. Also feinere Schrittweite, und auch reproduzierbar, also <<1 ns > wäre schon was. So 250 ps wäre wünschenswert und genau das sollte IDELAY > ja können. Wie im UG471 geschrieben, beträgt das Delay pro Tap bei 200MHz Ref Clock genau 78.125ps (5ns/64). Im Datenblatt des FPGA steht dann noch die Toleranz drin. Du kannst auch per ILA und VIO die Taps live einstellen. Das geht ja inzwischen auch relativ gut.
Christian R. schrieb: > Wichtig ist erst mal der 200,000MHz REF Clock. > Intern arbeitet das Ding mit einem Zähler, richtig, aber im Modus > VAR_LOAD kannst du über CNTVALUEIN direkt den Wert eingeben, wenn du C = > 1 und LED = 1 setzt. Siehe Tabelle 2-7 im UG471 und die Beschreibung in > dem Kapitel. Das klappt auch und ergibt immer das gleiche Delay. > Irgendwo muss ja auch das IDELAYCTRL im Design sein, das kalibibriert im > Hintergrund die Delays. 200 MHz habe ich dran. IDELAYCTRL ist vorhanden. Und eigentlich lade ich auch mit LD. Aber ich bekomme nicht immer das gleiche Delay. In der Simulation schon. Naja, muss ich eben untersuchen gehen. Christian R. schrieb: > Mit > einem Test Design hab ich die Breite des Datenauges bei 3 verschiedenen > Temperaturen ermittelt, und benutze seitdem die Mitte als Delay-Wert im > Modus FIXED. Klappt einwandfrei. Das macht Sinn. Christian R. schrieb: > Der Wizzard ist an manchen Stellen etwas unflexibel, daher hab ich nur > initial die VHDL Files erzeugen lassen und hab die dann selbst > entsprechend angepasst. Genau, ich habe mir auch die Files erzeugen lassen und das nachgebaut. Der Wizard bietet nämlich den LD eingang nicht an. Christian R. schrieb: > Terminierung ist bei uns auf beiden Seiten, also FPGA und ADC Ausgang. > Erst damit lief das zuverlässig. Hm. Gut, daran kann es natürlich liegen. Ich terminiere nur auf Empfängerseite. Warum sollte man LVDS denn auch an der Quelle terminieren? Reicht es da nicht die Stromstärke zu verringern? Christian R. schrieb: > Bei der Terminierung muss man aufpassen, die interne geht ausschließlich > mit 2,5V VCCO. Darauf habe ich geachtet, die Bank bekommt 2,5 V. Christian R. schrieb: > wie er dachte dass der > Chip funktionieren müsste bzw wie er ihn gebaut hätte. Allerdings! Ich hätte den Chip so gebaut, dass er immer überall funktioniert. Christian R. schrieb: > Bau erst mal die Bit Slip Logik ein, so wie sie dafür gedacht ist, > terminierung auf beiden Seiten an und dann mit dem IDELAY nur den > schnellen Takt verzögern. Werde ich schon noch machen. Du hast ja die Frame Clock verwenden um das Bitslip anzupassen. Sollte man da die Frame Clock als Daten verwenden oder sich vom ADC ein Sync Pattern ausgeben lassen? Wie ich das verstehe sollte das egal sein. Christian R. schrieb: > Wie im UG471 geschrieben, beträgt das Delay pro Tap bei 200MHz Ref Clock > genau 78.125ps (5ns/64). > Im Datenblatt des FPGA steht dann noch die Toleranz drin. So genau brauche ich das vermutlich nicht mal. Christian R. schrieb: > Du kannst auch per ILA Das ist etwas das ich noch nie verwendet habe. Bisher habe ich simuliert bis es funktionierte und dann lief das auch auf Hardware. Muss ich mir mal angucken.
Gustl B. schrieb: > Hm. Gut, daran kann es natürlich liegen. Ich terminiere nur auf > Empfängerseite. Warum sollte man LVDS denn auch an der Quelle > terminieren? Reicht es da nicht die Stromstärke zu verringern? Ich hab nochmal nachgeschaut, ist doch aus im endgültigen Design, hatte ich falsch in Erinnerung. LVDS Strom ist auf 1,75mA. Aber das ist ganz abhängig von den verwendeten Bauteilen. Gustl B. schrieb: > Allerdings! Ich hätte den Chip so gebaut, dass er immer überall > funktioniert. Ich bin mir sicher, der funktioniert, wenn er richtig bearbeitet wird ;) Gustl B. schrieb: > Werde ich schon noch machen. Du hast ja die Frame Clock verwenden um das > Bitslip anzupassen. Sollte man da die Frame Clock als Daten verwenden > oder sich vom ADC ein Sync Pattern ausgeben lassen? Wie ich das verstehe > sollte das egal sein. Ich hab den FRAME Ausgang genommen, der ist immer da und muss nicht aktiviert werden. Den genau so als Dateneingang wie die anderen, aber halt ohne DDR in meinem Fall. Die Bitslip Logik ist recht einfach:
1 | process (rx_bufg_x1_A) -- example bitslip logic, if required |
2 | begin
|
3 | if rising_edge(rx_bufg_x1_A) then |
4 | if state_A = '0' then |
5 | if rx_frame_A /= "00001111" then |
6 | bslip_A <= '1' ; -- bitslip needed |
7 | state_A <= '1' ; |
8 | count_A <= "000" ; |
9 | end if ; |
10 | elsif state_A = '1' then |
11 | bslip_A <= '0' ; -- bitslip low |
12 | count_A <= count_A + 1 ; |
13 | if count_A = "111" then |
14 | state_A <= '0' ; |
15 | end if ; |
16 | end if ; |
17 | end if ; |
18 | end process ; |
Die ganze Clock Sache mit IBUFGDS, BUFIO und BUFR hat der Wizzarrd korrekt rein gebaut?
Christian R. schrieb: > LVDS Strom ist auf 1,75mA. Aber das ist ganz > abhängig von den verwendeten Bauteilen. Das hat mich sogar sehr gewundert wie klein man den Strom einstellen kann. Ich kann hier von 0.5 bis 7.5 mA einstellen und bekomme nur bei 0.5 mA sichtbare Bitkipper. Christian R. schrieb: > Ich hab den FRAME Ausgang genommen, der ist immer da und muss nicht > aktiviert werden. Den genau so als Dateneingang wie die anderen Genau das dachte ich mir dabei auch. Wobei ich das schade finde, dass so ein SerDes nicht von sich aus schon einen Frame Eingang hat. Ich hatte das irgendwie erwartet ... Christian R. schrieb: > Ich hab nochmal nachgeschaut, ist doch aus im endgültigen Design Egal, ich hab das jetzt eingebaut, mal gucken ... Christian R. schrieb: > Die Bitslip Logik ist recht einfach: Danke! Klar ist das nicht irre komplex, mein Multiplexer aber auch nicht und der macht genau das Gleiche nur ohne Bits fallen zu lassen. Christian R. schrieb: > Die ganze Clock Sache mit IBUFGDS, BUFIO und BUFR hat der Wizzarrd > korrekt rein gebaut? Das mache ich aktuell selbst. Der SerDes bekommt nur die Daten und Clocks aus den IDELAYs. Aber mit der Terminierung: Wenn man den SerDes im Wizard klickt und die Eingänge als LVDS_25 angibt, dann ist die interne Terminierung aus. Und die kann man im Wizard auch nicht einschalten. Ich habe die im .xdc dazugebaut. Aber ob die dann wirklich im FPGA verwendet wird weiß ich nicht weil in dem Teil vom Wizard eben False steht und im .xdc True. Gibt es da eine Priorisierung?
Gustl B. schrieb: > Aber mit der Terminierung: > Wenn man den SerDes im Wizard klickt und die Eingänge als LVDS_25 > angibt, dann ist die interne Terminierung aus. Und die kann man im > Wizard auch nicht einschalten. Ich habe die im .xdc dazugebaut. Aber ob > die dann wirklich im FPGA verwendet wird weiß ich nicht weil in dem Teil > vom Wizard eben False steht und im .xdc True. Gibt es da eine > Priorisierung? Ja, das hatte mich auch geärgert. Man kann die dann aber im VHDL dazufügen bei den IBUFDS oder im XDC. Ob es wirklich dran ist, kann man sich beim Report ausgeben lassen, steht im Projekname_io_placed.rpt in .runs/impl_1/
Danke! So, das mit Bitslip funktioniert sehr ähnlich wie mein MUX nur dass es nach einem Fehler mehrere Takte braucht bis wieder korrekte Daten geliefert werden. Was bleibt ist, dass ich mit bestimmten Registerwerten im ADC ein korrektes Signal bekomme, wenn ich die aber erneut reinschreibe oder was ändere und dann nochmal die passenden Werte reinschreibe, dann bekomme ich kein korrektes Signal. Ich habe die Vermutung, dass es an den Resets liegt. Immer wenn ich dem ADC neue Werte gebe resette ich den SerDes danach weil sich ja die Phase vom Takt geändert haben kann. Ist das überhaupt nötig der Clock und IO Reset am Serdes? Für die Simulation ist der nötig weil sonst die Daten am Ausgang XXXX sind. Aber das ist ja vielleicht wie mit der PLL, die braucht in der Simulation ebenfalls einen Reset wenn man den Eingangstakt verändert, sonst lockt die nie. Aber in der Realität funktioniert die auch ohne Reset.
Hm, das wäre natürlich möglich. Das mit den Resets ist bissl tricky und wie immer schwer in den Dokumenten zu finden. Klar, braucht der Bit Slip ein paar Takte, da sich aber im Betrieb da nix ändert, ist das ja nur beim Einschalten. Ich hab das bei mir getrennt, es gibt einen CLK_RESET, der wirkt auf die BUFR und auf das IDELAYCTRL, dann gibts einen IO_RESET der auf alle anderen Elemente wirkt. Den CLK Reset halte ich aktiv, solange der MMCM nicht locked meldet, den IO Reset ebenfalls, aber der kann auch durch das User-Reset bedient werden.
Hm. Hier https://www.xilinx.com/support/documentation/ip_documentation/selectio_wiz/v5_1/pg070-selectio-wiz.pdf Seite 8 steht was zum Reset. I/O reset: Reset connected to all other elements in the circuit. For proper functionality, io_reset has to be deasserted when the clocks to SERDES are stable. Due to this requirement, io_reset must be deasserted after some cycles of clk_reset deassertion. For 8:1 serialization, sixteen cycles delay of I/O clock between clk_reset and io_reset can be used. Es steht aber nicht da was die I/O Clock ist, ist das die clk_div_out? Und es steht auch nicht aber, ob ich bei 8:1 Deserialisierung zwingend 8*n Takte nach clk_reset den io_reset loslassen muss. Wenn die I/O Clock clk_div_out ist, dann ist das ein Problem. Denn zuerst kommt der clk_reset, und während und kurz danach habe ich keine clk_div_out. Das dauert also etwas und da kann ich dann keine 8*n Takte für den io_reset zählen. Ausser ich würde natürlich nicht direkt die LVDS LCLK in den SerDes füttern sondern zuerst in einen MMCM/PLL, dort durch 4 teilen und das dann als Takt verwenden. Tja und dann nur zur Sicherheit noch eine Frage: Ich habe 9 Dateneingänge und 8:1, bekomme also 9*8=72 Bits raus. Welche Bits gehören da zu welchem Dateneingang? Mein Verständnis bisher ist, dass Daten(71 downto 63) die neusten Bits aller Eingänge sind und Daten(8 downto 0) die ältesten Bits aller Eingänge. Wenn ich also das Wort von Dateneingang 0 haben will dann besteht das aus: for I in 0 to 7 loop Wort(I) <= Daten(I*9+0); end loop; Stimmt das? Oder wo steht das? Und dann gibt es noch Constraints. Ich würde gerne für die Daten und für FCLK einstellen wie lange die um eine Flanke von LCLK herum stabil sind. LCLK habe ich als Takt mit 500 MHz beschrieben. Im Anhang das Bildchen zeit das Geschehen. Die Daten sind natürlich synchron zur Quelle und werden bei den Flanken erfasst. Die Frage ist jetzt welche Werte ich da eintrage. Im ADC Datenblatt steht dazu nix. 0.7 ns rise und Fall Time. Edit: Bild vergessen. Und diese Constraints, also 0.1 ns jeweils, schafft die Synthese nicht. Sie schafft aber auch keinen größeren Wert. Also lass ich das mit den Constraints? Edit2: So, das Ganze war wohl ein Reset Problem vom SerDes und auch vom ADC. Damit man der Inhalt mancher ADC Register x"31" und x"56" Anwendung findet muss man den ADC ausschalten, also den PD Pin nach High oder das entsprechende Register beschreiben. Aber dann geht natürlich auch LCLK aus und es dauert eher lange, so 15 us typischerweise laut Datenblatt bis der nach DP Low wieder voll da ist. Ich habe jetzt also den clk_reset vom SerDes weit weg vom Power Down des ADCs gelegt, also noch weiter als die 15 us die ich schon vorher verwendet hatte. Und den io_reset habe ich über den clk_reset noch gut 100 ns rausgezogen aber ich achte nicht auf die 8 Takte Unterschied und bin mit den Resets auch nicht synchron zu irgendeiner ADC/SerDes Clock. Jedenfalls funktioniert das jetzt wunderprächtig mit großteils den Defaultwerten im ADC. Ich schreibe nur: x"3A0202" x"3B0202" x"310001" x"560004" Also Register x3A/x3B das allen ADCs den Eingang 1 zuordnet. Dann x31, dort wird der interne Taktteiler auf 1 gesetzt und der HMCAD als 1 Kanal ADC konfiguriert. x56 ist die Startup Zeit. Jetzt sehe ich den 10 MHz Ton auch tatsächlich bei 10 MHz.
:
Bearbeitet durch User
Spitze! Das mit den Constraints am DDR ISERDES und IDELAY und MMCM für den Clock hab ich ehrlich gesagt auch nicht hinbekommen. Das geht bestimmt ist aber sicher deutlich komplexer als gedacht.
Christian R. schrieb: > Spitze! Leider nicht ganz. Also ich kann das Problem eingrenzen, und zwar hängt es am Reset des SerDes und nur daran. Aber ich muss den SerDes oft mehrmals resetten bis korrekte Daten rauskommen. Und das sollte ja nicht sein, dafür habe ich doch das Bitslip ... Edit: Bwahahaha bin ich dumm. Unfassbar! Da habe ich das Design auf Bitslip umgeschrieben, aber den Bitslip nicht am SerDes angeschlossen M-)
:
Bearbeitet durch User
Gustl B. schrieb: > Edit: > Bwahahaha bin ich dumm. Unfassbar! Da habe ich das Design auf Bitslip > umgeschrieben, aber den Bitslip nicht am SerDes angeschlossen M-) Oh, ein Zufallsgenerator. ;) Serdes und ADC Reset war aber hier trotzdem tricky, ich glaube es war wichtig dass der IO Reset synchron zu einem der Takte war, bin mit aber nicht mehr sicher...
Christian R. schrieb: > Oh, ein Zufallsgenerator. ;) Allerdings und jetzt mit Bitslip der auch in der Simulation funktioniert bekomme ich trotzdem manchmal Fehler. Da muss ich den Serdes noch mal resetten oder mehrmals resetten und dann wird es richtig. Christian R. schrieb: > ich glaube es war > wichtig dass der IO Reset synchron zu einem der Takte war Das kann gut sein. Aber während dem clk_reset habe ich die div_clock eben nicht. Die erscheint erst einige Zeit nachdem ich den clk_reset losgelassen habe. ------------------- Zitat: I/O reset: Reset connected to all other elements in the circuit. For proper functionality, io_reset has to be deasserted when the clocks to SERDES are stable. Due to this requirement, io_reset must be deasserted after some cycles of clk_reset deassertion. For 8:1 serialization, sixteen cycles delay of I/O clock between clk_reset and io_reset can be used. ------------------- Leider steht da nur "can be used" also bleibt für mich unklar ob das 8*n Takte sein müssen zwischen clk_reset und io_reset oder ob nur die Clock stabil sein muss. Da steht auch nicht welche Clock stabil sein muss. Die div_clock? Die ist ein Ausgang vom SerDes. Oder die LCLK die in den SerDes reingeht? Die liegt zu jedem Zeitpunkt beim Reset stabil an. Aber ich werde den io_reset etwas nach hinten verschieben. Edit: Sieht jetzt stabil aus. Man man man, es wäre so leicht gewesen aber da stand ich mir mal wieder selbst im Weg. Aber wieder was gelernt. Vielen Dank für die Hilfe! Und wo wie schonmal dabei sind: Viele neuere ADCs verwenden dieses JESD204b. Ich verstehe auch wieso, weniger IOs am ADC, man muss keinen Skew zwischen den Leitungen ausgleichen und FPGAs bekommen immer mehr schnelle Transceiver. Aber bei diesem JESD204b steht oft nur da was die maximale Datenrate ist, nicht die minimale Datenrate. Kann ich so ein JESD204b auch an einen Spartan/Artix anschließen oder brauche ich da einen FPGA mit den mit GTPs? (Ja, die gibt es auch am Artix, hat meiner aber nicht.) Und gibt es freie/gratis IPs zu dem JESD204b, im Vivado habe ich nix gefunden?
:
Bearbeitet durch User
Bei mir kommt der DIV CLK aus diesem BUFR geteilt raus. Sobald der da ist und es das IO Reset vom Booten oder von User Reset gab, wird das interne IO Reset über 2 FF synchronisiert. Ja, JESD204B geht nur mit MGT. Und freie Cores...hm, schwierig. Hab ich noch nicht gesehen.
Christian R. schrieb: > Bei mir kommt der DIV CLK aus diesem BUFR geteilt raus. Tatsache, den baut der Wizard da mit rein. Und der bekommt auch den clk_reset. DIV CLK ist also erst kurze Zeit nach dem Ende von clk_reset da. Aber gut, ich habe den io_reset jetzt so gebaut, dass der noch deutlich über den clk_reset aktiv ist. Allerdings nicht 8*n Takte und auch nicht synchron zur div clk. Christian R. schrieb: > Ja, JESD204B geht nur mit MGT. Und freie Cores...hm, schwierig. Hab ich > noch nicht gesehen. Das ist das kein lohnenswertes Bastelziel, schade.
Gustl B. schrieb: > Christian R. schrieb: >> Ja, JESD204B geht nur mit MGT. Und freie Cores...hm, schwierig. Hab ich >> noch nicht gesehen. > > Das ist das kein lohnenswertes Bastelziel, schade. Klar. Dann schreib ihn doch selber. Das Ding ist an sich nicht sooo komplex, jedoch ist es nervig, weil es sehr stark auf die MGT-Funktionalitäten schaut (bitslip, channelbonding,..). Ich finde dieses Thema sehr spannend. Prinzipfrage jedoch: JESD204B wurde wegen der hohen Datenübertragungsrate eingeführt um weiterhin mehrere ADC/DACs präzise synchron zu betreiben (LTE beispielsweise). Wenn du keinen schnellen DAC brauchst, dann wird der langsame wahrscheinlich auch kein JESD204B-Interface benötigen. freie cores: google "git jesd204b" ergab auch ein paar Treffer.
Klakx -. schrieb: > Dann schreib ihn doch selber. Das traue ich mir nicht zu. Und aktuell habe ich wirklich keinen Anwendungsfall. Klakx -. schrieb: > Ich finde > dieses Thema sehr spannend. Natürlich, mich interessiert das auch, aber kostet Geld und nur zum Selbstzweck finde ich das dann übertrieben. Vielleicht arbeite ich ja irgendwann mal was mit Elektronik, dann könnte ich das auf Firmenkosten lernen ... Klakx -. schrieb: > JESD204B wurde wegen der hohen > Datenübertragungsrate eingeführt um weiterhin mehrere ADC/DACs präzise > synchron zu betreiben (LTE beispielsweise). Genau. Das braucht auch eben weniger Leitungen und die FPGA IOs werden immer schneller. Ist also ein sinnvoller Schritt. Nur für Bastler schwierig, aber in dem Bereich wird es sowieso teuer. Klakx -. schrieb: > Wenn du keinen schnellen DAC brauchst, dann wird der langsame > wahrscheinlich auch kein JESD204B-Interface benötigen. Erstmal geht es mir hier nur um den ADC. Klar, mehr Bits wären fein, aber der HMCAD1511 reicht mir wunderbar. Sonst kann ich ja noch den HMCAD1520 nehmen mit 12 Bits bei 640 MSample/s. Als DAC habe ich mir einen eigenen Signalgenerator mit dem AD9747 (16 Bits 250 MSample/s mit parallelem Interface) und THS3215 (Verstärker) gebaut, siehe Beitrag "Re: Zeigt her eure Kunstwerke (2020)" (Schaltplan/Layout auf Anfrage, habe da zwei kleine Bugs drinnen). Klakx -. schrieb: > freie cores: google "git jesd204b" ergab auch ein paar Treffer. Tatsache! Ist gemerkt für den Fall, dass mir die Bastelprojekte ausgehen und ich im Lotto gewonnen habe.
Die untere Ebene des JESD204B kann man sich im MGT Core Generator zusammen bauen, aber da drüber ist noch einiges an Logik, was zumindest bei Xilinx im kostenpflichtigen IP Core steckt. Der Core kostete 2017 knapp 7000€. Wir haben das dann auch gelassen. Erst mal.
Christian R. schrieb: > Der Core kostete 2017 knapp 7000€. Wir haben das dann auch gelassen. > Erst mal. Ist immer noch so :-( https://www.digikey.de/product-detail/de/xilinx-inc/EF-DI-JESD204-SITE/EF-DI-JESD204-SITE-ND/3076739
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.