Forum: FPGA, VHDL & Co. HMCAD1511 Interface


von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

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
von Gustl B. (-gb-)



Lesenswert?

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
von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

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
von Gustl B. (-gb-)


Lesenswert?

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.

von Gerhard H. (ghf)


Lesenswert?

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
von Gustl B. (gustl_b)


Lesenswert?

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.

von Gustl B. (-gb-)


Lesenswert?

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.

von Gustl B. (-gb-)


Lesenswert?

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.

von Gustl B. (-gb-)


Lesenswert?

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?

von Christian R. (supachris)


Lesenswert?

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....

von Gustl B. (-gb-)


Lesenswert?

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
von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

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. ;-)

von Gustl B. (-gb-)


Lesenswert?

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.

von Jan (Gast)


Lesenswert?

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

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

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. :-(

von Gustl B. (-gb-)


Lesenswert?

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.

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

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.

von Gustl B. (-gb-)


Lesenswert?

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
von Christian R. (supachris)


Lesenswert?

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?

von Gustl B. (gustl_b)


Lesenswert?

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.

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

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
von Gustl B. (-gb-)


Lesenswert?

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.

von Jan (Gast)


Lesenswert?

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?

von Christian R. (supachris)


Lesenswert?

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.

von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

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.

von Christian R. (supachris)


Lesenswert?

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.

von Gustl B. (-gb-)


Lesenswert?

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.

von Christian R. (supachris)


Lesenswert?

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?

von Gustl B. (-gb-)


Lesenswert?

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?

von Christian R. (supachris)


Lesenswert?

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/

von Gustl B. (-gb-)


Lesenswert?

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.

von Christian R. (supachris)


Lesenswert?

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.

von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

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
von Christian R. (supachris)


Lesenswert?

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.

von Gustl B. (-gb-)


Lesenswert?

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
von Christian R. (supachris)


Lesenswert?

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...

von Gustl B. (-gb-)


Lesenswert?

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
von Christian R. (supachris)


Lesenswert?

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.

von Gustl B. (-gb-)


Lesenswert?

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.

von Klakx -. (klakx)


Lesenswert?

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.

von Gustl B. (-gb-)


Lesenswert?

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.

von Christian R. (supachris)


Lesenswert?

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.

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.