Das Bit 17 bei sum1 ist also das "Vorzeichenbit".
Bei sum2 ist Bit 31 das "Vorzeichenbit".
Wie kann ich diese beiden signed Vektoren nun korrekt addieren, damit
mir nicht die Vorzeichen um die Ohren fliegen?
Wenn ich einfach
1
sum:=sum1+sum2;
rechne, wird das Vorzeichenbit von sum1 ja nicht korrekt bewertet, oder?
Oder ist der signed Typ genau dafür da, dass genau das funktioniert?
Muss ich so rechnen?
Calc schrieb:> Wenn ich einfach sum := sum1 + sum2;> rechne, wird das Vorzeichenbit von sum1 ja nicht korrekt bewertet, oder?> Oder ist der signed Typ genau dafür da, dass genau das funktioniert?
Einfach mal den "+" Operator in der numeric_std ansehen:
http://www.csee.umbc.edu/portal/help/VHDL/numeric_std.vhdl
Denn dort steht dann:
1
-- Id: A.3
2
function"+"(L,R:UNSIGNED)returnUNSIGNED;
3
-- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0).
4
-- Result: Adds two UNSIGNED vectors that may be of different lengths.
Calc schrieb:> sum := sum1(17) & "00000000000000" & sum1(16 DOWNTO 0)
Das ist für signed FALSCH. Denn alle die Bits, die da jetzt '0' sind,
müssten sum(17) sein:
> sum := sum1(17) & sum1(17) & ... & sum1(17) & sum1(16 DOWNTO 0)
Ein Tipp: um dir das alles zu ersparen sieh dir mal die Funktion
resize() aus der numeric_std an...
Was macht die Funktion resize praktisch? Anschauen ob es signed ist
und dann anders rechnen?
Was spricht dagegen, das per Hand zu machen oder nur eine Sorte zu
benutzen in einem VHDL Modul?
Vielen Dank! Das ist ein guter Hinweis...
Wenn ich zwei signed Values mit gleicher Vektorlänge addiere, dann passt
das noch gut mit dem + zusammen, ist aber wohl unsauber.
Also muss ich das so
Rolf S. schrieb:> Was macht die Funktion resize praktisch?
Das, was in der Beschreibung steht: bei singed wird mit dem "linkesten"
Bit aufgefüllt. Bei unsigned mit '0'...
> Anschauen ob es signed ist und dann anders rechnen?
Warum siehst du dir die numeric_std nicht einfach mal an?
Dort ziemlich weit unten:
http://www.eda.org/rassp/vhdl/models/standards/numeric_std.vhd> Was spricht dagegen, das per Hand zu machen oder nur eine Sorte zu> benutzen in einem VHDL Modul?
Kann man machen, wenn man nur 1 Datentypen braucht. Aber wozu singed
verwenden, wenn bestimmte Werte nur unsigned sein können?
Calc schrieb:> Also muss ich das so> sum := signed(std_logic_vector(> unsigned(std_logic_vector(sum1)) + unsigned(std_logic_vector(sum2)) ));> machen?
Nein, so: sum := sum1 + sum2;
Calc schrieb:> Das Bit 17 bei sum1 ist also das "Vorzeichenbit".> Bei sum2 ist Bit 31 das "Vorzeichenbit".
Da fällt mir auf: das stimmt NICHT für normale Zweierkomplementzahlen.
Hast du ein anderes Zahlensystem?
Lothar M. schrieb:> Da fällt mir auf: das stimmt NICHT für normale Zweierkomplementzahlen.> Hast du ein anderes Zahlensystem?
Nein, habe ich nicht.
Wieso sollte diese Darstellung nicht für normale
Zweierkomplementzahlengelten?
Ich habe eine Summe, die positiv und negativ sein kann.
Wenn ich also bis maximal 2^3 in die eine Richtung zählen kann, füge ich
ein Bit hinzu und kann genauso weit in die andere Richtung zählen, oder
nicht?
-8...0...7 so kenne ich das, oder habe ich da auch noch einen
Denkfehler?
Calc schrieb:> -8...0...7 so kenne ich das, oder habe ich da auch noch einen> Denkfehler?
Die Übertragung ins Zweierkomplement...
Wie sieht 1 aus? Und wie -1? Sind die etwa gleich nur mit
unterschiedlichem "Vorzeichenbit"? Reicht es aus, das "Vorzeichenbit" zu
setzen, um das Vorzeichen umzukehren?
Fazit: es gibt kein "Vorzeichenbit". Sondern man kann einfach nur am
signifikanten Bit erkennen ob die Zahl positiv oder negativ ist.
Markus F. schrieb:> Rechner mit Einerkomplementdarstellung gab's auch mal...>
Aber auch beim Einerkomplement gibt es kein Vorzeichenbit. Anders sieht
das bei der "Sign-Magnitude" Darstellung aus.
@Calc - Lothars Link lohnt sich, einfach mal weiterlesen:
1
-- Id: A.4
2
function"+"(L,R:SIGNED)returnSIGNED;
3
-- Result subtype: SIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0).
4
-- Result: Adds two SIGNED vectors that may be of different lengths.
Das Addieren funktioniert also auch für signed-Zahlen mit
unterschiederlicher Breite - beantwortet das Deine Frage?
BTW: unsigned lässt sich auf mehr als eine Art in einen signed-Vektor
transformieren:
* durch Erweiterung um den negativen Wertebereich - zusätzliches Bit
* durch Subtraktion von 2**(N-1) - gleichbeibende Wortbreite
Letzteres Verfahren ist z.B. angebracht, wenn Werte aus einem ADC mit
unipolarem Ausgang symmetriert werden sollen, weil sie z.B. einem
Audio-Codec zugeführt werden.
Wer nur rechnen will, bleibt am Besten bei der Numeric. Da ist
sichergestellt, dass die Ergebnisse passen und nicht irgendwie
verschnitten werden.
Bei den Vektoren muss man immer gedanklich mitschleppen, wie viele
Kommastellen es da gab und mit welchem Vorfaktor das Ergebnis hinterlegt
ist. Das ist nur bei wenigen Applikationen sinnvoll, da aufwändiger,
wenn auch zumindest beim Kontakt des VHDL mit der Außenwelt zumindest an
zwei Stellen unumgänglich, wenn es auf die PORTS geht.
Wenn man allerdings jetzt noch den Sachverhalt hinzunimmt, dass man bei
komplizierteren Berechnungen sowieso die Repräsentation und Überläufe in
den "Variablen" vorberechnen und das Ganze designen muss, kann man die
Vektoroperationen gleich mitrechnen lassen. Der Vorteil ist dann der,
dass man wirklich sieht, wo man Bits einsparen kann. Und man kann es
sogar ein wenig steuern und trimmen.
Lothar M. schrieb:> Das, was in der Beschreibung steht: bei singed wird mit dem "linkesten"> Bit aufgefüllt. Bei unsigned mit '0'...
Man lernst nie aus...