Hallo zusammen,
ich bräuchte ganz dringend Hilfe bei der Erstellung einer Bibliothek für
Festkomma-Arithmetik für das DE2-Board von Altera. Das Ganze soll
lediglich als Teilprojekt in ein größeres Projekt einfließen, weshalb
ich für die Erstellung nicht unmäßig viel Zeit investieren möchte. Gibt
es irgendwo gute Quellen oder gar eine fertige Bibliothek für dieses
Thema? Neben den Grundrechenarten interessiert mich insbesondere das
Wurzelziehen, da hab ich nämlich momentan nicht mal einen guten Ansatz,
an die Sache heran zu gehen...
Hoffe auf schnelle Hilfe...
MfG, Keev
Das allgemeine Wurzelziehen ist zwar als Core implementiert, aber wie
sieht das bei Festkommazahlen aus?
Könntest du eine beispielhafte Berechnung einer (Festkomma-)Wurzel evtl.
mal hier posten?
Aber nochmal allgemein: Gibt es keine bestehende Library für
Festkomma-Arithmetik für das Altera-Board?
Noch eine andere Frage nebenbei: Könnt ihr mir erläutern, wie ich die
HW-Multiplizierer ansprechen kann (welche Pins muss ich Fitten, kann ich
leider dem Datenblatt nicht so wirklich entnehmen, oder ich hab's aus
mit meinen müden Augen einfach immer wieder überlesen...) und mit ihnen
die Festkomma-Multiplikation durchführen kann. Das Board, das ich hier
habe, ist, wie bereits oben erwähnt, das DE2 von Altera.
Wär super, wenn mir da noch einer helfen könnte...
Meine Xilinx-Tools generieren dabei einen HW-Multiplizierer (wenn der
Baustein das kann und ich das in den Options erlaube). Vielleicht
klappts bei Altera auch (sieht man dann beim Syntheseergebnis).
@Lothar: Ja, auch ALtera generiert den Multiplizierer automatisch. die
Frage ist jetzt nur, ob es dabei egal ist, an welchem Pin ich das Ganze
am DE2-Board anlege, hat da zufällig schon jemand Erfahrung mit gemacht?
Gibt's da besondere Auswirkungen auf das Timing? Ich meine, wie schnell
kann ca. eine Multiplikation zweier 8bit-Vektoren durchgeführt werden?
@Keev
>Frage ist jetzt nur, ob es dabei egal ist, an welchem Pin ich das Ganze>am DE2-Board anlege, hat da zufällig schon jemand Erfahrung mit gemacht?
Jain. Für maximalen Durchsatz brauchst du so oder so Pipline-Register.
>Gibt's da besondere Auswirkungen auf das Timing? Ich meine, wie schnell>kann ca. eine Multiplikation zweier 8bit-Vektoren durchgeführt werden?
Das steht im Datenblatt. Ich würde mal schätzen 200MHz++.
MFG
Falk
@Keev
>Hat jemand zufällig schon mal Pipelining mit dem DE2-Board durchgeführt?
Wahrscheinlich gibts da nicht viele, das ist ne relativ neue
Technologie, so wie Hyperthreading aufm P4.
>Falls ja, könnt mir derjenige bitte einen geeigneten Ansatz dafür geben?
Google ist dein Freund.
vhdl pipelining
MfG
Falk
P.S. Wer Ironie findet darf sie behalten.
1) Ja, die Synthese wird Multiplier spendieren, es sein denn, man hat
bei den constraints etwas anderes eingestellt. Dort gibt es eine
Funktion "auto" - sieh mal genauer nach.
2) Die muliplier arbeiten intern mit > 250Mhz, weil sie spec-gemäß
innerhalb eines Taktes die multiplikation durchführen können. Wenn man
aber direkt auf die Pins rausgeht, wird es routing-bdegint langsmer
sein, auch muss man sehen, wie schnell die IO-pins agieren. Ich würde da
mal auf 100Mhz tippen - eher weniger. Noch langsameer wird es, wenn man
breite Multiplikationen braucht, wo mehrere 18-Bitter neben einander
arbeiten und über Adiererer verknüpft sind.
3) Beim pipelining, wie Du es fragst, würde ich von den IOs indirekt
über ein Register an die Eingänge der Multiplier gehen und deren
Ausgänge ebenfalls übervRegister führen. Dann die IOs als fast input und
fast output deklarieren. Ich würde sagen, daß man dann in jedem Fall auf
getaktete 150MHz kommen kann. Mit einer DDR-Architektur und Multiplexer
an den Ein- und Ausgängen sowie verdoppelter Architektur, lassen sich
sicher 200MHz erreichen.
Als Service folgender Dummy-Code mit einem zusaezlichen Registern für
breite Multiplizierer:
Asynchroner Teil (non clocked)
ina0 <= PINS_A; inb0 <= PINS_B;
mulresult1 <= std_logic_vector(unsigned(ina1) * unsigend(inb1));
OUTPUT_PINS <= mulresult4;
Synchroner Teil (clocked)
ina1 <= ina0; inb1 <= inb0;
mulresult2 <= mulresult1;
mulresult3 <= mulresult2;
mulresult4 <= mulresult3;
Man kann nun "perform register retiming" anweisen und hoffen, daß die
multiplier-Stufen gut verteilt werden. mulresult2 , mulresult2 dürfen
aber nirgendwo verwendet werden.
Zumindest haben diese zusaezlichen Register den Effekt, daß die Synthese
gut quer über den Chip routen kann (auch ohne retiming). Bei niedrigen
Taktfrequenzen kann man die beiden weglassen und das Ergebnis mulresult2
direkt auf den output legen.
Es lohnt, damit einmal herumzuspielen und zu schauen, welche Architektur
wie hoch kommt mit der Frequenz.
Da es anscheinend wirklich keine bestehende Bibliothek für
Festkomma-Arithmetik gibt, hab ich jetzt erstmal ein grobes Gerüst
aufgestellt, dass ich gerne mit Euch zusammen mit Logik füllen würde.
Da ich, wie bereits erwähnt, grad an einem anderen Programm sitze, hoffe
ich, dass ihr hier kräftig an der kleinen Bibliothek mitarbeiten werdet.
Das Gerüst ist sicher noch fehlerhaft, da ich's grad in 10min
aufgestellt habe, wär super nett, wenn da auch nochmal jemand schnell
drüber gucken könnte.
Vor allem können die geplanten Komponenten bestimmt kombiniert werden
(Addition und Subtraktion, Multiplikation und Division), dadurch könnte
das alles noch wesentlich kürzer werden...
@Keev
Du erfindest das Rad neu. Und das nicht mal sonderlich gut. Einfache
Operationen wie Addition, Subtraktion und Multiplikation werden von
allen gängigen Compilern direkt unterstützt, hinschreiben und gut. Für
Division gibts optimierte Module. Problem gelöst. Für DSP-geschichten
gibt u.a. von Xilinx das DSP Developer Kit (oder so ähnlich), der
generiert VHDL das direkt synthetisierbar ist.
MfG
Falk
D.h. es existieren bereits sämtliche Rechenoperationen für
Festkommazahlen?
Falls ja, dann beschreibt mir bitte mal, wie ich in VHDL aus folgenden
beispielhaften Festkommazahlen Summe, Differenz, Produkt und Quotient
bilde:
(der Dezimalpunkt ist selbstverständlich nur zur Verdeutlichung der
Werte, in der Realität wird das Ganze über die explizite Kommaposition
im Typ angegeben)
101.1 (entspricht 5,5 Dezimal)
0.11 (entspricht 0,75 Dezimal)
Die Summe wäre in diesem Fall z.B. 110.01 (= 6,25 Dezimal), hierfür
müssten die Werte aber vorher entsprechend skaliert werden (dafür
bräuchte ich auch noch ne Funktion!), wenn ich aber in VHDL einfach 1011
+ 011 berechnen lassen würde, würde ich als Ergebnis 1100 (also Dezimal
12) erhalten und das will ich ja grad nicht...
Ich hoffe, meine Problematik dadurch etwas verdeutlicht zu haben...
Upps, es würde selbstverständlich bei 1011 + 011 folgendes rauskommen,
was ich nicht haben will: 1110 (also Dezimal 14)
kleiner Fehler in der Eile...;)
>wenn ich aber in VHDL einfach 1011>+ 011 berechnen lassen würde
Mit Verlaub, aber so ist das natürlich Quatsch.
Du hast doch zwei Stellen hinter dem Komma. Deine Nachkommabits sind
die letzten zwei Bits, also:
101,10 (= 5,5)
0,11 (= 0,75)
addiert ergibt das:
110,01 (= 6.25)
Und das soll ja wohl auch rauskommen.
@Keev
>D.h. es existieren bereits sämtliche Rechenoperationen für>Festkommazahlen?
LESEN! Addition, Subtraktion und Multiplikation. Division nur über
Module.
>(der Dezimalpunkt ist selbstverständlich nur zur Verdeutlichung der>Werte, in der Realität wird das Ganze über die explizite Kommaposition>im Typ angegeben)
???? Was für ein Typ?
Festkommazahlen haben auf Bitebene (und mit der musst du dich in VHDL
"rumschlagen") kein Komma. Es sind stinknormale std_logic_vector oder
eben signed/unsigned Signale.
>101.1 (entspricht 5,5 Dezimal)
???
>0.11 (entspricht 0,75 Dezimal)
???
Du wirfst Zahlensysteme (Binär, Dezimal) mit Fest/Fliesskomma
durcheinander. Nicht gut.
Einfacher Ansatz. Deine Zahlen sind immer 16 bit breit, die unteren acht
repräsentieren die nachkommastellen, die oberen die Vorkommastellen. Nun
kannst du ganz problemlos rechnen. Und wenn du irgendwann mal die Zahlen
in menschenlesbare Form bringen willst, musst du die unteren Bits in
ASCII als Nachkomma wandeln und die oberen in Vorkomma als ASCII.
Beispiel.
a <= x"0588";
Vorkomma 5
Nachkomma 0x88/256 = 136/256 = 0,53125
Ja, man kann dabei nicht einfach schreiben
a <= 1.34;
Das müsste man hier als
a <= x"0157";
schreiben.
>+ 011 berechnen lassen würde, würde ich als Ergebnis 1100 (also Dezimal>12) erhalten und das will ich ja grad nicht...>Ich hoffe, meine Problematik dadurch etwas verdeutlicht zu haben...
Du hast Festkommazahlen noch nicht wirklich verstanden.
MfG
Falk
Äh, genau das hab ich doch oben geschrieben?!?!? DAS ist ja auch genau
das, was ich haben möchte (und was ich, mit Verlaub, oben auch
beschrieben habe), aber ich kann ja in VHDL nicht direkt 101,10 als
Input geben, intern wird das doch immer als 10110 interpretiert. Ich
muss dem Programm ja irgendwie mitteilen, wo das Komma sitzt und
entsprechend skalieren (und wie bereits gesagt, würde mir solch eine
Skalierungsfunktion auch schon enorm weiterhelfen.
Diese Funktion müsste dann halt bei den Inputs 101(,)10 und 0(,)11
folgende Vektoren machen: 10110 und 00011 (also beide Vektoren auf die
gleiche Länge normieren)
Noch besser sieht man das an folgenden Inputwerten:
10.10001 und 1011, daruas müsste die Funktion folgernde Vektoren
generieren: 001010001 und 101100000
@Falk So hab ich das auch verstanden. Das Problem, was ich aber immer
noch hab, ist, dass ich zwei Inputs vom Typ std_logic_vector habe
(variable Längen!), die Position des Kommas wird explizit ebenfalls als
Input angegeben. Nun möchte ich mit diesen beiden Inputs die
Grundrechenarten durchführen können, dazu muss in der Regel skaliert
werden (der zweite Input an den ersten angepasst werden, so dass beide
Inputs über gleich viele Vor- und Nachkommastellen verfügen...
Das "Komma" hab ich oben immer nur mitgeschrieben, um zu verdeutlichen,
welche Werte ich haben möchte.
Selbstverständlich ist mir klar, dass ich eigentlich nur Bitfolgen
habe...
@Keev
>beschrieben habe), aber ich kann ja in VHDL nicht direkt 101,10 als>Input geben, intern wird das doch immer als 10110 interpretiert. Ich>muss dem Programm ja irgendwie mitteilen, wo das Komma sitzt und>entsprechend skalieren (und wie bereits gesagt, würde mir solch eine
Nöö, das ist der Hardware piepegal. Du musst dich um die Interpretation
kümmern.
>Skalierungsfunktion auch schon enorm weiterhelfen.
Das ist dann aber schon wieder Fliesskomma.
>Diese Funktion müsste dann halt bei den Inputs 101(,)10 und 0(,)11>folgende Vektoren machen: 10110 und 00011 (also beide Vektoren auf die>gleiche Länge normieren)
Das geht möglicherweise über Funktionen. Hab ich aber nicht so den
Durchblick im Moment. Im Prinzip brauchst du ja nur Makros, die
"normale" Bruchzahlem ala 1,234 in entsprechende Festkommazahlen
umwandeln (bei gegebenem Datenformat /Bitbreite).
>@Falk So hab ich das auch verstanden. Das Problem, was ich aber immer>noch hab, ist, dass ich zwei Inputs vom Typ std_logic_vector habe>(variable Längen!), die Position des Kommas wird explizit ebenfalls als>Input angegeben. Nun möchte ich mit diesen beiden Inputs die
Was soll das denn am Ende überhaupt werden?
>Grundrechenarten durchführen können, dazu muss in der Regel skaliert>werden (der zweite Input an den ersten angepasst werden, so dass beide>Inputs über gleich viele Vor- und Nachkommastellen verfügen...
Klingt sehr nach Fliesskomma.
>Selbstverständlich ist mir klar, dass ich eigentlich nur Bitfolgen>habe...
Jaja, aber mit der Interpretation ist es wohl nicht so klar.
MFG
Falk
Sollen das Dezimalwerte sein? Ich würde INT-Festkomma nehmen, denn dann
kann man leicht mit Nullen erweitern. Du solltes einfach mit 2
getrennenten Werten für Vorkomma und Nachkomma arbeiten.
Trotzdem frage ich mich, was das bringt, ausser einen Riesen overhead.
Ausserdem muss der user imer per Hand nachsklaieren, statt
Multiplkationen und Uminterpreationen driekt per "downto" in einem
Rutsch zu machen. Oft braucht er dann noch einen zusaetzlichen
clock-Takt.
@Olipolli
>kann man leicht mit Nullen erweitern. Du solltes einfach mit 2>getrennenten Werten für Vorkomma und Nachkomma arbeiten.
Das wäre dann quasi BCD. Dann kannst du aber sämtliche Arithmetische
Operationen per Hand machen.
MFG
Falk
Hm, mag sein, dass ich mich hier etwas verrannt habe.
Also mal eine Verständnisfrage für mich:
Wäre folgende Rechung Fest- oder Fließkomma (ich nehm jetzt einfach mal
Dezimalwerte)?
5,75 + 16,003
Oder handelt es sich nur um eine Festkommarechnung, wenn beide Operanden
die gleiche Anzahl an Vor- und Nachkommastellen haben, also sowas wie
5,5+6,1?
oder um in der VHDL-Thematik zu bleiben:
Wäre eine Rechnung zweier 8Bit-Vektoren nur eine Festkomma-Rechnung,
wenn für beide die gleiche Anzahl an Bits für Nachkommastellen definiert
sind? Ist alles andere automatisch Fließkomma?
In meiner Aufgabe steht nämlich leider explizit drin, dass ich eine
Bibliothek für Festkomma-Arithmetik einbinden soll...
Hm, in der Aufgabe steht aber leider auch folgendes:
"Man kann also einstellen wieviele Vorkomma- und
Nachkommastellen vorhanden sein sollen, es soll möglich sein mit
unterschiedlich langen Vor- und Nachkommastellen zu rechnen. Festlegung
des Ergebnistyps bzgl. Anzahl Nachkommastellen sollte einstellbar sein"
Leider nein, mein Prof ist zur Zeit im Urlaub und der Abgabetermin quasi
kurz nach seiner Rückkehr...:(
Naja, irgendwie krieg ich das wohl auch noch so hin, dachte nur, dass
mir hier im Forum evtl. ein paar Tipps zumindest für die Erstellung der
Bibliothek gegeben werden können.
Schau die mal auf der Seite:
http://www.accellera.org/apps/group_public/documents.php?wg_abbrev=vhdl
die Fixed & Floating-Point Libs an.
Die sollen auch in der kommenden Revision des VHDL-Standards mit
aufgenommen werden. Enthalten ist auch eine Version, die mit dem VHDL'93
Standard kompatibel ist. Diese kann wohl auch mit einigen
Synthesewerkzeugen verwendet werden, mit XST (ISE8.2) funktioniert es
nicht, zumindestens hab ich es nicht hinbekommen.
Aber vielleicht nützen dir die was, wegen der Vorgehensweise.
@Keev
>Also mal eine Verständnisfrage für mich:>Wäre folgende Rechung Fest- oder Fließkomma (ich nehm jetzt einfach mal>Dezimalwerte)?>5,75 + 16,003
Das häng von dir ab! Du kannst das mit Floating Point oder Fixpoint
rechnen. So wie du C selber entscheiden musst, ob du mit INT oder REAL
rechnest.
>Oder handelt es sich nur um eine Festkommarechnung, wenn beide Operanden>die gleiche Anzahl an Vor- und Nachkommastellen haben, also sowas wie>5,5+6,1?
Das hat damit nix zu tun. Du hast das Prinzip von Fest-und Fliesskomma
noch nicht verstanden. Da musst du dich nochmal ranmachen.
>Wäre eine Rechnung zweier 8Bit-Vektoren nur eine Festkomma-Rechnung,>wenn für beide die gleiche Anzahl an Bits für Nachkommastellen definiert>sind? Ist alles andere automatisch Fließkomma?
Nein, nein, nein.
Wenn du mit zwei 8 Bit Vektoren "normal" rechnest (also mit den von VHDL
direkt unterstützten Rechenoperationen), dann müssen beide Vektoren das
gleiche Festkommaformat haben, also gleiche Anzahl Vor-und
Nachkommastellen. (Jaja, die Profis können auch hier noch tricksen, wir
wollen den Aspiranten aber mal nicht noch mehr verwirren).
>In meiner Aufgabe steht nämlich leider explizit drin, dass ich eine>Bibliothek für Festkomma-Arithmetik einbinden soll
Aha, wir kommen dem Problem näher.
>"Man kann also einstellen wieviele Vorkomma- und>Nachkommastellen vorhanden sein sollen, es soll möglich sein mit>unterschiedlich langen Vor- und Nachkommastellen zu rechnen. Festlegung>des Ergebnistyps bzgl. Anzahl Nachkommastellen sollte einstellbar >sein"
Nun, das könnte man über Module mit Generics machen. Ist aber in der
praktischen Anwendung eher unpraktisch, weil dann alle Rechenoperationen
über die Verdrahtung von Modulen (ALUs) erfolgen, was nicht sonderlich
lesbar ist.
>Leider nein, mein Prof ist zur Zeit im Urlaub und der Abgabetermin quasi>kurz nach seiner Rückkehr...:(
Ahhhh, gaaaanz heiss! ;-)
>mir hier im Forum evtl. ein paar Tipps zumindest für die Erstellung der>Bibliothek gegeben werden können.
Die Aufgabe istrecht akademisch, sowas können Leute in der Praxis kaum
gebrauchen, deshalb wirst du wohl nicht viel finden.
MfG
Falk
@T.M.: Danke, die Quellen dort haben mich schon ein Stück weiter
gebracht.
@Falk: Hast du evtl. gute Quellen für den Gebrauch von Generics?
So, hab das andere Prog jetzt auch fertig, so dass ich mich vollends auf
diese Bibliothek stürzen kann. So langsam hab ich das mit den
Festkommazahlen auch verstanden (hoffe ich zumindest). Aber wenn ich das
richtig sehe, bleibt mir (da die Inputwerte verschiedene Längen und
"Kommapositionen" haben dürfen) nichts anderes übrig, als die Inputwerte
zu skalieren, sonst kann ich ja keine Addition bzw. Subtraktion
durchführen...