2013-11-26 8 views
5

Dies ist eine ziemlich einfache Frage, aber ich konnte diese Arbeit noch nicht machen, noch hat jede Suche bei Google oder hier etwas wirklich Nützliches ergeben .VHDL - Hinzufügen von zwei 8-Bit-Vektoren in einen 9-Bit Vektor

Alles, was ich versuche, ist, zwei 8-Bit-Vektoren hinzuzufügen und das Ergebnis in einem 9-Bit-Vektor zu speichern.

signal operand1, operand2 : STD_LOGIC_VECTOR(7 downto 0); 

signal sum : STD_LOGIC_VECTOR(8 downto 0); 

sum <= operand1 + operand2; 

Allerdings erhalte ich die Warnung:

Width mismatch. <sum> has a width of 9 bits but assigned expression is 8-bit wide. 

nicht VHDL haben sollte, eine Art in Routine gebaut zu wissen, dass ein zusätzliches Bit für die Zugabe Überlauf notwendig ist?

Ich habe diese Pakete enthalten:

use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.STD_LOGIC_UNSIGNED.ALL; 

Vielleicht std_logic_vector immer unterzeichnet? Wenn ja, muss ich sie explizit als unsigniert definieren?

Antwort

11

Wenn Ihr Ziel Arithmetik auf Ihre Signale zu tun ist, in die Gewohnheit sie mit besser geeigneten Typen für den Job zu erklären: unsigned oder integer sind eine gute Wahl in dein Fall.

Beachten Sie, dass Überlauf zu verhindern, müssen Sie verketten eine führende ‚0‘ auf jeden Operanden, anstatt sie zu dem Ergebnis zu tun:

sum <= ('0' & operand1) + ('0' & operand2); 
+4

für eine allgemeine Lösung das funktioniert auch mit SIGNED-Typen, Sie können RESIZE aus der numeric_std-Bibliothek verwenden (zB Summe <= RESIZE (operand1, operand1'LENGTH + 1) + RESIZE (operand2, operand2'LENGTH + 1)) – sbell

+0

@sbell +1 für das generische Lösung! – rick

-6

Versuchen Sie Folgendes: Kombinieren Sie Ihr Ergebnis logisch mit einem '0'-Vektor, bevor Sie es in den längeren Vektor schreiben. Für mich hat es geklappt.

sum <= '0' & (operand1 + operand2); 

Hoffnung, das hilft :)

+0

Früher habe ich versucht 'sum <=" 0 "& operand1 +" 0 "& operand2', aber das hat den Trick! Vielen Dank.Dennoch verwirrt mich, was VHDL tun würde, wenn der Wert in 9 Bit übergelaufen ist, aber zumindest der Code nicht beschweren – krb686

+2

Es gibt ein Problem mit diesem Code: es wird überlaufen und ein falsches Ergebnis geben, wenn die Summe größer als 255 ist Um einen Überlauf zu vermeiden, müssen Sie eine führende '0' mit jedem Operanden verknüpfen, anstatt mit dem Ergebnis zu arbeiten: 'summe <= ('0' & operand1) + ('0' & operand2); ' – rick

1

Der Vorschlag ist korrekt: Verwenden Sie die unsigned oder unterzeichnet Typ bei der Implementierung von arithmetischen Schaltungen (denken Sie daran, die numeric_std Paket in Ihrem Code enthalten).

Da in Ihrem Fall Summe hat ein zusätzliches Bit (im Vergleich zu den größten der Operanden), kann folgendes geschehen:

1) Wenn das System ohne Vorzeichen:

sum <= ('0' & operand1) + ('0' & operand2); 

2) Wenn das System angemeldet ist (erfordert Vorzeichenerweiterung):

sum <= (operand1(N-1) & operand1) + (operand2(N-1) & operand2); 
+0

Sie können auch Integer verwenden (Sie müssen keine Vektortypen verwenden) und sie können auch schneller simulieren. –

+0

Aus Interesse ... sind Sie diese Pedroni: http://books.google.co.uk/books/about/Circuit_Design_with_VHDL.html?id=b5NEgENaEn4C –

3

Use the standard ieee.numeric_std library.

Dann Ihre Zahlen entweder von unsigned oder signed Typ, Marke und die Verwendung der handlichen Resize-Funktion machen:

answer <= resize(operand1, answer'length) + resize(operand2, answer'length); 

Und denken Sie daran, dass viele Male ist es viel einfacher, nur ganze Zahlen verwenden, keine Konvertierung erforderlich ist, und Rechnen erfordert nicht, dass Sie durch Größenänderungsrahmen springen!