Forum: FPGA, VHDL & Co. Bitte Hilfe beim SPI-Code *verzweifel*


von Der D. (daimlerfahrer)


Angehängte Dateien:

Lesenswert?

Guten Tag zusammen,

so langsam verzweifle ich.
Die Aufgabenstellung ist so simpel wie (inwzischen) zeitraubend!
Ich habe 16 Bit die ich über eine SPI Schnittstelle auf meinen FPGA 
bekommen will.
Inzwischen habe ich 3 Versionen SPI-Code und keiner funktioniert 
zuverlässig, obgleich die Simulation bei allen funktioniert.

SPI1a und SPI1b unterscheiden sich nur unwesentlich, jedoch erschien mir 
Version a nicht besonders sauber, da ich einem Signal einen Wert zuweise 
und es direkt wieder zurücksetze.
Darum ist Version b entstanden, die bisher am ehesten Funktioniert, 
jedoch nicht immer...

Version 2 arbeitet mit einem "Masterclock" (50 MHz) der den SPI (500 
kHz) abtastet. Simulation ist hier OK - Realität FAILED.

Würde mich über eine kurze Code-Review sehr freuen und bedanke mich 
schonmal im Voraus!

von Nephilim (Gast)


Lesenswert?

hast du dir schonmal den realen datenstrom angeschaut ? z.B. mitm logic 
analyser. dann könnte man mit hilfe der ergebnisse im fpga dann 
rausfinden woran er sich stört. vielleicht is ja der reelle datenstrom 
anders als du ihn dir vorstellt.

von Volker (Gast)


Lesenswert?

1. In Version 2 wird SPI_Enable nicht sauber eingetaktet.
Real geht es an die Eingänge von verschiedenen FFs. Nun überleg die mal, 
was passiert, wenn die Änderung vom SPI_Enable Eingang exakt mit dem 
abtastenen
Takteingang stattfindet.

2. Simulation ist hier OK - Realität FAILED.
was bedeutet dies konkret, was geht nicht?

3. Schau die am besten mal den RTL-View an.

Gruß Volker

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


Lesenswert?

> In Version 2 wird SPI_Enable nicht sauber eingetaktet.
Merksatz:
Ein Signal geht durch (mindestens) 2 FFs, erst dann wird es verwendet.

Bei deinen 1er-Lösungen mußt du übrigens anschliessend noch die 
Taktdomäne wechseln (also das Schieberegister einsynchronisieren), falls 
das mit einem Mastertakt weiterverarbeitet werden soll.

Lösung 1a) und 1b) ist eine recht unübliche Beschreibung eines 
Clock-Enables. Sieh dir mal die gängigen Lehrbücher an: findest du dort 
so einen Konstrukt? Falls die Antwort "Nein" lauten sollte: warum wohl 
nicht?
1
   if (Reseta = '0') then
2
      SPI_SR(15 downto 0) <= (others => '0');
3
      counter <= 0;
4
   elsif (SPI_Enable = '0') then
5
      if rising_edge(SPI_Clock) then
6
        :
Was da herauskommt ist in der Hardware wohl dem Zufall (oder eher dem 
Synthesizer) überlassen ...

Wie sieht dein SPI_Clock real aus?
Ist das ein "schönes" Signal oder hat der Überschwinger...?

Probiers doch mal so (abgeleitet von 1a):
1
signal SPI_SR : std_logic_vector(15 downto 0);
2
signal OUTPUT : std_logic_vector(15 downto 0);
3
4
begin
5
SchiebeReg : process(SPI_Clock)
6
begin
7
  if rising_edge(SPI_Clock) then -- steigende Flanke --> Bit einlesen
8
      SPI_SR <= SPI_SR(14 downto 0) & SPI_Data;
9
  end if;
10
end process;
11
12
Ausgabe : process(SPI_Enable)
13
begin
14
   if rising_edge(SPI_Enable) then -- deselektieren --> Daten übernehmen
15
      OUTPUT <= SPI_SR;
16
   end if;
17
end process;

EDIT:
Für ein CPLD ist das ok,
aber in einem FPGA wäre der 2. Takt schon ein Kündigungsgrund ;-)

von Volker (Gast)


Lesenswert?

>aber in einem FPGA wäre der 2. Takt schon ein Kündigungsgrund ;-)

das ganze hängt aber auch davob ab, wie das "externe Timing" seiner 
SPI-Signale zueinander ist (speziell SPI_Enable zu SPI_Clock).

>Wie sieht dein SPI_Clock real aus?
>Ist das ein "schönes" Signal oder hat der Überschwinger...?

Und die Flanke selbst muss sauber sein, also keine Treppenstufe.

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


Lesenswert?

> das ganze hängt aber auch davob ab, wie das "externe Timing" seiner
> SPI-Signale zueinander ist (speziell SPI_Enable zu SPI_Clock).
Ja, gut, dass nach den SPI_Enable (landläufig wohl eher SlaveSelect SS#) 
etwas Zeit vergangen sein sollte, bevor der Clock kommt, und vice versa 
bevor der SPI_Enable inaktiv wird, das sollte schon sichergestellt sein. 
Aber dafür gibt es ja Datenblätter von anderen SPI-Slaves. Da ist es 
hilfreich, wenn man sich sowas mal vorher anschaut.

>> Ist das ein "schönes" Signal oder hat der Überschwinger...?
> Und die Flanke selbst muss sauber sein, also keine Treppenstufe.
Und halbwegs akzeptable Anstiegszeiten haben...und nicht verrauscht 
sein...
Eben schön...  ;-)

@ daimlerfahrer
SPI sind gekoppelte Schieberegister. Damnach braucht SPI keinen Zähler 
für die Anzahl der übertragenen Bits. Das Ende der Übertragung wird über 
den SlaveSelect markiert. Die letzten davor übertragenen Bits werden 
intern weiterverarbeitet. Wenn du 56 Takte machst, dann werden also nur 
die Bits 41-56 verwendet, weil die beim Deselektieren im Schieberegister 
stehen.

von Der D. (daimlerfahrer)


Angehängte Dateien:

Lesenswert?

Zu aller erst bedanke ich mich mal für eure Hinweise.
Hier ein Screenshot des SPI-Signals, mit diesem Signal gehe ich davon 
aus, dass dies nicht der Fehler ist. Die Daten werden zur fallenden 
Flanke gesetzt und zur steigenden übernommen.

Den Zähler habe ich eingebaut um eine gewisse "Sicherheit" zu haben, 
dass ein kompletter Datensatz gesendet wurde.

In der Realität tauchen verschiedenen "Symptome" auf.

1. Es werden 90% der Daten richtig übernommen und bei 10% werden die 
Daten an die zuvor eingestellte Adresse gesendet.

2. Die Zähler-Sicherung greift viel zu oft und es werden kaum Daten 
übernommen

Problematischer für meine Anwendung sind eher falsch übernommene 
Datensätze als ausbleibende Daten.
Soll heissen - lieber kommt mal ein Datensatz NICHT an, als dass ein 
falscher ankommt.

von Gast (Gast)


Lesenswert?

@Der Daimlerfahrer
könnten ggf. die SPI-CLK Flanken unsauber sein?
Die steigende Flanke erkenne ich mindestens so:
1
if SPI_Clock_old2 = '0' and SPI_Clock_old1 = '1' and SPI_Clock = '1' then
und muss natürlich SPI_Clock 2 mal mit dem Systemtakt syncronisiert 
haben.

von Volker (Gast)


Lesenswert?

meine ich dies nur, aber ist auf der 3. und 6. steigenden Taktflanke 
nicht eine Stufe vorhanden? Kann zwar an der Auflösung des Bildes 
liegen, aber mach mal folgendes:

Code mal in VHDL nen kleinen Counter, der einfach die SPI-Taktflanken 
zählt und schau dann mal, ob das Ergebnis mit den tatsächlich gesendeten 
übereinstimmt.

von Volker (Gast)


Lesenswert?

>2. Die Zähler-Sicherung greift viel zu oft und es werden kaum Daten
>übernommen

Dann gib halt mal das Zählerergebnis im Fehlerfall aus, vieleicht ist 
man dann ein Stück schlauer.

von Der D. (daimlerfahrer)


Lesenswert?

Also nachdem ich den Zählerstand mal ausgegeben habe musste ich 
feststellen, dass mein SPI richtig detektiert wurde, obgleich eine 
fehlerhafte Ausgabe erfolgte.
Also SPI steht richtig, aber Ausgang steht falsch!

Dies brachte mich auf eine andere Fehlerursache: Meine kombinatorische 
Logik scheint teilweise zu lang zu brauchen. Demnach werden schon Werte 
an die Ausgänge übergeben, obgleich die "Weichenstellung" durch meine 
CASE Struktur noch nicht durchlaufen ist.
Nach dem heruntertakten des Clocks an dieser Stelle treten bisher keine 
Fehler mehr auf.

Ich war der Meinung im ISE gab es einer Stelle an der einem die maximal 
Mögliche Arbeitsfrequenz eines Design vorgegeben wird, finde es aber 
nicht mehr - weiss einer wo das steht?

Danke und Grüße!

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


Lesenswert?

Dein Stichwort ist: Timing-Constraints
Processes - User Constraints - Create Timing Constraints
Im Tab Global im Constraints Editor dann die Zykluszeit für den Takt 
eingeben.

Daraufhin findet sich in der UCF-Datei mit einem Eintrag wie z.B. für 
das Signal clk mit 100MHz:
NET "clk" TNM_NET = "clk";
TIMESPEC "TS_clk" = PERIOD "clk" 10 ns HIGH 50 %;

Das kann auch manuell in der UCF-Datei eingegeben werden.

Aber einen ersten Tip gibt schon die Synthese mit der Angabe der 
maximalen Taktfrequenz ab.

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.