Forum: FPGA, VHDL & Co. CRC-Check in VHDL und C#


von CRC-Neuling (Gast)


Lesenswert?

Hallo Zusammen,
ich möchte für ein Projekt 64 Bit Daten (inkl. CRC) von einem FPGA 
mittels SPI an einen Raspberry Pi senden. Das Senden der Daten klappt 
bereits Prima und ich habe am Ende des 64 Bit langen Datenstranges noch 
bis zu einem Byte Platz um ein CRC zu übertragen.
Bei meinen Recherchen für ein geeignetes CRC-Verfahren bin ich auf viele 
Möglichkeiten gestoßen, jedoch nie auf ein CRC-Beispiel, das in 
kombination einmal als VHDl-Code für den FPGA und einmal in C# für den 
Raspberry Pi gezeigt wird.
Hat jemand so etwas schon einmal gemacht und könnte mir behilflich sein.
Generatorpolynom und Art des CRC-Verfahrens sind mir nicht so wichtig, 
auschlaggebend ist das es korrekt Funktioniert und Fehler feststellt.

Bastlerische Grüße

von CRC-Neuling (Gast)


Lesenswert?

Edit: Es wären auch 2 Byte frei um ein CRC16 mit zu senden

von Strubi (Gast)


Lesenswert?

Einen CRC32 findest du in jedem Ethernet-Core, und da auch immer mit dem 
gleichen Polynom. Bei so wenigen Daten macht's wohl Sinn, ihn über die 
ganze Sequenz zu berechnen/mitzuführen.
Vorsicht, bei CRC16, da gibts auch eine "kaputte" Variante, die fast 
gleich aussieht, da auf jeden Fall die CRC16-CCITT-Variante nehmen.

von Strubi (Gast)


Lesenswert?

Oh, erst jetzt richtig gelesen: Den CRC32 müsstest du dann wohl auf ein 
Byte runter 'verhashen'.

von Michael (Gast)


Lesenswert?

Und eine VHDL Version kann man hier erstellen:
http://www.easics.com/services/freesics/crctool.html

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


Lesenswert?

CRC-Neuling schrieb:
> auschlaggebend ist das es korrekt Funktioniert und Fehler feststellt.
Bei einem vernünftig ausgelegten SPI Interface wird dieser Fehlerzähler 
auf 0 bleiben. Warum willst du 16 Bits Overhead auf 64 Bit Nutzdaten 
setzen?
Spar dir die Rechenzeit für die CRC (irgendwie muss man den RPi auch 
langsam bekommen). Nimm stattdessen einfach ein Bit und erweitere auf 
gerade/ungerade Parität.

> ich möchte für ein Projekt 64 Bit Daten (inkl. CRC) von einem FPGA
> mittels SPI an einen Raspberry Pi senden.
Du hast aber sinnvollerweise schon den SPI Master im RPi und den Slave 
im FPGA?

von Andi (Gast)


Lesenswert?

Anstatt einer CRC kannst du auch einfach eine Prüfsumme bilden. Es 
werden alle übertragenen Bytes aufsummiert und dabei die Überläufe auf 
höherwertige Bytes ignoriert. Das Summenbyte wird dann als letztes Byte 
übertragen.
Das ist nicht ganz so sicher wie eine CRC aber für deine Zwecke allemal 
gut genug. (Wird z.B auch bei Modbus-ASCII verwendet).

Andi

von CRC-Neuling (Gast)


Lesenswert?

Lothar M. schrieb:
> Du hast aber sinnvollerweise schon den SPI Master im RPi und den Slave
> im FPGA?

Jap, das funktioniert auch ohne Probleme und wahrscheinlich wird der 
Fehlerzähler auch auf 0 bleiben, aber zum lernen und verstehen und für 
eine erhöhte Sicherheit kann es nicht so schlecht sein das mal zu machen 
dachte ich mir.

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


Lesenswert?

CRC-Neuling schrieb:
> zum lernen und verstehen und für eine erhöhte Sicherheit kann es nicht
> so schlecht sein das mal zu machen
Fürs erstere und das zweite stimmt das. Aber du darfst das niemals 
tatsächlich in der Hardware brauchen. Denn falls doch, dann ist darin 
ein Designfehler. Und sei es nur der falsche SPI Mode...

von M. Н. (Gast)


Lesenswert?

Strubi schrieb:
> Einen CRC32 findest du in jedem Ethernet-Core

Eine Ethernet FCS ist keine "astreine" CRC. Sie arbeitet minimal anders 
als ein purer CRC-Algorithmus.

Solltest du die 4 Byte für die CRC übrig haben ( kannst auch beide 
hälften x-odern, dann hast du eine 16 bit Prüfsumme, die allerdings eine 
geringere Hammingdistanz hat)

Diser VHDL Core funktioniert für eine Ethernet FCS:

https://github.com/pabennett/ethernet_mac/blob/master/source/CRC.vhd

C Code (Geht auch in C#, mit eventuellen minimalen Änderungen):

http://www.edaboard.com/thread120700.html

1. Antwort

Beide Code Snippets habe ich selbst getestet und arbeiten wie gefordert.

von CRC-Neuling (Gast)


Lesenswert?

Lothar M. schrieb:
> niemals
> tatsächlich in der Hardware brauchen

Macht man einen CRC-Check nicht auch um Fehler die durch äußere 
Störeinflüsse auf die Leitung ect. im schlimmsten Fall erkennen zu 
können oder hab ich da was vertauscht?

Ich habe es jetzt gelöst mit CCRC16-CCIT X-Modem,
für den FPGA mittels dem hier bereits erwähnten link:
http://www.easics.com/services/freesics/crctool.html
für den Raspberry in C# durch das einbinden dieses Codes in mein 
Programm:
http://www.sanity-free.com/133/crc_16_ccitt_in_csharp.html
und zum Nachrechnen habe ich mir ein Excel-Sheet erstellt bzw. diese 
Internetseite benutzt:
https://www.lammertbies.nl/comm/info/crc-calculation.html

Das einzig "komische" ist das bei der C# Funktion die beiden Bytes des 
CRC-Wertes Exakt vertauscht sind. Das habe ich aber durch vertauschen 
der Bytes vor dem vergleichen mit dem mitgesendeten CRC-Wert gelöst.

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


Lesenswert?

CRC-Neuling schrieb:
> Macht man einen CRC-Check nicht auch um Fehler die durch äußere
> Störeinflüsse auf die Leitung ect. im schlimmsten Fall erkennen zu
> können oder hab ich da was vertauscht?
Schon. Aber dann müsstest du für die "absolute Sicherheit" an jeden noch 
so kurzen Bus eine CRC schnallen.

Letztlich musst du für einen akzeptablen Aufwand also bis zu einer 
bestimmten Ebene von einer fehlerfreien Übertragung ausgehen. Und hier 
ist ein SPI Bus mit einem parallelen Adress-Datenbus gleichsetzbar, 
weil/wenn er die selbe Physik verwendet.

Oder andersrum: eine CRC zur Fehlererkennung oder gar Fehlerkorrektur 
macht man nur, wenn die Übertragungsstrecke mit einer signifikanten 
Wahrscheinlichkeit einen Fehler bringen wird (z.B. Ethernet wegen EMV 
oder wackeligen Steckern). Und zudem auch nur dann, wenn die Übertragung 
einmalige Daten übermittelt.
Wenn mit dem SPI z.B. zyklisch Eingänge gelesen werden, dann ist jeder 
Aufwand für die Datensicherheit unnötig, weil sowieso bald frische und 
aktuellere Daten hereinkommen.

Wie gesagt: für einen sauber designten SPI Bus ist eine CRC unnötig. 
Zigmilliarden Geräte beweisen es.

CRC-Neuling schrieb:
> Das einzig "komische" ist das bei der C# Funktion die beiden Bytes des
> CRC-Wertes Exakt vertauscht sind. Das habe ich aber durch vertauschen
> der Bytes vor dem vergleichen mit dem mitgesendeten CRC-Wert gelöst.
Hört sich irgendwie nach little und big endian und daraus resultierend 
irgendwie "hingebastelt" an. Wenn das das Lernziel der ganzen Aktion 
war...

: Bearbeitet durch Moderator
von CRC-Neuling (Gast)


Lesenswert?

Lothar M. schrieb:
> little und big endian

Wäre dann nicht das CRC-Ergebnis ein ganz anderes. Die Daten die ich in 
die C#-Funktion übergebe sind auf jedenfall Richtig herum, diese habe 
ich mir ausgeben lassen. Leider verstehe ich die Bildung des CRC-Wertes 
innerhalb der Funktion noch nicht ganz weshalb ich nicht weis woher der 
Dreher kommt.

Aber Sie haben recht, dass das nicht das Lernziel sein kann aber bis ich 
die Lösung gefunden habe ist es für mich eine akzeptable zwischenlösung.

von CRC-Neuling (Gast)


Lesenswert?

Gebe ich in die CRC-Funktion den gesamten Datenstrom (mit mitgesendetem 
CRC), so kommt als Ergebnis immer 0. Dies ist ja auch korrekt. Ich 
glaube der "Fehler" entsteht dadurch das die C# Funktion den CRC-Wert 
als unsigned short berechnet und dann mit der Methode 
BitConverter.GetBytes in zwei Bytes umwandelt. Diese macht zum Beispiel 
aus dem Wert 15 die Bytes 0F-00, also stellt das LSByte nach vorn.

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.