Forum: FPGA, VHDL & Co. Simulation - Bei Abtastung anliegendes Signal übernehmen


von Jochen (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Community,

in der angehängten Grafik (aus ModelSim) ist oben ein Takt dargestellt. 
Bei jeder steigenden Flanke wird das Eingangssignal (Mitte) abgetastet 
und auf das Ausgangssignal ausgegeben (unten). Was mich wundert ist, 
dass das Ausgangssignalignal im Abtastzeitpunkt (3) den Wert '0' 
annimmt, obwohl die '0' erst in diesem Takt auf das Eingangssignal 
zugewiesen wird. In der Realität kann das FF den Wert '0' doch in diesem 
Takt noch gar nicht haben, oder irre ich? Kann man ModelSIM irgendwie 
dazu bewegen, eher "REAL" zu handeln?

von Jochen (Gast)


Lesenswert?

Jochen schrieb:
> Hallo Community,
>
> in der angehängten Grafik (aus ModelSim) ist oben ein Takt dargestellt.
> Bei jeder steigenden Flanke wird das Eingangssignal (Mitte) abgetastet
> und auf das Ausgangssignal ausgegeben (unten). Was mich wundert ist,
> dass das Ausgangssignalignal im Abtastzeitpunkt (3) den Wert '0'
> annimmt, obwohl die '0' erst in diesem Takt auf das Eingangssignal
> zugewiesen wird. In der Realität kann das FF den Wert '0' doch in diesem
> Takt noch gar nicht haben, oder irre ich? Kann man ModelSIM irgendwie
> dazu bewegen, eher "REAL" zu handeln?

Sorry...

Hier noch mal der richtige Text, da ja bei Abtastzeitpunkt (3) alles 
richtig läuft... Es geht natürlich um den Abtastzeitpunkt (2)

> in der angehängten Grafik (aus ModelSim) ist oben ein Takt dargestellt.
> Bei jeder steigenden Flanke wird das Eingangssignal (Mitte) abgetastet
> und auf das Ausgangssignal ausgegeben (unten). Was mich wundert ist,
> dass das Ausgangssignalignal im Abtastzeitpunkt (2) den Wert '1'
> annimmt, obwohl die '1' erst in diesem Takt auf das Eingangssignal
> zugewiesen wird. In der Realität kann das FF den Wert '1' doch in diesem
> Takt noch gar nicht haben, oder irre ich? Kann man ModelSIM irgendwie
> dazu bewegen, eher "REAL" zu handeln?

von daniel__m (Gast)


Lesenswert?

Jochen schrieb:
> Kann man ModelSIM irgendwie
> dazu bewegen, eher "REAL" zu handeln?

Dazu würdest du "reale" Simulationsmodelle deiner FF benötigen und diese 
auch in deinem Quelltext einbauen müssen. Üblicherweise wird "nur" das 
gewünschte Verhalten beschrieben und der Rest wird als ideal angenommen. 
Hier kann es durchaus sein, dass dein Eingangssignal minimal (im ps- 
oder fs-Bereich) vor dem Takt bereits "1" war.

Für eine Reale Simulation käme evtl. eine Post-Place-Route Simulation in 
Frage. Aber wie gesagt, da müssten die Modelle stimmen und man muss das 
Ergebnis richtig interpretieren, was SEHR viel Erfahrung benötigt.

gruß

von J. S. (engineer) Benutzerseite


Lesenswert?

Das Verhalten IST real, da die Synthese letztlich dafür sorgt, dass die 
Timingthemen erledigt sind und sich (in der diskreten Betrachtung der 
Taktzyklen) das Schaltwerk exakt so verhält, wie es die Logik sagt. Du 
musst also im Rahmen der Simu nur die Logik glattstellen und bist 
fertig.

Eine Timingsimulation ist nur dann von Nöten, wenn man unterhalb der 
Taktgrenze mit eng tolerierten Signalen und Laufzeitproblemen zu tun 
hat, z.B. wenn man ein Signal nicht in dedizierten Takt sondern im 
nächsten übernehmen will, z.B. wenn man mit 400 MHz arbeitet und das 
input delay genau bei 0,1 bis 2,4ns sein muss, was nicht geht. Dann legt 
man es auf 2,6 bis 4,9ns und nutzt den fallenden Takt. Davon solltest Du 
daber die
Finger lassen, solange Du nicht genauer Bescheid weist.

Dass Deine Simu nicht das tut, was Du erwartest, kann 3 Ursachen haben:

1) Die Takte sind nicht auf die ps synchron und die tastende Flanke 
liegt in der Tat schon in der "0" und Du siehst es nur nicht...

2) Du hast ein Signal zu wenig in der Sens-Liste ...

3) Du arbeitest mit einem hingefummelten Takt, der mittels "after" 
konstruiert ist, da hat ModelSim nämlich Probleme, das korrekt zu 
kriegen.

Ich Tippe auf 2.

von Jochen (Gast)


Lesenswert?

Juergen Schuhmacher schrieb:
> Das Verhalten IST real, da die Synthese letztlich dafür sorgt, dass die
> Timingthemen erledigt sind und sich (in der diskreten Betrachtung der
> Taktzyklen) das Schaltwerk exakt so verhält, wie es die Logik sagt. Du

Ich dachte, dass das Signal eine gewissen "Zeit" nach dem Takt braucht, 
um sicher anzuliegen?!?! Das biegt die Synthese also so hin?

> 3) Du arbeitest mit einem hingefummelten Takt, der mittels "after"
> konstruiert ist, da hat ModelSim nämlich Probleme, das korrekt zu
> kriegen.

Das ist der Treffer. Mein Takt wird durch folgenden Prozess in der 
Testbench erzeugt:
1
PROCESS                                               
2
                                 
3
BEGIN                                                        
4
5
 clk <= '1';
6
 wait for 5 ns;
7
 clk <= '0';
8
 wait for 5 ns;
9
                                                      
10
END PROCESS;

wie mache ich das besser?

von J. S. (engineer) Benutzerseite


Lesenswert?

Das ist nicht eines der After-Kontrukte, die ich gemeint habe - Deine 
Formulierung ist ok so.

Du musst nicht per VHDL dafür sorgen, dass die FF-Aufgänge den Takt 
überlappen. Die Synthese biegt das auch nicht hin, sondern die Physik. 
Die Synthesetools sorgen dafür, dass die Takte niemals vor den Daten 
kommen, solange man das nicht irgendwie selber hindreht.

Konstruiert wird ausdrücklich Logigdesign. Relevant ist der 
Signalzustand während der Phase vor dem Flankenwechsel.

Jochen schrieb:
> Was mich wundert ist,
> dass das Ausgangssignalignal im Abtastzeitpunkt (3) den Wert '0'

Das ist korrekt so.

Was mich aber wundert, ist, dass es am Punkt 2 nicht auf 0 geht.

Das spricht dafür, dass die Daten kurz nach den Flanken aktualisiert 
werden, dann wird logischerweise jeweils high gesehen.

Zeig mal den Konstrukt deiner Daten her. Ich wette, die hängen am Takt.

von Jochen (Gast)


Lesenswert?

Juergen Schuhmacher schrieb:
> Relevant ist der
> Signalzustand während der Phase vor dem Flankenwechsel.

Eben das ist ja in der Sim nicht der Fall...

Juergen Schuhmacher schrieb:
> Was mich aber wundert, ist, dass es am Punkt 2 nicht auf 0 geht.

Ja, mein Text im ersten Posting war falsch.
Relevant ist Posting nummer 2 ;)

von Jochen (Gast)


Lesenswert?

PS.: Ich habe auch alle Eingangssignale in der sensitivity list

process(clk, sig)

von Duke Scarring (Gast)


Angehängte Dateien:

Lesenswert?

Jochen schrieb:
> PS.: Ich habe auch alle Eingangssignale in der sensitivity list
>
> process(clk, sig)
Das sig kann wieder raus (wenn es kein asynchroner Reset ist).
In die sens-list kommen nur Takte und asynchrone Signale.


Wie wird denn Dein Eingangssignal (Mitte) erzeugt?
Hast Du Dir mal im Modelsim angeschaut bei welchem Deltazyklus da was 
los ist?
Ich habe mal versucht Dein Szenario nachzustellen, siehe Anhang.
Bei mir ändert sich das Signal einen Deltazyklus vor dem Takt...

Die Simulation wird sequentiell abgearbeitet. Da ist es "Zufall" welches 
von zwei gleichzeitigen Ereignissen zuerst dran ist :-)

In der Realität bekommst Du setup-Zeit-Verletzungen an Deinem FF.

Duke

von Jochen (Gast)


Lesenswert?

Hallo Duke,

kann es sein, dass dein SIG_OUT sowieso die ganze Zeit '1' ist?


Mein Signal wird folgendermaßen erzeugt. Wie kann ich mir die 
DeltaDelays in ModelSIM anschauen?
1
always : PROCESS                                              
2
-- optional sensitivity list                                  
3
-- (        )                                                 
4
-- variable declarations                                      
5
BEGIN                                                         
6
                sig1 <= '0';
7
    
8
    wait for 24 ns;
9
    
10
    sig1 <= '1';
11
    
12
    
13
    wait for 8 ns;
14
    
15
    sig1 <= '0';
16
    
17
    
18
    wait for 8 ns;
19
    
20
    sig1 <= '1';
21
    
22
    
23
    wait for 8 ns;
24
    
25
    sig1 <= '0';
26
    
27
    
28
    wait for 8 ns;
29
    
30
WAIT;                                                        
31
END PROCESS always;

von Klaus F. (kfalser)


Lesenswert?

Juergen Schuhmacher schrieb:
> 1) Die Takte sind nicht auf die ps synchron und die tastende Flanke
> liegt in der Tat schon in der "0" und Du siehst es nur nicht...

Es braucht gar keine ps, es genügen schon delta-Zyklen und das ist ein 
Punkt, wo man mit VHDL aufpassen muss, wenn man z.B. eine Takt 
invertiert.

z.B.
1
Clk_inv = not clk;
2
3
process(clk) 
4
begin
5
  if rising_edge(clk) then 
6
     a <= not a;
7
  end if;
8
end;
9
10
process(clk) 
11
begin
12
  if rising_edge(clk) then 
13
     d1 <= a;
14
  end if;
15
end;
16
17
process(clk_inv) 
18
begin
19
  if falling_edge(clk) then 
20
     d2 <= a;
21
  end if;
22
end;

In diesem Fall werden d1 und d2 in der Simulation invertiert sein, in 
der Praxis aber nicht.

Das kommt daher, dass clk_inv in der Simulation einen delta-Zyklus 
später abtastet.
Im delta-zyklus 0 ändert sich clk, deshalb werdenclk_inv, a und d1 
aktualisiert.
Daraufhin wird im delta-zyklus 1 clk_inv als geändert gesehen, und d2 
aktualisiert. d2 wird aber mit dem nun schon geändertem Wert von a 
aktualisiert.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Jochen schrieb:
> Was mich wundert ist, dass das Ausgangssignalignal im Abtastzeitpunkt
> (3) den Wert '0' annimmt, obwohl die '0' erst in diesem Takt auf das
> Eingangssignal zugewiesen wird.
Das ist eine rein akademische Frage, die mit dem Stichwort Deltazyklus 
abgehandelt wird. Mach z.B. einfach mal ein
wait for 0 ns;
in den VHDL Code. Die Simulationsuhr bleibt stehen, aber es passiert 
trotzdem was: Signale werden zugewiesen und evtl. geändert, weil du 
solch einen zusätzlichen Delta-Zyklus eingefügt hast...

>>> In der Realität kann das FF den Wert '0' doch in diesem
>>> Takt noch gar nicht haben, oder irre ich?
Duke Scarring schrieb:
> In der Realität bekommst Du setup-Zeit-Verletzungen an Deinem FF.
Das ist er eigentliche Knackpunkt...

von Peter aus München (Gast)


Angehängte Dateien:

Lesenswert?

Lothar Miller schrieb:
> Das ist eine rein akademische Frage, die mit dem Stichwort Deltazyklus
> abgehandelt wird. Mach z.B. einfach mal ein
> wait for 0 ns;
> in den VHDL Code. Die Simulationsuhr bleibt stehen, aber es passiert
> trotzdem was: Signale werden zugewiesen und evtl. geändert, weil du
> solch einen zusätzlichen Delta-Zyklus eingefügt hast...

hmm... Hab ich jetzt gemacht. Das Ergebnis bleibt wie es ist... So ganz 
verstanden hab ich das noch nicht.

Hier mal meine Testbench
1
LIBRARY ieee;                                               
2
USE ieee.std_logic_1164.all;                                
3
4
ENTITY ydf_vhd_tst IS
5
END ydf_vhd_tst;
6
ARCHITECTURE ydf_arch OF ydf_vhd_tst IS
7
-- constants                                                 
8
-- signals                                                   
9
SIGNAL clk : STD_LOGIC;
10
SIGNAL reset : STD_LOGIC;
11
SIGNAL sig1 : STD_LOGIC ;
12
SIGNAL sig1_out : STD_LOGIC;
13
SIGNAL sig2 : STD_LOGIC;
14
SIGNAL sig2_out : STD_LOGIC;
15
16
17
18
19
20
COMPONENT ydf
21
  PORT (
22
  clk : IN STD_LOGIC;
23
  reset : IN STD_LOGIC;
24
  sig1 : IN STD_LOGIC;
25
  sig1_out : OUT STD_LOGIC;
26
  sig2 : IN STD_LOGIC;
27
  sig2_out : OUT STD_LOGIC
28
  );
29
END COMPONENT;
30
BEGIN
31
  
32
  i1 : ydf
33
  PORT MAP (
34
-- list connections between master ports and signals
35
  clk => clk,
36
  reset => reset,
37
  sig1 => sig1,
38
  sig1_out => sig1_out,
39
  sig2 => sig2,
40
  sig2_out => sig2_out
41
  );
42
init : PROCESS                                               
43
-- variable declarations                                     
44
BEGIN                                                        
45
46
 clk <= '1';
47
 wait for 5 ns;
48
 clk <= '0';
49
 wait for 5 ns;
50
 
51
 
52
                                                      
53
END PROCESS init;                                           
54
always : PROCESS                                              
55
-- optional sensitivity list                                  
56
-- (        )                                                 
57
-- variable declarations                                      
58
BEGIN      
59
60
                                       
61
      sig1 <= '0';
62
    sig2 <= '0';
63
    reset <= '1';
64
    wait for 12 ns;
65
    reset <= '0';
66
    wait for 12 ns;
67
    
68
    sig1 <= '1';
69
    sig2 <= '1';
70
  
71
    
72
    wait for 8 ns;
73
    wait for 0 ns;
74
    sig1 <= '0';
75
    sig2 <= '0';
76
    
77
    wait for 8 ns;
78
    wait for 0 ns;
79
    
80
    sig1 <= '1';
81
    sig2 <= '1';
82
    
83
    wait for 8 ns;
84
    wait for 0 ns;
85
    
86
    sig1 <= '0';
87
    sig2 <= '0';
88
    
89
    wait for 8 ns;
90
    
91
WAIT;                                                        
92
END PROCESS always;                                          
93
END ydf_arch;

und hier der zu testende Code:
1
    PROCESS(clk,reset,sig1,sig2)
2
    BEGIN
3
    if reset = '1' then
4
        sig1_out <= '0';
5
        sig2_out <= '0';
6
    
7
    elsif rising_edge(clk) then
8
      
9
        sig1_out <= sig1;
10
        sig2_out <= sig2;
11
      
12
    end if;
13
    END PROCESS;

von berndl (Gast)


Lesenswert?

du aenderst bei t=40ns gleichzeitig den Takt und deine Eingangssignale. 
Was soll der arme Simulator denn damit anfangen (und eine echte HW 
haette eine Setup-Verletzung)?
1
sig1 <= '0';
2
sig2 <= '0';
3
reset <= '1';
4
wait for 12 ns;
Aendere mal die 12ns um +/-1ns, dann sollte es klar werden

von Peter aus München (Gast)


Lesenswert?

berndl schrieb:
> du aenderst bei t=40ns gleichzeitig den Takt und deine Eingangssignale.
> Was soll der arme Simulator denn damit anfangen (und eine echte HW
> haette eine Setup-Verletzung)?

Ich habe jetzt mal ein neues Beispiel ausgearbeitet, in dem das 
Eingangssignal mit dem Clock synchron kommt. Ich denke hier wird mein 
Problem besser ersichtlich.

Ich hätte vermutet, dass das Eingangssignal mit dem Clock abgetastet 
wird, und erst bei der nächsten steigenden Flanke am Ausgang zu sehen 
ist.

Ich meine also beispielsweise, dass zum Zeitpunkt 20 ns eigentlich noch 
die '0' abgetastet hätte werden müssen. Zum Zeitpunkt 30 ns dann die '1' 
usw. Leider wird hier aber zum ZP 20 ns die 1 abgetastet und zum 
Zeitpunkt 30 ns die 2. Das kann doch in der Realität nicht sein?!?! Kann 
ich die Simulation durch irgendetwas dazu zwingen ?!?!

Hier nochmal meine DUT und die TB
1
LIBRARY ieee;
2
USE ieee.std_logic_1164.all;
3
USE ieee.numeric_std.all;
4
5
ENTITY ydf IS
6
  PORT
7
  (
8
    sig1        : IN std_logic_vector (2 downto 0):="000";  
9
    reset        : IN std_logic;
10
    clk        : IN std_logic;
11
    sig1_out      : OUT std_logic_vector(2 downto 0)
12
    );
13
END ENTITY;
14
15
ARCHITECTURE rtl OF ydf IS
16
                        
17
  BEGIN  
18
    PROCESS(clk,reset,sig1)
19
    BEGIN
20
    if reset = '1' then
21
        sig1_out <= "000";  
22
    
23
    elsif rising_edge(clk) then
24
        sig1_out <= sig1;
25
      
26
    end if;
27
    END PROCESS;
28
END;

Testbench
1
LIBRARY ieee;                                               
2
USE ieee.std_logic_1164.all;                                
3
4
ENTITY ydf_vhd_tst IS
5
END ydf_vhd_tst;
6
ARCHITECTURE ydf_arch OF ydf_vhd_tst IS
7
                                                
8
SIGNAL clk : STD_LOGIC;
9
SIGNAL reset : STD_LOGIC;
10
SIGNAL sig1 : STD_LOGIC_VECTOR(2 DOWNTO 0);
11
SIGNAL sig1_out : STD_LOGIC_VECTOR(2 DOWNTO 0);
12
COMPONENT ydf
13
  PORT (
14
  clk : IN STD_LOGIC;
15
  reset : IN STD_LOGIC;
16
  sig1 : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
17
  sig1_out : OUT STD_LOGIC_VECTOR(2 DOWNTO 0)
18
  );
19
END COMPONENT;
20
BEGIN
21
  i1 : ydf
22
  PORT MAP (
23
  clk => clk,
24
  reset => reset,
25
  sig1 => sig1,
26
  sig1_out => sig1_out
27
  );
28
  
29
  reset                 <= '1', '0' after 20 ns;
30
PROCESS
31
BEGIN
32
  clk <= '1';
33
  wait for 5 ns;
34
  clk <= '0';
35
  wait for 5 ns;
36
  
37
END PROCESS;
38
  
39
PROCESS (clk,sig1,reset)
40
variable cnt : integer range 0 to 5:=0;                                                                                 
41
BEGIN                                                    
42
  if rising_edge(clk) then
43
      if reset = '1' then
44
        sig1 <= "000";
45
      else
46
      cnt := cnt + 1;
47
      
48
      case cnt is
49
        when 1 =>
50
          sig1 <= "001";
51
        when 2 =>
52
          sig1 <= "010";
53
        when 3 =>
54
          sig1 <= "011";
55
        when others =>
56
          cnt := 1;
57
          sig1 <= "000";
58
      end case;
59
      
60
      end if;
61
    end if;
62
  
63
  
64
END PROCESS ;                                                                                     
65
END ydf_arch;

Ich danke euch vielmals für die zahlreichen Antworten ! Ich hoffe, dass 
ich bald verstehe was los ist.

von Jochen Peters aus München (Gast)


Angehängte Dateien:

Lesenswert?

und hier noch der Shot dazu...

Jochen

von J. S. (engineer) Benutzerseite


Lesenswert?

Klaus Falser schrieb:
> Juergen Schuhmacher schrieb:
>
>> 1) Die Takte sind nicht auf die ps synchron und die tastende Flanke
>> liegt in der Tat schon in der "0" und Du siehst es nur nicht...
>
> Es braucht gar keine ps, es genügen schon delta-Zyklen und das ist ein
> Punkt,

ja ja, nur wenn wir den TE nun auch noch mit solchen details bewerfen 
... :-)

Duke Scarring schrieb:
> Das sig kann wieder raus (wenn es kein asynchroner Reset ist).

es MUSS sogar wieder raus, weil es sonst andauern auf reset reagiert. 
Selbst, wenn das funktionell unerheblich ist, würde es zu unnötigem 
Simuaufwand führen, wenn der Compiler das nicht wegoptimiert, was ich in 
diesem Fall nicht unbedingt glaube. Bei anderen Signalen führt es zu 
seltsamen Ergebnissen.


Jochen schrieb:
> Juergen Schuhmacher schrieb:
>> Relevant ist der
>> Signalzustand während der Phase vor dem Flankenwechsel.
> Eben das ist ja in der Sim nicht der Fall...

Nun, ich würde sagen, dass ist durchaus der Fall. Die Sim vertut sich in 
dem Fall nicht, sondern nimmt sich den Zustand, den sie sieht:

>PROCESS (clk,sig1,reset)
raus mit dem reset und dem sig1

Du willst es doch abtasten und das tut der Clock. Eine Reaktion auf eine 
Signaländerung selbst ist unnötig und im Einzelfall falsch.

Was bei Dir das Problem ist, dass Du Deine Daten mit dem Takt änderst - 
siehe mal den CNT. Das ergibt logisch gesehen keinen Sinn. Abtasten 
macht nur Sinn, wenn die Daten sich langsamer ändern.

Du erzeugst also Daten mit einem Takt und tastest sie nochmal ab. Führt 
je nach Detailformulierung zu einem Überspringen und genau das sehe ich 
in Deinen Daten.

Nimm mal einen Takt zum erzeugen und einen mindestens doppelts so 
schnellen zu abtasten, dann macht die gesamte Mimik auch das, was Du 
vorhast.

von Jochen Peters aus München (Gast)


Lesenswert?

Juergen Schuhmacher schrieb:
> Was bei Dir das Problem ist, dass Du Deine Daten mit dem Takt änderst.
> Das ergibt logisch gesehen keinen Sinn. Abtasten macht nur Sinn, wenn
> die Daten sich langsamer ändern.
>
> Du erzeugst also Daten mit einem Daten und tastest sie nochmal ab. Führt
> je nach Detailformulierung zu einem Überspringen und genau das sehe ich
> in Deinen Daten.
>
> Nimm mal einen Takt zu erzeugen und einen mindestens doppelts so
> schnellen zu abtasten, dann macht die gesamte Mimik auch das, was du
> vorhast.

hmm... Das Problem ist, dass es in meinem realen Projekt (Masterarbeit) 
genau so abläuft.

Ich bekomme Daten von einer Avalon-ST Schnittstelle im Avalon-ST-Takt. 
Mit dem Avalon-ST-Takt läuft auch mein Design. Und mit dem Avalon 
ST-Takt gebe ich die Daten nach der Verarbeitung auch wieder an die 
nächste Avalon-ST Sink weiter... Mein reales Desing sieht also so aus:

....ST-SOURCE--> (SINK [MEIN DESING] SOURCE) --> SINK....

von J. S. (engineer) Benutzerseite


Lesenswert?

Das Problem ist nicht, dass die Realität nicht funktioniert, sondern 
Deine Testbench die Realität nicht richtig wieder gibt.

Entweder baust Du sie vollsynchron und änderst Deine Signale NACH dem 
Takt und nur mit dem Taktwechsel oder Du baust sie real mit Verzögerung.

Du kannst z.B. die Testbench mit falling edge bescheiben, dann hast Du 
während des interen Taktes immer stabile Verhältnisse. Dann wären Fehler 
mit irgendwelchen Setupthemen oder Deltazyklen weg. Wenn Du dann immer 
noch ein Problem hast, liegt es an der Schaltlogik.

Mach mal Deine Sensliste in Ordnung und arbeite jedes neue Datum nur mit 
dem Takt ab, dann geht das auch.

von Jochen Peters aus München (Gast)


Angehängte Dateien:

Lesenswert?

Juergen Schuhmacher schrieb:
> Mach mal Deine Sensliste in Ordnung und arbeite jedes neue Datum nur mit
> dem Takt ab, dann geht das auch.

Danke Jürgen! Das war scheinbar die Lösung!

Ich habe die Signale sig1 und reset jetzt aus der SensList genommen. Es 
funktioniert jetzt so, wie ich es erwartet habe. Das sollte jetzt auch 
der Realität entsprechen?!?!

Ich möchte allerdings verstehen, warum das jetzt funktioniert. Könntest 
du mir kurz erklären, natürlich nur wenn du etwas Zeit hast, warum das 
jetzt geht?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Peter aus München schrieb:
> in dem das Eingangssignal mit dem Clock synchron kommt.
> Ich denke hier wird mein Problem besser ersichtlich.
Das ist nach wie vor ein rein akademisches und theoretisches Problem.
Denn wenn du in der Realität Takt und Daten (annähernd) gleichzeitig 
änderst, dann brauchst du dich über solch ein Verhalten nicht zu 
wundern...

BTW:
variable cnt : integer range 0 to 5:=0;
Das mit der speichernden Variablen kann dich irgendwann auch mal 
einholen. Nimm für Zähler besser mal Signale. Der Klassiker im 
Beitrag "Variable vs Signal"

Jochen Peters aus München schrieb:
> Das sollte jetzt auch der Realität entsprechen?!?!
Du hast auf jeden Fall die Haltezeit ignoriert. Aber für eine 
Verhaltenssimulation ist es ok, zu sagen: die Eingangsdaten sind vor 
dem Takt stabil, und die Ausgangsdaten ändern sich sofort mit dem Takt. 
Aber dazu darfst du eben nur und genau 1 Takt und überall den selben 
Takt haben...

von Jochen Peters aus München (Gast)


Angehängte Dateien:

Lesenswert?

Lothar Miller schrieb:
> Du hast auf jeden Fall die Haltezeit ignoriert. Aber für eine
> Verhaltenssimulation ist es ok, zu sagen: die Eingangsdaten sind vor
> dem Takt stabil, und die Ausgangsdaten ändern sich sofort mit dem Takt.
> Aber dazu darfst du eben nur und genau 1 Takt und überall den selben
> Takt haben...

hmm... ich gehe davon aus, dass die Daten zur nächsten Flanke stabil 
sind.

D.h. das die Daten (neu) erst zum Zeitpunkt t+(ganz kleine Zeit) 
anliegen. Der Zeitpunkt t ist hierbei der Flankenwechsel des Taktes 
(rising)

Also so, wie ich es nochmal aufgezeichnet habe. Denke ich da richtig?

Lothar Miller schrieb:
> Aber dazu darfst du eben nur und genau 1 Takt und überall den selben
> Takt haben...

Ja, genau. Ich habe nur einen Takt!

von Jochen Peters aus München (Gast)


Lesenswert?

Lothar Miller schrieb:
> Das ist nach wie vor ein rein akademisches und theoretisches Problem.
> Denn wenn du in der Realität Takt und Daten (annähernd) gleichzeitig
> änderst, dann brauchst du dich über solch ein Verhalten nicht zu
> wundern...

Genau, das ist mir klar. Mein Problem lag jetzt eigentlich nur darin, 
der Testbench beizubringen, dass zum Zeitpunkt t immer noch der alte 
Wert anliegt und der neue erst bei der nächsten Flanke stabil ist.

von Jochen Peters aus München (Gast)


Angehängte Dateien:

Lesenswert?

Ich glaube ich habe geschafft, was ich wollte. Das neue Signal liegt 
jetzt erst zur nächsten Flanke an, indem ich sig1 einfach per after 1ps 
verzögert habe. Ist das legitim? (Siehe Curser bei 30 ns --> sig = 1)


Entity
1
LIBRARY ieee;
2
USE ieee.std_logic_1164.all;
3
USE ieee.numeric_std.all;
4
5
ENTITY ydf IS
6
  PORT
7
  (
8
    sig1        : IN std_logic_vector (2 downto 0):="000";  
9
    reset        : IN std_logic;
10
    clk        : IN std_logic;
11
    sig1_out      : OUT std_logic_vector(2 downto 0)
12
    );
13
END ENTITY;
14
15
ARCHITECTURE rtl OF ydf IS
16
                        
17
  BEGIN  
18
    PROCESS(clk,sig1,reset)
19
    BEGIN
20
    if reset = '1' then
21
        sig1_out <= "000";  
22
    
23
    elsif rising_edge(clk) then
24
        sig1_out <= sig1;
25
      
26
    end if;
27
    END PROCESS;
28
END;


Testbench
1
LIBRARY ieee;                                               
2
USE ieee.std_logic_1164.all;                                
3
4
ENTITY ydf_vhd_tst IS
5
END ydf_vhd_tst;
6
ARCHITECTURE ydf_arch OF ydf_vhd_tst IS
7
                                                
8
SIGNAL clk : STD_LOGIC;
9
SIGNAL reset : STD_LOGIC;
10
SIGNAL sig1 : STD_LOGIC_VECTOR(2 DOWNTO 0);
11
SIGNAL sig1_out : STD_LOGIC_VECTOR(2 DOWNTO 0);
12
13
COMPONENT ydf
14
  PORT (
15
  clk : IN STD_LOGIC;
16
  reset : IN STD_LOGIC;
17
  sig1 : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
18
  sig1_out : OUT STD_LOGIC_VECTOR(2 DOWNTO 0)
19
  );
20
END COMPONENT;
21
BEGIN
22
23
  i1 : ydf
24
  
25
  PORT MAP (
26
  clk => clk,
27
  reset => reset,
28
  sig1 => sig1,
29
  sig1_out => sig1_out
30
  );
31
  
32
  reset                 <= '1', '0' after 20 ns;
33
PROCESS
34
BEGIN
35
  clk <= '1';
36
  wait for 5 ns;
37
  clk <= '0';
38
  wait for 5 ns;
39
  
40
END PROCESS;
41
42
43
  
44
PROCESS (clk)
45
variable cnt : integer range 0 to 5:=0;                                                                                 
46
BEGIN                                                    
47
  if rising_edge(clk) then
48
      if reset = '1' then
49
        sig1 <= "000";
50
      else
51
      cnt := cnt + 1;
52
      
53
      case cnt is
54
        when 1 =>
55
          sig1 <= "001" after 1 ps;
56
        when 2 =>
57
          sig1 <= "010" after 1 ps;
58
        when 3 =>
59
          sig1 <= "011" after 1 ps;
60
        when others =>
61
          cnt := 1;
62
          sig1 <= "000" after 1 ps;
63
      end case;
64
      
65
      end if;
66
    end if;
67
  
68
  
69
END PROCESS ;                                                                                     
70
END ydf_arch;

von berndl (Gast)


Lesenswert?

Jochen Peters aus München schrieb:
1
PROCESS (clk)
2
variable cnt : integer range 0 to 5:=0;
3
4
BEGIN
5
  if rising_edge(clk) then
Du kannst auch einfach hier 'falling_edge(clk)' schreiben und auf die 
'after 1 ps' verzichten. Kommt genau das gleiche raus...

von Jochen Peters aus München (Gast)


Lesenswert?

berndl schrieb:
> Du kannst auch einfach hier 'falling_edge(clk)' schreiben und auf die
> 'after 1 ps' verzichten. Kommt genau das gleiche raus...

ja, schon probiert. Nur wenn ich es um 1ps. verzögere sieht es in der 
wave einfach leichter zu überschauen aus. Auch wenn es ein wenig mehr 
Schreibarbeit ist.

Danke dir trotzdem berndl

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Jochen Peters aus München schrieb:
> Nur wenn ich es um 1ps. verzögere sieht es in der wave einfach leichter
> zu überschauen aus.
Ja, das ist toll. Symbolische Verzögerungen in Verhaltenssimulationen. 
Die brauchst du nur, wenn du das "Vorher-Nachher"-Konzept aka. "Nach dem 
Takt ist vor dem Takt"-Prinzip noch nicht verstanden/verinnerlicht hast.

> Auch wenn es ein wenig mehr Schreibarbeit ist.
Und auch wenn du dir da nebenbei was in die Tasche lügst...
Siehe den Beitrag "Re: Frage zu Pseudozufallsgenerator!?"

Um im Beitrag "Re: Feedback für Drehgeber Design" ganz ganz 
unten.

Zusammenfassend gilt der 
Beitrag "Re: Functional Simulation mit Modelsim"

von Jochen Peters aus München (Gast)


Lesenswert?

Lothar Miller schrieb:
> "Nach dem
> Takt ist vor dem Takt"-Prinzip noch nicht verstanden/verinnerlicht hast.

anscheinend...

Ich dachte, dass man das in der Testbench tun darf. Ich habe die 
Verzögerungen jetzt mal wieder raus genommen und ALLES auf den "alten" 
Stand gebracht (siehe: 
Beitrag "Re: Simulation - Bei Abtastung anliegendes Signal übernehmen") und es funktioniert 
trotzdem... Jetzt versteh ich gar nichts mehr... Vorher war das Ergebnis 
der Sim anders... (Beitrag "Re: Simulation - Bei Abtastung anliegendes Signal übernehmen")

von Jochen Peters aus München (Gast)


Lesenswert?

Jochen Peters aus München schrieb:
> Ich dachte, dass man das in der Testbench tun darf. Ich habe die
> Verzögerungen jetzt mal wieder raus genommen und ALLES auf den "alten"
> Stand gebracht (siehe:
> Beitrag "Re: Simulation - Bei Abtastung anliegendes Signal übernehmen") und es 
funktioniert
> trotzdem... Jetzt versteh ich gar nichts mehr... Vorher war das Ergebnis
> der Sim anders... (Beitrag "Re: Simulation - Bei Abtastung anliegendes Signal 
übernehmen")

SO... Jetzt muss ich glaube ich eine Pause machen...

Wenn ich das ydf.vhd als Toplevel setze, bekomme ich folgendes 
Sim-Ergebnis
--> falsch.png

Wenn ich das Block1.bdf als TopLevel setze, bekomme ich das "richtige" 
Simulationsergebnis...
--> richtig.png

Das Ganze jetzt mit folgendem Code:

ENTITY UNDER TEST:
1
 
2
ENTITY ydf IS
3
  PORT
4
  (
5
    sig1        : IN std_logic_vector (2 downto 0):="000";  
6
    reset        : IN std_logic;
7
    clk        : IN std_logic;
8
    sig1_out      : OUT std_logic_vector(2 downto 0)
9
    );
10
END ENTITY;
11
12
ARCHITECTURE rtl OF ydf IS
13
                        
14
  BEGIN  
15
    PROCESS(clk,reset,sig1)
16
    BEGIN
17
    if reset = '1' then
18
        sig1_out <= "000";  
19
    
20
    elsif rising_edge(clk) then
21
        sig1_out <= sig1;
22
      
23
    end if;
24
    END PROCESS;
25
END;



TESTBENCH
1
 LIBRARY ieee;                                               
2
USE ieee.std_logic_1164.all;                                
3
4
ENTITY ydf_vhd_tst IS
5
END ydf_vhd_tst;
6
ARCHITECTURE ydf_arch OF ydf_vhd_tst IS
7
                                                
8
SIGNAL clk : STD_LOGIC;
9
SIGNAL reset : STD_LOGIC;
10
SIGNAL sig1 : STD_LOGIC_VECTOR(2 DOWNTO 0);
11
SIGNAL sig1_out : STD_LOGIC_VECTOR(2 DOWNTO 0);
12
13
COMPONENT ydf
14
  PORT (
15
  clk : IN STD_LOGIC;
16
  reset : IN STD_LOGIC;
17
  sig1 : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
18
  sig1_out : OUT STD_LOGIC_VECTOR(2 DOWNTO 0)
19
  );
20
END COMPONENT;
21
BEGIN
22
23
  i1 : ydf
24
  
25
  PORT MAP (
26
  clk => clk,
27
  reset => reset,
28
  sig1 => sig1,
29
  sig1_out => sig1_out
30
  );
31
  
32
  reset                 <= '1', '0' after 20 ns;
33
PROCESS
34
BEGIN
35
  clk <= '1';
36
  wait for 5 ns;
37
  clk <= '0';
38
  wait for 5 ns;
39
  
40
END PROCESS;
41
42
43
  
44
PROCESS (clk,sig1,reset)
45
variable cnt : integer range 0 to 5:=0;                                                                                 
46
BEGIN                                                    
47
  if rising_edge(clk) then
48
      if reset = '1' then
49
        sig1 <= "000";
50
      else
51
      cnt := cnt + 1;
52
      
53
      case cnt is
54
        when 1 =>
55
          sig1 <= "001" ;
56
        when 2 =>
57
          sig1 <= "010" ;
58
        when 3 =>
59
          sig1 <= "011" ;
60
        when others =>
61
          cnt := 1;
62
          sig1 <= "000" ;
63
      end case;
64
      end if;
65
    end if;
66
67
END PROCESS 
68
;                                                                                     
69
END ydf_arch;

von Jochen Peters aus München (Gast)


Angehängte Dateien:

Lesenswert?

hier die shots

von Jochen Peters aus München (Gast)


Lesenswert?

Ich danke euch für die vielen Antworten. Hab wirklich viel dabei 
gelernt. Ich wünsch euch nun ein schönes Wochenende und lass das Ganze 
erstmal bei einem Bierchen sacken!

von J. S. (engineer) Benutzerseite


Lesenswert?

Jochen Peters aus München schrieb:
> h dachte, dass man das in der Testbench tun darf

Du solltest in der Testbench immer das tun, was nötig ist, um den Test 
zu fahren, den Du haben willst. Da muss man eben das Ziel sehen: Wenn Du 
Timing simulieren wills, ok - wenn nur Mathematik, ok - wenn Logigk auch 
ok.

Wenn Du z.B. einen externen Bus hast, sollten die Daten in der Testbench 
so kommen, wie der externe Bus sie bringt. Also inklusive Jitter und 
Datenunsicherheit und um 10 Grad verschobenen, negierten Flanken, wenn 
es sein muss.

Wenn Du aber einen internen Bus oder einen synchronen Bus hast, wo das 
bereits gelöst ist, kannst Du Dich auf die Verhaltenssimulation 
beschränken.

Diese VS ist immer eine funktionelle Simulation, so wie sie auch in 
Matlab oder Excel laufen kann und hat nichts mit Timing unterhalb der 
Taktgeschwindigkeit zu tun. Das Timingthema ist da komplett 
ausgeklammert. Es werden nur Takte als solche und stabile Zustände aus 
der vorherigen Taktebene betrachtet und angenommen.

Es gibt im Logidesign nur granulare Zeitsprünge und Werte vom Typ Y(t+1) 
= f( x(t), y(t), ...... z(t) ) - Fertig. So lernt man das eigentlich an 
der Uni mit den Formelsprachen und so wurde es zu Beginn der PLD-Zeiten 
auch mal gemacht :-)

Du musst daher Dein Design z.B. komplett in Excel hinschreiben können, 
wo in jeder neuen Zeile ein Ergebnis aus den Werten von Kästchen in der 
Zeile DIREKT obendrüber gerechnet wird, so wie der Simulator nach einer 
Taktflanke in den FFs das stehen hat, was vorher am Eingang war. Da gibt 
es keine zeitlichen Überlappungen oder Berechnungen in der selben Zeit 
oder Rückgriffe auf eine vorvorherige Zeit und vor allem kein 
physikalisches Timing. Dass im Simulator da trotzdem Linien wie bei 
einem Oszilloskop angezeigt werden, ist irreführend und genau genommen 
falsch - im Grunde müssten da nur die Bit-Werte in Tabellen stehen und 
sonst nichts.

von Jochen Peters aus München (Gast)


Lesenswert?

Juergen Schuhmacher schrieb:
> Es werden nur Takte als solche und stabile Zustände aus
> der vorherigen Taktebene betrachtet und angenommen.

Genau das habe ich angenommen. Anscheinend habe ich mehrere Fehler 
gemacht, dass es eben nicht so war (siehe: 
Beitrag "Re: Simulation - Bei Abtastung anliegendes Signal übernehmen")

Dank der Hilfe, ist es ja nun endlich so, wie du es gerade beschrieben 
hast (und ich es von anfang an erwartet habe)

;)

Danke für die ausführlichen Erklärungen!

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.