Forum: FPGA, VHDL & Co. Rechnen mit VHDL signed/unsigned


von Marco (Gast)


Lesenswert?

Hallo,

möchte mit einem von mir generierten Signal rechnen und komme nicht so 
ganz weiter - der Fehler müsste wegen signed/unsigned komme aber ich 
komme gerade nicht weiter.

Das Signal ist vom Typ interger im Beispiel 7680
Mit diesem Signal möchte ich nun mittels Dreisatz ein neues Signal 
generieren
1
signal neues_signal, altes_signal integer;
2
neues_signal <= (300000*altes_signal)/16384);  -- 16384 für 14bit
was nun anliegt am neuen Signal anliegt -121519, was aber eigentlich 
richtig wäre: neues_signal=140625

Wie bekomme ich es hin aus dem sicherlich falschen signed Signal ein 
unsigned generieren zu lassen???

von RRR (Gast)


Lesenswert?

Ist integer nicht nur bis 2^31 definiert?
-->300000 * 7680 ist größer als 2^31  !

von Mark (Gast)


Lesenswert?

Hi Marco,

integer ist 32bit, Deine Werte sind zu groß dafür, das erste 
Zwischenergebnis
kommt offenbar in den neg. integer-Bereich, damit wird es falsch.
Du brauchst einen größeren Datentypen.

von Marco (Gast)


Lesenswert?

1000 DANK

von Start-ING (Gast)


Lesenswert?

schulmathematik bringt den ANsatz, erst mal die konstanten werte zu 
KÜRZEN, das führt zu
(9375*altes Signal)/512

von Marco (Gast)


Lesenswert?

Das passt ja ganz gut, danke, aber was mache ich wenn ich zwei Werte 
habe und über diese einen weitere Wert ermitteln möchte?
1
signal signal_1, signal_2, neues_signal integer;
2
3
neues_signal <= (9375*signal_1)/512) / (9375*signal_2)/512);

Die Fehlermeldung lautet: Operator <DIVIDE> must have constant operands 
or first operand must be power of 2

von Gast (Gast)


Lesenswert?

Du siehst aber schon, dass der Bruch so keinen Sinn macht oder?

von Christian (Gast)


Lesenswert?

1
signal signal_1, signal_2, neues_signal integer;
2
3
neues_signal <= (((9375*signal_1)/512) / ((9375*signal_2)/512));

von Gast (Gast)


Lesenswert?

Man munkelt, dass ist identisch mit sig1/sig2..

Divisionen sind aber in VHDL nicht so einfach umzusetzen wie in C oder 
Cpp.
Siehe Rechnen in VHDL

von Marco (Gast)


Lesenswert?

Gut, um nicht noch mehr Verwirrung zu stiften, erkläre ich nochmal 
ausführlich mein Problem:

Was ich habe sind 2 Signale (14Bit) die ich in meine Toplevel übertragen 
bekomme
1
Signal s_adc2, s_adc1: std_logic_vector (13 downto 0);

http://www.tek-tips.com/viewthread.cfm?qid=1455531&page=1
Dieser Aussage zufolge habe ich erst gar nicht versucht die beiden werte 
miteinander zu dividieren.

Also habe ich mit 2 signale "gebastelt" 0-16383, jedoch stehen diese 
beide nicht im gleichen Verhältnis zueinander
1
Signal signal_1, signal_2, neues_signal : integer;
2
 
3
signal_1 <= to_integer(unsigned(s_adc1));
4
signal_2 <= to_integer(unsigned(s_adc2));

also will ich diese erst mal auf das richtige Verhältnis bringen und 
dann miteinander dividieren. signal_1 soll von 0000-1000 reichen und 
signal_2 von 0000-3000 reichen
1
signal_1 <= ((signal_1*93)/512); -- 0000-3000
2
signal_2 <= ((signal_2*31)/512); -- 0000-1000
das ganze ist aber gerade durch das kürzen sehr ungenau!

zum Schluss will ich im Prinzip nur diese beiden Werte dividieren
1
neues_signal <= signal_1/signal_2;

später muss der Wert dann wieder zurück gewandelt werden in 14Bit aber 
so weit bin ich noch lange nicht...

Die Beispielsrechnung sieht wie folgt aus

neues_signal=s_adc1/s_adc2=(1200*100)/500=240
die 100 dient um auch im Ergebnis die 2 Nachkommastellen zu bekommen...
oder noch besser 
neues_signal=s_adc1/s_adc2=("01100110011001"*300)/"01111111111111"="0011 
1101011011"

Vielleicht hat ja jemand ne gute Idee (vielleicht sogar ganz ohne 
to_integer) Grüße MARCO

von Gast (Gast)


Lesenswert?

Für Divisionen stellen so gut wie alle (ich hoffe das stimmt jetzt, 
kenne nur die von Xilinx und Altera) extra IP-Cores bereit. Die sollten 
für deine Anwendung hinreichend sein.

Wenn du es um bedingt per Hand machen willst (das ist aber schon mit 
Aufwand verbunden), dann am besten mit einer Radix-2 Integer Division 
oder mit dem Verfahren nach Goldschmidt.

Gruß

von Mathi (Gast)


Lesenswert?

512 ist noch immer ne Zweier-Potenz... Da muss man nicht dividieren, 
sondern nur shiften...

von Gast (Gast)


Lesenswert?

Er will aber die 2 Signale durcheinander Teilen, da kommt er um eine 
Divisionseinheit nicht herum

von Marco (Gast)


Lesenswert?

Habe meine Division komplett umgebaut (wie in der 3. Klasse)
1
if s_adc1 > s_adc2 then
2
   s_adc1 <= if s_adc1 - s_adc2 then;
3
   zaehler <= zaehler + 1;
4
end if;

da ich die sache etwas genauer haben möchte erweitere ich das Signal 
s_adc1 um 100 => entspricht zwei Nachkommastellen.

Das ganze kostet zwar etwas Zeit aber auf die schnelle finde ich keine 
leichtere Lösung

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.