Hallo! Ich versuche mich gerade an einem SPI-Slave Device auf einem Cyclone 2. Es soll zum Test immer ein konstantes Muster "01101001"=0x69 auf MISO ausgebegen werden. Der MOSI wird jetzt mal ignoriert. Ich verwende die klassischen Signale MISO,MOSI,nCS und SCK. Bei jeder fallenden Flanke von SCK wird das nächste Bit von TEST_DATA an MISO ausgegeben und soll vom SPI an der steigenden gelesen werden. Auf einem ATmega wäre das CPOL=CPHA=0. Die fallende Flanke wir mittels 4 Samples ermittelt. CLK ist 50Mhz direkt aus einem Oszillator ohne PLL. (Laut Quartus schafft das Design ca. 250MHz). Der SPI-Master ist ein STM32F103 mit SCLK von 1,125MHz, der in einer Schleife ein Byte per SPI sendet. Jetzt habe ich das Problem, dass ich in ca. 30% der Fälle nicht "0x69" zurückbekomme, sondern etwas größer als 0x70. Könnte sich jemand bitte meine Design ansehen. Ich weiß nicht, was daran fasch sein könnte. (Das Bild im Anhang ist aus der post-layout Simulation) Danke!
Frage: wo kommt dein Reset her? Ist er einsyncronisiert? Beitrag "Re: Reset für mehrere Komponenten" > process(CLK, RESET) > > variable sck_act, sck_prev, sck_prev_2, sck_prev_3: std_logic := '0'; > variable cycle_count: natural range 0 to 7; > variable start_transmission: std_logic := '0'; > > begin > > if RESET = '0' then > > MISO <= '0'; > TEST_DATA <= "01101001"; > > cycle_count := 0;
Hallo, du verwendest in deinem Design Variablen falsch. In VHDL dienen sie nicht zum Speichern von Daten. Das wird aber nicht das Problem verursachen. Wenn deine Daten unterschiedlich vom Master verstanden werden, dann wirst du die Setup/Hold Zeiten nicht einhalten. D.h. die Daten ändern sich an der Flanke, die zum Einlesen dient. Sieh noch einmal nach, ob der Master wirklich an der steigenden Flanke liest. Achso, ein synchrones Design braucht keine *Timing*-Simulation. Tom
Fire Eagle schrieb: > Hallo! > > Ich versuche mich gerade an einem SPI-Slave Device auf einem Cyclone 2 Hmm, ja, netter Versuch... Ist dir eigentlich klar, dass SPI nur gekoppelte Schieberegister sind? Dass da also kein Zähler und kein Multipexer drin vorkommt? http://www.lothar-miller.de/s9y/categories/17-SPI Ich mach das in einem CPLD so: http://www.lothar-miller.de/s9y/categories/26-SPI-Slave Allerdings muss ich zugeben, dass ich im FPGA den SS einsynchronisieren und dann die Daten synchron übernehmen würde... > Jetzt habe ich das Problem, dass ich in ca. 30% der Fälle nicht "0x69" > zurückbekomme, sondern etwas größer als 0x70. Und zwar was genau? Immer das selbe oder immer ganz was anderes? Oder gibt es da ein Muster? > Könnte sich jemand bitte meine Design ansehen. Ich weiß nicht, was daran > fasch sein könnte. Warum diese überaus ausgiebige Verwendung von Variablen? Sieh mal den Beitrag "Variable vs Signal" an. > (Das Bild im Anhang ist aus der post-layout Simulation) Mach in Zukunft einfach nur eine funktionale Simulation, das reicht...
Thomas Reinemann schrieb: > Achso, ein synchrones Design braucht keine *Timing*-Simulation. Das wiederum halte ich fuer eine gewagte These... Lothar Miller schrieb: > Warum diese überaus ausgiebige Verwendung von Variablen? Das duerfte dann auch wohl fuer die Probleme sorgen, vor allem folgendes:
1 | sck_act := SCK; |
2 | if sck_prev_3='1' and sck_prev_2='1' and sck_prev='0' and sck_act='0' then |
Mit 'sck_act' bist du hier nicht am FF-Ausgang, sondern du verwendest den FF-Eingang (da variable)! Viel Spass mit Setup-Violations. Mach' das ganze mal mit signal und am besten noch mit einem std_logic_vector (x downto 0) und synchronisiere mit
1 | sck_sr <= sck_sr (x-1 downto 0) & SCK |
ein.
Lothar Miller schrieb: > Ist dir eigentlich klar, dass SPI nur gekoppelte Schieberegister sind? > Dass da also kein Zähler und kein Multipexer drin vorkommt? PS: Es kommt haeufig vor, dass man mit den seriellen Daten auf dem MOSI irgendwas dekodieren muss; also der MISO stream muss dynamisch aufgebaut werden. Dann geht es mit 'dummem' Schieberegister nicht mehr. Ist hier zwar Overkill, aber nicht grundsaetzlich falsch oder ungewoehnlich
Achja, und selbst wenn du diese Zeile:
1 | if sck_prev_3='1' and sck_prev_2='1' and sck_prev='0' and sck_act='0' then |
mit einem signal und Schieberegister machst, also z.B.:
1 | sck_sr <= sck_sr (2 downto 0) & SCK; |
2 | if sck_sr = b"1100" then ... |
dann kannst du dir boese Probleme einfangen. Warum: Du kommst von einem stabilen SCK und willst einen Flankenwechsel detektieren (das steht da oben). Wenn du jetzt aber Stoerungen (z.B. Ringing durch falsche Impedanzanpassung) hast, dann koennte dein SR auch den Wert b"1101" haben (ein Spike auf SCK). Ich frage beim SR immer so ab, dass ich das geaenderte Signal nur in einem FF habe, also z.B.:
1 | if sck_sr (3 downto 1) = b"110" |
oder auch
1 | if sck_sr (3 downto 0) = b"1110" |
Du bist dann weniger empfindlich ggue. Spikes...
berndl schrieb: > Thomas Reinemann schrieb: >> Achso, ein synchrones Design braucht keine *Timing*-Simulation. > > Das wiederum halte ich fuer eine gewagte These... Nein ist nicht gewagt. Für synchrone Designs braucht man in 99,9% der Fälle eine *Verhaltens*-simulation und eine statische Timinganalyse.
Klaus schrieb: >>> Achso, ein synchrones Design braucht keine *Timing*-Simulation. >> >> Das wiederum halte ich fuer eine gewagte These... > > Nein ist nicht gewagt. Für synchrone Designs braucht man in 99,9% der > Fälle eine *Verhaltens*-simulation und eine statische Timinganalyse. ups, das hatte ich oben falsch gelesen/interpretiert/getraeumt, sorry Thomas+Klaus. Ihr habt natuerlich recht.
berndl schrieb: > PS: Es kommt haeufig vor, dass man mit den seriellen Daten auf dem MOSI > irgendwas dekodieren muss; also der MISO stream muss dynamisch aufgebaut > werden. Dann geht es mit 'dummem' Schieberegister nicht mehr. Ich kann das... ;-) Denn wenn ich hinterher das Schieberegister sowieso parallel brauche, dann kann ich die Mustererkennung auch direkt auf das Schieberegister loslassen. Funktioniert bei einigen von mir implementieren seriellen Protokollen tadellos. berndl schrieb: > if sck_sr = b"1100" then ... > dann kannst du dir boese Probleme einfangen. Warum: Du kommst von einem > stabilen SCK und willst einen Flankenwechsel detektieren (das steht da > oben). Wenn du jetzt aber Stoerungen (z.B. Ringing durch falsche > Impedanzanpassung) hast, dann koennte dein SR auch den Wert b"1101" > haben (ein Spike auf SCK). Das habe ich da auch mal als "kritischen Fall" aufgeführt: http://www.lothar-miller.de/s9y/archives/18-Flinke-Flankenerkennung.html Aber das sollte nicht zu 30% Fehlerrate führen können. Und wenn du in einem SPI z.B. durch schlechtes Leiterplattendesign Spikes hast, dann kann dir mit käuflichen Bausteinen sowieso alles möglich passieren. btdt... :-(
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.