2017-09-23 20 views
0

Ich bin auf der Suche this example und unten Antwort, die eine schöne Lösung ergänzen, um zwei lautet:VHDL Typumwandlung unterzeichnet std_logic_vector

library ieee; 
use ieee.numeric_std.all; 
entity twoscomplement is 
    generic 
    (
    Nbits : positive := 8 
); 
    port 
    ( 
    A : in unsigned (Nbits-1 downto 0); 
    Y : out signed (Nbits downto 0) 
); 
end entity twoscomplement; 

architecture a1 of twoscomplement is 
begin 
    Y <= -signed(resize(A, Y'length)); 
end architecture; 

Ich mag das dieses Beispiel verwenden, Zweier-Komplement zu haben, und dann machen Sie ein "16-Bit-Subtrahierer ". Der Code wird wie folgt aussehen:

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.NUMERIC_STD.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 subtractor_16bit; 

architecture Behavioral of subtractor_16bit is 

component fulladder_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 component; 

component twoscomplement is 
    Port (
     A : in unsigned (15 downto 0); 
     C : out signed (15 downto 0) 
     ); 
end component; 

signal n1 : STD_LOGIC_VECTOR(15 downto 0); 

begin 

    twoscomplement_1: twoscomplement port map (a => a ,c => n1); --ERROR 
    fulladder_16bit_1: fulladder_16bit port map (a => a, b => n1, sum => sum , cin => cin, cout => cout, over => over); 

end Behavioral; 

Allerdings habe ich einen Fehler erhalte sagen: Fehler: Typfehler in der Nähe von a; aktueller Typ std_logic_vector; erwarteter Typ unsigniert.

Bitte helfen Sie mir, dieses Problem zu lösen.

+2

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

+0

Schauen Sie sich einfach die Implementierung von 'twoscomplement' an und Sie sehen bereits ein Beispiel für Typ-Casting ... – JHBonarius

+1

' 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

Antwort

1

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 astd_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 ...