Forum: FPGA, VHDL & Co. Schnelle Conversion bin2dec


von Spartanist (Gast)


Lesenswert?

Wie kann man einen 16 Bit Vektor in VHDL am schnellsten auf die 5 
benötigten Dezimalstellen (6.5.5.3.5) umrechnen, ohne das dividieren 
oder look up zu verwenden?

Ich habe es mal so versucht, dass ich jeweils anhand der vorderen Stelle 
entscheide, ob 1,2,3 ... 9 rauskommen soll und den Rest weitergegeben, 
und dann 5 von den Konstukten kaskadiert.

Scheint mir aber verbesserungsfähig.

von Duke Scarring (Gast)


Lesenswert?


von J. S. (engineer) Benutzerseite


Lesenswert?

Das Millerdesign braucht offenbar 581 slices! Ach Du Schreck! :-)

Spartanist schrieb:
> Scheint mir aber verbesserungsfähig.
In der Tat, der Direktvergleich lohnt nur bei der 3-Stellen-Version mit 
8 Bit, wie ich gefunden habe. Da sind es ja nur 3 Zweige und eine 
Restberechung.

Wenn es schnell sein muss, wirst Du ums Dividieren = inverses 
Multiplizieren nicht herum kommen.

Wie schnell muss das sein? In der Regel ist das doch gut zu pipelinen 
und man kann in jedem Takt einen Wert verarbeiten.

Die Division durch 10 lässt sich mit genügender Genauigkeit in geschätzt 
10 Bit machen, - beim o.g. Beispiel wären es 13 Bit, wenn ich richtig 
rechne (y = (51 * x + 50 ) / 512). Für die Einerstellen müsste auch (25 
* x + 24) / 256 reichen, denke ich.

Die meisten embedded Multiplier können das in einer Stufe und die dann 
nötige Restbetrachtung durch Abziehen von n*x kann im folgenden Akku 
passieren. Mit einer Schleife bekommt man das in einem aktuellen 
DSP-element in 6 Takten hin.

Wenn man es nur ausgeben will, müssen die Ergebnisse nicht mal 
zwischengespeichert werden, sondern die Ziffern purzeln in natürlicher 
Reihenfolge (MSF ... LSF) heraus.

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


Lesenswert?

J. S. schrieb:
> Das Millerdesign braucht offenbar 581 slices! Ach Du Schreck! :-)
Welches? Lies alles!
1
Dieser Ansatz ist also nur geeignet, wenn Ressourcen keine Rolle spielen.
Das heißt übersetzt:
es ginge zwar, aber man macht das nicht kombinatorisch.

Bei vielen Stellen nimmt man einfach das Shift-Add-6 Verfahren:
http://www.lothar-miller.de/s9y/archives/34-Vektor-nach-BCD.html

von Spartanist (Gast)


Lesenswert?

Lothar Miller schrieb:
> Bei vielen Stellen nimmt man einfach das Shift-Add-6 Verfahren:

Wie ich aus der TB erkenne, benötigt das etwa 12-14 Takte nach dem 
Start.

Das ist für meinen Fall leider zu langsam.

J. S. schrieb:
> Wie schnell muss das sein?

Ich brauche das Ergebnis möglichst sofort, einige Takte Verzögerung 
wären akzeptabel.

J. S. schrieb:
> wenn ich richtig
> rechne (y = (51 * x + 50 ) / 512). Für die Einerstellen müsste auch (25
> * x + 24) / 256 reichen, denke ich.

Könntest Du das etwas erklären, wie das gemeint ist?

>Mit einer Schleife bekommt man das in einem aktuellen
> DSP-element in 6 Takten hin.
Wäre das die Latenz oder die Gesamtzeit inklusive Ausgabe aller Stellen?

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


Lesenswert?

Spartanist schrieb:
> Das ist für meinen Fall leider zu langsam.
Was ist denn dein Fall?

> Ich brauche das Ergebnis möglichst sofort, einige Takte Verzögerung
> wären akzeptabel.
Und wie schnell bräuchtest du es denn?

> Wäre das die Latenz oder die Gesamtzeit inklusive Ausgabe aller Stellen?
Nein. Es wäre eine einzige Zehnerstelle ohne jegliche Ausgabe wo 
auch immer hin (weil die Ausgabe mit der Wandlung ja schon gleich 
überhaupt nichts zu tun hat, und ausserdem parallel erfol

> Könntest Du das etwas erklären, wie das gemeint ist?
Kannst du mal erklären, WAS du machen willst und WOFÜR du das brauchst?

von ähmm.. (Gast)


Lesenswert?

was spricht gegen die LUT ?
in zwei Takten bist du durch...
Gut, is ä weng mehr Arbeit.

Cheers

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


Lesenswert?

ähmm.. schrieb:
> was spricht gegen die LUT ?
Wie groß würdest du die LUT denn machen? Es könnte sein, dass da die 
Lösung mit den 581 Slices noch klein aussieht dagegen...  :-o
> in zwei Takten bist du durch...
Zeig mal...

von Spartanist (Gast)


Lesenswert?

Lothar Miller schrieb:
> Spartanist schrieb:
>> Das ist für meinen Fall leider zu langsam.
> Was ist denn dein Fall?

Eine Datenausgabe über einen herstellerspezifischen Bus. Die Daten 
kommen als 32Bit-Vektoren an und sollen in Echtzeit ausgeben werden. 
Damit die (langsame) embedded CPU das nicht tun muss, soll es der FPGA 
machen und schon mal wandeln.


>> Ich brauche das Ergebnis möglichst sofort, einige Takte Verzögerung
>> wären akzeptabel.
> Und wie schnell bräuchtest du es denn?
So schnell wie möglich, weil ich die Daten zu sammen mit anderen 
ausgeben muss und diese sonst in einem Fifo halten muss, was je Takt 
etwa 50-80 Register-FFs braucht.


>> Wäre das die Latenz oder die Gesamtzeit inklusive Ausgabe aller Stellen?
> Nein. Es wäre eine einzige Zehnerstelle ohne jegliche Ausgabe
D.h. 6 Takte je Zehnerstelle? Ich brauche 32 Bit und damit 8 Stellen.

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


Lesenswert?

Spartanist schrieb:
> Eine Datenausgabe über einen herstellerspezifischen Bus. Die Daten
> kommen als 32Bit-Vektoren an und sollen in Echtzeit ausgeben werden.
Und warum muss das Dezimal geschehen? Rechner arbeiten am besten und 
schnellsten Binär...

> Die Daten
> kommen als 32Bit-Vektoren an und sollen in Echtzeit ausgeben werden.
Wie schon mal erwähnt:
Lothar Miller schrieb:
>> Und wie schnell bräuchtest du es denn?
Zeiten werden in us angegeben, Datenraten in Bytes/s oder auch Worten/s 
usw. usf.

> D.h. 6 Takte je Zehnerstelle? Ich brauche 32 Bit und damit 8 Stellen.
Ja, dann rechne das mal aus. Und am besten noch ein wenig 
Handlingsgebühr dazu...

>>> Ich brauche das Ergebnis möglichst sofort, einige Takte Verzögerung
>>> wären akzeptabel.
>> Und wie schnell bräuchtest du es denn?
> So schnell wie möglich, weil ich die Daten zu sammen mit anderen
> ausgeben muss und diese sonst in einem Fifo halten muss, was je Takt
> etwa 50-80 Register-FFs braucht.
Du könntest da mit einem Fifo im BRAM was dagegen tun...

von Spartanist (Gast)


Lesenswert?

Lothar Miller schrieb:
> Spartanist schrieb:
>> Eine Datenausgabe über einen herstellerspezifischen Bus. Die Daten
>> kommen als 32Bit-Vektoren an und sollen in Echtzeit ausgeben werden.
> Und warum muss das Dezimal geschehen? Rechner arbeiten am besten und
> schnellsten Binär...
Weil sie halt ausgegeben werden sollen und die Umrechnung im schnellen 
FPGA erfolgen soll.


>> kommen als 32Bit-Vektoren an und sollen in Echtzeit ausgeben werden.
>Lothar Miller schrieb:
> Zeiten werden in us angegeben, Datenraten in Bytes/s oder auch Worten/s
Die Datenrate ist am Anschlag. Es kann nichts zwischengespeichert 
werden.


>> D.h. 6 Takte je Zehnerstelle? Ich brauche 32 Bit und damit 8 Stellen.
> Ja, dann rechne das mal aus. Und am besten noch ein wenig
> Handlingsgebühr dazu...
Schon passiert, 50 Takte ist zuviel



>> So schnell wie möglich, weil ich die Daten zu sammen mit anderen
> Du könntest da mit einem Fifo im BRAM was dagegen tun...
Braucht auch wieder Verwaltung und Platz, was ich mir gerne ersparen 
würde.

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


Lesenswert?

Bann nimm "meinen" bin2bcd-Wandler und instantiiere 20 davon. Deinen 
ersten 32-Bit-Wert schickt du in den ersten Wandler, den nächsten 
32-Bit-Wert in den zweiten und so fort...
So hast du ein paar Takte Latency, aber einen guten Durchsatz... ;-)

von Spartanius (Gast)


Lesenswert?

Lothar Miller schrieb:
> Bann nimm "meinen" bin2bcd-Wandler und instantiiere 20 davon. Deinen
> ersten 32-Bit-Wert schickt du in den ersten Wandler, den nächsten
> 32-Bit-Wert in den zweiten und so fort...
> So hast du ein paar Takte Latency, aber einen guten Durchsatz... ;-)

Ich glaube, ich belasse es besser bei meinem IF-Konstrukt, wie oben 
beschrieben. Der geht im schlimmsten Fall auch in einem Takt.

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


Lesenswert?

Spartanist schrieb:
>> Ich habe es mal so versucht, dass ich jeweils anhand der vorderen Stelle
>> entscheide, ob 1,2,3 ... 9 rauskommen soll und den Rest weitergegeben,
>> und dann 5 von den Konstukten kaskadiert.
Spartanius schrieb:
> Der geht im schlimmsten Fall auch in einem Takt.
Ja, das ist so.
Die Taktfrequenz muss nur langsam genug sein für (in deinem aktuellen 
32-Bit-Fall) annähernd 80 Vergleicher, dann 8 Subtrahierer, einige 
Multiplexer und was sonst noch dazukommt. Wie schnell ist denn dieses 
Elaborat? Was sagt die Synthese zum Thema maximale Taktfrequenz?

von J. S. (engineer) Benutzerseite


Lesenswert?

Lothar Miller schrieb:
> J. S. schrieb:
>> Das Millerdesign braucht offenbar 581 slices!
> Welches? Lies alles!
Langsam, langsam, ich bezog mich auf das von "Duke Scarring" gelinkte 
Design. Das ist das einzige, dass die Kriterien des TE erfüllt (also, 
schneller wäre, als seine Methode) und dieses hat diesen Bedarf.

>Dieser Ansatz ist also nur geeignet, wenn Ressourcen keine Rolle spielen.
Das habe ich selbstverständlich gelesen, aber auch in dem Fall, in dem 
man einseitig auf Tempo setzt und Resourceneinsatz ok wäre, ist das 
nicht der Weisheit letzter Schluss: Ich hatte hier...

Beitrag "Re: Schnelle Conversion bin2dec"

... ja bereits beschrieben, wie das funktioniert, wenn man auf Tempo 
designen möchte. Die Methode ist sowohl für sequenziellen Betrieb, als 
auch parallelen Betrieb machbar und dies im Übrigen sogar komplett 
kombinatorisch, in dem man die Multiplier durch Adder ersetzen lässt (es 
sind nur 4 Additionen) und alles in einen Takt schreibt. Dann kann die 
Synthese das auch runteroptimieren und Teile der Additionen mit der 
Subtraktion und Restbildung zusammenfassen.

Lothar Miller schrieb:
>> Wäre das die Latenz oder die Gesamtzeit inklusive Ausgabe aller Stellen?
> Nein. Es wäre eine einzige Zehnerstelle ohne jegliche Ausgabe wo
> auch immer hin (weil die Ausgabe mit der Wandlung ja schon gleich
> überhaupt nichts zu tun hat, und ausserdem parallel erfolt
Ihr habt das wohl beide nicht verstanden, wie ich das gemeint habe, also 
nochmal: Jede der Dezimalstellen wird von einem DSP-Element gerechnet 
und das bei den meisten FPGAs in einem einzigen Takt! Die Ausgabe hat 
mit der Wandlung insofern zu tun, als das bei der üblichen Nutzung 
zuerst die höherwertigen Stellen auf eine Anzeige gebracht werden und 
danach jede weitere in einem anderen Takt, sei es ein VGA-Buffer oder 
ein Display. Daher macht es Sinn, das sequenziell mit nur einem 
DSP-Element zu machen und pro Stelle einen Taktzyklus zu investieren. 
Das Dingens rechnet dann iterativ und wirf mit jedem Takt die 
anzuzeigende Ziffer raus. Klappt bestens.

Die Nutzung des DSP-Elementes, also genauer eines Multiplizierers und 
Subtrahierers tritt zusammen mit der geschickten Rundung an die Stelle 
der oben ebenfalls vorgeschlagenen LUT, bzw im anderen Vorschlag des 
Shift-Adders-Elementes. Dieses wäre, nebenbei gesagt, auch pipelinebar 
und / oder voll kombinatorisch aufzubauen, wenn man die FSM entfernt und 
die ablaufenden Zyklen schon während der Synthese per generate in eine 
Schaltung umsetzt. Das Shift-Adder Element macht nämlich bei genauerer 
Betrachtung nicht anderes, als partiell bedingt zu multiplizieren. Es 
ist eben nur aus Slices aufgebaut, während der MUL i.d.R schon vorhanden 
ist.

Spartanist schrieb:
> D.h. 6 Takte je Zehnerstelle? Ich brauche 32 Bit und damit 8 Stellen.
Das ist eben genau nicht richtig! Du bekommst aus einem 16 Bit-Vektor 
5 Stellen und damit insgesamt die o.a. 6 Takte.

In Deinem Fall, bei 32 Bit, sind das zudem auch nicht 8 Stellen, wie Du 
meinst, sondern 10, jedenfalls, wenn der Vektor voll ausgesteuert wird. 
Wenn Du das mit einer MUL-SUB-Anordnung wie oben beschrieben, machst, 
brauchts Du 11 Takte, gfs 12 für das gesamte Rechnen und Übertragen der 
letzen Ziffer. Wenn Du die nicht sofort wegschicken kannst, oder darfs, 
musst Du eben mit allem warten, bis die letzte Ziffer parat ist. Die 
Rechnung kann mit einem schnellen FPGA aber locker auf 250MHz getaktet 
werden, was immerhin 20MHz Datenrate wären. Viel mehr dürfte Deine CPU 
nicht abkönnen, sage ich mal.

Anders heum gesehen muss man sich fragen, ob man nicht doch die CPU das 
rechnen lässt, denn iterieren sollte die wohl auch können.

von Josef G. (bome) Benutzerseite


Lesenswert?

Die oben angesprochenen Verfahren habe ich nicht verstanden
und bin deshalb nicht sicher, ob das, was ich jetzt vorschlage,
etwas neues ist oder mit einem dieser Verfahren übereinstimmt:

Die 2er-Potenzen 2^0 .. 2^15 sind 16 5-stellige BCD-Konstanten.
Man bildet die per 15-facher BCD-Addition gebildete Summe
(Konstante0)*(b0) + .. + (Konstante15)*(b15)
wobei b0 .. b15 die Eingangs-Bits sind.

von Spartanius (Gast)


Lesenswert?

Josef G. schrieb:
> Die 2er-Potenzen 2^0 .. 2^15 sind 16 5-stellige BCD-Konstanten.
> Man bildet die per 15-facher BCD-Addition gebildete Summe
> (Konstante0)*(b0) + .. + (Konstante15)*(b15)
> wobei b0 .. b15 die Eingangs-Bits sind.

Das habe jetzt ich nicht verstanden. Ist das nicht der umgekehrte Weg 
von BCD-to-DEZ?


Lothar Miller schrieb:
> Bann nimm "meinen" bin2bcd-Wandler und instantiiere 20 davon. Deinen
> ersten 32-Bit-Wert schickt du in den ersten Wandler, den nächsten
> 32-Bit-Wert in den zweiten und so fort...

Ich habe probehalber die angegebene Schaltung mit dem Schieberegister im 
Original synthetisiert und erhalte 18 Takte für einen 16 Bit-Vektor, bei 
20 slices und 64 registern. Für 32 Bit sind es dann wohl geschätzt 34 
Takte bei 40 slices. Bei 32 Schaltungen also 1200 slices.


J. S. schrieb:
> In Deinem Fall, bei 32 Bit, sind das zudem auch nicht 8 Stellen, wie Du
> meinst, sondern 10, jedenfalls, wenn der Vektor voll ausgesteuert wird.
ok, kann sein, der range ist 0 ... 2hoch32-1.

> Wenn Du das mit einer MUL-SUB-Anordnung wie oben beschrieben, machst,
> brauchts Du 11 Takte, gfs 12 für das gesamte Rechnen und Übertragen der
> letzen Ziffer.
Klingt nicht schlecht. Leider ist mir der Weg immer noch nicht 
verständlich, wie man auf diese Formel kommt:

> rechne (y = (51 * x + 50 ) / 512)
?

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


Lesenswert?

Spartanius schrieb:
> Für 32 Bit sind es dann wohl geschätzt 34 Takte bei 40 slices.
> Bei 32 Schaltungen also 1200 slices.
Brauchst du 32 solcher Schaltungen? Kommt jeden Takt ein neues Wort 
herein? Wie sendest du die Daten dann wieder raus (wenn/weil ja aus 
jedem 32-Bit-Vektor 10 Stück 4-Bit-BCD-Vektoren werden)...

von Spartanius (Gast)


Lesenswert?

Lothar Miller schrieb:
> Spartanius schrieb:
>> Für 32 Bit sind es dann wohl geschätzt 34 Takte bei 40 slices.
>> Bei 32 Schaltungen also 1200 slices.
> Brauchst du 32 solcher Schaltungen?
war ja Dein Vorschlag :-)

> Kommt jeden Takt ein neues Wort herein?
Es wird pro FPGA-Takt (letztlich ~60-70MHz) / 16 eine Datengruppe 
berechnet, die zu wahrscheinlich 6 bis 8 Werten führt. Das sind 30MHz 
Daten unterschiedlicher Breite. Einige Werte müssen zusammen mit anderen 
Werten an die CPU. Diese müssen teilweise gewandelt werden.

Die Daten werden berechnet und gesendet und sobald die letzten Daten 
berechnet sind, stehen mir auch die Werte zu wandeln zur Verfügung. Die 
müssen sofort raus (60 MHz x 32 Bit), weil ich keine Bustakte verlieren 
darf. Lücke ist nicht, da die CPU noch andere Sachen machen muss.

Wenn ich zum Umrechnen Takte brauche, muss ich die anderen Daten 
zwischenspeichern, damit das Paket kompakt bleibt.


> Wie sendest du die Daten dann wieder raus
~60MHz x 32 Bit, also bezüglich der Dezimalzahlen max 4 Zahlen je Takt.

von Josef G. (bome) Benutzerseite


Lesenswert?

Spartanius schrieb:
> Ist das nicht der umgekehrte Weg von BCD-to-DEZ?

Die Frage im Eröffnungsbeitrag war, eine 16bit-Dualzahl solle
in eine 5 Ziffern lange Dezimalzahl umgewandelt werden.

Jede Dezimalziffer wird dargestellt durch 4 Bit  im Bereich
0000 bis 1001. "BCD" und "DEZ" sind in diesem Sinne dasselbe.

Die Zahl ist gegeben in Dualdarstellung (2^0)*(b0) + .. + (2^15)*(b15)
Man schreibt  2^0 .. 2^15  einzeln als Dezimalzahlen, multipliziert
mit  b0 .. b15  und addiert die Ergebnisse dezimal. So erhält man
die gesuchte Dezimaldarstellung der Zahl.

Die Additionen kann man baumartig zusammenfassen und
parallel ausführen. Einziges Problem dabei ist, dass man
Dezimal-Addierer braucht.

Ob der Hardware-Aufwand dann noch vertretbar ist, wenn
jetzt statt 16bit von 32bit die Rede ist, weiss ich nicht.

von Spartanius (Gast)


Lesenswert?

Josef G. schrieb:
> Die Zahl ist gegeben in Dualdarstellung (2^0)*(b0) + .. + (2^15)*(b15)
> Man schreibt  2^0 .. 2^15  einzeln als Dezimalzahlen, multipliziert
> mit  b0 .. b15  und addiert die Ergebnisse dezimal. So erhält man
> die gesuchte Dezimaldarstellung der Zahl.

Ich stehe da irgendwie auf dem Schlauch!

Angenommen, ich habe die 16-bit-Zahl 51432. (den 32-bit-Fall lassen wir 
jetzt mal beiseite).

Diese binäre Zahl liegt vor als: 1100.1000.1110.1000

Was fange ich damit an?

Rauskommen muss 0101.0001.0100.0011.0010

So mache ich das bisher:

   IF (Zahl >= 60000) THEN OUT5 <= 6; REST <= Zahl - 60000;
ELSIF (Zahl >= 50000) THEN OUT5 <= 5; REST <= Zahl - 50000;
...
ELSIF (Zahl >= 10000) THEN OUT5 <= 1; REST <= Zahl - 10000;
ELSE                       OUT5 <= 0; REST <= Zahl

Das geht dann in die nächste Stufe, die genau so aussieht und OUT4 
berechnet.

Frage:

Was ist bei Dir jetzt "b"?

So wie Du das beschreibst, errechnest Du doch einfach den Dezimalwert 
aus der BSD-Darstellung, oder nicht?

von Josef G. (bome) Benutzerseite


Lesenswert?

Spartanius schrieb:
> So wie Du das beschreibst, errechnest Du doch einfach den Dezimalwert
> aus der BSD-Darstellung, oder nicht?

Verstehe ich nicht.
Gegeben ist die Dualzahl c8e8 (in Hex-Schreibweise).
Ich erhalte mit meinem Verfahren die Dezimalzahl 51432   (*)
wobei die einzelnen Ziffern binär codiert sind. Da hast Du doch
die Ziffern, die Du brauchst? Oder blick jetzt ich nicht durch?

(*) würde ich evtl. vorrechnen, aber nur wenn erforderlich.

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


Lesenswert?

(*) Mach das bitte mal. Meinetwegen auch mit einer kleineren Zahl. Ich 
habe da einen Verdacht...

von J. S. (engineer) Benutzerseite


Lesenswert?

Ich rate mal:

C x 256 x 256 x 256
8 x 256 x 256
E x 256
8

liefert die Einzelergebnisse. Dann schlägt der Dezimaladdierer zu. Sowas 
konnten früher einige 8-Bit Prozessoren, wenn man sie auf BCD 
umgeschaltet hat. Letztlich ist das aber nichts anderes. Die 
"Intelligenz" (und auch der Aufwand) steckt im Addierer. Das muss von 
der Hardware vorgesehen sein, wenn es effektiv sein soll, was aber bei 
FPGAs definitiv nicht so ist.


Spartanius schrieb:
> Klingt nicht schlecht. Leider ist mir der Weg immer noch nicht
> verständlich, wie man auf diese Formel kommt:
>> rechne (y = (51 * x + 50 ) / 512)

Das ist die benötigte Division durch 10 und zwar die kleinst denkbarste, 
die gerade keine Rundungsfehler produziert. Allerdings sehe ich gerade, 
dass das die für 8 Bit ist. Sie ist genau bis 255. Für eine Stelle 
reicht auch weniger.

Du rechnest einfach Folgendes:

Zehntausender = Eingabezahl / 10000. Die 10000 bilstest du ab auf z.B. 
16384 und multiplizierst zuvor mit 1.6384. Die Auflösung der jeweiligen 
MUL muss so gewählt werden, dass sie nach dem Abschneiden der Stellen 
nicht zu einem Fehler kommt. In der Regel muss man mit +0.5 runden.

Aufgrund der Genauigkeit ist die Rechnung bei der grössten Zahl am 
Aufwändigsten. Beispiel:

Ausgabezahl = (3435973 * Eingabe + 343597) / 34359738368
Rest = Eingabe - 10000 * Ausgabezahl.

Du musst jetzt die kleinste mögliche Rechung finden, um sie den 
einzelnen Stufen anzupassen. Wenn du sequenziell arbeitest, nutzt Du 
diese eine eben mehrfach. Die Rechnung macht letztlich das, was Deine 
IF-THENs tun, nur halt in einem Takt. Ein aktueller FPGA hat z.B. 18x25 
Bit-MULS.

von Josef G. (bome) Benutzerseite


Lesenswert?

Lothar Miller schrieb:
> (*) Mach das bitte mal. Meinetwegen auch mit einer kleineren Zahl.

Beispiel: Dual 6c  / Soll-Ergebnis Dezimal 108

6c Hex = (ab hier ist alles dezimal)

         1*0 + 2*0 + 4*1 + 8*1 + 16*0 + 32*1 + 64*1 + 128*0  =

         4 + 8 + 32 + 64 = 108

Letzte Zeile ausgeführt mit BCD-Addierern:

 4 +  8  -->  0000.0000.0100 + 0000.0000.1000 = 0000.0001.0010

32 + 64  -->  0000.0011.0010 + 0000.0110.0100 = 0000.1001.0110

                                  Gesamtsumme = 0001.0000.1000

Begründung:
In Zeile 4+8 : 0100 + 1000       -->   1100 (duale Addition)
                                 --> 1.0010 (nach BCD-Korrektur)
Bei Bildung der Gesamtsumme
Berechnung der mittleren Stelle: -->   1010 (duale Addition)
                                 --> 1.0000 (nach BCD-Korrektur)

http://next-internet.com/ti_1/texte/ti1_2005_01_31_4f.pdf
(Abschnitt 5.2.4)

von Josef G. (bome) Benutzerseite


Lesenswert?

Um eine 32bit Dualzahl in die Dezimaldarstellung umzuwandeln,
braucht man die Konstanten 2^0 .. 2^31 in Dezimaldarstellung.
Jede Konstante wird mit 0 oder 1 multipliziert je nach dem
entsprechenden Bit der gegebenen Dualzahl. Die 32 Resultate
sind mit BCD-Addierern zu addieren.

Man kann die Zahl der Addierer verringern, indem man zB. die
untersten zwei Schichten des Addierer-Baums dadurch ersetzt,
dass man die Summen vorab berechnet und dann die richtige
Summe per Multiplexer auswählt:

Gegeben sei die Dualzahl H7.H6.H5.H4.H3.H2.H1.H0, wobei
die Hi die Hex-Ziffern sind. Man hat die Dezimal-Konstanten

0*(16^7), 1*(16^7), ..., 15*(16^7)   H7 wählt eine davon aus
0*(16^6), 1*(16^6), ..., 15*(16^6)   H6 wählt eine davon aus
...
0*(16^1), 1*(16^1), ..., 15*(16^1)   H1 wählt eine davon aus
0*(16^0), 1*(16^0), ..., 15*(16^0)   H0 wählt eine davon aus

Man erhält so 8 Dezimalzahlen und braucht noch
4+2+1=7 BCD-Addierer, um alles zu addieren.

von Spartanist (Gast)


Lesenswert?

Josef G. schrieb:
> Um eine 32bit Dualzahl in die Dezimaldarstellung umzuwandeln,
> braucht man die Konstanten 2^0 .. 2^31 in Dezimaldarstellung.
Aber die muss ich auch erst mal wieder erzeugen, dann brauche ich die 
ominösen BCD-Addierer.

Die Multiplexer, die Du beschreibst, brauchen auch wieder Platz und Zeit 
und wehe, sie sind nicht in einem Takt zu machen, dann müssen die 
breiten Vektoren registriert werden.

Ich kann mir beim besten Willen nicht vorstellen, dass das schneller 
ist.

Ich glaube zudem immer noch, dass Deine Interpretation der Fragestellung 
eine andere ist:

Du schreibst:
Josef G. schrieb:
> 32 + 64  -->  0000.0011.0010

DAS!!! ist aber genau der Stiefel! Wie kommt man in einem Schlag auf die 
Umrechnung der Binärzahl auf die Deziamldarstellung?

Du nimmst in Deinem Beispiel die 11.0010 = 0.3.2 einfach an, aber 
vorliegen "tut" die Zahl als 0010000.

Ich denke, wir drehen uns da im Kreis. Alles, was ich da erkenne, ist 
mehr und aufwändiger. Die Umrechung mit dem Shift-Addierer leistet ja 
dasselbe udn ist kleiner und schneller.

Einzige das hier werde ich noch prüfen:

J. S. schrieb:
> Ausgabezahl = (3435973 * Eingabe + 343597) / 34359738368
> Rest = Eingabe - 10000 * Ausgabezahl.

Soweit habe ich das kapiert - Du teilst einfach durch 10 und rechnest 
den Rest. Das Problem, das ich sehe, sind die 32Bit breiten Zahlen:

Ich müsste sie mit einem so grossen Teiler bearbeiten, dass die 
Genauigkeit gerade noch reicht. Das sind aber aber 32Bit immerhin 10-1=9 
Stellen. Ich brauche also einen geschätzt 32 Bit breiten Multiplizierer, 
der ein Ergebnis mit 64 Bit fassen kann.

Das geht in keinem Fall mit nur einem Element, zumal in meinem FPGA nur 
18x18 Multis zur Verfügung stehen. Ich werde mal versuchen, es zu bauen 
und schauen, wie schnell es ist. Ich gehe davon aus, dass ich mindestens 
3 Takte brauche, um die Multiplikation hinzubekommen und einen weiteren 
für die Addition des Offsets / bzw die Subraktion. Jede Stufe hätte also 
4 Takte = 40 Takte insgesamt. Das kommt dann schon in dieselbe 
grössenordnung, wie die Miller-Methode und sich verbraucht wertvolle 
Multiplier!

von Josef G. (bome) Benutzerseite


Lesenswert?

Spartanist schrieb:
> Aber die muss ich auch erst mal wieder erzeugen,

Nein, die rechnest du im Kopf oder mit dem Taschenrechner
aus und definierst sie im VHDL-Design als Konstanten.

> Die Multiplexer, die Du beschreibst, brauchen auch wieder Platz

Da die gemultiplexten Werte Konstanten sind, besteht ein
Multiplexer nur aus einer einzigen LUT für jedes Bit.

> Josef G. schrieb:
>> 32 + 64  -->  0000.0011.0010
>
> DAS!!! ist aber genau der Stiefel! Wie kommt man in einem Schlag auf die
> Umrechnung der Binärzahl auf die Deziamldarstellung?

Du hast den Zwischenschritt aus meinem Beitrag weggelassen:

> 32 + 64  -->  0000.0011.0010 + 0000.0110.0100 = 0000.1001.0110

Die beiden Einzelwerte werden als Konstanten in das Design
hineingesteckt. Die Summe liefert der BCD-Addierer.

> Alles, was ich da erkenne, ist  mehr und aufwändiger.

Ich will nicht behaupten, dass mein Verfahren besser ist.
War nur ein Hinweis auf eine Alternativ-Möglichkeit.

von Spartanist (Gast)


Lesenswert?

Ich gebe zu, ich kapiere nicht, wie das gehen soll und an welcher Stelle 
man was tun muss.

Könnte man das anhand einer Formel oder eines VHDL-Beispiels 
beschreiben?

Josef G. schrieb:
> Du hast den Zwischenschritt aus meinem Beitrag weggelassen:
>
>> 32 + 64  -->  0000.0011.0010 + 0000.0110.0100 = 0000.1001.0110
>
> Die beiden Einzelwerte werden als Konstanten in das Design
>
> hineingesteckt. Die Summe liefert der BCD-Addierer.

Ich glaube, so langsam komme ich auf den Trichter:
Du hängst Dich an der Bildung der Endsumme auf. Darum geht es aber 
nicht.

Es geht um den Wert 0000.0011.0010. Wie kommt man im allgemeinen Fall zu 
diesem?

aus dem Kopf kann ich das sofort sehen, ja, aber wie sieht es der FPGA?

Ich habe doch diesen Wert nicht, ohne in zu berechen. Dass ich ihn in 
einen BCD Addierer schieben kann, ok, mag sein. Wobei noch zu klären 
wäre, wie der dann aussehen müsste.

von Josef G. (bome) Benutzerseite


Lesenswert?

Spartanist schrieb:
> Es geht um den Wert 0000.0011.0010.

constant zweihochfuenf : std_logic_vector (11 downto 0) := x"032";

(bin nicht sicher bzgl. der genauen Syntax)

von Spartanist (Gast)


Lesenswert?

Ok, JETZT habe ich es: Du verwendest die einzelnen Bits des Vektors 
jeweils einzeln und multiplizierst Dir 32 Teilergebnisse in BCD-format 
hin. Das sieht dann offenbar so aus:

1) XXXX.XXXX.XXXX
2) +    XXXX.XXXX.XXXX
3) +         XXXX.XXXX.XXXX
...
32) +                                    XXXX.XXXX.XXXX

Da sehe ich 3 Problme:

1) Muss man sich überlegen, was man womit addiert, oder man muss 
alles formulieren und die Synthese das Gewurschtel zusammenfassen 
lassen.

2) Ich bekomme eine gewaltige Menge an Scheinaddieren, die sich gfs 
nicht vernüftig zusammenfassen lassen, bzw die Synthese kreigt es nicht 
100% hin

3) Ich muss diese BCD-Addierer bauen und die scheinen mir nicht anders 
funktionieren zu können als selektive Addierer mit Umschaltungen, wenn 
ein Überlauf entseht.

Ich denke, dass das mathematisch 100% funktioniert, aber 
umsetzungstechnisch schon ein bischen ein overkill ist. Ich glaube auch 
nicht, dass das kleiner wird. Ich synthetisiere gerade mein design für 
S3E: Hat 210 slices mit 30 MHz netto ohne irgendwas.

Wenn ich es in ein design packe, 3 FF stage dahinter packe und retiming 
verwende, gelange ich zu den gewünschten 60MHz

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


Angehängte Dateien:

Lesenswert?

Spartanist schrieb:
> Ich synthetisiere gerade mein design für S3E:
> Hat 210 slices mit 30 MHz netto ohne irgendwas.
>
> Wenn ich es in ein design packe, 3 FF stage dahinter packe und retiming
> verwende, gelange ich zu den gewünschten 60MHz
Ich kann das hier bieten:
1 Takt pro BCD-Stelle, Takt 70MHz auf einem S3, Verbrauch 78 Slices, 
Aufwand 15 Minuten...
(ich hatte nur den Thread aus dem Auge verloren ;-)
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity Vector2BCD is
6
    Port ( clk      : in  std_logic;
7
           vector   : in  std_logic_vector (15 downto 0);
8
           start    : in  std_logic;
9
           busy     : out std_logic;
10
           bcd      : out std_logic_vector (19 downto 0));
11
end Vector2BCD;
12
13
architecture Behavioral of Vector2BCD is             
14
type states is (idle,calc);                          
15
signal state : states := idle;                       
16
signal stelle : integer range 0 to 4;
17
signal wert : integer range 0 to 100000;
18
begin
19
   process
20
   variable x : integer range 0 to 100000;
21
   begin
22
      wait until rising_edge(clk);
23
      busy <= '0';
24
      case state is
25
         when idle => 
26
            wert <= to_integer(unsigned(vector));            
27
            if (start='1') then 
28
               stelle <= 4;
29
               busy <= '1';
30
               state<=calc;
31
            end if;
32
                      
33
         when calc => 
34
            x := wert;
35
            if    (x>=90000) then x:=x-90000; bcd(stelle*4+3 downto stelle*4) <= x"9";
36
            elsif (x>=80000) then x:=x-80000; bcd(stelle*4+3 downto stelle*4) <= x"8";
37
            elsif (x>=70000) then x:=x-70000; bcd(stelle*4+3 downto stelle*4) <= x"7";
38
            elsif (x>=60000) then x:=x-60000; bcd(stelle*4+3 downto stelle*4) <= x"6";
39
            elsif (x>=50000) then x:=x-50000; bcd(stelle*4+3 downto stelle*4) <= x"5";
40
            elsif (x>=40000) then x:=x-40000; bcd(stelle*4+3 downto stelle*4) <= x"4";
41
            elsif (x>=30000) then x:=x-30000; bcd(stelle*4+3 downto stelle*4) <= x"3";
42
            elsif (x>=20000) then x:=x-20000; bcd(stelle*4+3 downto stelle*4) <= x"2";
43
            elsif (x>=10000) then x:=x-10000; bcd(stelle*4+3 downto stelle*4) <= x"1";
44
            else                              bcd(stelle*4+3 downto stelle*4) <= x"0";
45
            end if;
46
            wert <= x*10;
47
                    
48
            if stelle=0 then
49
               busy <= '0';
50
               state <= idle;
51
            else
52
               busy <= '1';
53
               stelle <= stelle-1;
54
            end if;
55
            
56
      end case;
57
   end process;
58
end Behavioral;

von Spartanist (Gast)


Lesenswert?

ok, das sieht nicht schlecht aus. Ist eine Mischung aus meinem Design 
und einer zyklischen Bearbeitung. Vom speed her passt es ja auch, dann 
probiere ich es gfs mal aus, wenn ich die Zeit habe, leider plagen mich 
einige andere technische Sorgen:
Beitrag "Resourcenproblem mit Spartan6"

von J. S. (engineer) Benutzerseite


Lesenswert?

Spartanist schrieb:
> Soweit habe ich das kapiert - Du teilst einfach durch 10 und rechnest
> den Rest. Das Problem, das ich sehe, sind die 32Bit breiten Zahlen:

Das stimmt natürlich, für 32 Bits wird das bei den schwachbrüstigen 
FPGAs nicht mehr in einem Takt machbar sein, wobei ich denke, dass dann 
die LÖsung mit der Kombinatorik besser sein müsste, weil sich die 
Folgeschritte, z.B. die Subraktion etc. damit verheiraten lassen und 
weniger Logik-Tiefe rauskommt, als bei verketteten Multipliern samt 
Adder-chain. Käme auf einen Versuch an.

Ich würde aber mal denken, dass in diesem Fall die internen 
LUT-/Bitkombinationen, die bei der Optimierung des kombinatorischen 
Multipliers entstehen, irgendwo dieselben sein müssten, wie sie bei der 
ausdrücklichen Abfragemethode mit den 10 Zweigen entstehen, da es ja 
derselbe Informationsgehalt ist, der verarbeitet wird und alles 
Unbenutzte an Bitausgängen rausflöge, weil der gleiche Vektor abgefragt 
wird.

Das Problem ist in beiden Fällen die Bitbreite. Lothars Code müsste dann 
auch auf die volle Stellenzahl aufgebohrt werden, also auf sogar 
9.000.000.000 abgefragt werden, wegen der unteren Stellen. Der Code 
sollte am Ende aber nicht ineffektiver sein, als Deine verketteten 
Abfragen, weil deren Ergebnisse auch irgendwie registriert werden 
müssten um auf die Geschwindikeit zu kommen. In 1-2 Takten bekommt man 
das aufgrund der Grösse einfach nicht hin.

Die verketteten Abfragen also alle hinzuschreiben, wie Du es machst, hat 
damit nur den Vorteil der vollen Bandbreite, wenn wirklich mit jedem 
FPGA-Takt auch Daten kommen.(?)

Vielleicht kann man je jeweils 2 Stufen zusammenfassen, vierfach 
pipelinen und 4fach takten, um den Umrechner genügend schnell gegenüber 
der datenspeisenden domain zu machen. Ich denke aber, dass alle Versuche 
letztlich immer wieder zu mehr FFs führen werden und kein Einspareffekt 
erzielt werden kann.

von Spartanist (Gast)


Lesenswert?

J. S. schrieb:
> Lothars Code müsste dann
> auch auf die volle Stellenzahl aufgebohrt werden, also auf sogar
> 9.000.000.000 abgefragt werden, wegen der unteren Stellen.

Ich habe nun bei beiden Versionen (der letzten von Lothar und der 
meinen) das Problem, dass ich nicht durch den Endwert teilen kann.

Ich habe das o.g. design auf 9.000.000.000 erweitert und schlage, wie 
bei meinem an dem Integerwert für 32 Bit an, wobei er mir 2h31 schon 
nicht mehr baut.

Ich müsste also erst auf die erste Stelle prüfen (1,2,3,4) da 32 Bit ja 
4 Mia sein können und danach mit den unteren Stellen fortfahren. So, wie 
es jetzt ist, funzt die Schaltung nur für Werte <= 999.999.999.

Gibt es dafür eine elegante Abfrage, die nicht an der INT-Granze 
scheitert?

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


Lesenswert?

Spartanist schrieb:
> Gibt es dafür eine elegante Abfrage, die nicht an der INT-Granze
> scheitert?
Man kann unsigned nehmen, das geht auch weit über die integer Grenze 
raus:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity Vector2BCD is
6
    Port ( clk      : in  std_logic;
7
           vector   : in  std_logic_vector (31 downto 0);
8
           start    : in  std_logic;
9
           busy     : out std_logic;
10
           bcd      : out std_logic_vector (39 downto 0)); -- 10 BCD-Stellen
11
end Vector2BCD;
12
13
architecture Behavioral of Vector2BCD is             
14
type states is (idle,calc);                          
15
signal state : states := idle;                       
16
signal stelle : integer range 0 to 9;
17
signal wert : unsigned (35 downto 0);
18
begin
19
20
   process
21
   variable x : unsigned (35 downto 0);
22
   begin
23
      wait until rising_edge(clk);
24
      busy <= '0';
25
      case state is
26
         when idle => 
27
            wert <= "0000"&unsigned(vector);     
28
            if (start='1') then 
29
               stelle <= 9;
30
               busy <= '1';
31
               state<=calc;
32
            end if;
33
                      
34
         when calc => 
35
            x := wert;
36
            if    (x>=x"218711a00") then x:=x-x"218711a00"; bcd(stelle*4+3 downto stelle*4) <= x"9";
37
            elsif (x>=x"1dcd65000") then x:=x-x"1dcd65000"; bcd(stelle*4+3 downto stelle*4) <= x"8";
38
            elsif (x>=x"1a13b8600") then x:=x-x"1a13b8600"; bcd(stelle*4+3 downto stelle*4) <= x"7";
39
            elsif (x>=x"165a0bc00") then x:=x-x"165a0bc00"; bcd(stelle*4+3 downto stelle*4) <= x"6";
40
            elsif (x>=x"12a05f200") then x:=x-x"12a05f200"; bcd(stelle*4+3 downto stelle*4) <= x"5";
41
            elsif (x>=x"0ee6b2800") then x:=x-x"0ee6b2800"; bcd(stelle*4+3 downto stelle*4) <= x"4";
42
            elsif (x>=x"0b2d05e00") then x:=x-x"0b2d05e00"; bcd(stelle*4+3 downto stelle*4) <= x"3";
43
            elsif (x>=x"077359400") then x:=x-x"077359400"; bcd(stelle*4+3 downto stelle*4) <= x"2";
44
            elsif (x>=x"03b9aca00") then x:=x-x"03b9aca00"; bcd(stelle*4+3 downto stelle*4) <= x"1";
45
            else                                            bcd(stelle*4+3 downto stelle*4) <= x"0";
46
            end if;
47
            wert <= resize(x*10, 36);
48
                    
49
            if stelle=0 then
50
               busy <= '0';
51
               state <= idle;
52
            else
53
               busy <= '1';
54
               stelle <= stelle-1;
55
            end if;
56
          
57
      end case;
58
   end process;
59
   
60
end Behavioral;

Aber jetzt brauchen wir schon 182 Slices und haben nur noch 60MHz...

von Spartanist (Gast)


Lesenswert?

Lothar Miller schrieb:
> Man kann unsigned nehmen, das geht auch weit über die integer Grenze
Das ist gut, das baue ich so um! Prima!

Lothar Miller schrieb:
> Aber jetzt brauchen wir schon 182 Slices und haben nur noch 60MHz...
Da lässt sich sicher noch ein wenig machen. Man schauen, was geht ...

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


Lesenswert?

Spartanist schrieb:
> Da lässt sich sicher noch ein wenig machen. Man schauen, was geht ...
Mit einer expliziten Reduzierung auf die nötigen 34 Bits 
(0...9999999999) sind es noch 164 oder gar 157 Slices:
1
signal wert : unsigned (33 downto 0);
2
:
3
:
4
   variable x : unsigned (33 downto 0);
5
   :
6
-- damit braucht das Design 164 Slices und schafft noch 60MHz:
7
            if    (x>="10"&x"18711a00") then x:=x-"10"&x"18711a00"; bcd(stelle*4+3 downto stelle*4) <= x"9";
8
            elsif (x>="01"&x"dcd65000") then x:=x-"01"&x"dcd65000"; bcd(stelle*4+3 downto stelle*4) <= x"8";
9
            :
10
            :
11
12
-- so brauchts 157 Slices bei nur 50MHz:
13
            if    (x>=resize(x"218711a00",34)) then x:=x-resize(x"218711a00",34); bcd(stelle*4+3 downto stelle*4) <= x"9";
14
            elsif (x>=resize(x"1dcd65000",34)) then x:=x-resize(x"1dcd65000",34); bcd(stelle*4+3 downto stelle*4) <= x"8";
15
            :
16
            :

Wobei mich der Unterschied schon ein wenig verwundert...  :-o

von Spartanist (Gast)


Lesenswert?

Weniger slices kann auch darin begründet liegen, dass er in manchen 
Pfaden keine FFs meht braucht, was dann die speed limitiert.

Wenn man mit "timing driven placement" und "register duplicating" 
arbeitet, sollte das nicht passieren.

Ich brauche jetzt 75MHz. Doppelte Architektur will ich in keinem Fall, 
lieber ein paar slices mehr.

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


Lesenswert?

Spartanist schrieb:
> Ich synthetisiere gerade mein design für S3E:
> Hat 210 slices mit 30 MHz netto ohne irgendwas.
> Wenn ich es in ein design packe, 3 FF stage dahinter packe
> und retiming verwende, gelange ich zu den gewünschten 60MHz
Spartanist schrieb:
> Ich brauche jetzt 75MHz.
Das ist ja fast schon inflationär...

von J. S. (engineer) Benutzerseite


Lesenswert?

Spartanist schrieb:
> Lothar Miller schrieb:
>
>> Aber jetzt brauchen wir schon 182 Slices und haben nur noch 60MHz...
>
> Da lässt sich sicher noch ein wenig machen. Man schauen, was geht ...

Versuche mal maximale Syntheseeinstellungen: "timing driven" + manuell 
eingestellt: "Register Duplication" - das ist nämlich nicht mit 
voreingestellt, wie ich zumindest bei der aktuellen ISE sehen muss. Auch 
"retiming" (physical resynthesis) und "restructure multiplexers" (sehr 
wichtig hier um klein & schnell zu werden).

Dann kannst du sehen, ob das überhaupt geht und dann ein wenig 
rückbauen. Rumprobieren ist da durchaus nicht falsch, bei der 
verkrüppelten XST, die taugt nämlich nicht so arg viel. Wenn, dann 
verwende Ich gerne den SMART Explorer. Der hat mir heute wieder mal ein 
Überraschungsergebnis geliefert.

Da in den thread nun schon recht viel rein gesteckt würde, schlage ich 
vor, wir machen einen Artikel daraus und jeder postet seine Version 
rein. Dann kann man mal vergleichen, bei welchen Bedingungen, welche die 
beste ist.

von Josef G. (bome) Benutzerseite


Lesenswert?

J. S. schrieb:
> schlage ich vor, wir machen einen Artikel daraus

Lohnt sich nicht.
Das Dezimalsystem wird ja eh bald abgeschafft.

von Spartanist (Gast)


Lesenswert?

Josef G. schrieb:
> Lohnt sich nicht.
>
> Das Dezimalsystem wird ja eh bald abgeschafft.

Hat wer festgelegt?

von Josef G. (bome) Benutzerseite


Lesenswert?

Spartanist schrieb:
> Hat wer festgelegt?

Vielleicht hätte ich explizit dazuschreiben sollen: Kleiner Scherz.

von MLG (Gast)


Lesenswert?

Zwischenfrage: Wozu benötigt man eine deart schnelle Konversion zum BCD 
Formamt, dass man mit MHz da ran gehen muss? Was baut ihr da für 
Monsterapplikationen?

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.