In vielen Prüfständen sehe ich das folgende Muster für die Taktgenerierung:
process
begin
clk <= '0';
wait for 10 NS;
clk <= '1';
wait for 10 NS;
end process;
In anderen Fällen sehe ich:
clk <= not clk after 10 ns;
Letzteres gilt als besser, da es geplant wird, bevor ein Prozess ausgeführt wird, und somit Signale, die synchron zur Clk-Kante geändert werden, ordnungsgemäß behandelt werden. Die folgenden Abschnitte des LRM scheinen diese Theorie zu unterstützen:
Seite 169: 12.6.4 Der Simulationszyklus Ein Simulationszyklus besteht aus folgenden Schritten:
- b) Jedes aktive explizite Signal im Modell wird aktualisiert. (Infolgedessen können Ereignisse auf Signalen auftreten.)
Dies sollten die Signale mit einem neuen projizierten Wert sein, wie z. B. Signale, die durch die verzögert werden after
.
- d) Wenn P für jeden Prozess P derzeit für ein Signal S empfindlich ist und in diesem Simulationszyklus ein Ereignis auf S aufgetreten ist, wird P fortgesetzt.
Das wäre der größte Teil der zu simulierenden Logik
- e) Jeder nicht verschobene Prozess, der im aktuellen Simulationszyklus fortgesetzt wurde, wird ausgeführt, bis er angehalten wird.
Und jetzt werden alle Prozesse ausgeführt, die von a angehalten wait for
werden.
TL; DR:
- Ist die
after
Methode der Methode immer überlegenwait for
? - Hilft es, die Probleme beim synchronen Setzen von Eingangssignalen zu vermeiden?
wait for
s) ändern, oder Signale, die von der Flanke des Clk ausgelöst werden und daher einen Delta-Zyklus später sind?after
Version besser ist? Mir wurde noch nie beigebracht, dass es besser ist, ich bevorzuge es einfach, da es eine einzelne Zeile ist :)wait until
oder ändernwait for
.Antworten:
Der Simulator kann nicht wirklich dafür verantwortlich gemacht werden, dass er sich manchmal so verhält, als ob die Uhr unmittelbar nach oder unmittelbar vor der Änderung des Eingangs passiert wäre, wenn Sie beide
clk
und Eingänge mit zuweisenwait for
. Zu fragen, ob ein Stil dem anderen überlegen oder unterlegen ist, ist in gewisser Weise die falsche Frage. Sie müssen das Verhalten nicht mehrdeutig angeben, wenn Sie eine deterministische und nicht mehrdeutige Ausgabe wünschen.Was ich jahrelang gemacht habe und für mich ziemlich fehlerfrei gearbeitet habe (für synchrone Designs), ist, die ihnen vorangestellten Eingaben mit
wait until rising_edge(clk)
oder zuzuweisenwait until falling_edge(clk)
. Wie Sie das generieren,clk
wird unwichtig. Für einfache Testbenches derafter
Einzeiler macht den Job gut und prägnant, aber bietet nicht die Flexibilität einesprocess
mitwait for
oderwait until
Aussagen.Ich habe ein kleines einfaches Verfahren, das mir gute Dienste geleistet hat:
Was ich in einem aufbewahre
tb_pkg.vhd
, den ich immeruse
in Testbenches habe.Ein Anwendungsbeispiel könnte sein:
Einige Designer weisen ihre Stimulussignale an der gegenüberliegenden Kante dem zu, für das das zu testende Gerät empfindlich ist. Ich persönlich mache das nicht gerne, weil es nicht so ist, wie der Rest der Schaltung simuliert, wo sich die Signale an der Triggerflanke ändern. Aber an diesem Ansatz ist sicherlich nichts auszusetzen. Das obige Verfahren kann auch dafür verwendet werden.
quelle
Ich habe diesen Thread vor langer Zeit gelesen, hatte aber keine Zeit zu antworten, bis ich in den Ruhestand ging.
Es ist interessant zu sehen, wie verschiedene Leute ihre Testbench-Uhren erstellen und anhand welcher Kriterien beurteilt wird, wie "gut" sie sind. Für mich würde ich mir den Code ansehen und fragen: Wie vielseitig ist er? Wie schwer ist es zu ändern, wenn sich die Taktrate ändert? Oder wenn ich die Testbench in einer Back-Annotated-Gate-Simulation verwenden möchte?
Hier ist mein sehr langer Weg, um sicherzustellen, dass Änderungen einfach sind und die Testbench vielseitig einsetzbar ist:
Die Taktrate, die Dateneinrichtungszeit und die Datenhaltezeiten sollten als Generika oder Konstanten definiert werden, zum Beispiel:
Generieren Sie dann Kanten für die Testbench, die zum Bereitstellen von Daten, Entfernen von Daten sowie für "Ereignisse" zum Anstieg und Abfall der Uhr verwendet werden sollen:
Es kann dann ein Stimulus angewendet werden (Gehen eines Eingangs mit dem für dieses Beispiel verwendeten vld / rdy-Protokoll):
Alle Eingangsdatenübergänge sind weit entfernt von der aktiven (ansteigenden) Taktflanke. Es fängt sogar Fehler wie eine zusätzliche Inversion in der Uhr ab.
Es ist elegant, lesbar, vielseitig und leicht zu ändern. Es gibt keine Literale, die von der Taktfrequenz oder der Datenbreite abhängen. So würde ich es schreiben.
quelle