Rechnen mit VHDL signed/unsigned

Gast #894753
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???
Gast #894769
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.
Gast #940769
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
Gast #941204
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
Gast #941317
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ß
Gast #942026
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren