Forum: FPGA, VHDL & Co. Usb Checksumme (CRC5)


von Johannes T. (johnsn)


Lesenswert?

Hallo!

Ich versuche gerade die - an sich einfache - CRC5 für Usb in VHDL zu 
implementieren. Begonnen hätte ich mal damit die Polynomdivison händisch 
durchzuführen, allerdings komme ich da auf kein gültiges Resultat.

Was mich dabei verwirrt ist die Sache, dass Usb, die einzelnen 
Informationen LSB first schickt. Bedeuted das jetzt das das 
Generatorpolynom x5+x2+1 (100101) auch gespiegelt werden muss?

Warum wird im USB2.0 Standard erwähnt, "The binary bit pattern that 
represents this polynomial is 00101B", obwohl das doch 100101 sein 
müsste?

Beispiel aus http://www.usb.org/developers/whitepapers/crcdes.pdf
1
LSB       MSB
2
|           |
3
1000.0000.000 ... 11 Bit, die geprüft werden sollen.
4
1001.01       ... Generatorpolynom CRC5 (Usb)
5
6
Berechnung:
7
8
1000.0000.0000.0000
9
1001.01
10
--------
11
   1.0100.0
12
   1.0010.1
13
   --------
14
      110.100
15
      100.101
16
      -------
17
       10.0010.
18
       10.0101.
19
       --------
20
           111.000
21
           100.101
22
           -------
23
            11.1010
24
            10.0101
25
            -------
26
             1.1111 ... CRC5
27
       
28
Rückrechnung (check):
29
30
1000.0000.0001.1111
31
1001.01
32
-------
33
   1.0100.0
34
   1.0010.1
35
   --------
36
      110.100
37
      100.101
38
      -------
39
       10.0011.
40
       10.0101.
41
       --------
42
           110.111
43
           100.101
44
           -------
45
            10.0101
46
            10.0101
47
            -------
48
                  0 ... korrekt!

In diesem Whitepaper (siehe Link) steht aber, dass die Checksumme 10111 
sein sollte und nicht 11111. Allerdings stimmt doch meine Berechnung, 
oder wo liegt hier ein Fehler?

von Alban (Gast)


Lesenswert?

Hast du dir mal das Projekt auf opencores angesehen um zu vergleichen 
wie es dort gemacht wird?

Vieleicht hilft das ja?

von Johannes T. (johnsn)


Lesenswert?

Hi,

danke für den Tipp. Wenn du das Projekt "USB 1.1 Host and Function IP 
core" in Verilog geschrieben meinst, ja! Der Kollege lässt sich hier 
aber die Checksumme rein kombinatorisch ausrechnen, was meiner Meinung 
nach sehr ineffizient ist und zuviel Platz braucht. Die Implementierung 
funktioniert zwar (portiert auf VHDL und Modelsim), aber ich würde das 
ganze gerne mit Registerstufen machen und darüber hinaus meinen 
Denkfehler finden.

Bin für jeden Ratschlag dankbar.

von Alban (Gast)


Lesenswert?

Ich nehme mal deinen 1. Post:

>Was mich dabei verwirrt ist die Sache, dass Usb, die einzelnen
>Informationen LSB first schickt. Bedeuted das jetzt das das
>Generatorpolynom x5+x2+1 (100101) auch gespiegelt werden muss?

Nein. Der CRC wird immer in der gleichen Reihenfolge berechnet. Am 
einfachsten kannst du dir das mit einer LFSR Implementierung vorstellen. 
Wenn jetzt wie bei USB die Daten LSB first geschickt werden, dann kommt 
als 1. Bit das LSB an, aber am Polynomial wird nichts gedreht.

>Warum wird im USB2.0 Standard erwähnt, "The binary bit pattern that
>represents this polynomial is 00101B", obwohl das doch 100101 sein
>müsste?

Ich hab hier ein Buch "Advanced Digital Logic Design" von Sunggu Lee, da 
beschäftigt sich ein Kapitel mit einem USB Analysator. Dort steht 
geschrieben:

"... the 5-bit generator polynomial used is G5(x) = x^5 + x^2 + 1 (= 
00101 as a 5-bit vector; the x^5 position is implicit)."

Vielleicht hilft das die andere Bitfolge zu erklären?

Zur Berechnung, die in dem Buch über LFSR beschrieben wird, dort werden 
alle Register auf 1 initalisiert. Jetzt weiss ich nicht genau wie du das 
bei deiner Berechnung einbauen musst.

Vielleicht hilft das etwas.

von Johannes T. (johnsn)


Lesenswert?

@Alban:

- Das mit der Reihenfolge ist mir jetzt klar.
- Die Sache mit x5 + x2 + 1 = 00101, auch.

Doch trotzdem komme ich mit der händischen Berechnung (siehe oben) nicht 
auf das gewünschte Ergebnis, obwohl der CRC-Check beim Empfänger ja dann 
richtig ist!

Eine Implementierung habe ich auch bereits gemacht, nämlich genau mit 
LFSR, dabei kann man die CRC quasi rücksetzen und für ein neues Paket 
bereit machen, indem man alle Register auf 1 setzt. Das gemeine ist 
jetzt, das diese Implementierung auch funktioniert, ich will das ganze 
aber auch händisch berechnen können.

von Alban (Gast)


Lesenswert?

Ich hab mal das folgende Beispiel von dem Dokument das du angegeben hast 
durchgerechnet und es scheint zu stimmen.
1
crc5 1000 0000 000
2
10111

Beide Werte scheinen mit LSB links geschrieben zu sein. Da alle Register 
im LFSR auf 1 initalisiert werden, hab ich das der Berechnung 
vorangestellt.

Für die Berechnung ist jetzt LSB rechts:
1
1111.1110.0000.0000.0
2
1001.01
3
-------
4
 110.101
5
 100.101
6
 -------
7
  10.0000
8
  10.0101
9
  -------
10
      101.000
11
      100.101
12
      -------
13
        1.1010.0
14
        1.0010.1
15
        --------
16
          1000.10
17
          1001.01
18
          --------
19
             1.1100.0
20
             1.0010.1
21
             --------
22
               1110.1   <--- Rest  [msb..lsb]

In dem Dokument gehe ich davon aus das der Rest genauso wie der 
Eingabewerte [lsb..msb] angeben ist.

von Johannes T. (johnsn)


Lesenswert?

Danke vielmals!! Soweit hab ich nicht gedacht, dass ich diese 
Initialwerte auch bei der händischen Berechnung berücksichtigen soll. 
Damit wäre der Fall nun gelöst.

Gruß,
Johnsn

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.