Hallo,
ich habe eine Platine mit LTC2325 entworfen, bestückt und funktioniert
eigentlich ganz so wie sie soll. Drauf ist auch ein FPGA-Modul von
Trenz.
Jetzt hat der ADC ein SPI Interface (ich verwende SDR CMOS) und gibt
auch eine Clock aus mit deren steigender Flanke ich die Daten eintakten
kann. Also Schieberegister das das schön weiter schiebt und wenn gerade
nicht geschoben wird (Ruhephase wenn nCNV high ist) wird der Inhalt als
fertiges Sample übernommen. Soweit so gut. Jetzt bekomme ich aber nur
gerade Werte vom ADC. Im Datenblatt steht Zweierkomplement, in VHDL
wandele ich das so um:
1
output<=std_logic_vector(unsigned(not(input))+1);
Habt ihr irgendeine Idee was falsch laufen könnte? Wenn ich Statt der
ADC-Werte einen Zähler im FPGA verwende und dessen Wert zum PC schicke
funktioniert das wunderbar.
Was ich auch nicht verstehe ist wieso
Zweierkomplement nicht umwandelt. Ich verstehe das so, dass mit signed()
der std_logic_vector "Kabelbaum" betrachtet wird als Zahl im
Zweierkomplement. Dann wird daraus eine Integer und diese mit
to_unsigned() in eine Bitrepräsentation ohne Zweierkomplement. Wo ist
mein Fehler?
Dachte ich auch aber in der Simulation gehen 16 Takte raus und sollten
auch mit etwas Latenz auf Clockout vom ADC zurückkommen. Vor allem mache
ist das mit einem Schieberegister, wenn ich also eins zu oft oder zu
selten schiebe, dann sollte nach ein paar Zyklen Müll drin stehen aber
die Samples sehen grob betrachtet gut aus, man sieht das Signal sauber
nur sind die Werte eben immer gerade.
Wie macht man das eigentlich sauber?! Ich will 5MSample/s und habe
100MHz als Takt im FPGA. Jetzt habe ich einen Zähler 0 bis 19 der mit
den 100MHz läuft und nCNV erzeuge ich dann daraus und SCK auch.
1
begin
2
3
LTC2325_SCK<=clk100whencounter>3else'0';
4
5
processbegin
6
waituntilrising_edge(clk100);
7
counter<=counter+1;
8
ifcounter=19then
9
counter<=0;
10
endif;
11
12
LTC2325_nCNV<='0';
13
ifcounter<2orcounter>18then
14
LTC2325_nCNV<='1';
15
endif;
16
endprocess;
Das macht also 30ns nCNV und danach 16 Takte auf SCK. Ist das OK so oder
macht man das anders?
Ja, ist mir klar, aber wie sonst? Ich soll die Clock ja nicht dauerhaft
laufen lassen laut Datenblatt. Also möchte ich die irgendwie abschalten
können zwischendurch.
Steht jedenfalls da im Datenblatt.
http://www.linear.com/docs/56677
Ich mach das bisher bei ADCs immer so mit der Clock, funktioniert ja
auch. Das ist jetzt das erste Mal dass ich da länger dran sitze. Morgen
geh ich mal mit dem Oszi an die Signale.
Wird hier wieder mal der eine einzige FPGA Takt des gesamten Designs mit
einem Signal namens SCLK verwechselt?
Oder andersrum: im und für das FPGA ist SCLK kein Takt.
Gustl B. schrieb:> Ja, ist mir klar, aber wie sonst?
Ich mach das so:
http://www.lothar-miller.de/s9y/categories/45-SPI-Master
Und offenbar funktioniert das auch bei anderen... ?
Du erzeugt die Clock also selber. Ja wird funktionieren, aber für 100MHz
SCK bräuchte ich dann 200MHz im FPGA. Ich will eigentlich auch kein
volles SPI bauen, bei den ADCs bisher hat ein einfaches Schieberegister
genügt. Das war sehr übersichtlich.
Mir ist klar dass SCK bei mir kein Takt ist im Sinne von Taktnetze im
FPGA. Aber bei Dir doch auch nicht das SCLK?
Und was ist daran schlecht wenn das Signal sonst im FPGA nicht verwendet
wird? Das geht doch nur raus zum ADC und muss nicht intern im FPGA FFs
erreichen.
Also eigentlich müsste ich einen BUFMRCE verwenden, also einen Clock
Buffer mit Enable Eingang.
Schlimm ist dass der CLK100 dann global auf einem Logik Netz laufen
muss, und nicht auf einem Taktnetzwerk innerhalb des FPGA. Nimm ein DDR
Out Flipflop und gib den Takt damit aus wenn es unbedingt notwendig ist.
Dann bist du sauber und kannst auch sehr bequem die Phase und die
Freigabe steuern.
Gustl B. schrieb:> Du erzeugt die Clock also selber. Ja wird funktionieren, aber für 100MHz> SCK bräuchte ich dann 200MHz im FPGA.
Bei 100MHz SPI-Takt wirst du in der Tat ganz genau aufs Timing schauen
müssen. Aber in der Tat: da kommst du mit dem "traditionellen"
SPI-Ansatz nicht weiter. Da geht es um einzelne ns...
> Ich will eigentlich auch kein volles SPI bauen, bei den ADCs bisher hat> ein einfaches Schieberegister genügt.
"SPI" und "Schieberegister" sind eh' nur die beiden Seiten der selben
Medaille.
-gb- schrieb:> Morgen geh ich mal mit dem Oszi an die Signale.
Das erscheint mir als die richtige Herangehensweise...
Nimmst du den CLKOOUT des ADC zum Eintakten der Daten? Das wäre der
richtige Ansatz, denn nur der CLKOUT ist im Bezug zu den Daten
ausreichend genau spezifiziert:
1
CLKOUT (Pin 33): Serial Data Clock Output.
2
CLKOUT provides a skew-matched clock to latch the SDO output
3
at the receiver (FPGA). ...
4
This pin echoes the input at SCK with a small delay.
Vielen Dank! Jetzt mit ODDR2 sieht die Post Implementation Timing
Simulation schon besser und vor allem glitchfrei aus.
Christian R. schrieb:> Schlimm ist dass der CLK100 dann global auf einem Logik Netz laufen> muss, und nicht auf einem Taktnetzwerk innerhalb des FPGA.
Das verstehe ich nicht, also ja, kann ich nachgucken und ist so, aber
wieso wird nicht lokal an nur dieser einen Stelle die Clock vom globalen
Taktnetz abgezweigt und auf die LUT gegeben die zum Ausgang führt?
Und irgendwie ist das Datenblatt seltsam:
http://cds.linear.com/docs/en/datasheet/232516fa.pdf
Auf Seite 26 unten ist das Timing eingezeichnet. Für mich besteht ein
t_CYC also aus t_CNVH + t_CONV + t_READOUT.
Auf Seite 5 ist t_CYC aber beschrieben als t_CNVH + t_CONV mit minimalen
200ns was für 5MSample/s passt. Nur t_READOUT fehlt.
Mir geht es um t_CONV, wie groß muss die mindestens sein? Ein
Minimalwert steht nicht im Datenblatt.
So, hab das jetzt mit Oszi angeguckt, das Timing sieht schön aus, auf
CLOCKOUT kommen auch 16 Takte zurück, aber die Daten sind seltsam. Bei
der letzten steigenden Flanke von CLOCKOUT ist SDO immer Low egal
welches Signal ich in den ADC reinfütttere.
Bei den Bildern ist der gelbe Kanal immer nCNV also ein FPGA Ausgang.
In Bild 2 und 3 ist der grüne Kanal CLOCKOUT, also das kommt aus dem
ADC.
In den Bildern 4 und 5 ist der gründe Kanal ein SDO Ausgang vom ADC. Man
sieht da schön die einzelnen Bits, aber das letzte Bit ist immer LOW.
Die Marker zeigen das Maximum des ersten und letzten Taktes von
CLOCKOUT.
Edit: Bei den Bildern 2 und 3 sieht man die Clock auch im gelben Kanal,
das ist aber nur der Fall wenn ich mit dem Oszi auch ein Taktsignal
messe. Ich vermute daher das ist von mir messtechnisch unsauber, leider
habe ich nicht viele Stellen an denen ich an die Masse komme.
Jetzt bin ich mal so frei und lege einen 17. Takt an.
Hat auch nichts gebracht. Man sieht weiterhin 15 Bits die sich
verändern, dann eines das immer Low ist und jetzt ein 17tes dahinter das
immer High ist.
Und nochmal Datenblatt:
Seite 25:
> In SDR mode (SDR/DDR Pin 23 = GND), the falling edge> of this clock shifts the conversion result MSB first onto> the SDO pins.
Aber im Bildchen Seite 26 ist D15 schon vor der SCK da, also die erste
fallende Flanke von SCK schiebt D14 auf SDO.
Gustl B. schrieb:> Mir geht es um t_CONV, wie groß muss die mindestens sein? Ein> Minimalwert steht nicht im Datenblatt.
Und wenn du ihm mal die 170ns gönnst, die als Maximalwert angegeben
sind, bevor du mit dem Austakten des Ergebnis beginnst? (entsprechend
Fig. 21 im Datenblatt).
Vielleicht meint die Datenblattlogik, dass der ADC maximal 170ns braucht
(und du frühestens nach 170ns mit dem Auslesen anfangen solltest).
Kann ich machen, aber ... mit den 30ns nCNV bin ich doch dann schon bei
200ns. Also das glaube ich einfach nicht, dass das dann als 5MSample/s
ADC verkauft wird wenn da nicht alle 200ns ein neues Sample rausfällt.
Gustl B. schrieb:> Hab ich auch schon nachgeguckt, mehrfach. Aber steht wirklich auf dem IC> richtig drauf.
Hast Du den Baustein über einen der offiziellen Händler/Distributoren
bezogen oder über einen Händler bei Alibaba, Ebay o.ä.?
Ja, über den HBE Shop.
Wie soll ich das überhaupt verstehen. D15 ist da vor der ersten SCK. Und
D15 wird am Ende mit der letzten SCK rausgeschoben - gehört dann das D15
am Anfang noch zum vorherigen Sample? Stelle ich mich gerade unfassbar
dumm an und jage ein Gespenst oder ist das einfach schlecht
dokumentiert?
@ Lattice User:
Das hatte ich schonmal gesehen als ich mich über den ADC informierte vor
dem Kauf, aber damals hab ich das ignoriert, es sieht doch recht
kompliziert aus und so einen eigentlich einfachen Signalverlauf aus dem
Datenblatt konnte ich bisher auch selber mit wenig VHDL nachbauen.
Edit:
Wenn ich mehr Zeit lasse zwischen fallender Flanke von nCNV und dem
Auslesen bleibt das letzte Bit weiterhin Low. Bin nachher wieder da.
Gustl B. schrieb:>> @ Lattice User:> Das hatte ich schonmal gesehen als ich mich über den ADC informierte vor> dem Kauf, aber damals hab ich das ignoriert, es sieht doch recht> kompliziert aus und so einen eigentlich einfachen Signalverlauf aus dem> Datenblatt konnte ich bisher auch selber mit wenig VHDL nachbauen.>
Offensichtlich hast du da etwas übersehen. Ein Vergleich wäre also
durchaus interessant.
Ich habe allerdings einen Verdacht.
Das Timing Diagram auf Seite 2 zeigt nicht den Ablauf, sondern dient nur
dazu um Flankenbeziehungen mit Timingwerten zu versehen.
Der Ablauf wird auf den Seiten 14 und 15 gezeigt.
Hier steht auch, dass die gelesenen Daten aus dem vorhergehenden
Conversionszyklus stammen. Auf Seite 25 steht unter /CNV dass SCK auch
die Conversion der SAR ADCs antreibt.
Deinem Osciaufnahmen ist zu entnehmen, dass du nCNV schon während des
letzen SCK Pulses auf High setzt. Möglichweise wird dadurch die
Conversion zu früh beendet und das LSB ist immer 0.
Setze mal nCNV einen Takt später auf High.
-gb- schrieb:> Steht jedenfalls da im Datenblatt.> http://www.linear.com/docs/56677>> Ich mach das bisher bei ADCs immer so mit der Clock, funktioniert ja> auch. Das ist jetzt das erste Mal dass ich da länger dran sitze. Morgen> geh ich mal mit dem Oszi an die Signale.
Im Datenblatt (S. 14) ist SCK zwar als abgeschaltet (während /CNV high
ist) gezeichnet - aber heisst dass auch zwangsläufig, das sie
abgeschaltet werden muss? Zumindest kenne ich ADCs (z.B. AD7476A) bei
denen sie durchlaufen darf.
@ Lattice User:
Vielen Dank! Tatsache wenn ich am Ende einen Takt Pause lasse dann
ändert das LSB seinen Wert. Nun brauche ich aber 21 Takte, erreiche also
die 5MSample/s nichtmehr. Gut, ich könnte intern aus den 100MHz 110MHz
machen, dann würde das passen.
@ Burkhard K.:
Das habe ich noch nie probiert sondern immer den Takt abgeschaltet. Rein
vom Gefühl her einfach damit das weniger rauscht.
Gustl B. schrieb:> Nun brauche ich aber 21 Takte, erreiche also> die 5MSample/s nichtmehr. Gut, ich könnte intern aus den 100MHz 110MHz> machen, dann würde das passen.>
Das Beispielcode von Linear verwendet 110 MHz. (hast du wahrscheinlich
gesehen)
Du kannst versuchen den Takt Pause am Anfang wegzulassen, ich finde im
Datenblatt keinen Grund (ausser dem Bilden) warum diese Pause notwendig
sein sollte.
Naja, im Datenblatt steht aber auch, dass eine 100MHz Clock reicht für
5MSample/s.
Nun, zu früh anfangen geht nicht laut Oszi braucht es irgendwie doch
etwas Zeit bis das MSB auftaucht. Nicht viel, aber so ein Takt oder so.
Ich überlege gerade was schöner ist, die SCK mit ODELAY zu verschieben
bis es passt oder einfach 110MHz zu verwenden.
Gustl B. schrieb:>> Nun, zu früh anfangen geht nicht laut Oszi braucht es irgendwie doch> etwas Zeit bis das MSB auftaucht. Nicht viel, aber so ein Takt oder so.
Laut Datenblatt sollten das nur 3 ns sein.
> Ich überlege gerade was schöner ist, die SCK mit ODELAY zu verschieben> bis es passt oder einfach 110MHz zu verwenden.
Verschiebe nCNV um einen halben Takt.
Dazu auch als ODDR2 implementieren, und folgende Folge ausgeben
11
10 Start n
00 (dabei SCK als 10 ausgeben)
.. insgesamt 16 mal 00
01
11
11
10 Start n+1
00
Aber eine Frage: hast du sichergestellt dass für nCNV ein IO Register
verwendet wird?
Ok, jetzt mache ich nCNV und SCK über je ein ODDR2, die sind ja doch
recht schön zu benutzen (habe bisher diese Herstellerspezifischen
Features gemieden wo es ging).
Was meinst Du mit IO Register?
In den Constraints habe ich
set_property IOB TRUE [get_ports LTC2325_nCNV]
drinnen.
Edit:
So wie im Bildchen sim0 im Anhang habe ich das jetzt und das LSB bleibt
dauerhaft Low. nCNV sind 30ns und noch früher mit dem Auslesen anfangen
geht nicht, da verliere ich das MSB. Ich könnte noch nCNV etwas kürzen
...
So, jetzt auch Bildchen sim1. nCNV ist jetzt nur noch 25ns, also kürzer
als der Minimalwert im Datenblatt. Und es sieht gut aus! Ich teste noch
etwas, aber auf dem Oszi kann ich 16 Bits sehen.
Und noch mehr Bildchen:
Gelb ist jeweils nCNV vom FPGA.
In Bild 6 in Grün ist SCK vom FPGA
In Bild 7 in Grün ist CLKOUT vom LTC2325
In Bild 8 und 9 in Grün ist SDO. Auffällig ist, dass das erste Bit MSB
etwas kürzer ist. Es wird aber schön eingetaktet im FPGA.
Die Marker bleiben unverändert bei allen Bildern.
Ebenfalls jetzt das VHDL im Anhang.
Vielen Dank für die super Hilfe!
Gustl B. schrieb:>> nCNV ist jetzt nur noch 25ns, also kürzer> als der Minimalwert im Datenblatt.
Keine gute Idee. Damit wird die Sampling Aperture um 5 ns verkürzt, und
das geht auf die Genauigkeit. (Siehe Step Response auf Seite 9)
Ob du damit leben kannst, hängt von deinem zu messenden Analogsignalen
ab. (Frequenz, Amplitude)
OK, sehe ich ein. Also mit PLL SCK auf 110MHz ändern und schneller
auslesen?
Aber gut, ich wollte den Stein erstmal in Betrieb nehmen, die Platine
ist dafür auch nicht optimal und nur zweilagig. Mal gucken was am Ende
überhaupt benötigt wird, vermutlich reichen auch weniger Bits locker.
Gustl B. schrieb:> OK, sehe ich ein. Also mit PLL SCK auf 110MHz ändern und schneller> auslesen?>> Aber gut, ich wollte den Stein erstmal in Betrieb nehmen, die Platine> ist dafür auch nicht optimal und nur zweilagig. Mal gucken was am Ende> überhaupt benötigt wird, vermutlich reichen auch weniger Bits locker.
Wolltest du nicht alle eine Beiträge immer in Code-Tags einschließen?
Hab nichts mehr gemacht weil es gut genug funktioniert.
Jürgen S. schrieb:> Das mit den manuellen Takten ist> sicher behoben, oder?
Mir wurden doch hier DDR FFS empfohlen?! Was würdest denn Du verwenden?
SCK hängt an einem Clock capable Pin, sollte ich dann direkt eine Clock
auf diesen Pin geben und sie im FPGA mit einem BUFGCE abschalten wenn
sie "stumm" seien soll?
Und wieso sollte man das überhaupt anders machen?
Wieso habe ich noch keinen 110MHz Takt verwendet? Weil auf dem Board
eine 100MHz Taktquelle drauf ist. Würde ich mit einer PLL 110MHz
erzeugen hätte ich vermutlich mehr Jitter wie wenn ich die 100MHz ohne
PLL verwende und manuell die Takte ausgebe.
So, ich wärme meinen alten Thread nochmal neu auf.
Dieses Mal erzeuge ich SCK und #CNV nicht im FPGA sondern lokal beim ADC
mit einer Digitalgattergrabschaltung. Und wieder habe ich das Problem,
dass je nach Timing das letzte Bit 0 bleibt. Das möchte ich jetzt
klären.
In dem Timing aus dem Datenblatt ist zu sehen, dass das erste Bit nach
der fallenden Flanke von #CNV länger anliegt. Und dann ist da noch ein
letztes Bit das leer ist?!
In meinem alten Timing von oben (Bildchen im Anhang) ist zu sehen, dass
das auch funktioniert und das erste Bit aber kürzer ist und kein 17. Bit
am Ende folgt.
Tja, aber damals wurde ich kritisiert:
Lattice User schrieb:> Keine gute Idee. Damit wird die Sampling Aperture um 5 ns verkürzt, und> das geht auf die Genauigkeit. (Siehe Step Response auf Seite 9)
Hier das Datenblatt:
https://www.analog.com/media/en/technical-documentation/data-sheets/232516fa.pdf
Und die Frage dazu:
Auf was bezieht sich diese Step Response? Ist das sie Zeit ab einer
Flanke von #CNV in der nichts gemacht werden sollte? Oder ist das
einfach nur die Zeit die es nach einer großen Spannungsänderung dauert
bis sich das eingeschwungen hat?
Jedenfalls, ich habe jetzt ein neues Timing mit minimal schnellerem
Takt. 104 MHz gegenüber 100 MHz und bekomme grob 30 ns für #CNV High.
Im Datenblatt ist das eher seltsam, da ist für einen Cycle minimal 200
ns angegeben. Für #CNV High minimal 30 ns (halte ich ein). Aber bei
tACQUISITION steht Typisch 28 ns. Naja.
Jedenfalls habe ich jetzt ein lang genuges #CNV High, einen Abstand
zwischen dem ersten Takt und der Fallenden Flanke von #CNV und die 16
Takte sind vor der steigenden Flanke von #CNV fertig.
Ich kann mir nicht erklären wieso kein 16. Bit ausgegeben wird bzw.
warum das immer Low ist. Der ADC weiß ja nicht dass da bald die
steigende Flanke von #CNV kommen wird.
Ach so ja, ich kenne die Lösung. Ich schiebe die SCK Takte etwas nach
vorne. Aber das ist Probieren. Mich interessiert also:
Steht das im Datenblatt in welchem Zeitraum genau die Takte liegen
müssen?
Tja warum bleibt das letzte Bit leer? Das steht so halb im Datenblatt.
tConv darf maximal 170 ns lang sein. Wenn jetzt ein Cycle länger als 200
ns ist und tConvh 30 ns lang ist, dann ist tConv länger als die maximal
erlaubten 170 ns. Es könnte also sein, dass später als 170 ns nach der
fallenden Flanke von #CNV keine Bits ausgegeben werden.
Aber das kann ich nicht glauben weil ja mit langsamerem SPI Takt sonst
keine Übertragung der 16 Bits möglich wäre.
So, jetzt habe ich erstmal die Tastköpfe mit Gaffertape an der Platine
befestigt und die Spitzen mit kurzem verdrillten Draht festgelötet. Das
ergibt also ein etwas hybscheres Bildchen mit Zeitmessung.
So wie ich das verstehe halte ich das Timing vom Datenblatt ein - bis
auf einen Punkt und zwar ist t_CONV bei mir 2 oder 3 ns länger als die
maximalen 170 ns. Wobei ... wenn man den ADC mit einem langsameren Takt
betreiben würde, dann wird t_CONV auch zwangsläufig länger weil man
sonst nicht die 16 Bits heraustakten könnte.
Das ist für mich also ein Rätsel wieso das letzte Bit 0 bleibt.
Ich kann mir auch nicht vorstellen, dass der Stein nur 15 Bits ausgibt
wenn innerhalb der ersten paar ns nach der fallenden Flanke von #CNV
kein CLK Puls kam.
Mache ich da etwas grob falsch?
Edit:
Nach der fallenden Flanke von #CNV liegt ja schon das MSB an. Danach
wird mit jeder fallenden Flanke von SCK ein weiteres Bit
herausgeschoben. Man braucht also nur 15 Takte weil die fallende Flanke
des 15. Takts das LSB herausschiebt. Und diese 15 Takte liegen bei mir
schön mittig und auch innerhalb der maximal 170 ns nach der fallenden
Flanke von #CNV.
Und dann habe ich dazu diesen Thread gefunden:
https://ez.analog.com/data_converters/precision_adcs/f/q-a/105697/ltc2325-16-lsb-always-0
Darin wird behauptet:
> I have been told that the tDSCKHCNVH spec has a typographical error and> should be 10ns instead of 0ns.
Und:
> The solution to this is to move the rising CNV edge at least 10ns from the last
SCK edge.
Tja, das stimmt aber einfach mal nicht, siehe neues Bildchen. Da gebe
ich den Takt schon früher aus, ja, sieht nicht schön aus, aber das sind
16 Bits. Und der letzte Takt ist deutlich näher als 10 ns an der
steigenden Flanke von #CNV.
Edit:
So, noch ein NOT Gatter in den Takt eingebaut und es sieht gut aus. Das
MSB ist noch etwas kürzer als der Rest. Da löte ich jetzt noch ein AND
Gatter zur Verzögerung ein.
Dein Takt sieht ja schrecklich aus. Ich würden den erstmal
verlangsamen und das Timing verlängern. Damit würde ich
schauen, dass die Schiebelogik funktioniert.
Danach kannst du die Frequenz erhöhen.
Santa
Jo, aber die letzte Taktflanke ist egal und die Anzahl offensichtlich
auch. Wenn laut Datenblatt nur 15 Takte benötigt werden aber selbst dort
16 gezeichnet sind dann kann ich da auch 17 oder noch mehr anlegen.
Damit der letzte halbe Takt aber wegfällt und das MSB etwas länger
anliegt habe ich den Takt jetzt mit einem AND Gate verzögert.
In einem weiteren Bild ist auch CLKOUT zu sehen (blau).
Edit:
Ja, es wäre vermutlich sinnvoller statt der 17 Takte nur 16 Takte
auszugeben und dafür #CNV High etwas länger zu machen. Aber ... es ist
immer noch unklar von was es abhängt ob das LSB 0 ist oder nicht. Daher
lasse ich das jetzt so. #CNV ist grob 30 ns High und erfüllt damit die
Angabe im Datenblatt mit typisch 28 ns.