Forum: FPGA, VHDL & Co. [isim] Probleme mit Testbench


von A. M. (am85)


Angehängte Dateien:

Lesenswert?

Hi

Für die Uni sollte ich eine Ampelsteuerung entwickeln. Diese läuft zwar 
auch ganz wunderbar auf der Zielhardware, nur leider nicht im Simulator. 
Das Design sollte nur mit einem Taktsignal ganz normal durchlaufen. In 
Hardware ist das kein Problem und man kann schön dabei zusehen, wie die 
Zustände nach der gewünschten Zeit wechseln. Im Simulator passiert 
leider rein gar nichts. Das Taktsignal wackelt immer schön hin und her, 
aber an den Zuständen ändert sich nichts. Jetzt weiß ich nicht, ob meine 
Testbench vielleicht fehlerhaft ist oder ob ich an einer anderen Stelle 
etwas übersehen habe. Ich habe sowohl die Taktperiode als auch den 
Zählerstand für den Taktteiler variiert, aber getan hat sich am Ausgang 
nichts. Ich würde mich sehr über jede Hilfe freuen.

Schöne Grüße

von Christian R. (supachris)


Lesenswert?

Unabhängig von der Simulator-Frage: Wer hat dir denn erzählt, es gäbe 
außerhalb einer Testbench ein "after x ns" Statement??? Mach die mal 
alle ganz schnell raus, der Sythesizer müsste dir doch massenhaft 
Fehler/Warnungen um die Ohren werfen dafür. Sowas kann man 
ausschließlich in der Simulation machen, in der Hardware gibts sowas 
nicht.

Zum Simulator: Hast du denn auch ausreichend lange simulieren lassen?

von A. M. (am85)


Lesenswert?

Das mit den "after x ns" ist ein Überbleibsel alter Digitaltechnik 
Zeiten. Das Synthesetool (ISE 12.x bzw. 13.1) geht da offensichtlich 
einfach drüber. Es gibt weder Warnings noch Fehler wegen dieser 
Anweisungen.

Den Simulator habe ich bis zu 10 Sekunden simulieren lassen. Real waren 
es also einige Minuten. Bis auf die in der Testbench angegebenen 
Stimulisignale ändert sich rein gar nichts.

von Duke Scarring (Gast)


Lesenswert?

André M. schrieb:
> auch ganz wunderbar auf der Zielhardware, nur leider nicht im Simulator
Ohne mir jetzt Deine Quellen angeguckt zu haben: Das klingt nach 
unvollständigen Sensitivitätslisten.

Duke

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


Angehängte Dateien:

Lesenswert?

Wenn die Sensitivlisten falsch sind, dann ist die Simulation falsch. so 
einfach ist das. Hier ist zuviel drin:
ANFORDERUNG_HAUPTS: process(CLK, HS1_S, HS2_S, FN_S)
ANFORDERUNG_NEBENS: process(CLK, NS1_S, NS2_S, FH_S)
COUNTER: process(CLK, ENCLK, COUNTER_EN)
Hier würde jeweils der CLK ausreichen, aber das ist noch nicht so 
schlimm, damit wird "nur" unnötig viel gerechnet.

Aber hier ist zu wenig drin:
SN: process(ZUSTAND, ANFORDERUNG_NS, ANFORDERUNG_HS, BLINK_S)
Es fehlt COUNT, und das ist natürlich böse, denn genau wenn sich COUNT 
ändert, sollte der Prozess neu berechnet werden...  :-(

André M. schrieb:
> Das Synthesetool (ISE 12.x bzw. 13.1) geht da offensichtlich
> einfach drüber. Es gibt weder Warnings noch Fehler wegen dieser
> Anweisungen.
Das steht im XST User Guide. Ein after ist auf einem FPGA nicht 
synthetisierbar. Bisher von keinem Synthesizer...

André M. schrieb:
> Den Simulator habe ich bis zu 10 Sekunden simulieren lassen.
> Real waren es also einige Minuten.
Wie kommst du darauf?
Das hier macht aus den 50MHz erst mal 2 Hz. Also vergehen zwischen jedem 
Enable 0,5 Sekunden.
1
-- Taktteiler von 50 MHz auf 2 Hz
2
PRESCALER: process(CLK)
3
begin
4
  if CLK='1' and CLK'event then
5
    if CNT = 25000000 then
Wirklich schneller geht die Simulation, wenn du das Enable wesentlich 
öfter generierst. So z.B. simuliert das blitzschnell:
1
    if CNT = 25 then

Warum legst du deinen Reset gleich einen halben Tag lang an? 20ms sind 
eine Eeeeeeeeeeeeewigkeit...
Mach das doch so, wenn du schon meinst, einen Reset zu brauchen:
1
   -- Stimulus process
2
   stim_proc: process
3
   begin    
4
      -- hold reset state for 100 ns.
5
    RESET <= '1';
6
      wait for 100 ns;  
7
    RESET <= '0';
8
      wait;
9
   end process;
Du brauchst aber eigentlich keinen Reset, weil du jedem Signal einen 
Initialisierungswert zuweisen kannst, also auch deinem ZUSTAND. Ohne 
Zuweisung wird hier übrigens immer der erste Wert der Definition 
verwendet. In deinem Fall also INIT.

Das passiert dann auch mit deinem Signal COUNT:
signal COUNT  : std_logic_vector(4 downto 0);
Weil du dem nie was zuweist, ist der Wert von COUNT anfänglich "UUUUU". 
Und dann eins draufaddiert ergibt "XXXXX". Und damit bekommst du niemals 
ein sinnvolles Simulationsergebnis.

Beim CNT hast du übrigens aus Versehen Glück gehabt, denn dessen 
Init-Wert (der linke Wert des Typs) ist durch den eingeschränkten 
Bereich
signal CNT   : integer range 0 to 25000000
glücklicherweise 0.

Kurz und gut:
Du solltest also in deiner Simulation alle Signale initialisieren. Am 
besten so, dann brauchst du keinen Reset.
1
-- Zählersignal des Taktteilers        
2
signal CNT   : integer range 0 to 25000000  := 0;
3
-- COUNTER
4
signal COUNT  : std_logic_vector(4 downto 0) := (others=>'0');
5
6
signal ZUSTAND  : ZUSTANDS_TYP := INIT;

Zusammengefasst sind 2 grundlegende Fehler in deinem Code:
1. die unvollständige Sensitivliste
2. der nicht initialisierte Zähler

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


Lesenswert?

Da ist mir dann noch aufgefallen, dass dein Vorteiler falsch läuft. Der 
erzeugt nicht aus 50MHz die gewünschten 2Hz, sondern 1,99999992Hz. Und 
zwar, weil von 0..24999999 schon 25000000 Zählschritte nötig sind. Du 
zählst aber von 0...25000000 = 25000001 Zählschritte.

Und nein. Das "kann man doch vernachlässigen" gilt hier nicht!
Denn diesen Fehler wirst du auch machen, wenn du mal nur bis 16 zählen 
willst... :-/

von A. M. (am85)


Lesenswert?

Hi

Danke erstmal für eure Antworten.

Lothar Miller schrieb:
> Wenn die Sensitivlisten falsch sind, dann ist die Simulation falsch. so
> einfach ist das. Hier ist zuviel drin:
> ANFORDERUNG_HAUPTS: process(CLK, HS1_S, HS2_S, FN_S)
> ANFORDERUNG_NEBENS: process(CLK, NS1_S, NS2_S, FH_S)
> COUNTER: process(CLK, ENCLK, COUNTER_EN)
> Hier würde jeweils der CLK ausreichen, aber das ist noch nicht so
> schlimm, damit wird "nur" unnötig viel gerechnet.

Ich habe gelernt, dass neben dem Takt auch alle Signale in die 
Sensitivityliste sollen, die in if, etc. abgefragt werden.

Lothar Miller schrieb:
> André M. schrieb:
>> Das Synthesetool (ISE 12.x bzw. 13.1) geht da offensichtlich
>> einfach drüber. Es gibt weder Warnings noch Fehler wegen dieser
>> Anweisungen.
> Das steht im XST User Guide. Ein after ist auf einem FPGA nicht
> synthetisierbar. Bisher von keinem Synthesizer...

Die "after x ns" sollen auch nur in der Simulation Sinn machen. Sie 
sollen einfach nur Gatterlaufzeiten im Simulator nachbilden.

Lothar Miller schrieb:
> André M. schrieb:
>> Den Simulator habe ich bis zu 10 Sekunden simulieren lassen.
>> Real waren es also einige Minuten.
> Wie kommst du darauf?
> Das hier macht aus den 50MHz erst mal 2 Hz. Also vergehen zwischen jedem
> Enable 0,5 Sekunden.

Wie gesagt, ich habe die Werte auch schon variiert, passiert ist 
trotzdem nichts.

Lothar Miller schrieb:
> Warum legst du deinen Reset gleich einen halben Tag lang an? 20ms sind
> eine Eeeeeeeeeeeeewigkeit...
> Mach das doch so, wenn du schon meinst, einen Reset zu brauchen:

Die Testbench und der Ampelcode sind "nur" die aktuellen Fassungen 
gewesen, die ich hochgeladen habe. Die Zeiten habe ich ebenfalls 
variiert.

Lothar Miller schrieb:
> Da ist mir dann noch aufgefallen, dass dein Vorteiler falsch läuft. Der
> erzeugt nicht aus 50MHz die gewünschten 2Hz, sondern 1,99999992Hz. Und
> zwar, weil von 0..24999999 schon 25000000 Zählschritte nötig sind. Du
> zählst aber von 0...25000000 = 25000001 Zählschritte.
>
> Und nein. Das "kann man doch vernachlässigen" gilt hier nicht!
> Denn diesen Fehler wirst du auch machen, wenn du mal nur bis 16 zählen
> willst... :-/

Keine Sorge, das wollte ich auch gar nicht vernachlässigen ;-) Ganz im 
Gegenteil, ich bin froh, dass du mich darauf nochmal hingewiesen hast. 
Mein Code ist an der Stelle natürlich fehlerhaft.

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


Angehängte Dateien:

Lesenswert?

André M. schrieb:
> Ich habe gelernt, dass neben dem Takt auch alle Signale in die
> Sensitivityliste sollen, die in if, etc. abgefragt werden.
Das ist falsch gelernt. In die Sensitivliste müssen alle Signale, die 
eine Neuberechnung des Prozesses erfordern, auf die der Prozess also 
empfindlich (=sensitive) zu sein hat.
In der Praxis ist das in einem reinen getakteten Prozess nur der Takt. 
Nur eine Änderung des Taktsignals hat Auswirkungen auf das Ergebnis des 
Prozesses.
Evtl. kommt dann noch ein asynchroner Reset dazu. Alles was weiters 
dabei steht, ist verdächtig...

> Die Testbench und der Ampelcode sind "nur" die aktuellen Fassungen
> gewesen, die ich hochgeladen habe. Die Zeiten habe ich ebenfalls
> variiert.
Ich habe mal eine Simulation mit den Zeiten aus deinen anfangs 
geposteten Files laufen lassen und da meine beiden angesprochenen 
Änderungen aus dem Beitrag "Re: [isim] Probleme mit Testbench" 
eingebaut:
> 1. die unvollständige Sensitivliste
SN: process(ZUSTAND, ANFORDERUNG_NS, ANFORDERUNG_HS, BLINK_S, COUNT)
> 2. der nicht initialisierte Zähler
signal COUNT : std_logic_vector(4 downto 0) := "00000";
Und nach ein paar Stunden Simulationsdauer kommt das heraus, was du 
erwartest...

von Christian R. (supachris)


Lesenswert?

Sinnvollerweise kannst du den Vorteiler-Wert als Generic machen und 
durch den Simulator dann auf einen sinnvoll simulierbar kleinen Wert 
setzen lassen (falls ISim das kann, ansonsten gleich den Generic in der 
TB fest vorgeben). Somit musst du am Code nix zwischen Simulation und 
Hardware ändern.

von A. M. (am85)


Lesenswert?

Etwas spät, aber ich wollte noch Danke sagen. Es hat jezt alles prima 
geklappt. Und wieder etwas dazu gelernt :-)

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.