VHDL: Wann wird die Prozesssensitivitätsliste ausgelöst?

In der VHDL-Simulation gibt es ein Konzept der „Delta-Zeit“, das grob als „Gruppe von Ereignissen, die durch die vorherige Delta-Zeit ausgelöst werden“ interpretiert wird. Nach einer Änderung, sobald sich alle kaskadierenden Änderungen erledigt haben und keine weiteren Delta-Zeit-Ereignisse mehr erzeugt werden, rückt die Simulationszeit vor. (Außerdem kann die Simulationszeit nach N Deltazeitereignissen vorrücken, da es eine Obergrenze für die Länge einer Kaskade gibt.)

Wann wird in einem bestimmten Prozess eine Änderung an der Prozesssensitivitätsliste ausgelöst? Wird es nur ausgelöst, wenn sich der Zustand eines Signals zu einer Simulationszeit im Vergleich zur vorherigen Simulationszeit unterscheidet, oder kann es als Ergebnis eines beliebigen Deltazeitereignisses ausgelöst werden? Wenn es zu einer beliebigen Deltazeit ausgelöst wird, kann ein Prozess mehr als einmal ausgelöst werden, wenn es eine kurzlebige kombinatorische Logik gibt?

Betrachten Sie dieses Beispiel:

schematisch

Simulieren Sie diese Schaltung – Mit CircuitLab erstellter Schaltplan

Nehmen wir an, wir beginnen mit dem stationären Zustand A = 1, B = 0, C = 1. Nehmen wir außerdem an, dass es keine externe Entität gibt, die Signal B untersucht – es ist rein intern.

Führen Sie nun ein Simulationsereignis ein: A=0.

Dies erzeugt für die nächste Deltazeit ein Ausgangsereignis für B = 1 und ein Ausgangsereignis für C = 0. Zur nächsten Deltazeit wird ein neues Ausgabeereignis für C = 1 generiert, und es werden keine weiteren Ereignisse generiert, sodass die Simulationszeit vorrücken kann.

Nehmen wir nun an, ich habe einen Prozess mit C in der Sensitivitätsliste. Nehmen wir an, dieser Prozess erhöht bei jedem Aufruf einen Zähler.

Wird dieser Zähler infolge einer Änderung von A zweimal erhöht? Das wäre der Fall, wenn Deltazeitänderungen Prozesse provozieren/auslösen/aufrufen.

Oder wird dieser Zähler null Mal inkrementiert? Das wäre der Fall, wenn nur Änderungen zur Simulationszeit Prozesse provozieren/auslösen/aufrufen.

Oder ist die Beziehung zwischen Change-in-A und Prozesszähler undefiniert? Wenn beispielsweise der Simulator (oder Synthesizer für Hardware) die NOT-and-XOR-Wahrheitstabelle optimiert, wird er sagen, dass C immer 1 ist, aber wenn er es nicht optimiert, kann er zwei Änderungen für C und erzeugen also den Vorgang zweimal auslösen?

Zweite Frage: Was ist das richtige Wort für das „Provozieren/Auslösen/Aufrufen“ eines Prozesses durch Ändern eines Signals in seiner Empfindlichkeitsliste?

Zweimal. Ein solcher Zähler würde in der Simulation funktionieren, wäre aber natürlich physikalisch nicht realisierbar. Der Simulator darf die Logik nicht optimieren: Die Tatsache, dass er hier einen potenziellen Fehler aufdeckt, ist ein Feature, kein Fehler!
Die Verwendung eines Signalereignisses als Uhr erfordert eine Qualifikation (z. B. wenn C'Ereignis und C = '1', dann ... ), die die mystischen Eigenschaften hat, a) nur eine Flanke zu erfassen, b) synthesefähig zu sein und c) Hardware zu reflektieren. Das Wort, nach dem Sie suchen, ist Ereignis, zusammen mit dem Verständnis der Unterscheidung von Transaktion. Siehe Einträge im Glossar von IEEE Std 1076 sowie den Unterabschnitt über die Ausführung eines Modells und dessen Unterabschnitt über den Simulationszyklus. Versuchen Sie neben dem LRM Peter Ashendens „The VHDL Designer's Guide“, 3. Ausgabe, als maßgebliche Referenz.
@Brian Ich denke, eine Art Fusselnachricht oder Warnung wäre angemessen, anstatt es als Feature zu bezeichnen. Warum sollte dieses Verhalten nicht synthetisierbar sein? (Ich versuche hier, ein robustes mentales Modell aufzubauen.)
Sie inkrementieren Hardware-Zähler mit Taktflanken, entweder 0->1 oder 1->0, aber nicht beides, während Sie beschrieben haben, wie der Zähler auf beiden betrieben wird, was nicht synthetisiert wird. Ein von C gesteuerter Zähler würde Übergangspaare zählen, indem er steigende oder fallende Taktflanken zählt. Was eine Warnung betrifft, würden Sie eine benötigen, wenn Sie kombinatorische Gatter an den Ausgang eines beispielsweise asynchronen 4-Bit-Zählers anschließen? Denken Sie an die Hardwarebeschreibung, nicht an die Software. Die C-Impulsbreite ist die Inverterverzögerung plus jegliche Differenz in der Anstiegs- und Abfallzeit. Ohne Modellierung dieser Verzögerungen ist die Impulsbreite ein Delta-Zyklus. (Eine Panne).
David hat es sehr gut beantwortet. Diese Frage/Antwort kann auch hilfreich sein. stackoverflow.com/questions/13954193/…
Anstatt zu fragen, was ein Simulator tun würde, warum nicht eintippen und auf einem Simulator ausführen? Das wird Ihnen helfen, Ihr robustes mentales Modell aufzubauen!
Die Untersuchung der Details des jeweiligen Simulators, auf den ich Zugriff habe, sagt mir nur, was dieser Simulator tut. Es wird mir nicht sagen, ob die meisten Simulatoren dasselbe tun werden, noch warum.

Antworten (1)

Die Zeit wird erst dann vorgerückt, wenn durch kein Ereignis mehr Prozesse geweckt werden können. Wenn der Prozess "P" durch seine Empfindlichkeitsliste aufgeweckt wird, wird er in Nullzeit ausgeführt und Signalzuweisungen geplant, und diese Zuweisungen können andere Prozesse aufwecken. Wenn beim nächsten Delta (das die Zeit nicht vorrückt) irgendein Prozess (einschließlich sich selbst) die Sensitivitätsliste von P beeinflusst, dann wird P erneut geweckt. Dies geschieht so oft wie nötig (oder bis der Simulator aufgibt oder die eingestellte maximale Anzahl von Deltas aufgetreten ist).

In dem speziellen Beispiel Ihrer Frage mit ABC = 101, wenn Sie:

process(A,B) begin 
    B <= not A; 
    C <= A xor B;
end process;

process(C) begin
end process;

Bei Änderungen Aan werden mit Zuweisungen von geplant . Ein Delta passiert, wird und erweckt den Prozess erneut, der zurück zu plant . Am Ende dieses zweiten Deltas sind die Werte , und es gibt keine weiteren Ereignisse, die den Prozess aufwecken könnten, und wenn kein anderer Prozess aufgeweckt werden kann, rückt die Zeit vor.0BC10B1C1011

Folglich process(A,B)wird einmal geweckt, wenn Asich etwas ändert, und ein zweites Mal, wenn Bes sich ändert. Dadurch zählt der "Process Awakening Counter" doppelt.

Im Fall von process(C)wird es auch zweimal geweckt, weil C"Delta-Glitch" aufgrund von process(A,B).

Wenn jedoch Bimplizit war:

process(A) begin 
    C <= A xor (not A);
end process;

process(C) begin
end process;

Oder wenn Bes eine lokale Variable war:

process(A) 
    variable B : std_logic_vector;
begin 
    B := not A;
    C <= A xor (not B);
end process;

process(C) begin
end process;

Dann würde Prozess (A) nur einmal geweckt werden, aber Prozess (C) würde ausgesetzt bleiben.

Aber meine Frage war, ob der Gegenprozess zweimal unsere Nullbindungen auslösen würde, oder ob das tatsächlich nicht gut definiert war. Ich habe bereits beschrieben, was mit A, B und C passieren würde.
Technisch wird es nicht geweckt, wenn A oder B wechseln. Es wird immer dann erwachen, wenn sich C ändert; dh zweimal, in den Delta-Zyklen, NACHDEM sich A und B geändert haben, da A den XOR-Prozess aufweckt, der ein Ereignis auf C plant (und B dito).
@Brian Ich bezog mich auf Prozess (A, B), ich habe die Frage bearbeitet, um dies zu klären, und auch Prozess (C) ausdrücklich erwähnt.