Wie kann ich mit VHDL einen einfachen D-Latch nur für Q implementieren?

Ich habe heute mit VHDL angefangen und bin der Typ Mensch, der nur lernen kann, indem er Dinge tut. Nachdem ich also einige grundlegende Gates in VHDL erstellt habe, habe ich versucht, einen einfachen D-Latch (also kein Taktsignal) zu erstellen, jedoch ohne Erfolg. Ich erhalte alle Arten von Fehlern wie in1 nicht definiert, std_logic nicht definiert usw.

Hier ist mein Code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity dflip is

end dflip;

architecture structural of dflip is

    component AND2
        port (in1, in2:in std_logic; out1: out std_logic);
    end component;

    component OR2
        port (in1, in2:in std_logic; out1: out std_logic);
    end component;

    component NOT1
        port (in1: in std_logic; out1: out std_logic);
    end component;

    signal D, E, E_NOT, Q, OUT_AND1, OUT_AND2: std_logic;

begin   
    U0: NOT1    port map (E, E_NOT);
    U1: AND2    port map (E, D, OUT_AND1);
    U2: AND2    port map (E_NOT, Q, OUT_AND2);
    U3: OR2     port map (OUT_AND1, OUT_AND2, Q);
end structural;


entity NOT1 is
    port (in1: in std_logic; out1: out std_logic);
end NOT1;

architecture behavioral_not of NOT1 is
begin
    out1 <= not in1;
end behavioral_not;


entity AND2 is
    port(in1, in2: in std_logic; out1: out std_logic);
end AND2;

architecture behavioral_and2 of AND2 is
begin

    out1 <= in1 and in2;

end behavioral_and2;


entity OR2 is
    port (in1, in2: in std_logic; out1: out std_logic);
end OR2;

architecture behavioral_or of OR2 is
begin
    out1 <= in1 or in2;
end behavioral_or;

Ich habe es strukturell gemacht, weil ich es nicht schaffen konnte, verhaltensorientiert zu arbeiten, weil ich anscheinend keine if-Anweisungen verwenden kann, wenn ich verhaltensorientiert schreibe (macht Sinn). Das Problem liegt bei diesem Q-Ausgang, der mit dem Eingang eines UND-Gatters verbunden werden muss.

Wie mache ich das?

Der Code zwischen 'ARCHITECTURE ... BEGIN' und 'END ...' ist gleichzeitig. Jede Zeile wie 'U0 : NOT port map' wird vom Simulator jedes Mal neu ausgewertet, wenn ein Ereignis (z. B. ein Übergang) an einem der Eingänge auftritt. Die Codereihenfolge ist irrelevant. Sequentielle Teile (wie „traditioneller“ imperativer Code) müssen innerhalb von PROCESS-Deklarationen stehen. Im Gegensatz zu C-Code gibt es kein Problem damit, eine Variable vor der Zuweisung zu verwenden, solange das Signal irgendwo zugewiesen wird.

Antworten (4)

Latches und Flip-Flops können nicht mit Logikgattern in VHDL modelliert werden, dies gilt nur für analoge Simulatoren! Die Feedback-Logik verheißt nichts Gutes für den VHDL-Simulator. Außerdem würde kein Synthesizer es als Latch/Flip-Flop erkennen.

Um ein Latch/Flip-Flop zu instanziieren, können Sie entweder die Primitive Ihres Anbieters instanziieren oder diesen generischen Code verwenden:

LATCH: process(en, d)
begin
    if en = '1' then
        q <= d;
    end if;
end process LATCH;

DFF_ASYNC: process(rst, clk)
begin
    if rst = '1' then
        q <= '0';
    elsif rising_edge(clk) then
        q <= d;
    end if;
end process DFF_ASYNC;

DFF_SYNC: process(clk)
begin
    if rising_edge(clk) then
        if rst = '1' then
             q <= '0';
        else
             q <= d;
        end if;
    end if;
end process DFF_SYNC;

Verwenden Sie Logikgatter nur für kombinatorische Schaltungen. Wenn Sie eine Herausforderung suchen, können Sie besser mit der Simulation von ALU-Logik als mit synchronen Elementen umgehen. Denken Sie abschließend daran, dass die Verwendung von Logikgattern zum Entwerfen von Schaltungen Masochisten vorbehalten ist. Die meisten VHDL-Designer verwenden Konstrukte auf höherer Ebene, die einfacher zu lesen und zu debuggen sind.

Aktualisieren

Anscheinend können Latches in VHDL mit Logikgattern simuliert werden (danke @David Koontz). Sehen Sie sich seine Antwort an, um zu sehen, wie!

Vielen Dank! Mit Konstrukten auf höherer Ebene meinen Sie die Verwendung von Verhaltensmodellen?
Ich meine RTL (Register Transfer Level). Es ist ein Modell, in dem Sie Register (unter Verwendung meines Beispielcodes) und wie sie verbunden sind, beschreiben. Als Beispiel hätte ein Addierer die Register x, y und s und die Anweisung s <= x + y eingeschlossen in eine steigende_flanke-Anweisung. Ich betrachte Verhaltens-VHDL-Code, der nicht synthetisierbar ist.

Es ist möglich, ein strukturelles Gate-Modell eines D-Latch in VHDL zu generieren. Nehmen Sie eine Seite aus dem PLD-Design heraus, wo wir finden, dass ein Konsensbegriff erforderlich ist:

library ieee;
use ieee.std_logic_1164.all;

entity not1 is
    port ( 
        in1:    in  std_logic;
        outp:   out std_logic
    );
end entity;

architecture foo of not1 is

begin
    outp <= not in1;
end architecture;

library ieee;
use ieee.std_logic_1164.all;

entity and2 is 
    port (
        in1:    in  std_logic;
        in2:    in  std_logic;
        outp:   out std_logic
    );
end entity;

architecture foo of and2 is

begin
    outp <= in1 and in2;
end architecture;

library ieee;
use ieee.std_logic_1164.all;

entity or3 is 
    port (
        in1:    in  std_logic;
        in2:    in  std_logic;
        in3:    in  std_logic;
        outp:   out std_logic
    );
end entity;

architecture foo of or3 is

begin
    outp <= in1 or in2 or in3;
end architecture;

library ieee;
use ieee.std_logic_1164.all;

entity dlatch is
    port (
        d:  in  std_logic;
        en: in  std_logic;
        q:  out std_logic
    );
end entity;

architecture fum of dlatch is

    signal not_en:      std_logic;
    signal w1, w2, w3:  std_logic;
    signal q_int:       std_logic;

    component not1 is
        port (
        in1:    in  std_logic;
        outp:   out std_logic
        );
    end component;

    component and2 is
        port (
        in1:    in  std_logic;
        in2:    in  std_logic;
        outp:   out std_logic
        );
    end component;    

    component or3 is
        port (
        in1:    in  std_logic;
        in2:    in  std_logic;
        in3:    in  std_logic;
        outp:   out std_logic
        );
    end component;

begin
U0:
    not1 
        port map (
        in1 => en,
        outp => not_en
        );
U1:
    and2
        port map (
        in1 => q_int,
        in2 => not_en,
        outp => w1
        );

U2:
    and2
        port map (
        in1 => d,
        in2 =>  en,
        outp => w2 
        );

U3: -- consensus term
    and2
        port map (
        in1 =>  d,
        in2 => q_int,
        outp => w3
        );

U4:
    or3
        port map (
            in1 => w1,
            in2 => w2,
            in3 => w3,
            outp => q_int
        );

    q <= q_int;

end architecture;

library ieee;
use ieee.std_logic_1164.all;

entity dlatch_tb is
end entity;

architecture test of dlatch_tb is
    signal d:   std_logic := '0';
    signal en:  std_logic := '0';
    signal q:   std_logic;

    component dlatch is
        port (
            d:  in  std_logic;
            en: in  std_logic;
            q:  out std_logic
        );
    end component;

begin
DUT:
    dlatch
        port map (
            d => d,
            en => en,
            q => q
        );
STIM:
    process
    begin
        wait for 10 ns;
        en <= '1';
        wait for 10 ns;
        en <= '0';
        wait for 10 ns;
        d <= '1';
        wait for 10 ns;
        en <= '1';
        wait for 10 ns;
        en <= '0';
        wait for 10 ns;
        wait;
    end process;
end architecture;

Die strukturelle Architektur mit instanziierten Gattern erzeugt:

dlatch_tb Structural.png (anklickbar)

Latches und Flip-Flops können nicht mit Logikgattern in VHDL modelliert werden, dies gilt nur für analoge Simulatoren!

Die Moral von der Geschichte ist, dass Sie hier nicht immer Meinung von Wissen oder Erfahrung in Antworten trennen können. Diesen kleinen Leckerbissen finden Sie in Digital Design Principles and Practices , 3. Auflage von John F. Wakerly, 8.2.6 Registers and Latches in ABEL and PLDs , am wenigsten digitales Design wird zu einer verlorenen Kunst. Früher war es allgemein bekannt, als das digitale Design von PLDs (PALs) dominiert wurde.

Ohne den Konsensterm wird die Ausgabe oszillieren. Es gibt andere Möglichkeiten, die Oszillation zu stoppen, die durch die Delta-Zyklusverzögerung durch die not1 verursacht wird. Dies ist eine von mindestens zwei Möglichkeiten, wie ein Tragwerksentwurf simuliert und implementiert werden kann.

Und natürlich ist die große Frage, wie viele echte Digitaldesigner heute auf der Welt gebraucht werden? Wissen und Erfahrung stammen aus der Lösung realer Probleme, und wie die akzeptierte Antwort indirekt hervorhebt, ist es nicht erforderlich zu wissen, dass es in VHDL eine Antwort gibt.

Für diejenigen, die digitales Design mit Strukturelementen tatsächlich benötigen, kann es nützlich sein, neben digitalem Design nach Gefahrenlogik und/oder Konsensbegriff zu googeln .

Diese spezielle Frage kommt mir in den Sinn, weil sie einst eine Interviewfrage für einen Job war, der digitales Design in VHDL in einer Ära primitiverer Synthesewerkzeuge und langsamerer Simulationen durchführte, was bedeutete, dass Erfahrung im digitalen Design mehr zählte.

Wenn Sie schauen, und der Fleisch- und Kartoffelteil des Latches wird mit drei UND-Gattern und einem ODER-Gatter ausgeführt. Wir sehen, dass dies auch als Earle-Latch bezeichnet wird :

Earl Latch

Dieses Bild stammt aus Seite 40 von The Microarchitecture of Pipelined and Superscalar Computers , 1999 von Amos R. Omandi. Das Buch und der Earle-Latch- Link sagen uns, dass wir einen Earle-Latch in andere AND OR-Strukturen (wie Carry Look Ahead Adders) und die Geschichte einbetten können, die in den frühen 1960er Jahren auf einem IBM 360/91 verwendet wurde.

Der Konsensterm, das mittlere UND-Gatter in der obigen Abbildung, überwindet die gleiche Anzahl von Gatterverzögerungen (oder Delta-Simulationszyklusverzögerungen in einem Nullzeitmodell) im Rückkopplungspfad und bewahrt eine „1“ am Ausgang, wenn der Eingang ebenfalls a ist '1'.

In dem oben gezeigten VHDL-Design not1sorgt der Inverter auch dann für zumindest in eine Richtung verunsichernde Rückkopplung, wenn der not1Ausgang vom UND-Gatter (U2) des Eingangs verwendet worden wäre dlatch d- mit anderen Worten, wenn das Latch extern versorgt not_enund enüber das erzeugt worden wäre Wechselrichter not1.

Die Verwendung beim Verbergen von Latches in bestehenden UND-ODER-Strukturen basiert auf einer großen Anzahl von Begriffen, die für frühe CPLDs (PALs) etwas untypisch sind, ein Vorteil, den wir heute in FPGAs nicht haben, die sowieso andere Carry-Chain-Implementierungen implementieren. Es verdoppelt die Anzahl der Terme.

Sie können die Notwendigkeit von Konsensbegriffen in RS-basierten Latches und Flip-Flops eliminieren, indem Sie die Rückkopplungsverzögerungen zwischen der R- und S-Seite aus dem Gleichgewicht bringen, typischerweise durch Hinzufügen einer Verzögerung (wie bei einer Gate-Verzögerung). Dies wirkt sich auf die Rüst- und Haltezeiten aus.

Danke für die Korrektur, wie Sie wahrscheinlich sehen können, habe ich nur ein PAL in Logikklassen berührt, bevor ich etwas über VHDL und FPGAs gelernt habe. Wissen Sie, ob dies auf einem beliebigen Synthesizer einem Latch-Primitiv zugeordnet werden würde?
Ich würde nicht wetten, dass es irgendwo einem Latch-Primitiv zugeordnet werden würde. Es sollte ein funktionierendes Latch basierend auf einer UND-ODER-Struktur mit drei Termen erzeugen. Der treibende Grund, der in PLDs/PALs bekannt war, hat mit Ressourcenknappheit zu tun, es gibt heute im Allgemeinen keinen Grund in einem FPGA. Sie können auch Konsensbegriffe verwenden, um Modelle von Flip-Flops auf Gate-Ebene zum Laufen zu bringen. Denn das Verhaltens-Latch q_int <= (q_int and not en) or (d and en);funktioniert ganz gut, weil es keine Delta-Zyklusverzögerung gibt, die eine Konsens-Term-Abdeckung benötigt.

Wenn Sie ein strukturelles Design wünschen, ist die Instanziierung von Komponenten der richtige Weg, aber Latches werden nicht wirklich mithilfe der strukturellen Modellierung modelliert. Verhalten ist einfacher und Sie können die if-Anweisung für diese Methode verwenden. Schaut euch dieses Video an-

http://appliedelectronicsengineering.blogspot.com/2015/10/how-to-implement-d-latch-in-vhdl.html

Bitte fassen Sie einige der Informationen im Video zusammen.

Latches können in VHDL auf viele Arten modelliert werden, einschließlich mit Logikgattern; und der so erzeugte VHDL-Code kann synthetisiert werden (zumindest mit Synplify Pro).

Die gemeldeten Fehlermeldungen,

in1 nicht definiert, std_logic nicht definiert usw.

zeigen an, dass der Fehler Bibliotheks- und Verwendungsklauseln fehlt. Tatsächlich war das einzige, was ich getan habe, um Ihren Code zu korrigieren, diese vor jeder Entity-Deklaration hinzuzufügen. Hier der korrigierte Code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity NOT1 is
port (in1: in std_logic; out1: out std_logic);
end;

architecture behavioral_not of NOT1 is
begin
    out1 <= not in1;
end;


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity AND2 is
port (in1, in2: in std_logic; out1: out std_logic);
end;

architecture behavioral_and2 of AND2 is
begin
    out1 <= in1 and in2;
end;


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity OR2 is
port (in1, in2: in std_logic; out1: out std_logic);
end;

architecture behavioral_or of OR2 is
begin
    out1 <= in1 or in2;
end;


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity dflip is
port (D, E: in std_logic; Q: out std_logic);
end;

architecture structural of dflip is
    signal E_NOT, Q_int, OUT_AND1, OUT_AND2: std_logic;
begin   
    U0: entity work.NOT1
    port map (E, E_NOT);
    U1: entity work.AND2
    port map (E, D, OUT_AND1);
    U2: entity work.AND2
    port map (E_NOT, Q_int, OUT_AND2);
    U3: entity work.OR2
    port map (OUT_AND1, OUT_AND2, Q_int);

    Q <= Q_int;
end;

Lassen Sie uns als Bonus eine kürzere Implementierung des ungetakteten D-Latch sehen, mit denselben Gattern, aber ohne separate Einheiten für jedes Gatter:

architecture short of dflip is
    signal Q_int: std_logic;
begin
    Q_int <= (D and E) or (not E and Q_int);
    Q <= Q_int;
end;

Beachten Sie, dass Sie in der Praxis mit ziemlicher Sicherheit getaktete, flankengetriggerte Flipflops anstelle von Latches verwenden würden. Diese lassen sich schön mit bedingter Signalzuweisung ausdrücken:

Q <= D when rising_edge(clock) and E = '1';