Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial programming >> VHDL

So verwenden Sie signiert und unsigniert in VHDL

Die Typen mit und ohne Vorzeichen in VHDL sind Bitvektoren, genau wie der Typ std_logic_vector. Der Unterschied besteht darin, dass der std_logic_vector zwar großartig für die Implementierung von Datenbussen ist, aber für die Durchführung arithmetischer Operationen nutzlos ist.

Wenn Sie versuchen, eine beliebige Zahl zu einem std_logic_vector-Typ hinzuzufügen, erzeugt ModelSim den Kompilierungsfehler:Keine zulässigen Einträge für den Infix-Operator „+“. Dies liegt daran, dass der Compiler nicht weiß, wie er diese Sammlung von Bits, die der Vektor ist, interpretieren soll.

Dieser Blogpost ist Teil der Reihe Basic VHDL Tutorials.

Wir müssen unseren Vektor als signiert oder unsigniert deklarieren, damit der Compiler ihn als Zahl behandelt.

Die Syntax zum Deklarieren von signierten und unsignierten Signalen lautet:
signal <name> : signed(<N-bits> downto 0) := <initial_value>;
signal <name> : unsigned(<N-bits> downto 0) := <initial_value>;

Genau wie bei std_logic_vector können die Bereiche to sein oder downto jede Reichweite. Aber das Deklarieren von Signalen mit anderen Bereichen als downto 0 ist so ungewöhnlich, dass es uns nur verwirren würde, wenn wir uns noch länger mit diesem Thema beschäftigen würden. Der Anfangswert ist optional, standardmäßig ist er 'U' für alle Bits.

Wir haben bereits den integer verwendet Typ für arithmetische Operationen in früheren Tutorials. Warum brauchen wir also die signierten und unsignierten Typen? Die meisten Digitaldesigner möchten mehr Kontrolle darüber haben, wie viele Bits ein Signal tatsächlich verwendet.

Außerdem werden vorzeichenbehaftete und vorzeichenlose Werte umlaufen, während der Simulator einen Laufzeitfehler auslöst, wenn ein integer wird über Grenzen hinaus inkrementiert. Schließlich können signiert und unsigniert andere Werte wie 'U' haben und 'X' , während ganze Zahlen nur Zahlenwerte haben können. Diese Metawerte können uns helfen, Fehler in unserem Design zu entdecken.

Übung

In diesem Video erfahren wir, wie sich signierte und unsignierte Signale gleich verhalten und wie sie sich unterschiedlich verhalten:

Der endgültige Code, den wir in diesem Tutorial erstellt haben:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity T12_SignedUnsignedTb is
end entity;

architecture sim of T12_SignedUnsignedTb is

    signal UnsCnt : unsigned(7 downto 0) := (others => '0');
    signal SigCnt : signed(7 downto 0)   := (others => '0');
    
    signal Uns4   : unsigned(3 downto 0) := "1000";
    signal Sig4   : signed(3 downto 0)   := "1000";
    
    signal Uns8   : unsigned(7 downto 0) := (others => '0');
    signal Sig8   : signed(7 downto 0)   := (others => '0');

begin

    process is
    begin

        wait for 10 ns;
        
        -- Wrapping counter
        UnsCnt <= UnsCnt + 1;
        SigCnt <= SigCnt + 1;
        
        -- Adding signals
        Uns8 <= Uns8 + Uns4;
        Sig8 <= Sig8 + Sig4;

    end process;
end architecture;

Das Wellenformfenster in ModelSim, vergrößert auf die interessanten Teile:

Analyse

Die Basis aller Signale in der Wellenform wird auf hexadezimal gesetzt, damit wir sie gleichermaßen vergleichen können.

Im Wrapping-Counter-Beispiel sehen wir, dass sich signierte und unsignierte Signale genau gleich verhalten. Beide UnsCnt und SigCnt beginnen bei 0 und werden nacheinander bis FF erhöht. Hex FF (dezimal 255) ist der größte Wert, den unsere 8-Bit-Signale aufnehmen können. Daher setzt das nächste Inkrement beide auf 0 zurück.

Wir haben die beiden 4-Bit-Signale Uns4 erzeugt und Sig4 , und gab beiden einen Anfangswert von „1000“. Wir können aus der Wellenform ersehen, dass sie beide nur Hex 8 (binär 1000) sind.

Die letzten beiden 8-Bit-Signale, die wir erstellt haben, waren Uns8 und Sig8 . Wir können aus der Wellenform ersehen, dass ihre Anfangswerte 0 sind, wie man es erwarten würde. Aber von da an verhalten sie sich anders! Anscheinend machten vorzeichenbehaftete und vorzeichenlose Typen einen Unterschied, wenn zwei Signale unterschiedlicher Länge hinzugefügt wurden.

Dies liegt an etwas, das als Sign Extension bekannt ist . Das Addieren positiver oder negativer Zahlen, die in Vektoren gleicher Länge gespeichert sind, ist die gleiche Operation in der digitalen Logik. Das liegt daran, wie das Zweierkomplement funktioniert. Wenn die Vektoren unterschiedlich lang sind, muss der kürzeste Vektor verlängert werden.

Die vorzeichenlose 4-Bit-Binärzahl „1000“ ist dezimal 8, während die vorzeichenbehaftete 4-Bit-Zahl „1000“ dezimal -8 ist. Die „1“ ganz links neben der vorzeichenbehafteten Zahl zeigt an, dass es sich um eine negative Zahl handelt. Daher werden die beiden 4-Bit-Signale vom Compiler unterschiedlich vorzeichenerweitert.

Dies ist eine Visualisierung, wie die Zeichenerweiterung die unterschiedlichen Werte für Uns8 erstellt und Sig8 Signale:

Imbiss

Weiter zum nächsten Tutorial »


VHDL

  1. Signiert vs. Unsigniert in VHDL
  2. So verwenden Sie eine Prozedur in einem Prozess in VHDL
  3. So verwenden Sie eine unreine Funktion in VHDL
  4. So verwenden Sie eine Funktion in VHDL
  5. So verwenden Sie eine Prozedur in VHDL
  6. So verwenden Sie Konstanten und generische Karten in VHDL
  7. So verwenden Sie die Port Map-Instanziierung in VHDL
  8. So installieren Sie kostenlos einen VHDL-Simulator und -Editor
  9. PIC18-Mikrocontroller:Was er ist und wie er verwendet wird
  10. Was ist ein Referenzdesignator und wie verwenden wir ihn in der Montage?