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.
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.
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?
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?
ä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...
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.
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...
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.
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... ;-)
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.
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?
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.
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.
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)
?
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)...
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.
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.
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?
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.
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.
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.
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!
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.
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.
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)
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
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 ;-)
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"
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.
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?
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:
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 ...
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
signalwert:unsigned(33downto0);
2
:
3
:
4
variablex:unsigned(33downto0);
5
:
6
-- damit braucht das Design 164 Slices und schafft noch 60MHz:
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.
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 60MHzSpartanist schrieb:> Ich brauche jetzt 75MHz.
Das ist ja fast schon inflationär...
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.
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?