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:
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?
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 A
an 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.0
BC
10
B
1
C
1
011
Folglich process(A,B)
wird einmal geweckt, wenn A
sich etwas ändert, und ein zweites Mal, wenn B
es 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 B
implizit war:
process(A) begin
C <= A xor (not A);
end process;
process(C) begin
end process;
Oder wenn B
es 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.
user_1818839
Benutzer8352
Jon Watte
Benutzer8352
user_1818839
Philipp
Jon Watte