Forum: FPGA, VHDL & Co. FPGA <-> SPI <-> FPGA


von Paul (Gast)


Angehängte Dateien:

Lesenswert?

Hallo allerseits,

ich möchte Informationen zwischen zwei FPGAs (Cyclone IV @100MHz) via 
SPI austauschen. Das muss nicht schnell sein, deshalb habe ich mich für 
SPI entschieden und die Implementierung nach:
http://www.lothar-miller.de/s9y/categories/45-SPI-Master
auf dem einen Cyclone und den Slave auf dem zweiten Cyclone nach:
http://www.lothar-miller.de/s9y/categories/26-SPI-Slave
programmiert.
Auf dem Master ist "TX_Data" mit "RX_Data" über ein D-FF
1
process begin
2
   wait until rising_edge(TX_DONE);
3
   TX_Data <= RX_Data;
4
end process;
sozusagen "geloopbackt". Jetzt gebe ich auf der Slave-Seite einen 
konstanten Wert vor und vergleiche diesen mit dem empfangenen Datenwort. 
Dabei treten leider sporadisch Fehler auf: Das letzte Bit in einem Wort 
kippt dann, wie auf dem Oszillogramm zu sehen. (Grün SCKL Gelb SS Blau 
MISO Pink MOSI)

Die Einstellungen von Master und Slave sind:
CPOL & CPHA = 0
Quarzfrequenz = 100'000'000
SPI freq = 1'000'000
wortlaenge = 12

Meine erste Vermutung war, dass es an der Art meines Loopbacks liegt. 
Allerdings sind die Ein- und Ausgänge des Masters ja synchron zum 
globalen clk auf dem FPGA (also kein Einsynchronisieren mehr nötig?) und 
auch einen Delay von 1-100 Taktzyklen zwischen dem zeitpunkt "TX-DONE" 
und der Übernahme eines neuen TX-Wortes haben nichts gebracht.

Hat jemand, der sich mit den Beiden auskennt, eventuell einen Tipp für 
mich, wo ich weitersuchen könnte?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Paul schrieb:
> process begin
>    wait until rising_edge(TX_DONE);
>    TX_Data <= RX_Data;
> end process;
Das ist böse...
Du sollst nur einen Takt haben!
Probiers eher mal so:
1
process begin
2
   wait until rising_edge(clk);
3
   if TX_DONE ='1' then
4
     TX_Data <= RX_Data;
5
   end if; 
6
end process;
Das wäre richtig synchron.

BTW: Wie viele Takte hast du denn sonst noch?
Ein Takt ist alles, was mit 'event oder *_edge() zu tun hat...

> Grün SCKL Gelb SS
Kannst du mal dieses letzte Bit (oder die letzten paar Bits) 
herauszoomen?

> Meine erste Vermutung war, dass es an der Art meines Loopbacks liegt.
> Allerdings sind die Ein- und Ausgänge des Masters ja synchron zum
> globalen clk auf dem FPGA (also kein Einsynchronisieren mehr nötig?)
Hast du das der Toolchain angegeben? Sind der Toolchain die Laufzeiten 
bekannt (constraints)?


> ich möchte Informationen zwischen zwei FPGAs (Cyclone IV @100MHz)
> ... austauschen. Das muss nicht schnell sein
Ich hätte dafür asynchrone serielle Schnittstellen genommen, weil die 
vollkommen unabhängig und bidirektional ist. Und mit passender Baudrate 
könntest du sogar mit einem PC einfach "mithören"...

von Paul (Gast)


Angehängte Dateien:

Lesenswert?

Hallo und vielen Dank für die schnelle Antwort
> Probiers eher mal so:process begin
>    wait until rising_edge(clk);
>    if TX_DONE ='1' then
>      TX_Data <= RX_Data;
>    end if;
> end process;
Habe ich versucht und hat leider nichts gebracht.

>
> BTW: Wie viele Takte hast du denn sonst noch?
> Ein Takt ist alles, was mit 'event oder *_edge() zu tun hat...
Für die SPI Kommunikation habe ich nur einen Takt (100MHz aus der PLL) 
und natürlich den SPI-Takt. Es ist an anderer Stelle des Designs noch 
ein zweiter clk vorhanden. Beide Teile sind aber völlig unabhängig 
voneinander, ich denke also nicht, dass die Lösung dort zu suchen ist.

>> Grün SCKL Gelb SS
> Kannst du mal dieses letzte Bit (oder die letzten paar Bits)
> herauszoomen?
>
Habe die SPI-Taktfrequenz mal runtergedreht (Fehler ist nicht abhängig 
von der SCLK Frequenz) und einen neuen Screenshot gemacht, wo die Bits 
besser zu erkennen sind.


Habe heute noch herausgefunden, dass der Fehler nur MISO seitig 
auftritt. Wenn ich also auf den beiden FPGAs jeweils einen Slave und 
einen Master platziere und dann immer nur MOSI benutze klappts. Unschön 
aber ein Notbehelf...

Hatte mich für SPI entschieden, da ich mir von der separaten clk Leitung 
eigentlich einen wesentlich robusteren Bus versprochen habe.

Grüße

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Paul schrieb:
>> BTW: Wie viele Takte hast du denn sonst noch?
>> Ein Takt ist alles, was mit 'event oder *_edge() zu tun hat...
> Für die SPI Kommunikation habe ich nur einen Takt (100MHz aus der PLL)
> und natürlich den SPI-Takt.
Du hattest aber mindestens bisher auch den TX_DONE-Takt. Denn ein 
rising_edge(TX_DONE) ist ein Takt.

Beim SPI-Slave musst du aufpassen, denn der SCLK ist natürlich asynchron 
zum globalen Clock und deshalb gehört der SS erst mal 
einsynchronisiert...

Zeig doch einfach mal deine beiden Designs.

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.