Forum: FPGA, VHDL & Co. Verilog Frage


von VERILOGGER (Gast)


Lesenswert?

Hallo,
ich habe eine Frage zu folgendem Code:
1
module funny;
2
  reg a;
3
  initial
4
    a=1;
5
  
6
  always@(a)
7
    if(a)
8
      begin
9
        $display($time,,,"a ist %d",a);
10
        a =0;
11
      end
12
    else
13
      $display($time,,,"a ist %d",a);
14
endmodule

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

von SuperWilly (Gast)


Lesenswert?

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:

1
module funny(); 
2
    reg a;  
3
  
4
    assign b = a;
5
6
    initial begin 
7
        a = 1; 
8
        #1 a = 0; 
9
        $display(b); 
10
    end 
11
endmodule


Es wird eine 1 ausgegeben.

VG, SuperWilly

von Harald F. (hfl)


Lesenswert?

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?

von SuperWilly (Gast)


Lesenswert?

> 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

von VERILOGGER (Gast)


Lesenswert?

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?

von SuperWilly (Gast)


Lesenswert?

>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!

von SuperWilly (Gast)


Angehängte Dateien:

Lesenswert?

ModelsimPE Screenshot siehe Anhang

von Harald F. (hfl)


Lesenswert?

-> 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

von SuperWilly (Gast)


Lesenswert?

Folgendes Modul würde zu einer Ausgabe
1
a ist 1
2
a ist 0
führen:
1
module funny;
2
  reg a;
3
  initial
4
   a=1;
5
  
6
  always@(a)
7
    if(a)
8
      begin
9
         $display($time,,,"a ist %d",a);
10
         a =0;
11
         $display($time,,,"a ist %d",a);
12
      end
13
    else
14
       $display($time,,,"a ist %d",a);
15
endmodule


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:
1
module funny;
2
  reg a;
3
  initial
4
   a=1;
5
  
6
  always@(a)
7
    if(a)
8
      begin
9
         $display($time,,,"a ist %d",a);
10
         a <=0;
11
         $display($time,,,"a ist %d",a);
12
      end
13
    else
14
       $display($time,,,"a ist %d",a);
15
endmodule


Ausgabe:
1
a ist 1
2
a ist 1
3
a ist 0



VG, SuperWilly

von VERILOGGER (Gast)


Lesenswert?

ok danke für die Antworten

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.