Testbench für INOUT-Port in VHDL

Ich habe im Internet und bei Stackexchange nach der Lösung gesucht, aber ich weiß immer noch nicht, warum es nicht funktioniert. Lösungen, die ich hier gefunden habe, sollten funktionieren, aber wahrscheinlich mache ich immer noch etwas falsch.

Ich schreibe VHDL-Code. Ich habe in meinem Design INOUT-Ports. In Libero funktioniert die Soc-Synthese und -Kompilierung einwandfrei. Jetzt möchte ich mein Design simulieren und hier ist das Problem. Ich verwende ModelSim von Mentor Graphics. Beim Kompilieren der Testbench erhalte ich einen Fehler

Nicht aufgelöste Signaldaten haben mehrere Quellen.

architecture architecture_max11046_interface_tb of max11046_interface_tb is

component max11046_interface is
    port (
        -- Clock and resets
        i_clk           : in std_ulogic;
        i_rst_asyn      : in std_ulogic;
        i_rst_syn       : in std_ulogic;

        -- Max11046 interface
        o_cs        : out std_ulogic;
        o_wr        : out std_ulogic;
        o_rd        : out std_ulogic;
        o_convst    : out std_ulogic;
        o_shdn      : out std_ulogic;
        i_eoc       : in  std_ulogic;
        io_data      : inout  std_ulogic_vector(15 downto 0)
    );
end component;


-- input signals
signal eoc:    std_ulogic := '1';
signal data:   std_ulogic_vector(15 downto 0) := x"ABAB";

-- signals
signal rst: std_ulogic := '0';
signal clk: std_ulogic := '0';

signal ADC_Data: std_ulogic_vector(15 downto 0);
begin
    Conversion_end: process
    begin
        wait until convst = '1';
        wait for 500 NS;
        eoc <= '0';
    ADC_Data <= x"ABCD";
        wait for 50 NS;
        eoc <= '1';
    end process;

    data <= ADC_Data when eoc = '0' else (others => 'Z');        

    max11046: max11046_interface
        port map (
            i_clk       => clk,
            i_rst_asyn  => '1',
            i_rst_syn   => rst,
            o_cs        => cs,
            o_wr        => wr,
            o_rd        => rd,
            o_convst    => convst,
            o_shdn      => shdn,
            i_eoc       => eoc,
            io_data      => data
        );

 end architecture_max11046_interface_tb;

Ich habe einen Teil des Codes gelöscht, um ihn leichter lesbar zu machen. Meine Frage ist, was falsch sein kann. Kann ich kein internes Signal von mehreren Quellen treiben? Im Design mache ich es so mit Ports und es funktioniert:

data <= ADC_Data when eoc = '0' else (others => 'Z');

Wenn ich nicht auf den Port schreibe, ist er hochohmig und ich kann Daten lesen.

PS Ich möchte nicht std_logic_vector anstelle von std_ulogic_vector verwenden.

Verweisen Sie auf alle erforderlichen Bibliotheken? "Nonresolved" deutet für mich darauf hin, dass der Compiler den genauen Typ von data.

Antworten (3)

Sie versuchen, ein Tri-State-Signal für 'Daten' des nicht aufgelösten Typs std_ulogic_vector zu erstellen. „Unaufgelöst“ bedeutet, dass beim Festlegen des Werts eines Signals (dh eines „Signals“ oder „Ports“) keine Auflösungsfunktion verwendet wird.

Eine Auflösungsfunktion nimmt den Wert von jeder der Quellen auf ein Signal und löst sie alle in einen einzigen Zuordnungswert auf.

Der von Ihnen ausgewählte nicht aufgelöste Datentyp lässt also per Definition nur eine Quelle zu. Die Lösung besteht darin, einen aufgelösten Typ zu verwenden, da sie mehrere Quellen auf einem einzigen Signal verarbeiten, was Sie implementieren wollten.

Die typischen aufgelösten Typen sind hier stattdessen std_logic und std_logic_vector. (Sie erklären nicht, warum Sie sie nicht verwenden möchten, nur dass Sie dies nicht tun.)

Die Anfangswerte Ihrer Signale stellen übrigens keine weitere Quelle dar. Das sind nur Werte, mit denen Ihr Simulator in den Signalen beginnt. In ihrer Abwesenheit würde Ihr Simulator 'U's auf die Signale setzen, die Sie haben.

Als kleine Korrektur: Die Auflösung löst mehrere Quellen auf, nicht Treiber. Nur Signale können aufgelöst werden (dazu gehören auch Ports, da Ports Signale sind)
Danke @Paebbels, behoben. Hält Ports jedoch von Signalen getrennt, klarer für OP.

Die TL;DR-Erklärung

Mehrere Treiber erfordern eine Auflösung, um den effektiven Wert eines Signals zu bestimmen.

IEEE Std 1076-2008 6.4.2.3 Signalerklärungen , Absatz 8:

Ein Signal kann eine oder mehrere Quellen haben . Für ein Signal eines skalaren Typs ist jede Quelle entweder ein Treiber (siehe 14.7.2) oder ein out - , inout - , buffer - oder Linkage- Port einer Komponenteninstanz oder einer Blockanweisung, der das Signal zugeordnet ist. Für ein Signal eines zusammengesetzten Typs ist jede zusammengesetzte Quelle eine Sammlung von skalaren Quellen, eine für jedes skalare Unterelement des Signals. Es ist ein Fehler, wenn nach der Ausarbeitung einer Beschreibung ein Signal mehrere Quellen hat und es sich nicht um ein aufgelöstes Signal handelt. Es ist auch ein Fehler, wenn nach Ausarbeitung einer Beschreibung ein aufgelöstes Signal mehr Quellen hat als die Anzahl von Elementen im Indexbereich vom Typ des formalen Parameters der dem aufgelösten Signal zugeordneten Auflösungsfunktion.

Quellen macht Auflösung hierarchisch -

13 Bemessungseinheiten und ihre Analyse , 13.1 Bemessungseinheiten , Absatz 1:

Bestimmte Konstrukte werden unabhängig analysiert und in eine Designbibliothek eingefügt; diese Konstrukte werden Designeinheiten genannt . Eine oder mehrere aufeinanderfolgende Designeinheiten umfassen eine Designdatei .

Eine instanziierte Komponente stellt einen externen Block dar (3.1), eine Designeinheit besteht aus einer Kontextklausel (die leer sein kann) und einer Bibliothekseinheit, entweder einer primären Einheit (z. B. einer Entitätsdeklaration) oder einer sekundären Einheit (z. B. einer passenden Architektur). ).

Sie können nicht alle tatsächlichen Treiber bis zur Ausarbeitung bestimmen. Ports sind aus diesem Grund Signale.

14.7.3 Ausbreitung von Signalwerten , 14.7.3.1 Allgemeines , Absatz 5:

Der Kernprozess ermittelt während bestimmter Simulationszyklen zwei Werte für bestimmte Signale. Der treibende Wert eines bestimmten Signals ist der Wert, den dieses Signal als Quelle für andere Signale bereitstellt. Der Effektivwert eines gegebenen Signals ist der Wert, der durch Auswertung eines Verweises auf das Signal innerhalb eines Ausdrucks erhältlich ist. Der treibende Wert und der Effektivwert eines Signals sind nicht immer gleich, insbesondere wenn Auflösungsfunktionen und Umwandlungsfunktionen oder Typumwandlungen an der Ausbreitung von Signalwerten beteiligt sind.

Ein Port-Signal liefert den effektiven Wert für alle Quellen (Treiber und Ports von Mode out, inout, Buffer oder Linkage), die zum effektiven Wert dieses Port-Signals beitragen. Ports können gelesen oder ausgewertet werden, wenn der Wert eines ausgearbeiteten Netzes aufgelöst wird:

6.5.2 Schnittstellenobjekte , Absatz 9 und 10 (auszugsweise):

Ein Schnittstellenobjekt stellt einen Kommunikationskanal zwischen der Umgebung und einem bestimmten Teil einer Beschreibung bereit. Der Wert eines Schnittstellenobjekts kann durch den Wert eines zugeordneten Objekts oder Ausdrucks in der Umgebung bestimmt werden; ähnlich kann der Wert eines Objekts in der Umgebung durch den Wert eines zugeordneten Schnittstellenobjekts bestimmt werden. Die Art und Weise, wie solche Zuordnungen vorgenommen werden, ist in 6.5.7 beschrieben.

Der Wert eines Objekts wird gelesen, wenn eine der folgenden Bedingungen erfüllt ist:

— Wenn das Objekt ausgewertet wird, und auch (indirekt), wenn das Objekt mit einem Schnittstellenobjekt der Modi in , inout oder linkage verknüpft ist .

...

Der Schlüssel hier ist, dass es mehrere Treiber (mehrere Quellen) für datain Ihrer Testbench gibt -

14.7.2 Fahrer , Absatz 1:

Jede Signalzuweisungsanweisung in einer Prozessanweisung definiert einen Satz von Treibern für bestimmte skalare Signale. Es gibt einen einzelnen Treiber für ein gegebenes Skalarsignal S in einer Prozessanweisung, vorausgesetzt, dass es mindestens eine Signalzuweisungsanweisung in dieser Prozessanweisung gibt und dass das längste statische Präfix des Zielsignals dieser Signalzuweisungsanweisung S oder a bezeichnet zusammengesetztes Signal, von dem S ein Unterelement ist. Jede solche Signalzuweisungsanweisung soll diesem Fahrer zugeordnet sein. Die Ausführung einer Signalzuweisungsanweisung wirkt sich nur auf den/die zugeordneten Treiber aus.

14.2 Ausarbeitung einer Designhierarchie , Absatz 1:

Die Ausarbeitung einer Designhierarchie schafft eine Sammlung von Prozessen, die durch Netze miteinander verbunden sind; Diese Sammlung von Prozessen und Netzen kann dann ausgeführt werden, um das Verhalten des Designs zu simulieren.

und gleichzeitige Anweisungen (einschließlich interner und externer Blöcke) werden als Blockanweisungen und/oder Blockanweisungen und -prozesse ausgearbeitet (11. Nebenläufige Anweisungen). Die Signalzuordnung erfolgt garantiert in einer Prozessanweisung, eine Auflösung mit mehreren Quellen ist erforderlich .

Das erfordert aufgelöste Datentypen mit Auflösungsfunktionen.

4.6 Auflösungsfunktionen , Absatz 1:

Eine Auflösungsfunktion ist eine Funktion, die definiert, wie die Werte mehrerer Quellen eines bestimmten Signals in einen einzigen Wert für dieses Signal aufgelöst werden sollen. Auflösungsfunktionen werden Signalen zugeordnet, die eine Auflösung erfordern, indem der Name der Auflösungsfunktion in die Deklaration des Signals oder in die Deklaration des Subtyps des Signals aufgenommen wird. Ein Signal mit einer zugehörigen Auflösungsfunktion wird als aufgelöstes Signal bezeichnet (siehe 6.4.2.3).

6.4.2.3 Signalerklärungen , Absatz 3:

Wenn eine Auflösungsangabe in der Subtypangabe in der Deklaration eines Signals oder in der Deklaration des zur Deklaration des Signals verwendeten Subtyps erscheint, wird jede Auflösungsfunktion im Subtyp entsprechend dem deklarierten Signal oder einem Unterelement des deklarierten Signals zugeordnet . Ein solches Signal oder Unterelement wird als aufgelöstes Signal bezeichnet .

Für std_logic- oder std_logic-Elemente wird die Auflösungsfunktion im Paket std_logic_1164 in der Deklaration des Untertyps std_logic bereitgestellt. std_ulogic (der Elementtyp von std_ulogic_vector) ist kein aufgelöster Typ.

All dies läuft darauf hinaus, dass std_ulogic_vector nicht als Typ verwendet werden kann, für dataden ein aufgelöster Elementtyp erforderlich ist.

Ihnen fehlen auch Deklarationen für die Signale convst, cs, wr, rdund shdn.

@TonyM Ich konnte dir nicht ganz zustimmen. Std_ulogic_vector oder std_ulogic ist ein nicht aufgelöstes Signal, aber Sie könnten damit wie im Code arbeiten

data <= ADC_Data when eoc = '0' else (others => 'Z');   

Wenn es nicht als Ausgang verwendet wird, ist es hochohmig und stellt kein Problem mit der Auflösung dar.

Auf diese Weise weiß der Benutzer genau, was er tut. In synopsys synplify wird es kein Problem mit der Synthese geben, wenn der Code so geschrieben ist.

Korrigieren Sie mich, wenn ich falsch liege, aber ich habe std_ulogic so verwendet und es hat gut funktioniert.

Wie Sie sagten, dienen die Anfangswerte nur der Simulation.

Ein Synthesetool, das dies nicht als Fehler behandelt, wäre nicht mit dem VHDL-Standard konform und könnte nicht portierbar sein. Sie könnten auch feststellen, dass es dataim Aggregatausdruck in der Testbench (der für die Simulation verwendet wird) eine Zuweisung zu von 'Z's gibt. Ihre Antwort soll vielleicht ein Kommentar sein?
Ich konnte die Kommentare anderer Leute nicht kommentieren, immer noch zu niedrigem Reputationswert :) Danke für deine Antwort!
Stimmt nicht, bitte lesen Sie die Definition der Auflösungsfunktion erneut. In VHDL ist eine hohe Impedanz (dh Z) eine Quelle und mehrere Quellen erfordern eine Auflösung. Die Frage von OP bezog sich auf einen Fehler von ModelSim, nicht von Synplify. Schon mal in ModelSim probiert? Abwertung.