Ich möchte einen Block kombinatorischer Logik mit VHDL entwerfen, aber gelegentlich enthält das synthetisierte Ergebnis einen unbeabsichtigten Latch.
Welche Codierungsrichtlinien muss ich befolgen, um zu vermeiden, dass der Synthesizer auf Latches schlussfolgert?
Beispiel: Sollte ich in einem kleinen Codesegment if-else-Anweisungen verwenden?
Um Latches zu vermeiden, müssen Sie sicherstellen, dass alle Ihre Ausgänge allen möglichen Zweigen des Codes zugewiesen sind.
zum Beispiel,
if a = '1' then
b(0) <= '1';
else
b(1 downto 0) <= "00";
end if;
würde einen Latch erzeugen, da in der ersten Bedingung der Wert von b(1) nicht angegeben ist, sodass der Compiler entschieden hat, dass Sie den vorherigen Wert von b(1) dort behalten möchten. Eine Möglichkeit, dies zu schreiben, die keinen Latch erzeugen würde, ist:
if a = '1' then
b <= prev_b;
b(0) <= '1';
else
b(1 downto 0) <= "00";
end if;
...
if rising_edge (clk)
prev_b <= b;
end if;
Hier geben Sie explizit an, dass b seinen alten Wert behalten soll, und überschreiben dann b(0) mit dem neuen Wert.
Eine andere Möglichkeit besteht darin, einen Standardwert anzugeben, wie in der Antwort von @TomiJ.
Wenn Sie den Code posten, den Sie erhalten, können wir Ihnen helfen, den genauen Grund zu finden.
b <= b
eine Verriegelung vermeiden wird, da der Zustand des Signals immer noch erhalten bleiben muss.Vier Regeln zur Vermeidung von Latches:
Wenn Sie mehrere kombinatorische Prozesse haben, stellen Sie außerdem sicher, dass Sie keine Schleife erstellen.
Mehrere Codierungsstile können Ihnen helfen, sich an diese Regeln zu halten, zum Beispiel der Stil in der Antwort von @TomiJ. Wie @Martin Thompson betont, ist es möglicherweise besser, kombinatorische Logik insgesamt zu vermeiden. Legen Sie stattdessen alles in einen getakteten Prozess.
Wenn Sie Prozesse für kombinatorische Logik verwenden (und ich rate aus genau diesem Grund davon ab), dann stellen Sie sicher, dass jeder Pfad durch den Prozess jedem Signal, das der Prozess antreibt, etwas zuweist. Keine der Ausgaben kann von irgendeiner der Ausgaben vom "letzten Mal", als der Prozess lief, abhängig sein.
Andernfalls leiten Sie ein Latch ab, da der Prozess beim nächsten Einplanen den Wert des Signals beibehalten muss, das beim letzten Mal keinen neuen Wert erhalten hat.
Ich ziehe es vor, eine rein kombinatorische Logik als kontinuierliche Zuweisungen beizubehalten und Prozesse für getaktete Logik zu verwenden, dann bekomme ich keine Latches.
Wie von @fbo und @Martin Thompson betont, müssen Sie sicherstellen, dass jedem vom Prozess angesteuerten Signal in jedem Zweig des Prozesses ein bestimmter Wert zugewiesen wird, und dieser Wert darf nicht vom vorherigen Zustand eines der Ausgänge abhängen des Prozesses.
Der einfachste Weg, dies sicherzustellen, besteht darin, jedem Ausgang ganz am Anfang des Prozesses einen Standardwert zuzuweisen, zum Beispiel (Kooptierung des Beispiels von fbo):
COMBO: process(a)
begin
b <= (others => '0'); -- Assign default value to b
if a = '1' then
b(0) <= '1';
else
b(1 downto 0) <= "00";
end if;
end process COMBO;
W5VO