Hallo,
für eine Testbench, d.h. nicht synthesefähigen Code, in VHDL (Vivado
2019.2.1) wollte ich den folgenden Ausdruck verwenden:
1
signalx:STD_LOGIC;
2
...
3
...
4
...
5
my_proc:process
6
constantt:time:=123ns;
7
begin
8
if((xaftert)='0')then
9
...
10
endif;
11
endprocessmy_proc;
Auch wenn ich das verzögerte Signal "x after t" einer prozesslokalen
Variable zuweise, meckert Vivado. Nur dann, wenn ich ein Signal
verwende, funktioniert das ganze.
Gibt es eine Kurzschreibweise ohne zusätzliches Signal?
Dazu müsste der Simulator doch in die Zukunft gucken können? Du
verlangst jetzt eine Entscheidung die aber auf dem Zustand eines Signals
in der Zukunft basiert. Dieser Zustand ist aber im aktuellen
Simulationsschritt noch nicht bekannt/errechnet worden.
-gb- schrieb:> Sorry, bitte ignorieren.
Wieso, deine Erklärung geht doch in die richtige Richtung?
@TO: was willst du mit der Abfrage denn erreichen? Interresiert dich in
der Abfrage der Wert von x 123ns später? (den kann der Simulator nicht
kennen).
Oder interessiert der um 123ns verzögerte Wert von x? Dann hättest du
dem Simulator 123ns vorher sagen müssen, dass er sich das "merken" soll.
Die nebenläufige Anweisung
y <= x after 123 ns;
wird vom Simulator bei jeder Änderung von x ausgewertet. Dann merkt er
sich vor, dass er 123 ns später den Wert von y anpassen muss und führt
das zum entsprechenden Zeitpunkt aus. Das ergibt eine definierte Abfolge
von Aktionen beim Simulator. Deine Abfrage
if ((x after t) = '0') then
ergibt das imho nicht.
Achim S. schrieb:> @TO: was willst du mit der Abfrage denn erreichen? Interresiert dich in> der Abfrage der Wert von x 123ns später? (den kann der Simulator nicht> kennen).
Nein.
> Oder interessiert der um 123ns verzögerte Wert von x? Dann hättest du> dem Simulator 123ns vorher sagen müssen, dass er sich das "merken" soll.
Ja. Ich modelliere gerade einen AD-Wandler, dessen serieller
Datenausgang durch eine Chip-Select-Leitung zwischen aktiv und tristate
umgeschaltet wird. Laut Datenblatt reagiert der Baustein aber erst
etliche Nanosekunden verzögert.
> Die nebenläufige Anweisung>> y <= x after 123 ns;>> wird vom Simulator bei jeder Änderung von x ausgewertet. Dann merkt er> sich vor, dass er 123 ns später den Wert von y anpassen muss und führt> das zum entsprechenden Zeitpunkt aus. Das ergibt eine definierte Abfolge> von Aktionen beim Simulator. Deine Abfrage>> if ((x after t) = '0') then>> ergibt das imho nicht.
Ist dieses Verhalten im VHDL-Standard (2003, 2008, ...) genau so
beschrieben oder ein Implementierungsdetail des Vivado-Simulators?
"Darf" der Simulator in solchen Situationen keinen weiteren
Auswertungszeitpunkte erkennen und anwenden?
Andreas S. schrieb:> Ist dieses Verhalten im VHDL-Standard (2003, 2008, ...) genau so> beschrieben oder ein Implementierungsdetail des Vivado-Simulators?> "Darf" der Simulator in solchen Situationen keinen weiteren> Auswertungszeitpunkte erkennen und anwenden?
Ich habe immer noch nicht verstanden, welches Verhalten du vom Simulator
erwartest/welche Vormerkungen der Simulator in deiner Anwendung
beherrschen sollte. Ich kenne after nur als Bestandteil einer Waverform,
die auf der rechten Seite einer Zuweisung steht.
http://rti.etf.bg.ac.rs/rti/ri5rvl/tutorial/TUTORIAL/IEEE/HTML/1076_8.HTM#8.4.1
Wenn du eine andere Bedeutung/Anwendung von after kennst, würde mich
interessieren, wo diese beschrieben ist.
Achim S. schrieb:> Ich habe immer noch nicht verstanden, welches Verhalten du vom Simulator> erwartest/welche Vormerkungen der Simulator in deiner Anwendung> beherrschen sollte.
Der Simulator soll nur das physikalische Verhalten meines extern
angeschlossenen Peripheriebausteins nachbilden. Diese Worst-Case-Zeiten
stammen aus dem Datenblatt des ADC (TI ADS1672). Anbei ein
Bildschirmfoto des Simulators:
1. Der rote Pfeil stellt dar, dass das Signal ADC_DOUT erst 8 ns nach
dem Aktivieren des Chip-Selects ADC_CS_N vom Tri-State auf eine aktive 0
wechselt.
2. Der gelbe Pfeil stellt dar, dass das Signal ADC_DOUT dem zugehörigen
Taktsignal ADC_SCLK um 3 ns hinterherhinkt.
Diese und auch noch ein paar andere Timings lassen sich natürlich nur
mit Hilfe der beschriebenen "after"-Anweisungen darstellen. Das FPGA
aktiviert den Chip-Select und der Baustein reagiert eben erst kurz
danach mit DOUT, usw..
> Ich kenne after nur als Bestandteil einer Waverform,> die auf der rechten Seite einer Zuweisung steht.> http://rti.etf.bg.ac.rs/rti/ri5rvl/tutorial/TUTORIAL/IEEE/HTML/1076_8.HTM#8.4.1
Ja, genau so ist es ja üblich, bedeutet aber natürlich, dass man eben
eine Zuweisung an ein Signal durchführt.
> Wenn du eine andere Bedeutung/Anwendung von after kennst, würde mich> interessieren, wo diese beschrieben ist.
Hä? Das ist doch genau die von mir gestellte Frage, ob es möglich ist,
die explizite Zuweisung an ein Signal zu vermeiden. Offenbar ist solch
ein Ausdruck mit "after" nur im Rahmen von Zuweisungen, aber nicht bei
Vergleichen zulässig. Für meine Testbench wäre es eben nur eleganter
gewesen.
Bei einer synthesefähigen Beschreibung würde ich natürlich einen
entsprechende Tri-State-Treiber instantiieren und ein T-Signal
mitführen. Aber zum einen wäre "after" je eh nicht synthesefähig, und
zum anderen hätte ich dann ja eh meinen externen ADC. Und den
synchronisiere ich dann natürlich auch entsprechend ein.
PS.: Die 123 ns in meinem Beispiel waren zur Illustration willkürlich
gewählt und finden sich nicht im Bildschirmfoto wieder.
Andreas S. schrieb:> Hallo,>> für eine Testbench, d.h. nicht synthesefähigen Code, in VHDL (Vivado> 2019.2.1) wollte ich den folgenden Ausdruck verwenden:>>
1
>signalx:STD_LOGIC;
2
>...
3
>...
4
>...
5
>my_proc:process
6
>constantt:time:=123ns;
7
>begin
8
>if((xaftert)='0')then
9
>...
10
>endif;
11
>endprocessmy_proc;
12
>
>> Auch wenn ich das verzögerte Signal "x after t" einer prozesslokalen> Variable zuweise, meckert Vivado. Nur dann, wenn ich ein Signal> verwende, funktioniert das ganze.>> Gibt es eine Kurzschreibweise ohne zusätzliches Signal?
Mit dem VHDL Attribut 'delayed(t) *) kannst du dir den Wert des Signals
zum Zeitpunkt now-t geben lassen. Ist es das was du willst? Wirklich
eindeutig ist es nicht was du da vor hast.
In die Zukunft blicken geht nicht, schon allein nicht um den Prozess zum
richtigen Zeitpunkt anzuwerfen. In deinem Fall wuerdest du einen
Vergleich zum Transistion Zeitpunkt t0 mit x durchfuehren, mit der
Information wie x zum Zeitpunkt t0 + 123 ns aussieht. Das kann nicht
funktionieren.
Was allerdings geht: Du kannst den Prozess zum Zeitpunkt t+123ns
anwerfen mit dem Signal x vor 123ns in der Vergangenheit, ala:
1
my_proc:process(x'delayed(123ns))
2
begin
3
if(x='0')then
4
...
5
endif;
6
endprocessmy_proc;
Das wuerde zumindest mal die Zeitachse beibehalten, nur den
Referenzzeitpunkt der Auswertung aendern.
Vielleicht erklaerst du auch mal den Kontext, evtl. gibt es allgemein
eine funktionierende und elegantere Loesung.
*) Eine Uebersicht von Signal Attribuetn findest du z.B. hier:
https://www.csee.umbc.edu/portal/help/VHDL/attribute.html
Vielen Dank für die Antworten, aber ich habe den Kontext ja bereits
genannt. Und der Weg über ein entsprechendes verzögertes Signal
funktioniert ja auch prächtig, wie man anhand der Simulation sehen kann.
Es geht ausschließlich um eine mögliche Kurzschreibweise, und das
Attribut "delayed" war mir bislang noch nicht bekannt. Das müsste
wahrscheinlich genau die von mir gewünschte Funktionalität besitzen.
Andreas S. schrieb:> Vielen Dank für die Antworten, aber ich habe den Kontext ja bereits> genannt. Und der Weg über ein entsprechendes verzögertes Signal> funktioniert ja auch prächtig, wie man anhand der Simulation sehen kann.
Ich glaube du hattest deine ausfuehrliche Erlaeuterung parallel zu
meiner geschrieben, daher kannte ich die beim Verfassen noch nicht.
Jetzt war es dann doch deutlich klarer.
Achim S. schrieb:> Wieso, deine Erklärung geht doch in die richtige Richtung?
Ne, da hatte ich verstanden, dass er keinen Blick in die Zukunft,
sondern in die Vergangenheit will.
Andreas S. schrieb:> if ((x after t) = '0') then
Das verlangt einen Blick in die Zukunft und geht daher nicht. Es fragt
nämlich: Wird x in der Zeit t den Wert 0 haben?
Wenn er aber schreibt:
x_verzögert <= x after t;
und dann abfragt
if x_verzögert = '0' then ...
dann enthält x_verzögert einen Blick in die Vergangeheit. x_verzögert
enthält den Wert, den x vor der Zeit t hatte. Die Abfrage lautet also:
Hatte x vor der Zeit t den Wert 0?
Und das kann man natürlich bauen, weil in dem Fall tatsächlich ein alter
Wert von x aufgehoben/gespeichert wird.
Gustl B. schrieb:> Ne, da hatte ich verstanden, dass er keinen Blick in die Zukunft,> sondern in die Vergangenheit will.
Kein Wunder: offenbar mussten alle, die sich an dem Thread beteiligt
haben, erst mal um Klärung bitten, was der Code denn tatsächlich
bewirken soll. Weil der TO zunächst einen nicht funktionierenden
Lösungsansatz gezeigt hat und dachte, damit sei jedem seine
Problemstellung schon klar.
Geschickter wäre gewesen, mit dem funktionierenden, aber in seinen Augen
uneleganten Code zu starten.
Damit wäre seine Problemstellung tatsächlich klar beschrieben gewesen
(in Form einer funktionierenden VHDL-Beschreibung). Und auch die Frage,
ob man eine Signalzuweisung weglassen kann beantwortet sich viel besser,
wenn die betreffende Signalzuweisung tatsächlich gezeigt wird - und
nicht der Phantasie der Leser überlassen.
Gustl B. schrieb:> Wenn er aber schreibt:> x_verzögert <= x after t;> und dann abfragt> if x_verzögert = '0' then ...>> dann enthält x_verzögert einen Blick in die Vergangeheit. x_verzögert> enthält den Wert, den x vor der Zeit t hatte. Die Abfrage lautet also:> Hatte x vor der Zeit t den Wert 0?> Und das kann man natürlich bauen, weil in dem Fall tatsächlich ein alter> Wert von x aufgehoben/gespeichert wird.
Richtig, und genau dass kann man in VHDL eleganter schreiben, so wie es
Tobias erklärt hat: Beitrag "Re: VHDL: if-Anweisung mit verzögertem Signal"
Das Attribut 'delayed kannte ich auch lange nicht. Für die Simulation
gibt es noch weitere praktische Attribute: 'stable(t), 'quiet(t),
'last_event, 'last_active, 'last_value.
Christoph Z. schrieb:> Das Attribut 'delayed kannte ich auch lange nicht.
Ich kannte es bis zu diesem Thread nicht sondern hätte es mal mit
"transport" versucht. Aber wieder was gelernt, vielen Dank!
-gb- schrieb:> Ich kannte es bis zu diesem Thread nicht sondern hätte es mal mit> "transport" versucht. Aber wieder was gelernt, vielen Dank!
Hmm, "transport" hat aber eine andere Bedeutung und ist nur zusammen mit
"after" gültig, ähnlich wie "inertial". Nun wieder die Frage: Gibt es
auch hierzu eine äquivalente Attribut-Darstellung?
Gustl B. schrieb:> Ne, da hatte ich verstanden, dass er keinen Blick in die Zukunft,> sondern in die Vergangenheit will.
Genau.
> Andreas S. schrieb:>> if ((x after t) = '0') then>> Das verlangt einen Blick in die Zukunft und geht daher nicht. Es fragt> nämlich: Wird x in der Zeit t den Wert 0 haben?
Meine ursprüngliche Annahme bestand darin, dass der Compiler/Simulator
selbst einen Merker einfügen könnte, denn schließlich ist "(x after t)"
ein gültiger R-Wert. Offenbar scheint das aber bei VHDL nicht der Fall
zu sein. Die Existenz des "delayed"-Attributs belegt aber, dass
entsprechende Anforderungen auch bei den Entwicklern des
VHDL-Sprachstandards bekannt waren. Vermutlich konnten sie dieses
Attribut recht einfach einführen.
> Wenn er aber schreibt:> x_verzögert <= x after t;> und dann abfragt> if x_verzögert = '0' then ...>> dann enthält x_verzögert einen Blick in die Vergangeheit. x_verzögert> enthält den Wert, den x vor der Zeit t hatte. Die Abfrage lautet also:> Hatte x vor der Zeit t den Wert 0?> Und das kann man natürlich bauen, weil in dem Fall tatsächlich ein alter> Wert von x aufgehoben/gespeichert wird.
Und genau so war es auch gemeint.
Ich räume ein, dass es ein Fehler war, nicht den funktionsfähigen Code
zu veröffentlichen, sondern nur in Form des Satzes "Nur dann, wenn ich
ein Signal verwende, funktioniert das ganze." am Rande zu erwähnen.
Andreas S. schrieb:> Diese und auch noch ein paar andere Timings lassen sich natürlich nur> mit Hilfe der beschriebenen "after"-Anweisungen darstellen.
Mach das mal ordentlich mit waits.
Weltbester FPGA-Pongo schrieb im Beitrag #6279266:
> Mach das mal ordentlich mit waits.
Hmm, die Semantik ist in vielen Fällen eine deutlich andere,
insbesondere bei der Verwendung von "transport" oder
"inertial"-Attributen. Dann muss man deren Verhalten unnötigerweise in
der Testbench nachbilden, was natürlich neue Fehlerquellen beinhaltet.
"after" ist bei korrekter Verwendung kurz und prägnant.
Außerdem ist "wait" nicht zulässig bei Prozessen mit Sensitivitätsliste.