Hallo,
ich verwende ein ZedBoard, auf welchem sich ein ARM Cortex A befindet.
Nun habe ich den ARM mit dem FPGA verbunden und moechte Daten vom ARM
zum Zedboard mittels AXI Lite senden.
Mein FPGA-Design sieht es vor 2x 32 bit Werte zu empfangen. Einen 32 Bit
Wert fuer eine Vorkommastelle, eine fuer eine Nachkommastelle.
Nun habe ich in dem C-Teil ein double wert, diesen ich gerne in 32 Bit
Vorkommastelle und 32 Bit Nachkommastelle aufteilen moechte.
Mein erster Versuch war, die Vorkommastelle als u32 zu casten. - Hat
funktioniert.
Problem:
Moechte ich die Nachkommastelle umwandeln in integer, schneidet er mir
die fuehrenden Nullen ab.
z.B. 9.000414
(int) Vorkommastelle = 9
(int) Nachkommastelle = 414 (anstatt 000414)
Habt ihr vll. noch eine Idee wie das funktionieren koennte?
Danke im voraus.
Eine Double-Zahl in einem µC besteht nicht aus Vor- und
Nachkommastellen, sondern aus Mantisse und Exponent. Die Interpretation
als Vor- und Nachkommastellen ist nur eine Sache der Darstellung für
eine Anzeige und hat mit der internen Darstellung ausgesprochen wenig zu
tun. Wenn du auf dem FPGA eine Fixkommazahl brauchst, wäre es also eher
sinnvoll, direkt eine 64-Bit uint mit passender Normierung zu
übertragen.
LilaLauneBart schrieb:> Problem:> Moechte ich die Nachkommastelle umwandeln in integer, schneidet er mir> die fuehrenden Nullen ab.
Nein. Ein int ist immer gleich lang, da kann nicht einfach was
abgeschnitten werden. Ich vermute, daß du den Wert irgendwie ausgibst,
und die Nullen bei der Ausgabe abgeschnitten werden.
LilaLauneBart schrieb:> Nun habe ich in dem C-Teil ein double wert, diesen ich gerne in 32 Bit> Vorkommastelle und 32 Bit Nachkommastelle aufteilen moechte.>> Mein erster Versuch war, die Vorkommastelle als u32 zu casten. - Hat> funktioniert.>> Problem:> Moechte ich die Nachkommastelle umwandeln in integer, schneidet er mir> die fuehrenden Nullen ab.>> z.B. 9.000414> (int) Vorkommastelle = 9> (int) Nachkommastelle = 414 (anstatt 000414)>> Habt ihr vll. noch eine Idee wie das funktionieren koennte?
Wieso?
Passt doch.
Was du an deinen FPGA überträgst, ist die Information, dass der
Nachkommateil aus 414 Millionstel bestehen. Das es sich dabei um
Millionstel handelt ist der entscheidende Punkt! Das weiss dein ARM,
weil du zur Gewinnung des ganzzahligen Anteils mit 1 Million
multipliziert hast und das muss auch im FPGA berücksichtigt werden, wenn
du dort die komplette Zahl wieder zusammensetzt. Tatsächlich hast du
deine Zahl x nicht einfach nur in Vorkomma und Nachkommaanteil
aufgedröselt, sondern du hast sie in die Form
1
b
2
x = a + ---------
3
1000000
gebracht, so dass a und b ganzzahlig sind. Die 1000000 übergibst du aber
nicht an den FPGA, sondern die ist bzw. muss als implizites Wissen in
den beiden Kommunikationspartnern vorhanden sein.
>> z.B. 9.000414> (int) Vorkommastelle = 9> (int) Nachkommastelle = 414 (anstatt 000414)>> Habt ihr vll. noch eine Idee wie das funktionieren koennte?>> Danke im voraus.
double zahl = 9.000414;
int Vorkommastelle = (int) zahl
Nachkommastelle = (zahl - Vorkommastelle)*10^6 geht so nicht?
LilaLauneBart schrieb:> Mein FPGA-Design sieht es vor 2x 32 bit Werte zu empfangen. Einen 32 Bit> Wert fuer eine Vorkommastelle, eine fuer eine Nachkommastelle.
Ich würde sagen, dann liegt der Fehler an dieser stelle.
Wenn der FPGA mit den Werten weiterrechnen soll, dann wäre eine
Aufteilung nach (z.B.) 2^20 statt 10^6 vermutlich viel sinnvoller.
Oder, wenn es dir darum geht, dass die Zahlen nachher schön "human
readable" angezeigt werden, dann z.B. gleich BCD.
Ein Design wie deines ist zwar für Menschen naheliegend, weil die ihr
ganzes Leben primär mit Zahlendarstellungen zur Basis 10 gerechnet
haben, für digitale Systeme aber eher ungünstig.
LilaLauneBart schrieb:> Mein FPGA-Design sieht es vor 2x 32 bit Werte zu empfangen. Einen 32 Bit> Wert fuer eine Vorkommastelle, eine fuer eine Nachkommastelle.
Falsches Design: 1,034 sähe in den 2x32bit genauso aus wie 1,34.
Die Dezimalstellen müssen entweder als Character übertragen werden oder
es braucht die zusätzliche Angabe eines Offsets für die führenden
Nullen.
LilaLauneBart schrieb:> Moechte ich die Nachkommastelle umwandeln in integer,
durch x-(int)x ? Und wie dann in int ?
> schneidet er mir die fuehrenden Nullen ab.>> z.B. 9.000414> (int) Vorkommastelle = 9> (int) Nachkommastelle = 414 (anstatt 000414)
Es gibt keine führenden Nullen bei int Zahlen.
LilaLauneBart schrieb:> Nun habe ich in dem C-Teil ein double wert, diesen ich gerne in 32 Bit> Vorkommastelle und 32 Bit Nachkommastelle aufteilen moechte.
Ein 64 bit double Wert hat keine 32 Vorkomma und 32 Nachkommabits.
Er ist ein Floating Point Wert, guckst du frexp
https://msdn.microsoft.com/en-us/library/w1xfschh.aspx
Ob das, was bei (int)x entsteht, überhaupt in 32 bit passt, ist völlig
unklar. War die Zahl grösser, ist der Rest kommentarlos verschluckt
worden.
Und wie viele nachkommastellen sie hat, ist ebenfalls unklar, von keine
bis 308 ist wohl alles möglich, und vieles davon passt nicht in 32 bit.
Du hast also ein prinzipielles Verständnisproblem, der Compiler
reflektiert das nur.
Wenn du immer 6 Nachkommastellen erwartest, und es dir Scheissegal ist
was passiert wenn das nicht der Fall ist, kannst du
f=(int)(100000.0*(x-(int)x)
rechnen. Vermutlich hast du auch so deine 414 erhalten. Dann kannst du
sie immer mit 6 Stellen ausgeben printf("%06u",f).
Wenn es nicht um Super-High-Speed geht, habe ich immer den folgenden Weg
gewählt:
Fließkommazahl minus Int(Fließkommazahl).
printf (Puffer, "%.10f", Fließkommazahl);
Im Puffer steht dann etwas wie "0.000414".
Damit kannst Du dann machen, was Du willst.
Das Ganze ist zwar nicht übermäßig elegant, aber in 10 Jahren auch noch
lesbar.
Fragt man sich natürlich, was das FPGA mit diesem, aus Sicht der
Zahlendarstellung, recht komischen Mischmasch überhaupt anfangen soll?
Für Ziffernausgabe wäre - wie schon geschrieben - BCD günstiger, für
Fixkommarechnung ein 64 Bit Integer. Und echtes 64bit IEEE-Float im FPGA
möchte man eher selten haben.