Forum: FPGA, VHDL & Co. CRC kombinatorisch berechnen


von Ronaldo (Gast)


Lesenswert?

Hallo zusammen,

ich stehe gerade vor einem Problem und habe keine Idee, wahrscheinlich 
feiert mein Gehirn schon Weihnachten :)

Ich habe einen 64bit Datenbus mit einem valid Signal.

Für dieses Datenpaket möchte ich innerhalb eines Taktes byteweise eine 
CRC16 berechnen. Ich müsste also combinatorisch 8 CRC Berechnungen 
durchführen.

Mit dem Tool von easics.com werden mir zahlreiche XOR Gatter augespuckt. 
Diese lassen sich natürlich kombinatorisch verschalten.

Ich habe leider nicht nicht viel mit Variablen gearbeitet. Bisher konnte 
ich immer alles sauber mit Signalen lösen. Aber an dieser Stelle werde 
ich wohl nicht drum herumkommen ;)

Kann mir jemand erklären, wie ich für die CRC Berechnung den Index des 
Datenbusses verändern kann, damit ich mir das zu berechnende Byte 
herauspicken kann?

Wäre das eine Idee?
1
PROCESS
2
BEGIN
3
  v_newcrc(0) := v_oldcrc(0) XOR v_oldcrc(3) XOR DATA(3+v_index*8) XOR DATA(0+v_index*8) ...
4
  -- hier dann die ganzen anderen XOR Glieder etc.
5
6
  v_oldcrc := v_newcrc;
7
  IF v_index<8 THEN
8
    v_index := v_index + 1;
9
  ELSE
10
    s_ergebnis_crc <= v_newcrc;
11
  END IF;
12
END PROCESS;

Kommt das irgendwie so hin, oder muss ich da noch mehr mit den Variablen 
machen, damit da was sinnvolles bei raus kommt?
Freilich ist das noch kein sauberes und synthetisierbares VHDL, aber 
stimmt die Idee weitestgehend? Wie kann ich v_index sauber wieder auf 0 
setzen für den nächsten "Durchlauf", ohne dass mir hier 10000 CRCs 
berechnet werden?

Das hier ein großes Konstrukt entsteht, wo das Timing kritisch werden 
könnte, ist mir bewusst. Die Taktrate ist aber gering genug, so dass es 
aufgehen sollte.

Vielen Dank!
Ron

von Falk B. (falk)


Lesenswert?

@ Ronaldo (Gast)

>Ich habe einen 64bit Datenbus mit einem valid Signal.

>Für dieses Datenpaket möchte ich innerhalb eines Taktes byteweise eine
>CRC16 berechnen. Ich müsste also combinatorisch 8 CRC Berechnungen
>durchführen.

Dafür nutzt man eine Tabelle, bzw. ROM. Siehe CRC.

>Kann mir jemand erklären, wie ich für die CRC Berechnung den Index des
>Datenbusses verändern kann, damit ich mir das zu berechnende Byte
>herauspicken kann?

Das wird so einfach nicht gehen, dann dazu brauchst du 8 ROMs. Die 
Druchlaufzeiten addieren sich. Sonderlich schnell wird das nicht, dazu 
muss man Pipelining nutzen.

>Das hier ein großes Konstrukt entsteht, wo das Timing kritisch werden
>könnte, ist mir bewusst. Die Taktrate ist aber gering genug, so dass es
>aufgehen sollte.

Zahl? Siehe Netiquette.

von Ronaldo (Gast)


Lesenswert?

Hallo Falk und vielen Dank!

Falk Brunner schrieb:
> Dafür nutzt man eine Tabelle, bzw. ROM. Siehe CRC.
Die Grundlagen vom CRC sind mir weitestgehend bekannt.
Es geht mir lediglich um die Vorgehensweise, wenn ich 8 CRC Berechnungen 
ungetaktet hintereinander ausrechnen möchte.
Ich bekomme also auf einen Schlag 64 Bit und möchte das gleiche Ergebnis 
haben, als wenn ich 8 Byte hintereinanderweg verrechnen würde.
Getaktet klappt das schon gut. Ich nehme meine 64bit, greife mir immer 
ein Byte heraus und schiebe es in die CRC XOR Verknüpfungen rein. Das 
Ergebnis wird dann mit dem nächsten Byte aus dem 64 Bit Vektor 
verrechnet und nach 8 Rechenschritten habe ich meine Prüfsumme.
8 Takte sind leider nur zu langsam, da dann schon die nächsten Daten am 
Eingang anliegen können und so wollte ich mich mal nach Ideen umschauen, 
wie ich das beschleunigen kann. Daher der Ansatz alles in einem Takt 
abzuhandeln.
Statt 8 Takte und 1 XOR Netz brauche ich dann 1 Takt mit 8 XOR Netzen...

> Das wird so einfach nicht gehen, dann dazu brauchst du 8 ROMs. Die
> Druchlaufzeiten addieren sich. Sonderlich schnell wird das nicht, dazu
> muss man Pipelining nutzen.
Das sich die Durchlaufzeiten addieren ist mir bewusst. Es sind ja statt 
einer CRC Berechnung nun 8, also habe ich auch 8 hintereinander 
geschaltete XOR Netze... das ist der Preis von paralleler Logik.

> Zahl? Siehe Netiquette.
Ich hatte überlegt, ob ich diesen Aspekt mit betrachte, da ich leider 
noch keine Zahl parat habe. Also wollte ich das Timing erstmal beiseite 
legen und mich auf auf die funktionale Umsetzung konzentrieren.

Vielen Dank!
Ron

von Falk B. (falk)


Lesenswert?

@ Ronaldo (Gast)

>Es geht mir lediglich um die Vorgehensweise, wenn ich 8 CRC Berechnungen
>ungetaktet hintereinander ausrechnen möchte.

Dann brauchst du wie gesagt 8 ROMs, denn das Ergbenis der 1. 8-Bit CRC 
geht in die neue CRC ein. Kann man über eine Schleife in einem Prozess 
beschreiben.

>8 Takte sind leider nur zu langsam, da dann schon die nächsten Daten am
>Eingang anliegen können

PIPELINING! Die 1. Stufe berechnet im 1. Takt die 1. Teil-CRC des 1. 
Datenworts, im 2. Takt aber schon die 1. Teil-CRC des 2. Datenworts!
Deine 8 Stufen müssen nicht jeweils 8 Takte warten, bis sie wieder 
arbeiten dürfen.

>und so wollte ich mich mal nach Ideen umschauen,
>wie ich das beschleunigen kann. Daher der Ansatz alles in einem Takt
>abzuhandeln.

Ist nicht schneller.

>einer CRC Berechnung nun 8, also habe ich auch 8 hintereinander
>geschaltete XOR Netze... das ist der Preis von paralleler Logik.

Nö, das ist (zu) komplexe Kombinatorik. Echt parallel Logik arbeitet 
schnell, weil eben parallel und nicht seriell.

>> Zahl? Siehe Netiquette.
>Ich hatte überlegt, ob ich diesen Aspekt mit betrachte, da ich leider
>noch keine Zahl parat habe. Also wollte ich das Timing erstmal beiseite
>legen und mich auf auf die funktionale Umsetzung konzentrieren.

OMG! Du "optimierst" also ohne Ziel. Nicht sinnvoll!

http://www.mikrocontroller.net/articles/AVR-GCC-Codeoptimierung#Prinzipien_der_Optimierung

Gilt auch für VHDL, ist fast allgemeingültig für fast alle technischen 
Belange.

von Steffen R. (steffen_rose)


Lesenswert?

Die CRC Berechnung erfolgt über einen Bitstrom, d.h. ursprünglich Bit 
für Bit.

Die Berechnung von 8Bit gleichzeitig und die Nutzung einer lookup Table 
ist bereits eine optimierte Variante für 8 Bit Prozessoren (und ähnlich 
arbeitende Systeme).

Die 8bit optimierte Variante würde ich nicht für die Überlegung 
heranziehen, sondern beim Ursprung beginnen und hieraus deine 
Optimierung erarbeiten.
Das bedeutet leider aber auch, dass Du die Grundlagen kennen und 
anwenden können mußt.

Mein Ansatz wären 64 Polynomdivisionen (mit den XOR Gattern), denen 
jeweils das vorhergehende Ergebnis um ein Bit verschoben zugeführt wird.

Geht sowas auch ungetaktet? Da bin ich etwas skeptisch.

Nebenbei @falk: Bei VHDL hätte ich erwartet, dass man die CRC mit 
Gattern berechnet und keine lookup table nutzt. Wird das echt so 
umgesetzt?

von Lattice User (Gast)


Lesenswert?

Steffen Rose schrieb:

> Nebenbei @falk: Bei VHDL hätte ich erwartet, dass man die CRC mit
> Gattern berechnet und keine lookup table nutzt. Wird das echt so
> umgesetzt?

Eine Lookuptable macht dann, und nur dann Sinn wenn man beliebige 
Polynome zur Laufzeit einstellen will. In der Regel ist aber das Polynom 
fest vorgegeben.

Die XOR Gleichungen für das Bearbeiten von mehr als ein Bit pro Takt 
kann man vorbebrechnen, ist zwar von Hand mühsam aber es gibt 
massenweise Tools dafür.

Das geht auch für 64 Bit in einem Takt, eine Lookuptable ist in diesem 
Fall unmöglich.

Worstcase (bei 64bit) sind es 16 Gleichungen mit (64+16) XOR Termen. Pro 
Gleichung werden bei einer LUT4 Architektur 28 LUT4 und 4 Logikebenen 
gebraucht. (ohne Gewähr)

von Heiner (Gast)


Lesenswert?

>Es geht mir lediglich um die Vorgehensweise, wenn ich 8 CRC Berechnungen
>ungetaktet hintereinander ausrechnen möchte.

In den CRC-Generierungstools (z.B. Easics) kann man angeben, wie breit 
das Eingangsdatenwort für die Berechnung sein soll. Ob Du das dann 
kombinatorisch oder getaktet machst, bleibt dir überlassen!

Gruß, Heiner

von Ronaldo (Gast)


Lesenswert?

Hallo und vielen Dank!

Lattice User schrieb:
> Die XOR Gleichungen für das Bearbeiten von mehr als ein Bit pro Takt
> kann man vorbebrechnen, ist zwar von Hand mühsam aber es gibt
> massenweise Tools dafür.
Genau das habe ich meiner Meinung nach schon gemacht.
Hier kommen 16 Gleichungen (pro Bit des neuen CRCs) mit XOR 
Verknüpfungen raus. Ich habe dazu das Tool von 
http://www.easics.com/webtools/crctool verwendet.

Dort wird ein Package mit einer Funktion definiert, die man einfach 
verwenden kann. Die XOR Terme habe ich mir rauskopiert und habe meinen 
getakteten Prozess damit gefüttert. Das funktioniert gut.

Nun frage ich mich, wie ich diese Funktion innerhalb einer Taktperiode 
mehrmals aufrufen kann und dabei eine Art "Schablone" immer byteweise 
durch die Eingangsdaten schiebe.

Falk Brunner schrieb:
> OMG! Du "optimierst" also ohne Ziel. Nicht sinnvoll!
Ich weiß, dass ich keine 8 Takte habe, bis das CRC Ergebnis fertig sein 
soll. Auch mit einer Pipeline kann ich zwar mit jedem Takt neue Daten 
verarbeiten, aber ich habe dennoch ein Delay X, in der meine Rechnung 
fertig ist. Am Delay ändert sich nichts, ich kann nur mehr daten 
Verarbeiten.
Mit diesem mir einzig bekannten Fakt kann ich meiner Meinung nach schon 
ohne bekannte Taktfrequenz schlussfolgern, dass ich parallele Logik 
brauche :)

Vielen Dank!
Ron

von Heiner (Gast)


Lesenswert?

Wozu eigentlich Variablen? Wenn Du mit rein kombinatorischen Prozessen 
arbeitest, dann geht das auch mit Signalen.


VG,
Heiner

von Christoph Z. (christophz)


Lesenswert?

Ronaldo schrieb:
> Ich weiß, dass ich keine 8 Takte habe, bis das CRC Ergebnis fertig sein
> soll. Auch mit einer Pipeline kann ich zwar mit jedem Takt neue Daten
> verarbeiten, aber ich habe dennoch ein Delay X, in der meine Rechnung
> fertig ist. Am Delay ändert sich nichts, ich kann nur mehr daten
> Verarbeiten.
> Mit diesem mir einzig bekannten Fakt kann ich meiner Meinung nach schon
> ohne bekannte Taktfrequenz schlussfolgern, dass ich parallele Logik
> brauche :)

Nein, weisst du nicht!

Ohne Fakten wie hoch dein Delay X sein darf, mit welcher Rate die 
parallelen Daten vorliegen, wie schnell dein Design getaktet 
wird/maximal getaktet werden kann/soll kennst du deine 
Entscheidungsmöglickeiten nicht.

Z. B.: Wenn dein Delay 4 Takte sein darf aber nicht 8, dann reicht es ja 
wenn du deine 64 bit in einer Schlaufe durch eine 16 Bit breite CRC 
Logik schleust.

Z. B.: Wenn deine 64 Bit Daten mit 250 MHz kommen, dein FPGA max. mit 
100 MHz taktet und dein Delay "sehr kurz" sein soll, dann muss du nicht 
optimieren sondern gescheite Spezifikationen verlangen. :-)

von Christoph Z. (christophz)


Lesenswert?

Heiner schrieb:
> Wozu eigentlich Variablen? Wenn Du mit rein kombinatorischen Prozessen
> arbeitest, dann geht das auch mit Signalen.

Das Tool von easic generiert ein package mit einer function drin, die 
interne variablen besitzt.

Das hat den Fragesteller zuerst mal verwirrt, wie er jetzt das benutzen 
und in sein Design ingegrieren soll.

Eine wichtige Frage wäre also, was macht eigentlich der Synthesizer mit 
diesem Package und der Funktion, wenn man sie aufruft.

von Ronaldo (Gast)


Lesenswert?

Hallo,

Christoph Z. schrieb:
> Ohne Fakten wie hoch dein Delay X sein darf, mit welcher Rate die
> parallelen Daten vorliegen, wie schnell dein Design getaktet
> wird/maximal getaktet werden kann/soll kennst du deine
> Entscheidungsmöglickeiten nicht.
Ich wollte lediglich die funktionale Umsetzung betrachten und noch nicht 
an Timings denken. Wollte es auch erstmal nur 
simulieren/testen/ausprobieren...
Aber Ok, dann gibt es folgende Vorgaben:
- maximales Delay ein Takt
- Dateneingangsfrequenz = Systemfrequenz = 100kHz

Heiner schrieb:
> Wenn Du mit rein kombinatorischen Prozessen
> arbeitest, dann geht das auch mit Signalen.
Ja das stimmt... aber gibt es einen Unterschied zwischen Variablen und 
kombinatorischen Signalen, außer dass die Signale auch außerhalb des 
Prozesses sichtbar sind?

Ich habe jetzt folgende Idee:
1
FOR i IN 0 TO 7 LOOP
2
  IF I = 0 THEN
3
    v_crc(i)(0) := DATA(4) xor ... xor v_crc(i)(8) xor v_crc(i)(9);
4
    ...
5
    v_crc(i)(15) := DATA(7) xor ... xor v_crc(7) xor v_crc(8);
6
  ELSE
7
    v_crc(i)(0) := v_crc(i-1)(4) xor ... xor v_crc(i)(8) xor v_crc(i)(9);
8
    ...
9
    v_crc(i)(15) := v_crc(i-1)(7) xor ... xor v_crc(7) xor v_crc(8);
10
  END IF;
11
END LOOP;

v_crc muss ich dann nur mit (OTHERS => '0') starten lassen und meine 
fertige Prüfsumme liegt dann auf v_crc(7)(15 DOWNTO 0).

Ist die Idee nachvollziehbar?

Vielen Dank!
Ron

von Lattice User (Gast)


Lesenswert?

Ronaldo schrieb:
> Lattice User schrieb:
>> Die XOR Gleichungen für das Bearbeiten von mehr als ein Bit pro Takt
>> kann man vorbebrechnen, ist zwar von Hand mühsam aber es gibt
>> massenweise Tools dafür.
> Genau das habe ich meiner Meinung nach schon gemacht.
> Hier kommen 16 Gleichungen (pro Bit des neuen CRCs) mit XOR
> Verknüpfungen raus. Ich habe dazu das Tool von
> http://www.easics.com/webtools/crctool verwendet.
>
> ....
>
> Nun frage ich mich, wie ich diese Funktion innerhalb einer Taktperiode
> mehrmals aufrufen kann und dabei eine Art "Schablone" immer byteweise
> durch die Eingangsdaten schiebe.
>

Wozu? Wie von Heiner schon angmerkt das Easics Tool kann dir auch die 
xor Gleichungen für 64bit Daten in einem Schritt ausrechnen.

von Ronaldo (Gast)


Lesenswert?

Hallo,

Lattice User schrieb:
> Wozu? Wie von Heiner schon angmerkt das Easics Tool kann dir auch die
> xor Gleichungen für 64bit Daten in einem Schritt ausrechnen.

Es ist doch aber ein Unterschied ob ich einmal 64bit zur CRC Berechnung 
heranziehe, oder 8x ein Byte verrechne.
Einmal habe ich ein 64bit Schieberegister und einmal habe acht 8-bit 
Schieberegister.

Wenn da das gleiche herauskommen soll, habe ich die CRC Berechnung wohl 
doch noch nicht verstanden?!

Viele Grüße,
Ron :)

von Lattice User (Gast)


Lesenswert?

Ronaldo schrieb:
>
> Es ist doch aber ein Unterschied ob ich einmal 64bit zur CRC Berechnung
> heranziehe, oder 8x ein Byte verrechne.
> Einmal habe ich ein 64bit Schieberegister und einmal habe acht 8-bit
> Schieberegister.
>
> Wenn da das gleiche herauskommen soll, habe ich die CRC Berechnung wohl
> doch noch nicht verstanden?!
>

Acht 8bit Schieberegister ist im Endeffekt das gleiche wie ein 64bit 
Schieberegister, du musst nur auf die Bitreihenfolge achten, sprich 
Endiness.

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.