Ist das Verhalten so OK?

OP #7803703
Lesenswert?

Hallo, vielleicht ist es zu spät und ich bin Matsche im Kopf, aber das finde ich seltsam, also ein Minimalbeispiel:

1
library ieee; 
2
use ieee.std_logic_1164.all; 
3
use ieee.numeric_std.all;
4

5
entity tb_while is
6
end tb_while;
7

8
architecture tb of tb_while is
9

10
  signal counter                        : integer := 0;
11

12
begin
13

14
  process
15
  begin
16
    while counter < 15 loop
17
      wait for 10 ns;
18
      counter <= counter + 1;
19
    end loop;
20

21
    wait;
22
  end process;
23

24
end;

Welchen Wert nimmt counter maximal an? Ja, richtig, 16.

Warum ist das so? Weil

while counter < 15 loop

dann schon wieder ausgewertet wird wenn die Addition/Zuweisung

counter <= counter + 1;

noch nicht fertig ist. Schreibt man noch einen kurzen wait dazu

counter <= counter + 1; wait for 1 ps;

funktioniert es wie gewünscht.

Meine Frage ist, ob das jetzt schlicht normales Verhalten ist, also alles OK, oder ob das in aktuelleren Modelsim Versionen anders ist. Ich verwende die letzte freie von Intel, 2020.1.

Vielen Dank!

Moderator (Firma: Titel) Persönliche Seite #7803790
Lesenswert?

Markus F. schrieb:

wann werden Signale in einem Prozess aktualisiert?

Immer beim nächsten "wait".

Und dann die "Ausnahme" zum Verwirren von Anfängern: der Anfang eines Prozesses mit Sensitivliste ist ein implizierter "wait on".

1
  process (a,b,c) begin
2
    :
3
  end process;
4

5
  -- entspricht 
6

7
  process begin
8
    wait on a,b,c;
9
    :
10
  end process;

Und weil nach dem "Bearbeiten" eines Prozesses sofort wieder an dessen Anfang gesprungen wird, ergibt sich das "gefühlte" Verhalten, dass Signale in Prozessen mit Sensitivliste "am Prozessende" aktualisiert werden. Korrekterweise werden sie aber erst beim nächsten Prozessanfang, also beim nächsten impliziten "wait on" aktualisiert.

Man müsste hier also lediglich den counter in die Sensitivliste aufnehmen, dann wäre bei 15 Schluss.

OP #7803897
Lesenswert?

Lothar M. schrieb:

Und dann die "Ausnahme" zum Verwirren von Anfängern

Exakt! Denn so hatte ich das gelernt, dass die neuen Werte am Ende vom Prozess zugewiesen werden.

Klar, mit dem wait macht natürlich Sinn, das habe ich verstanden. Ich hatte irgendwie angenommen, dass auch vor einer Abfrage wie while die Werte aktualisiert werden die im Code auch noch weiter oben steht. Wieder was gelernt.

Gast #7804154
Lesenswert?

Die Logik in deinem Prozess ist mit dem while unnötig kompliziert. Das wait sollte immer nur einmal im Prozess vorkommen, normalerweise am Anfang oder in der Sensitivity Liste.

1
    process
2
    begin
3
        wait for 10 ns;
4
        if counter < 15 then
5
            counter <= counter + 1;
6
        end if;
7
    end process;

Schleifen würde ich nur mit Variablen und nicht mit Signalen verwenden, Variablen werden direkt bei der ":=" Zuweisung geändert, und entsprechen dann der üblichen C-Programmierlogik.

#7805639
Lesenswert?

@udok: Deine Variante zählt zwar richtig, aber hat kein 'Ende'. Ich verwende gerne Testbenches bzw. Simulationen, die sich von selbst beenden. Dazu dürfen keine Events mehr offen sein:

1
...
2
   signal simulation_run : boolean := true;
3
...
4
begin
5

6
   tb_clk <= not tb_clk after tb_clk_period/2 when simulation_run;
7
...        
8
   stim_proc: process
9
   begin
10
      -- do some stimulus
11
      wait for 200 ns;
12

13
      -- do some more stimulus
14
      wait for 20 us;
15

16
      simulation_run <= false;
17
      wait;
18
   end process;
19
end architecture;

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren