mikrocontroller.net

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


Autor: Marco (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
signal neues_signal, altes_signal integer;
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???

Autor: RRR (Gast)
Datum:

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

Autor: Mark (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Marco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1000 DANK

Autor: Start-ING (Gast)
Datum:

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

Autor: Marco (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?
signal signal_1, signal_2, neues_signal integer;

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

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du siehst aber schon, dass der Bruch so keinen Sinn macht oder?

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
signal signal_1, signal_2, neues_signal integer;

neues_signal <= (((9375*signal_1)/512) / ((9375*signal_2)/512));            

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Marco (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
Signal s_adc2, s_adc1: std_logic_vector (13 downto 0);

http://www.tek-tips.com/viewthread.cfm?qid=1455531...
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
Signal signal_1, signal_2, neues_signal : integer;
 
signal_1 <= to_integer(unsigned(s_adc1));
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
signal_1 <= ((signal_1*93)/512); -- 0000-3000
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
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

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Mathi (Gast)
Datum:

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

Autor: Gast (Gast)
Datum:

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

Autor: Marco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe meine Division komplett umgebaut (wie in der 3. Klasse)
if s_adc1 > s_adc2 then
   s_adc1 <= if s_adc1 - s_adc2 then;
   zaehler <= zaehler + 1;
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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.