Forum: FPGA, VHDL & Co. Datenbereitstellung für SPI


von King Julian (Gast)


Lesenswert?

Ich habe eine SPI Kommunikation zwischen einem FPGA und einem uC. Der uC 
ist der Master und kann per unterschiedliche Commands entwerder 
Datensätzte lesen oder schreiben.
Meine Frage, wie kann ich das auf dem FPGA sauber implementieren?
Momentan ist es so gelöst, dass die zu einem Command gehörenden Signale 
auf dem FPGA in Records gebündelt sind und das Command dann im Control 
Modul per Switch Case aufgrund der aktuellen Bytenumber des Frames das 
entsprechende Signal an den Ausgang legt respektive die neuen Daten ins 
Register schreibt.
Das gibt allerdings sehr viel ifs und whens und ich frage mich ob man 
das nicht sauberer lösen kann.

Ein shared memory wäre eventuell eine Möglichkeit aber da gewisse 
Signale quasi Echtzeit geschrieben werden (mit jedem Taktzyklus) stelle 
ich mir die Implementation da etwas schwirig vor.

Hat da jemand eine gescheite Idee?

von Klakx (Gast)


Lesenswert?

Es kann schon ein großes if/elsif Konstrukt werden, solang das Timing 
das mitmacht.

Ansonsten besteht auch die Möglichkeit eine Abstraktionsschicht höher zu 
gehen. Z.B. mit dem ersten SPI-Kommando adressieren und mit dem zweiten 
Kommando Lesen/Schreiben.

von King Julian (Gast)


Lesenswert?

Ich versuch es mal mit einem input und einem output memory, das sollte 
das Ganze etwas übersichtlicher machen.

Kann man in VHDL eigentlich substitutionieren? Also sowas wie
1
std_logic_vector(15 downto 8) & std_logic_vector(7 downto 0)
ersetzten durch
1
std_logic_vector(highbyte) & std_logic_vector(lowbyte)

?

von Duke Scarring (Gast)


Lesenswert?

King Julian schrieb:
> Kann man in VHDL eigentlich substitutionieren? Also sowas
> wie std_logic_vector(15 downto 8) & std_logic_vector(7 downto 0)
> ersetzten durch std_logic_vector(highbyte) & std_logic_vector(lowbyte)
Jein.
Du könntest aliase verwenden:
1
 alias highbyte : std_logic_vector(7 dowto 0) is slv16(15 downto 8);
2
 alias lowbyte  : std_logic_vector(7 dowto 0) is slv16( 7 downto 0);

Duke

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


Lesenswert?

King Julian schrieb:
> Momentan ist es so gelöst, dass die zu einem Command gehörenden Signale
> auf dem FPGA in Records gebündelt sind und.......
Mein erster Eindruck: du denkst viel zu abstrakt.

> Ein shared memory wäre eventuell eine Möglichkeit aber da gewisse
> Signale quasi Echtzeit geschrieben werden (mit jedem Taktzyklus) stelle
> ich mir die Implementation da etwas schwirig vor.
Wie wird denn in deinem Zielsystem so ein Shared Memory implementiert? 
Meinst du evtl. gar Shared Variable?

Letztlich ist eine SPI Übertragung was simples: du empfängst ein 
Kommando und sendest zugleich die Antwort auf das (Achtung, jetzt kommt 
der Trick:) vorhergehende Kommando. Du setzt also nach dem Empfang 
eines Kommandos ganz entspannt das Ergebnis zusammen und sendest dieses 
Ergebnis bei der nächsten Übertragung zurück (während du schon wieder 
ein neues Kommando empfängst).
Dann hast du echten Vollduplex Betrieb und quasi die doppelte Datenrate, 
weil du gleichzeitig sendest und empfängst. So wie es der SPI 
eigentlich vorsieht.

Wenn dir das Verfahren nicht ganz klar ist, dann sieh dir mal den AD7490 
an. Der macht es genau so.

> quasi Echtzeit
Wenn du eine halbwegs brauchbare Beschreibung hinlegst, dann ist 
Echtzeit locker etwas im 10ns Bereich. Ein Taktzyklus eben...

von King Julian (Gast)


Lesenswert?

Vielleicht war meine Problemstellung etwas gar umständlich.
Ich habe in meinem FPGA rund 80 8bit Register. Die Hälfte soll vom SPI 
Master schreibbar, die andere lesbar sein.
In einem SPI Frame werden jeweils ca. 20 Bytes zusammengefasst.

Nun war meine Idee mit einem Offset und einem Bytecounter quasi ein 
Memory "abzugrasen" anstatt effektiv für jedes 8bit Signal den Link zum 
entsprechenden SPI byte herzustellen.

Als Beispiel, ich empfange folgende Sequenz:

0x10 0x05 0x01 0x02 0x03 0x04 0x05

Nun ist das zu interpretieren als

0x10 Offset
0x05 Msg Length
0x01 - 0x05 Data Bytes

Was ist der sauberste Weg so eine Zuweisung zu realisieren?

von -gb- (Gast)


Lesenswert?

Musst Du überhaupt die Länge mit liefern? Man könnte das als Speicher 
bauen und wenn neue Daten reinkommen, wird ein Zeiger mit dem Offsetwert 
gesetzt und alles was danach kommt nacheinander in den Speicher 
geschrieben ab dieser Position.

von King Julian (Gast)


Lesenswert?

Ich brauch die Länge um zu wissen wann der CRC kommt

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


Lesenswert?

King Julian schrieb:
> Was ist der sauberste Weg so eine Zuweisung zu realisieren?
Nimm ein DPRAM und schreib oder ließ es byteweise ab dem Offset.
Dann brauchst du nur einen einzigen Zeiger mit 7 oder 8 Bit, der mit dem 
Offset geladen und hinterher nach jedem Byte inkrementiert wird.
Eine kleine FSM verwaltet das Ganze.

von Pandur S. (jetztnicht)


Lesenswert?

Wenn du Messages mit variabler Laenge bearbeiten willst bist du 
eigentlich schon bei einem Controller und bearbeitest Microcode. Fuer 
SPI braucht man keinen CRC, weil SPI sowieso nur kurze Laengen hat, 
maximal ueber eine Leiterplatte, nie ueber einen Stecker.

Was soll's denn werden ?

von King Julian (Gast)


Lesenswert?

Ob der CRC notwendig ist oder nicht darf sicher diskutiert werden. Da 
das FPGA aber keinesfalls falsche Daten in den Registern haben darf, 
haben wir uns mal für einen CRC entschieden. Es ist ein Controller für 
optische in/outputs. Über das Webinterface soll das Verhalten 
parametrisierbar sein.

Wie stell ich bei einem DP Ram sicher, dass nicht gelesen und 
geschrieben gleichzeitig wird? Oder ist das gar kein Problem?
In diesem Fall bräuchte ich zwei DPRAM oder? Eines für die eingehenden 
Daten (write port auf Seite SPI) und eines für die ausgehenden Daten 
(read port auf Seite SPI).

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


Lesenswert?

King Julian schrieb:
> Da das FPGA aber keinesfalls falsche Daten in den Registern haben darf
Wir drehen uns im Kreis...
> haben wir uns mal für einen CRC entschieden.
Wenn ich der Projektleiter wäre, würde ich ein besseres Argument hören 
wollen.

> Wie stell ich bei einem DP Ram sicher, dass nicht gelesen und
> geschrieben gleichzeitig wird? Oder ist das gar kein Problem?
Es ist kein Problem im Sinne eines atomaren Zugriffskonflikts. Du liest 
entweder das alte oder das neue Byte.
Allerdings ist es ein Problem, wenn die gerade gelesenen Daten Teil 
eines größeren Konstrukts sind und z.B. 4 Bytes zusammen gehören. Dann 
ist es durchaus kritisch, wenn die Hälfte alte und die andere Hälfte 
neue Daten enthält. Aber dieses Semaphorenproblem ist besonders aus der 
Softwareentwicklung allseits bekannt und muss durch passende Sperr- und 
Freigabemechanismen behandelt werden.

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.