Forum: FPGA, VHDL & Co. Wieder einmal CRC32


von Thomas B. (thomas1)


Lesenswert?

Ich habe von http://www.electronicdesignworks.com den CRC32-Generator 
für Ethernet generieren lassen (VHDL-Code), weil es mir zu hoch war, den 
Algorithmus selber zu schreiben.
Allerdings ist mir immer noch schleierhaft, in welcher Reihenfolge die 
Bits in den Generator geschoben werden, und welche invertiert werden 
müssen. Kann mir da jemand klipp und klar erklären, wie die 
Spezifikation für eine gültige Ethernet-FCS ist?

Einige Ansätze habe ich zusammengeklaubt, bei denen ich mir jedoch nicht 
sicher bin!
- Ziel MAC-Adresse invertieren
- CRC am Schluss wieder invertieren
- Vom MSB des obersten Bytes der Ziel-MAC bis zum LSB des untersten 
Datenbytes werden die Bits in den CRC Generator geschoben

Bitte korrigiert mich!

Wir können das ganze ja mal an einem Diskussionsbeispiel angucken:
Ziel-MAC (Broadcast) : 0xFFFFFFFFFFFF
Quell-MAC            : 0x02FFFFFFFFFF
Ethertype (IPv4)     : 0x0800
Daten                : 0xAFFE0000000... restliche Bytes bis 46 sind 0x00

Das gibt folgendes Ethernetframe (für CRC ja bekanntlich ohne Präambel 
und SFD):
0xFFFFFFFFFFFF02FFFFFFFFFF0800AFFE12345678900000000000000000000000000000 
00000000000000000000000000000000000000000000000000

Also, wie werden da die Bits nun verarbeitet?

Vielen Dank

von Thomas B. (thomas1)


Lesenswert?

Hoppla, ein Fehler!!!

> Das gibt folgendes Ethernetframe:
0xFFFFFFFFFFFF02FFFFFFFFFF0800AFFE00000000000000000000000000000000000000 
00000000000000000000000000000000000000000000000000

von Thomas B. (thomas1)


Lesenswert?

Oder hat vielleicht jemand einen Core-Generator implementiert, der auf 
Anhieb einwandfrei funktionierte?
Wenn ja, welchen? Und wie steuert Ihr ihn an?

Danke.

von D. I. (Gast)


Lesenswert?

Also ich finde hier ist das doch gut erklärt:

http://de.wikipedia.org/wiki/Ethernet#FCS_.28Frame_Check_Sequence.29

von Thomas B. (thomas1)


Lesenswert?

Es wäre sehr hilfreich, wenn mir jemand am oben aufgeführten Beispiel 
die CRC32 Generierung vorführen könnte...

Merci

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

Thomas B. schrieb:
> Es wäre sehr hilfreich, wenn mir jemand am oben aufgeführten Beispiel
> die CRC32 Generierung vorführen könnte...
>
> Merci

Beitrag "Ethernet GMII"

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

Schau dir die ether_tx.vhd aus dem Beitrag "Ethernet GMII" an.
Diese CRC32 Berechnung läuft.

Zu deinen Fragen.
Die ersten 32 bit sind negiert.

Einige Ansätze habe ich zusammengeklaubt, bei denen ich mir jedoch nicht
sicher bin!
- Ziel MAC-Adresse invertieren
Richtig. Nur wenn die Register auf 0x0 intialisiert werden.
Werden die Register mit 0xFFFFFFFF im Reset gefüllt dann werde die 
ersten einlaufenden Bits negiert und die sind genau so lang wie die Ziel 
Mac-Adresse. Das ist der Grund warum im Reset 0xFFFFFFFF alles geset 
wird. Dann muss nicht die ZielMac negiert werden. Optimierung Nummer 
eins.


- CRC am Schluss wieder invertieren
Ja. Siehe auch ether_tx.vhd

- Vom MSB des obersten Bytes der Ziel-MAC bis zum LSB des untersten
Datenbytes werden die Bits in den CRC Generator geschoben

Reihenfolge weiss ich jetzt auch nicht au dem Kopf.
Steht auch in der ether_tx.vhd

von Thomas B. (thomas1)


Lesenswert?

@ René D.

Du gibst ja der CRC-Funktion 8 Bit Daten hinein, und Dein Ethernetframe 
ist mindestens 64 Bytes, bzw. 60 Bytes ohne CRC.
In welcher Reihenfolge schickst Du die Bytes hinein?

Meine Idee ist, den CRC-Generator gerade laufend mit den Daten zu 
füttern, die ich auf das MII setze. Wenn dann die CRC-Übertragung an die 
Reihe kommt, steht mir die neue CRC gerade zur Verfügung.

Wie kann man das mit Deiner Funktion bewerkstelligen?
1
function crc (data_in:std_logic_vector (7 downto 0); crc_value:std_logic_vector(31 downto 0))  return std_logic_vector is
2
--http://de.wikipedia.org/wiki/Zyklische_Redundanzpruefung
3
--sehr gutes C Beispiel!!!!!
4
--G(X)=x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
5
variable crc_out: std_logic_vector(31 downto 0);
6
7
begin
8
9
   crc_out:=crc_value;
10
  for k in 0 to 7 loop 
11
    if crc_out(0) /=data_in(k) then
12
      crc_out:=('0'& crc_out(31 downto 1)) xor X"EDB88320";
13
    else
14
      crc_out:=('0'& crc_out(31 downto 1));
15
    end if;
16
  end loop;
17
  return crc_out;
18
end crc;

Irgendwie habe ich ja nach jedem Byte, das ich durch die Funktion lasse, 
eine CRC, die ich beim nächsten Byte wieder berücksichtigen muss!

Exgüse, wenn ich mich etwas schwer tue, mit dieser CRC32...

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.