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
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.
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...
Das löst das Problem des Threaderstellers aber nur zufällig (Takt startet invertiert).
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.
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; |
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.