Merkwürdiges Verhalten eines Flipflops bei der Simulation

Gast #2229916
Lesenswert?
• ▲
▼
Moinsen,
ich habe schnell mal eben im Xilinx Project-Navigator ein D-FlipFlop in 
VHDL beschrieben (siehe dff.vhd) Und eine Testbench erzeugen lassen 
(siehe dff_tb.vhd). Soweit so gut. Beschreibe ich meine Clock und meinen 
Stimulus in der Testbench wie folgt:

   clock_process: process
   begin
      while not stop_the_clock loop
         clock <= '0', '1' after clock_period / 2;
         wait for clock_period;
      end loop;
      wait;
   end process;

   stim_proc: process
   begin
      wait for 3*clock_period/2;
      d <= '1';
      wait for clock_period;
      d <= '0';
      wait;
   end process;
END;

so ist die Simulation in Ordnung und liefert das erwartete Ergebnis 
(siehe DFF1.png)

Beschreibe ich meine Clock aber auf folgende Weise:

   clock_process :process
   begin
      clock <= '0';
      wait for clock_period/2;
      clock <= '1';
      wait for clock_period/2;
   end process;

bekomme ich ein völlig anderes und meiner Meinung nach auch falsches 
Verhalten im Simulator (ISIM (Win und Linux) und auch bei GHDL/GtkWave 
angezeigt (siehe DFF2.vhd).

Vielleicht kann mir jemand erklären, warum sich die beiden verschiedenen 
Clock Beschreibungen im Simulator so unterschiedlich verhalten.

Gruß Wolfgang
Angehängte Dateien:
Gast #2229940
Lesenswert?
• ▲
▼
Klingt nach einem Delta-Cycle-Problem, das ist so das 
Setup/Hold-Equivalent der Simulatoren... Das "'1' after clock_period / 
2;" macht die Zuweisung nicht vom Takt-Signal abhängig, sondern direkt 
von der Zeit. D.h. Clk und Data wird wirklich gleichzeitig geändert, der 
FF-Prozess wird erst dann simuliert, wenn sich das stabilisiert hat. 
Damit sieht er schon die geänderten Daten und die Taktflanke, die Werte 
scheinen "durchzurutschen".

Du musst die Testdatenerzeugung echt synchron zum Taktsignal machen, 
d.h. auch ein wait until oder rising_edge. Dann stimmt die Kausalität 
wieder.

Ähnliche Effekte gibt es übrigens, wenn man Takte per Signalzuweisung 
weiterreicht. In der Realität ein Draht, im Simulator aber 
Verzögerungsleitungen mit infinitesimal kurzem Delay, der aber >0 ist.
#2231130
Lesenswert?
• ▲
▼
ti6wb schrieb:
> clock_process :process
>    begin
>       clock <= '0';
>       wait for clock_period/2;
>       clock <= '1';
>       wait for clock_period/2;
>    end process;

ich mache das so (tut auch mit GHDL):
1
   clk_process : process
2
   begin
3
      loop
4
         clk <= '1';
5
         wait for clk_period/2;
6
         clk <= '0';
7
         wait for clk_period/2;
8
         exit when end_of_sim = '1';
9
      end loop;
10
      wait;
11
   end process;
Unterschied zu deiner Version: loop-statement und exit condition...
Gast #2231757
Lesenswert?
• ▲
▼
ti6wb schrieb:
> stim_proc: process
>    begin
>       wait for 3*clock_period/2;
>       d <= '1';
>       wait for clock_period;
>       d <= '0';
>       wait;
>    end process;

Das solltest Du besser so schreiben :
1
    begin
2
        wait until clk = '1'; -- wartet auf steigende Flanke !
3
        wait until clk = '1';
4
        d <= '1';
5
        wait until clk = '1';
6
        d <= '0';
7
       wait;
8
    end process;

Dies garantiert, dass das Signal d kurz NACH der Taktflanke gesetzt 
wird.
Gast #2231778
Lesenswert?
• ▲
▼
Klaus Falser schrieb:
> Das solltest Du besser so schreiben :    begin
>         wait until clk = '1'; -- wartet auf steigende Flanke !
>         wait until clk = '1';
>         d <= '1';
>         wait until clk = '1';
>         d <= '0';
>        wait;
>     end process;

Steh ich gerade auf dem Schlauch, oder sollte es nicht am besten so 
heißen (so richtig old school synchron halt):
1
begin
2
  wait until rising_edge(clk);  -- wartet auf steigende Flanke !
3
  d <= '1';
4
  wait until rising_edge(clk);
5
  d <= '0';
6
  wait;
7
end process;
Gast #2232130
Lesenswert?
• ▲
▼
Ich mag den folgenden Einzeiler für die Takterzeugung:
1
signal   simulation_run  : boolean   := true;
2

3
constant tb_clock_period : time      := (1 sec / 50_000_000); -- 50 MHz
4
signal   tb_clock        : std_logic := '0';           -- vordefinieren
5

6
...
7
 
8
tb_clock <= not tb_clock after tb_clock_period / 2 when simulation_run;
9

10
...
11
process
12
begin
13
  ...
14
  simulation_run <= false;
15
  report "simulation end" severity note;
16
  wait;
17
end process;

Mit simulation_run müssen dann alle Takt-/Signalquellen abgeschaltet 
werden. So kommt man ohne den häßlichen failure aus der Simulation 
raus.

Duke
Moderator (Firma: Titel) Persönliche Seite #2238092
Lesenswert?
• ▲
▼
ti6wb schrieb:
> bekomme ich ein völlig anderes und meiner Meinung nach auch falsches
> Verhalten im Simulator
Lustigerweise beschreibst du mit der ganz am Anfang gezeigten Erzeugung 
von 'd' im stim_proc genau das, was an/in einem FPGA zu Metastabilität 
führen wird: die Eingangsdaten (hier 'd') ändern sich nicht WEGEN des 
Takts sondern GENAU GLEICHZEITIG zum Takt.
Und damit ist bei der steigenden Flanke an 'clock' auch schon der "neue" 
Pegel an 'd' zu finden. Das Stichwort hat Georg schon dazu geliefert.

So gesehen sind beide Simulationsergebnisse RICHTIG, denn mit genau 
diesem D-FF und dieser Beschreibung der FPGA-Umgebung können auch beide 
Waveforms in der Realität herauskommen...  :-o

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