VHDL – K-map reduzierte charakteristische Gleichung schlägt fehl

Ich habe diese Schaltung (D-Latch) :

Geben Sie hier die Bildbeschreibung ein

und ich kann die logische Gleichung direkt schreiben, indem ich nur die Tore beobachte:

Q = ( ( D C ) + Q ¯ ) + ( C D ¯ ) ¯

Wenn ich dies minimieren möchte, schreibe ich zuerst eine vorherige Status - nächste Statustabelle:

Geben Sie hier die Bildbeschreibung ein

Und verwenden Sie die K-Reduktion wie folgt:

Geben Sie hier die Bildbeschreibung ein

Ich habe die reduzierte Gleichung:

Q = ( C ¯ Q ) + ( C D )

Ich habe dieses VHDL-Beispiel geschrieben und D-Latch funktioniert einwandfrei, wenn ich die nicht minimierte Formel verwende E:. Es funktioniert jedoch nicht wie erwartet für minimierte Formel F:.

-- A:
library ieee;
use ieee.std_logic_1164.all;

-- B:
entity d_latch is
    port(
        d: in std_ulogic; -- Input (DATA)
        c: in std_ulogic; -- Input (CONTROL)
        q: inout std_ulogic -- Input/output (OUTPUT)
    );
end d_latch;

-- C:
architecture logic_001 of d_latch is
begin

    -- E:
    --q <= ((d and c) nor q) nor (c and not d);

    -- F:
    q <= ((not c) and q) or (c and d);

end architecture logic_001;

Wenn ich die .dotDateien für beide .vhdlDateien exportiere, um zu überprüfen, welche Art von Hardware erstellt wurde, bemerke ich einen Unterschied!

Hier ist die erstellte Hardware, die funktioniert:

Geben Sie hier die Bildbeschreibung ein

Hier ist die erstellte Hardware, die dies nicht tut:

Geben Sie hier die Bildbeschreibung ein

Ist meine K-Map-Reduktion falsch? Oder was zum Teufel ist mit VHDL los?


Simulationen

Ich habe auch die VHDL-Testbench geschrieben:

-- A:
library ieee;
use ieee.std_logic_1164.all;

-- B:
entity d_latch_tb is
end d_latch_tb;

-- C:
architecture test_001 of d_latch_tb is
    
    -- D:
    component d_latch
        port(
            d: in std_ulogic; -- Input (DATA)
            c: in std_ulogic; -- Input (CONTROL)
            q: inout std_ulogic -- Input/output (OUTPUT)
        );
    end component;

    -- E:
    signal dx: std_ulogic; -- Input (SET)
    signal cx: std_ulogic; -- Input (RESET)
    signal qx: std_ulogic; -- Input/output (OUTPUT)

begin

    -- F:
    -- c1: d_latch port map (dx, cx);
    -- c1: d_latch port map (dx, cx, qx);
    c1: d_latch port map (d => dx, c => cx, q => qx);

    -- G:
    process begin
        
        -- H:
        cx <= '0';
        dx <= '0';
        wait for 1 ns;
        cx <= '0';
        dx <= '1';
        wait for 1 ns;
        cx <= '0';
        dx <= '0';
        wait for 1 ns;
        cx <= '1';
        dx <= '0';
        wait for 1 ns;
        cx <= '1';
        dx <= '1';
        wait for 1 ns;
        cx <= '0';
        dx <= '1';
        wait for 1 ns;
        cx <= '0';
        dx <= '0';
        wait for 1 ns;

        -- I:
        assert false report "END OF TEST!";
        
        -- J:
        wait;

    end process;

end architecture test_001;

Ich habe diese Testbank verwendet, um Wellenformen zu erzeugen, wie in den Kommentaren vorgeschlagen. Zu meiner Überraschung sehen auch die Wellenformen identisch aus! Aber sie erzeugen unterschiedliche Ergebnisse auf der Hardware.

Dies ist die simulierte Wellenform für die ursprüngliche Gleichung:Geben Sie hier die Bildbeschreibung ein

Dies ist die simulierte Wellenform für die reduzierte K-Map-Gleichung:Geben Sie hier die Bildbeschreibung ein

Also ... Die Simulation sieht gleich aus, aber die Hardware liefert unterschiedliche Ergebnisse. Auf Hardware verhält sich die reduzierte K-Map-Gleichung genau wie ein einfaches UND-Gatter. Der Ausgang ist nur dann hoch, wenn beide hoch sind. Und der Ausgangszustand wird nicht gespeichert.

Makefile:

Es ist möglich, dass dies eine Art Kompilierungsproblem ist. Weil VHDL zuerst in Verilog übersetzt wird und dann die Opensource-Toolchain verwendet wird, um Verilog zu kompilieren!

Hier ist das Makefile:

####################################################################################################
# Makefile's paragraphs:
#
# A: Properly set these parameters before running any of the targets in the makefile.
#
#    Here we have to choose a solver that "yosys-stmbmc" uses. We can choose one of these:
#    z3, boolector, cvc4, yices, mathsal
#
#    NOTE: mathsal is not installed on our system...
#    NOTE: boolector is experiencing a broken pipeline error...
#
# B: This target first synthesizes VHDL file to verilog file.
#
#    Then it synthesizes verilog (.v) file to a netlist (.blif) file. Then it  place & routes
#    the netlist file and creates an ASCII bitstream file (.asc). This file is then used to create
#    an FPGA binary file (.bin) for "iCE40-UP5K-SG48".
#
# C: This flashes the binary file (.bin) to the "iCE40" device connected to our workstation.
#
# D: This creates a simulation for our design. In order to create simulation we first use ghdl with
#    parameter "-s" to check the syntax of .vhdl files. Then we use a parameter "-a" to analyze the
#    .vhdl files in order to know where to find entities... This will create a ".pc" file that is
#    also needed to write the .vcd file in the last step where we use parameter "-r" that runs the
#    simulation.
#
# E: Use design verilog file (.v) to synthesize an SMT-LIB-v2 file (.smt2) on which we use a SAT
#    solver that executes a formal verification (BMC method).
#
#    NOTE: This only produces .vcd file if formal verification fails!
#    NOTE: Usage of parameter "-formal" defines a macro "FORMAL" and in source code we use this to
#          automatically enable blocks meant exclusively for "formal verification". automatisation
#          is achieved by using "ifdef FORMAL".
#
# F: Use design verilog file (.v) to synthesize an SMT-LIB-v2 file (.smt2) on which we use a SAT
#    solver that executes a formal verification (induction method).
#
#    NOTE: This only produces .vcd file if formal verification fails!
#    NOTE: Usage of parameter "-formal" defines a macro "FORMAL" and in source code we use this to
#          automatically enable blocks meant exclusively for "formal verification". automatisation
#          is achieved by using "ifdef FORMAL".
#
# G: Use design verilog file (.v) to synthesize an SMT-LIB-v2 file (.smt2) on which we use a SAT
#    solver that executes a formal verification (cover method).
#
#    NOTE: This only produces .vcd file if formal verification fails!
#    NOTE: Usage of parameter "-formal" defines a macro "FORMAL" and in source code we use this to
#          automatically enable blocks meant exclusively for "formal verification". automatisation
#          is achieved by using "ifdef FORMAL".
#    NOTE: Target is not implemented in this design.
#
# H: Preview the generated .vcd file in gtkview.
#
# I: We first read the verilog file, then use "proc" which replaces the processes in the design with
#    multiplexers, flip-flops and latches. Then we use "show" to generate a .dot file and openm it
#    with xdot viewer.
#
#    TODO: This still does not work for multiple verilog files!!!
#
# J: Delete all the generated files.
#
####################################################################################################

# A:
file_main = d_latch
file_pcf = icebreaker
file_cpp = driver
solver = z3

module_top = d_latch
entity_top = $(module_top)
entity_top_tb = $(module_top)_tb

####################################################################################################

# B:
all:
    yosys \
        -m ghdl \
        -p "ghdl $(file_main).vhdl -e $(entity_top); write_verilog $(file_main).v"
    yosys \
        -p "synth_ice40 -top $(module_top) -blif $(file_main).blif" \
        $(file_main).v
    arachne-pnr \
        -d 5k \
        -P sg48 \
        -o $(file_main).asc \
        -p $(file_pcf).pcf $(file_main).blif
    icepack $(file_main).asc $(file_main).bin

# C:
flash:
    iceprog $(file_main).bin

# D:
simulate:
    ghdl -s $(file_main).vhdl
    ghdl -s $(file_main)_tb.vhdl
    ghdl -a $(file_main).vhdl
    ghdl -a $(file_main)_tb.vhdl
    ghdl -r $(entity_top_tb) --vcd=$(file_main).vcd

####################################################################################################

# E:
verification_bmc:
    yosys \
        -p "read_verilog -sv -formal $(file_main).v" \
        -p "hierarchy -check -top $(module_top)" \
        -p "prep -nordff -top $(module_top)" \
        -p "write_smt2 -wires $(file_main).smt2"
    yosys-smtbmc -t 100 -s $(solver) --dump-vcd $(file_main).vcd $(file_main).smt2
    
# F:
verification_induction:
    yosys \
        -p "read_verilog -sv -formal $(file_main).v" \
        -p "hierarchy -check -top $(module_top)" \
        -p "prep -nordff -top $(module_top)" \
        -p "write_smt2 -wires $(file_main).smt2"
    yosys-smtbmc -i -t 100 -s $(solver) --dump-vcd $(file_main).vcd $(file_main).smt2

# G:
verification_cover:
    yosys \
        -p "read_verilog -sv -formal $(file_main).v" \
        -p "hierarchy -check -top $(module_top)" \
        -p "prep -nordff -top $(module_top)" \
        -p "write_smt2 -wires $(file_main).smt2"
    yosys-smtbmc -c -t 100 -s $(solver) --dump-vcd $(file_main).vcd $(file_main).smt2

#################################################################################################

# H:
vcd:
    gtkwave $(file_main).vcd

# I:
dot:
    yosys \
        -p "read_verilog -sv -formal $(file_main).v" \
        -p "hierarchy -check -top $(module_top)" \
        -p "proc" \
        -p "show -prefix $(file_main) -notitle -colors 2 -width -format dot"
    xdot $(file_main).dot

#################################################################################################

# J:
.PHONY: clean
clean:
    @rm -f *.bin
    @rm -f *.blif
    @rm -f *.asc
    @rm -f -r obj_dir
    @rm -f *.elf
    @rm -f *.vcd
    @rm -f *.smt2
    @rm -f *.dot
    @rm -f *.v
    @rm -f *.cf

Um die Binärdateien zu kompilieren, verwende ich das Ziel makeund make flashlade dann die Binärdateien auf das Ziel-FPGA hoch.

Ich verwende make simulate, um .vcdWellenform-Simulationsdateien zu erstellen.

Hardware- .dotVorschaudateien wurden mit einem Ziel generiert make dot.

Es gibt auch andere Ziele im Makefile, die für die formale Überprüfung verwendet werden können, aber ignorieren Sie sie einfach.

Können Sie die Simulationswellenformen für beide Fälle hinzufügen?
@MituRaj Ich habe die Wellenformen hinzugefügt.
Die Wellenformen der Verhaltenssimulation sehen gleich aus. Verwenden Sie Xilinx?
Ich verwende YOSYS FOSS-Tools, um die VHDL zu kompilieren und zu simulieren. Mein Board ist ICE Breaker V1.0e. Es hat ein Lattice-FPGA.
Hast du auf einem echten Board nachgesehen? Vielleicht ist Ihr Synthese-/Testwerkzeug das Problem. Cz-Latches sind manchmal schwierig zu synthetisieren.
Wenn ich meine Entwürfe simuliere, erzeugen sie dieselbe Simulationswellenform. Dann lade ich sie auf die Hardware hoch und sie erzeugen unterschiedliche Ausgaben. Erstaunlich ... Ich kann es nicht glauben. :)
Dies ist jedoch eine Verhaltenssimulation. Sie können Post-Synthese-Simulationswellenformen mit demselben Prüfstand überprüfen, um zu sehen, was in der Hardware passiert. Überprüfen Sie, ob es dort vorbeigeht.
@Mitu Raj. Interessant. Ich habe noch nie eine "Post-Synthese-Simulation" durchgeführt . Wie kann dies geschehen?
Hier können Sie sich fast auf die Hardwarefunktionalität verlassen. Nicht sicher, wie man in Lattice vorgeht. In Xilinx ist es ziemlich direkt. Möglicherweise müssen Sie die Werkzeuganleitung von Lattice überprüfen.
Ich bin eher erstaunt, dass die ersten Arbeiten durchwegs funktionieren, wenn man die gleiche Rennbedingung hat und die Logikketten per se nicht ausgeglichen zu sein scheinen .
Ich habe gerade aus Neugier Ihren Code in Xilinx überprüft, und er erlaubt mir aufgrund von DRC-Fehlern nicht, auf Board hochzuladen, da Sie aufgrund der Kombinationsschleife ein klassisches Rennproblem haben. Ich frage mich jedoch, wie Sie dies im Gitter tun konnten.
@MituRaj Gibt es eine Möglichkeit, mich auf das Rennproblem hinzuweisen. Ich bin neu bei FPGA und es ist ziemlich schwer, irgendetwas aus den Kommentaren zu verstehen. Es ist sehr wahrscheinlich, dass ich ein schlechtes Design gemacht habe. Aber ich muss auch darauf hinweisen, dass dieses Design aus dem Buch "Grundlagen des Digital- und Computerdesigns mit VHDL" (Sandige) stammt. Ich werde auch eine hinzufügen makefile, die ich mit der FOSS-Toolchain verwende. Vielleicht kann jemand dort einige Probleme erkennen!
Ich konnte den DRC-Fehler umgehen und habe interessanterweise das gleiche Verhalten an Bord beobachtet, wie Sie es beschrieben haben. Ich glaube, ich habe das Problem/die Lösung gefunden. Die Antwort poste ich später.
@MituRaj Ist es möglich, dass dies auf Störungen zurückzuführen ist!? Meine K-Karte hat zwei Gruppen von 1ern, aber Gruppen sind nicht verbunden! Es besteht also die Möglichkeit eines Fehlers! Und genau das passiert auf der Hardware! Aber es passiert nicht in der Software-Simulation, weil die Simulation die Setup-Zeit und die Haltezeit des D-Latches nicht berücksichtigt! Ich habe dem Thema ein weiteres Bild hinzugefügt, das die Möglichkeit eines Fehlers beschreibt! Nun, wie auch immer ... Bitte posten Sie eine Antwort, wenn Sie das herausfinden!

Antworten (2)

Latches müssen auf ihren Pfaden richtig zeitgesteuert sein, um das beabsichtigte Latch-Verhalten zu erhalten. Latches haben ein kombinatorisches Feedback und daher kann ihr Timing von einem FPGA-Synthesizer nicht korrekt analysiert werden, wenn es naiv in LUTs synthetisiert wird. Dies ist einer der Gründe, warum Latches oder kombinatorische Schleifen als „schlecht“ und unvorhersehbar auf einem FPGA in HDL zu synthetisieren gelten.

Aus Neugier habe ich beide Versionen Ihres Codes auf einem Xilinx-Board ausprobiert, wobei Kombinatorschleifenwarnungen umgangen wurden, und das gleiche Verhalten beobachtet, wie Sie es beschrieben haben. Die erste Version des Codes funktionierte überraschenderweise als D-Latch an Bord. Aber die zweite Version des Codes (die reduzierte K-Karte) tat es nicht. Es verhielt sich wie ein UND-Gatter.

Nach ein wenig Graben habe ich herausgefunden, dass das Problem darin besteht, dass Sie in Ihrem reduzierten K-Map-Ausdruck eine Statik-1-Hazard (wie eine „Störung“, lesen Sie hier mehr) haben Q ' = ( C ¯ Q ) + ( C D ) , was die Ursache für dieses unvorhersehbare Verhalten sein kann.

Dieser Fehler von 0 bei Q ' passiert, wenn es einen Übergang im aktuellen Zustand gibt, [ C , D , Q ] : [ 0 , 1 , 1 ] [ 1 , 1 , 1 ] innerhalb der Ö R A N G e Gruppe in der K-Map angezeigt. dh., Q ' ändert sich momentan von 1 0 und es ändert wiederum den 'Eingang' Q (weil es rückgekoppelt wird) aus 1 0 , richtig, wenn die Uhr C ändert sich von 1 0 . Dies sollte eine Hold-Verletzung verursachen, und der Latch kann den Wert nicht speichern 1 was war bei Q kurz vor dem Uhrenwechsel.

Wiki sagt: "Ein von Huffman bewiesenes Theorem sagt uns, dass durch Hinzufügen einer redundanten Schleife die Gefahr beseitigt wird."

Wenn Sie also den redundanten Begriff hinzufügen Q . D in den K-Map-Ausdruck (die Gruppe in Ö R A N G e Farbe):Geben Sie hier die Bildbeschreibung ein

Der neue Ausdruck wird zu:

Q ' = ( C ¯ Q ) + ( C D ) + ( Q . D )

Dies sollte der reduzierte Ausdruck ohne statische Gefahren sein, den Sie verwenden sollten, um die Verriegelung in HDL zu modellieren. Es funktionierte für mich an Bord als D-Latch.

Ich empfehle jedoch aus dem zuvor genannten Grund nicht, Latches auf FPGA zu modellieren.

Ich habe gerade die gleiche Antwort geschrieben, heheheh!
Oh haha. Ja, gut, dass du das auch herausgefunden hast.
Wirklich sehr interessant. Und ich habe meinen ersten Fehler behoben! :)
Um nicht zu sagen, dass dies ein Beispiel aus dem Buch ist! Scheint ein schlechtes Buch zu sein...

Ich habe herausgefunden, dass in diesem Fall die K-Reduktion einen Fehler verursacht! Dieser Fehler wird nicht in der Simulation angezeigt, aber er zeigt sich auf der Hardware, da die Simulation die Setup-Zeit und die Haltezeit des D-Latches nicht berücksichtigt, wie in diesem Bild gezeigt:

Geben Sie hier die Bildbeschreibung ein

Wenn D in der Nähe der negativen Flanke von C geändert wird, schafft es D Latch nur, den Eingangszustand für kurze Zeit zu speichern und kehrt dann in den vorherigen Zustand zurück. Was bleibt, ist ein Glitch ... Ich habe diesen Glitch nicht beobachtet. Ich habe es nur in dem Buch gelesen.

Um den Fehler zu beheben, musste ich meine K-Karte reparieren und die vorhandenen Gruppen mit einer Gruppe III verbinden :

Geben Sie hier die Bildbeschreibung ein

Das gibt mir eine andere Gleichung:

Q = ( C ¯ Q ) + ( C D ) + ( D Q )

Und das funktioniert in VHDL! Aber in diesem Fall bringt mir die K-Map-Reduktion nicht viel, oder sie kann mehr schaden als nützen. Was ich immer noch nicht verstehe ist, warum und wie Glitch die Hardware daran hindert, sich so zu verhalten, wie sie sollte.

Ich werde diese Antwort von mir nicht akzeptieren, wenn jemand erklären kann, wie und warum dieser Fehler dazu führt, dass mein Design als UND-Gatter fungiert.

Suchen Sie nach 'Earle Latch'