Forum: FPGA, VHDL & Co. schnelles Vergleichen


von Da M. (damicha)


Lesenswert?

Hallo.

Ich möchte zwei 64 Bit Zahlen miteinander vergleichen. Größer, kleiner
oder gleich soll das Ergebnis sein.
Bisher habe ich die oberen und unteren Hälften getrennt miteinander
verglichen. Je nach dem, ob die oberen Hälften gleich sind oder nicht,
wird das Ergebnis des unteren bzw. oberen Vergleichs genommen.
Das funktioniert auch schon ganz gut.
Es könnte aber immer noch ein wenig schneller sein ;-).

Vielleicht kennt jemand von Euch noch einen passenden Algorithmus, der
sich gut im FPGA implementieren lässt.

Gruß DaMicha.

von Kest (Gast)


Lesenswert?

Hast Du mit ">" "<" "=" ausprobiert (VHDL oder Verilog)? Ist es nicht 
schnell genug? Sind die Tools nicht intelliegent genug?

Fragen über Fragen...

Kest

von FPGAküchle (Gast)


Lesenswert?

Die synthese ist meist schon optimal was das einbauen von Comperatoren 
betrifft. wo stammen die 64 bit her, register, counter? Bei letzteren 
hasst du Optimierungsmöglichkeiten (Vergleich mit wert eins Kleiner 
(up-counter) und pipiline). Ansonsten kannst du ja versuchen spezielle 
FPGA Eigenheiten zu benutzen (LUT oder Carry chain). Oder du zerhackst 
den 64 bit vergleicher um RAMBlöcke als Lokkuptabelle für den vergleich 
zu verwenden. Aber da optimiert man weniger das VHDL (Synthese) als das 
man spitzfindig das Mapping und routing ausnutzt.

Wie schnell ist den dein bisheriger vergleicher?

von Falk (Gast)


Lesenswert?

???
Ein 64-Bit Subtrahierer (Für Grösser/kleiner) und ein 64 Bit XOR (für
gleich). Das XOR kann die Carry Chain nutzen (zumindest bei Xilinx), das
wird schon sehr schnell. Wenn schneller gehen soll (höherer Takt)
-> Pipelining

Was ist für dich "schnell" ?

MfG
Falk

von Xilinxuser (Gast)


Lesenswert?

Wird denn die Synthese nicht schon automatisch bei der Prüfung auf 
"Gleich" ein XOR einsetzen? Wenn sie das nicht kann, was kann sie dann 
überhaupt? Ich habe mir darum noch nie Geanken gemacht.

von Falk (Gast)


Lesenswert?

@Xilinxuser

>Wird denn die Synthese nicht schon automatisch bei der Prüfung auf
>"Gleich" ein XOR einsetzen? Wenn sie das nicht kann, was kann sie dann

Das wird sie schon. AFAIK waren aber die älteren Versioen von XST nicht 
so schalu, auch die Carry-Chain zu benutzten(beim Vergeleicher).

>überhaupt? Ich habe mir darum noch nie Geanken gemacht.

Die kann schon einges ;-)

MFG
Falk

von Da M. (damicha)


Lesenswert?

Hallo.

Erstmal danke für die Antworten.

@Kest: Mein Vergleich sieht folgendermaßen aus:
1
    if    (a < b) then
2
        v.cmp := CMP_LOWER;
3
    elsif (a > b) then
4
        v.cmp := CMP_HIGHER;
5
    else
6
        v.cmp := CMP_EQUAL;
7
    end if;

Alles andere war langsamer. Selbst ein (a = b fürs Equal) war nicht 
schneller.
Ich denke mal, dass die Carrypfade für <,> schon extrem schnell sind.

Die Werte a und b kommen aus Registern, das Vergleichsergebnis schaltet 
Adressen über einen Multiplexer und das Ergebnis landet wieder in einem 
Register.
Davor und danach sind Blockram-Zugriffe. Die Zeit von dem Blockram bzw. 
aus dem Blockram benötige ich für Netzdelays und weitere Multiplexer.
Mit dem vollen 64 Bit Vergleich kommen ich auf 155 MHz bei der Synthese 
bei 2x 32 Bit sind es 213 MHz bei der Synthese und 180 MHz nach dem 
Place&Route. Der Zielfpga ist ein Virtex 4 fx60 und die Zielfrequenz 156 
MHz bei momentan minimaler Auslastung (4% Slices und 10% Blockrams). Das 
ist soweit OK, aber man hat ja immer gerne etwas Luft.

Ich habe inzwischen noch weiter rumprobiert, aber leider lässt sich 
nicht mehr viel machen. Durch ein weiteres Aufteilen des Vergleiches in 
kleiner Werte wird das Design wieder langsamer.

Hatte gehofft, dass es noch einen Trick zum Vergleichen von großen Werte 
gibt...

@Falk: eine weitere Pipelinestufe ist eine Option würde aber durch die 
Latenzzeit mein Taktschema beeinflußen und wahrscheinlich den Durchsatz 
drücken, da ich einen Takt verliere, während ein RAM-Access läuft.

Danke nochmal,
 DaMicha.

Hier noch mal die 2x32 Bit Version:
1
    -- bit 63 downto 32 --
2
    if    (a_h < b_h) then
3
        cmp_h := CMP_LOWER;
4
    elsif (a_h > b_h) then
5
        cmp_h := CMP_HIGHER;
6
    else
7
        cmp_h := CMP_EQUAL;
8
    end if;
9
10
    -- bit 31 downto  0 --
11
    if    (a_l < b_l) then    
12
        cmp_l := CMP_LOWER;
13
    elsif (a_l > b_l) then
14
        cmp_l := CMP_HIGHER;
15
    else
16
        cmp_l := CMP_EQUAL;
17
    end if;
18
19
    if (cmp_h = CMP_EQUAL) then       -- use lower bits
20
        v.cmp := cmp_l;
21
    else
22
        v.cmp := cmp_h;
23
    end if;

  

von Kest (Gast)


Lesenswert?

Nur eine Idee:

ich würde ausprobieren auf "EQUAL" und auf "LOWER" gleichzeitig zu 
überprüfen. Der ausgang ist dann nur die Verknüpfung der beiden

Pseudocode:

EQUAL='1' when (a=b) else '0';

LOWER='1' when (a<b) else '0';

HIGHER='1' when (EQUAL='0' and LOWER='0) else '0';


(sorry, mag sein, dass mit Variablen das gleiche rauskommt, aber ich 
wollte nur was in den Raum werfen, was von den anderen ruhig "zerrissen" 
werden kann ;-))

Kest

von Falk (Gast)


Lesenswert?

@Da Micha

>Alles andere war langsamer. Selbst ein (a = b fürs Equal) war nicht
>schneller.

Hmm, dannscheint der Compiler schon recht gute Arbeit zu leisten, aber . 
.

>Ich denke mal, dass die Carrypfade für <,> schon extrem schnell sind.

Sicher, aber das ist nur die halbe Miete.

>Die Werte a und b kommen aus Registern, das Vergleichsergebnis schaltet
>Adressen über einen Multiplexer und das Ergebnis landet wieder in einem
>Register.

HA! Das ist ja schon ein recht langer Pfad. Ich würde das 
Vergleichsergebnis erstmal in ein Register packen und danch weiter 
nutzen. Klar, das braucht einen Takt länger, sollte aber deutlich 
schneller werden.

>bei 2x 32 Bit sind es 213 MHz bei der Synthese und 180 MHz nach dem
>Place&Route. Der Zielfpga ist ein Virtex 4 fx60 und die Zielfrequenz 156

Hmmmm, 180 MHz für nen 32 Bit Vergleich finde ich so rein aus dem Bauch 
heraus für Virtex4 nicht so dolle. Liegt aber whrscheinlich daran, dass 
du danach noch die MUX und Adressen schaltest.

MFG
Falk

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.