Da niemand antwortet und niemand abstimmt, werde ich antworten.
Blick auf die Fehler
Error: type error near a; current type std_logic_vector; expected type unsigned.
Nun ein Blick auf Einheit subtractor_16bit
.
[...]
entity subtractor_16bit is
Port ( a : in STD_LOGIC_VECTOR(15 downto 0);
[...]
component twoscomplement is
Port (
A : in unsigned (15 downto 0);
[...]
twoscomplement_1: twoscomplement port map (a => a ,c => n1);
[...]
Was sehen Sie? twoscomplement
erwartet eine unsigned
, während a
std_logic_vector
ist! Genau wie der Fehler sagt.
std_logic_vector
und unsigned
sind zwei separate Typen. Da VHDL eine stark typisierte Sprache ist, können Sie die Daten nicht einfach von einem Typ in einen anderen eingeben. Sie müssen die Typkonvertierung verwenden.
Für nicht verwandte Typen sollten Sie eine Typumwandlungsfunktion implementieren. Oder funktioniert, wenn Sie eine bidirektionale Konvertierung wünschen. Z.B.
function (input : type_a) return type_b;
Aber in diesem Fall std_logic_vector
und unsigned
haben den gleichen zugrunde liegenden Typ, std_logic
. (std_ulogic
eigentlich seit VHDL-2008 glaube ich.) In diesem Fall können Sie explizit von einem Typ in einen anderen konvertieren. Z.B.
signal a_u : unsigned(y downto 0);
signal a_slv : std_logic_vector(y downto 0);
begin
a_u <= unsigned(a_slv);
Als nächstes Instanziieren Ihr nicht die twoscomplement
Komponente richtig. Die Entität hat eine generische Nbits
. Standardmäßig setzen Sie es auf 8. Aber in Ihrer Architektur Behavioral
von subtractor_16bit
, füttern Sie es mit 16 Bits, ohne den generischen Wert zu ändern. Das funktioniert nicht.
Auch: twoscomplement
hat zwei Ports: A
und Y
. Aber in subtractor_16bit
beginnen Sie mit A
und C
. Das ist eine schlechte Programmierpraxis.
Schließlich können Sie die component
Deklarationen fallen lassen. Instantiieren Sie die Entitäten einfach aus der Bibliothek. Z.B.
twoscomplement_1: entity work.twoscomplement [...]
So subtractor_16bit
sollte wie folgt aussehen:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity subtractor_16bit is
Port (
a : in STD_LOGIC_VECTOR(15 downto 0);
b : in STD_LOGIC_VECTOR(15 downto 0);
cin : in STD_LOGIC;
sum : out STD_LOGIC_VECTOR(15 downto 0);
cout : out STD_LOGIC;
over : out STD_LOGIC
);
end entity;
architecture structural of subtractor_16bit is
use IEEE.NUMERIC_STD.ALL;
signal n1 : signed(a'range);
begin
twoscomplement_1: entity work.twoscomplement
generic map(
NBits => a'length
)
port map (
a => unsigned(a),
y => n1
);
fulladder_16bit_1: entity work.fulladder_16bit
port map (
a => a,
b => std_logic_vector(n1),
sum => sum,
cin => cin,
cout => cout,
over => over
);
end architecture;
...
JEDOCH dies funktioniert immer noch nicht.
Wenn Sie Ihr Unternehmen sehen twoscomplement
, Port A
eine Größe von NBits
hat und Port Y
eine Größe von NBits
+1 hat. Das liegt daran, dass Sie scheinbar eine 16-Bit-Wertpräzision beibehalten möchten. Wenn Sie also Vorzeichen in Vorzeichen konvertieren, müssen Sie ein 17. Bit für das Vorzeichen hinzufügen. Als Folge muss der Rest von Ihnen geändert werden!
.... Aber das kann auf eine andere Art und Weise behoben werden. Ich werde Ihnen etwas über Zweierkomplement lernen: -a = not(a) + 1
.
Proof (Take 4 Bit signed precision):
- 0 = B'0000 => -0 ist
not(b'0000)+1
= b'1111'+1
= b'0000'
- 7 = b'0111 => -7
not(b'0111)+1
= b'1000'+1
= b'1001'
- -6 = b'1010' => 6
not(b'1010)+1
= b'0101'+1
= b'0110'
Sehen Sie?
So, jetzt werde ich dein ganzes Puzzle für Sie lösen:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity subtractor_16bit is
Port (
a : in STD_LOGIC_VECTOR(15 downto 0);
b : in STD_LOGIC_VECTOR(15 downto 0);
sum : out STD_LOGIC_VECTOR(15 downto 0);
cout : out STD_LOGIC;
over : out STD_LOGIC
);
end entity;
architecture structural of subtractor_16bit is
begin
fulladder_16bit_1: entity work.fulladder_16bit
port map (
a => a,
b => not(b),
sum => sum,
cin => '1',
cout => cout,
over => over
);
end architecture;
Sie noch die cout
und over
Verhalten ändern/reparieren müssen ...
Es gibt mindestens drei Fehler sichtbar, ohne eine [ Minimales, vollständiges und überprüfbares Beispiel] (https://stackoverflow.com/help/mcve). In der Zweierkomplementportkarte (a => a, c => n1); --FEHLER'. C in Zweierkomplement wird als Typ signiert deklariert, während n1 als Typ std_logic_vector definiert ist. die Größe von A und C haben einen generischen Standardwert, der hier nicht modifiziert wird, Länge 8 und 9, während A 16 ist, wie auch C. Das generische muss übergeben und die Länge von n1 angepasst werden. Zweierkomplement kann auch in einem Ausdruck ohne ein Strukturelement durchgeführt werden. – user1155120
Schauen Sie sich einfach die Implementierung von 'twoscomplement' an und Sie sehen bereits ein Beispiel für Typ-Casting ... – JHBonarius
' type_conversion :: = type_mark (expression) 'Explicit * type conversions * sind Ausdrücke, die zwischen * eng verwandten Typen * konvertieren. Zwei Array-Typen sind eng miteinander verwandt, wenn die Typen dieselbe Dimensionalität haben und die Elementtypen eng verwandt sind. Ein Typ ist eng mit sich selbst verwandt. IEEE Std 1076-2008 9.3.6 Typkonvertierungen. Array-Typen signed und std_logic_vector sind eng verwandt und haben den gleichen Element-Basistyp. – user1155120