Was wäre eurer Meinung nach die Ausgabe? Nach meinem Verständnis müsste
zuerst "a ist 1" und dann "a ist 0" ausgegeben werden. Der
Icarus-Simulator gibt jedoch nur "a ist 1". Durch die Zuweisung a=0
müsste eigentlich doch der always-Block nochmal durchlaufen werden und
dann in den else-Zweig gehen?
Das ganze klappt wenn ich statt a=0 eine non-Blocking Zuweisung a<=0
benutze. Ich verstehe eber nicht warum. Ich hoffe ihr könnt mir da
helfen.
Danke
Du provozierst eine klassische Race Condition mit deinem Verilog-Code.
Folgendes Beispiel veranschaulicht das Problem auf andere Art und Weise,
ist aber im Prinzip dasselbe Problem:
Hallo Verilogger,
wir hatten das vor kurzem mal in einem anderen Thread. Marcus hat dabei
darauf hingewiesen, dass es in Verilog keine "sensitivity list" im
strengen Sinne wie in VHDL gibt. Dein always-Statement wird "immer"
ausgeführt, und das @(a) kann man so lesen, dass die Ausführung dort
stehen bleibt bis der Trigger eintritt. Wenn sich a dann bewegt, dann
wird das if-Statement ausgeführt. In diesem if-Statement wird (unter
anderem) a verändert, aber wenn das always-Statement verlassen wird,
dann bewegt sich a danach nicht mehr. always ist nicht rekursiv.
Dass das mit einem <= klappt, das kann man damit erklären, dass bei
einem non-blocking-assignment die Zuweisungen nicht sofort ausgeführt
werden, sondern am Ende eines Simulationsschritts, also wenn alle
Anweisungen fertig sind, also wenn das always verlassen wurde.
Harald
p.s. dass der Code nicht nur funny sondern auch etwas strange ist, ist
dir schon klar?
> die Zuweisungen nicht sofort ausgeführt>werden, sondern am Ende eines Simulationsschritts, also wenn alle>Anweisungen fertig sind, also wenn das always verlassen wurde.
Stimmt das?
Die Display-Anweisung befindet sich doch im Always-Block? Also wie kann
deine Behauptung stimmen?
VG, SuperWilly
zuerst mal danke für die Antworten.
@SuperWilly,
bei deinem Code wird mir ne 0 ausgegeben (so wie ich das auch erwartet
hätte). Was daran ist genau eine Race-Condition?
>bei deinem Code wird mir ne 0 ausgegeben (so wie ich das auch erwartet>hätte). Was daran ist genau eine Race-Condition?
Das genau ist die Race Condition! Modelsim gibt eine 1 aus, d.h. der
Simulator muss sich entscheiden, jeder Simulator macht es anders!
-> SuperWilly
Harald:
... die Zuweisungen nicht sofort ausgeführt werden, sondern am Ende
eines Simulationsschritts, also wenn alle Anweisungen fertig sind, also
wenn das always verlassen wurde.
SuperWilly:
Stimmt das? Die Display-Anweisung befindet sich doch im Always-Block?
Also wie kann deine Behauptung stimmen?
Harald: Dazu zitiere ich mal das Verilog LRM
How the simulator evaluates non-blocking procedural assignments
When the simulator encounters a non-blocking procedural assignment, the
simulator evaluates and executes the non-blocking procedural assignment
in two steps.
1. The simulator evaluates the right-hand side and schedules the
assignment of the new value to take place at a time specified by a
procedural timing control.
2. At the end of the time step, in which the given delay has expired or
the appropriate event has taken place, the simulator executes the
assignment by assigning the value to the left-hand side.
Bezogen auf das Beispiel heißt das:
1 always@(a)
2 if(a)
3 begin
4 $display($time,,,"a ist %d",a);
5 a =0;
6 end
7 else
8 $display($time,,,"a ist %d",a);
1. In Zeile 5 wird der "new value" von a auf 0 gesetzt. a selbst bleibt
aber auf 1.
2. Am Ende des Simulationsschritts, in dem Fall wenn "the event has
taken place" wird a auf den "new value" von a gesetzt.
Grüße,
Harald
D.h.
1. Die Display-Ausgabe vor dem "a=0" zeigt die Änderung des Wertes nicht
an (also wie bei der Verwendung einer Variablen in VHDL)
2. Der ELSE-Zweig wird nicht betreten
Zum Vergleich mit non-blocking: