Forum: FPGA, VHDL & Co. Wie Clockdomain crossing für FT232H, wie debuggen?


von Gustl B. (-gb-)



Lesenswert?

Hallo, sorry für diesen weiteren Thread aber ich habe einen komischen 
Fehler bei dem ich nicht weiß wie man den debuggen kann:

Die ganzen Einzelteile funktionieren, aber zusammen funktioniert es 
nicht.
Ich habe:
FT232H im FIFO Modus (liefert 60MHz Clock)
FT232R als UART
6 ADCs in 3 AD7356
80MHz Clock im FPGA
Einen Zähler als Datengenerator für Testdaten im FPGA
Einen dual Clock FIFO (Xilinx) im FPGA
Viel BRAM um Samples zu speichern für das UART.

Über UART kann ich eine Datenquelle im FPGA auswählen. Deren Samples 
werden dann gleichzeitig über den FT232H gestreamt, also Sample mit 
80MHz in das FIFO und mit 60MHz wieder raus zum FT232H.
Und gleichzeitig werden immer Samples in BRAM abgelegt und dann langsam 
über das UART rausgeschrieben.

Nun, über das UART bekomme ich immer alles in richtig. Die Daten vom ADC 
sehen gut aus und wenn ich den Zähler als Quelle wähle kommen da auch 
die entsprechenden Daten raus, wunderbar.
Über den FT232H FIFO bekomme ich auch ADC und Zähler, aber auch sehr 
viele Fehler. ADC- und Zähler Werte sind 12Bit, die Teile ich auf zwei 
Bytes auf:

fifo_din <= "00" & ADC_data(11 downto 7) & '1';
und
fifo_din <= ADC_data(6 downto 0) & '0';

Die Fehler betreffen gar nicht die Nutzdaten, sondern schon die 1 oder 0 
am Ende sind oft falsch bzw. zwei am PC nacheinander empfangene Bytes 
enthalten eine 1 oder 0 am Ende.

Das seltsame ist, dass ich das das hier im Code drin habe um die Quelle 
auszuwählen:
1
case ADC_select is
2
when "001"  => ADC_data <= AD7356_1_data; ADC_data_ready <= AD7356_12_data_ready;
3
when "010"  => ADC_data <= AD7356_2_data; ADC_data_ready <= AD7356_12_data_ready;
4
when "011"  => ADC_data <= AD7356_3_data; ADC_data_ready <= AD7356_34_data_ready;
5
when "100"  => ADC_data <= AD7356_4_data; ADC_data_ready <= AD7356_34_data_ready;
6
when "101"  => ADC_data <= AD7356_5_data; ADC_data_ready <= AD7356_56_data_ready;
7
when "110"  => ADC_data <= AD7356_6_data; ADC_data_ready <= AD7356_56_data_ready;
8
when others => ADC_data <= fifo_counter;  ADC_data_ready <= fifo_counter_ready;
9
end case;

Wenn ich das feste auf den Zähler als Datengenerator verbinde
1
ADC_data <= fifo_counter;  ADC_data_ready <= fifo_counter_ready;

Gibt es genau keine Fehler, ich kann mehrere Gigabytes an Zählerwerten 
über den FT232H zum PC schieben ohne einen einzigen Bitfehler. Wobei das 
aber natürlich nur die Nutzdaten ändert und sonst nichts.

Wie debuggt man sowas?

Im Anhang mal das Projekt.

von Gustl B. (-gb-)


Lesenswert?

Ich kann auch statt des MUX, also dieser fetten case Struktur das fest 
auf einen der ADCs verdrahten, also z. B.

ADC_data <= AD7356_1_data; ADC_data_ready <= AD7356_12_data_ready;

Das ist wirklich nur diese eine Änderung, das case komplett rauswerfen 
und stattdessen diese eine Zeile reinsetzen. Und schon kommen fehlerfrei 
über UART und auch FT232H FIFO die Samples dieses ADCs an.

Also das mit dem FT232H funktioniert, der dual Clock FIFO davor dann 
wohl auch, UART funktioniert mit Pufferung der Daten im BRAM (für den 
FT232H FIFO werden die Daten nicht gepuffert, die ADCs haben 5MSample/s 
und ein Sample wird in zwei Bytes gesendet. Das kann also in Echtzeit 
gestreamt werden.)
Die Beschreibung für die ADCs funktioniert.
Bleibt dieses case Konstrukt. Aber auch das scheint ja zu funktionieren! 
Wenn ich das drinnen habe, kann ich auswählen welche Daten gesendet 
werden und für die UART Schnittstelle funktioniert das auch fehlerfrei. 
Sprich ADC_data und ADC_data_ready werden richtig zugewiesen. Aber genau 
diese Signale werden auch von der Schreiblogik ins dual-clock FIFO 
verwendet, das sollte also auch für diese passen.

Ich weiß einfach nicht wie ich da sinnvoll rangehen kann um rauszufinden 
was nicht funktioniert.

Edit:
Statt case im getakteten Process eine kombinatorische with ... select 
Anweisung hilft auch nicht. Ich kann sogar gleichzeitig über das UART 
korrekte Daten lesen während die kaputt über den FT232H ankommen. Wenn 
ich fest ein Quelle verdrahte ist alles bestens.

: Bearbeitet durch User
von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

So, gefunden.

Wie man sieht ist das vhdl fast identisch - und es war auch gar nicht 
die Ursache sondern der FIFO-IP.

Bei dem FIFO Generator kann man einstellen:
- Independent Clocks Block RAM
- Independent Clocks Builtin FIFO

Mit Ersterem gibt es hier Fehler, beim Builtin FIFO sind keine Fehler 
da.

Funfact:
Beim Builtin FIFO soll man im FIFO Generator die Read und Write Clock 
Taktraten angeben. Das hatte in anfangs übersehen und es funktionierte 
trotzdem fehlerfrei, ich betrachte das also als optional. Schreibt man 
nichts in die Felder steht da später 1 (MHz) drinnen.

Fazit:
Ich weiß immer noch nicht ob es ein Fehler vom FIFO Generator war oder 
meine Beschreibung unsauber ist. Und wie ich das hätte finden können 
außer durch ausprobieren nach dem Ausschlussverfahren. Ich werde jetzt 
eben den Builtin FIFO verwenden, der nutzt am Ende auch BRAM.

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.