Forum: FPGA, VHDL & Co. Verständinsfrage bezüflich State Machine Testbench


von Johannes H. (Gast)


Lesenswert?

Hallo liebe Forenbesucher :)

Um nicht allzu lange um den heißen Brei zu reden, komm ich gleich zu 
meiner Frage. Wie auch schon im Betreff angegeben, handelt sich meine 
Frage um das Verständnis einer State-Machine Testbench.

Angenommen ich habe eine 3-Prozess Moore FSM entworfen, in der Form:
1
architecture rtl of cntr_first_submodule is 
2
  subtype t_state is std_logic_vector (1 downto 0);
3
  ...
4
  signal s_present_state, s_next_state : t_state;
5
begin 
6
  
7
  p_zustandakt : process (clk_i, reset_i)  -- Zustandaktualisierung 
8
  begin 
9
    if reset_i = '1' then 
10
      ...
11
    elsif clk_i = '1' and clk_i'event then    
12
          s_present_state <= s_next_state;
13
    end if;
14
  end process p_zustandakt;
15
  
16
  p_nextstate : process (s_present_state)  -- Next state
17
    case s_present_state is 
18
      when ... => s_next_state <= ....
19
      ...
20
  end process p_nextstate;
21
  
22
  p_outputlogic : process (s_present_state) -- Outputlogic
23
  begin 
24
    case s_present_state is 
25
      when ...
26
  end process p_outputlogic;
27
end architecture rtl;

Meine Frage ist jetzt:

Wenn ich richtige liege, übernimmt mir, durch den ersten 
Prozess(Zustandsaktualisierung) und durch die Sensitivity List
1
clk_i, reset_i
, bei jedem clock- oder reset- wechsel in der Simulation das 
s_present_state den s_next_state.

Was passiert jetzt aber in der Simulation, wenn ich mein present state 
nicht ändere, sprich nur in einem Zustand verharre? Dadurch wird, 
solange sich mein present state nicht ändert, der 2. Prozess (Next 
State) mein present state nicht aktualisieren, da der Simulator, durch 
die Sensitivity List im 2. und 3. Prozess nur dann neu berechnet, wenn 
sich der present state ändert.

Somit wird sich meine Ausgangslogik (zumindest in der Simulation) auch 
nicht ändern. Ich habe das Problem, dass ich in der Ausgangslogik je 
nach Zustand entweder rauf oder runter zähle und in der Simulation macht 
er den Schritt nur einmal und das wars.

Ich hoffe ihr könnt mir den Knoten auflösen.
Lg

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Johannes H. schrieb:
> da der Simulator, durch
> die Sensitivity List im 2. und 3. Prozess nur dann neu berechnet, wenn
> sich der present state ändert.

Hmm ja ...

Tipp von mir: Man kommt fast immer mit Prozessen aus, die so aussehen:
1
process(clk)
2
begin
3
  if rising_edge(clk) then
4
    if reset='1' then
5
      ...
6
    else
7
      ...
8
    end if;
9
  end if;
10
end process;

Da sparst du dir die ganzen Überlegungen mit der Sensitivity-Liste und 
alles ist immer sauber taktsynchron, lässt sich synthetisieren und der 
Simulator macht das richtige, man kann für die Sensitivity-List kein 
Signal vergessen und es können sich keine Latches oder kombinatorische 
Loops ergeben.

Wenn es tatsächlich mal kombinatorisch sein soll, dann kann man auch gut 
ohne Prozesse leben und einfach hinschreiben, was man meint ;-)

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


Lesenswert?

Johannes H. schrieb:
> Ich habe das Problem, dass ich in der Ausgangslogik je nach Zustand
> entweder rauf oder runter zähle
Wenn du in "der Ausgangslogik zählst", dann hast du mit Sicherheit eine 
kombinatorische Schleife.
http://www.lothar-miller.de/s9y/archives/42-Kombinatorische-Schleifen.html

> und in der Simulation macht er den Schritt nur einmal und das wars.
Dann ist deine Sensitivliste unvollständig.

> Ich hoffe ihr könnt mir den Knoten auflösen.
Du musst alle Signale, die eine Neuberechunng des Prozesses nötig 
machen, in die Sensitivliste aufnehmen. Also alle Signale, die rechts 
von := oder <= oder in einer if- oder case-Abfrage stehen.
Und wenn du deine Sensitivliste dann vervollständigt hast, dann kommt 
die kombinatorische schleife auch im Simulator zutage... ;-)

Mampf F. schrieb:
> Tipp von mir: Man kommt fast immer mit Prozessen aus, die so aussehen
Ich liebe Ein-Prozess-FSM:
http://www.lothar-miller.de/s9y/archives/43-Ein-oder-Zwei-Prozess-Schreibweise-fuer-FSM.html
http://www.lothar-miller.de/s9y/archives/16-Takt-im-Prozess.html

Johannes H. schrieb:
> clk_i, reset_i
Zum Thema "asynchroner Reset" noch die anmerkung, dass du das externe 
Resetsignal vom Resetpin hoffentlich einsynchronisierst und synchron 
deaktivierst.
 Falls nicht, dann lass den Reset besser ganz weg, sonst kann es sein, 
dass dein Design "manchmal seltsam losläuft"...
Dazu ein paar Worte dort in der Mitte:
http://www.lothar-miller.de/s9y/categories/35-Einsynchronisieren
Und das hier:
http://www.lothar-miller.de/s9y/archives/70-Asynchroner-Reset.html

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Lothar M. schrieb:
>> Tipp von mir: Man kommt fast immer mit Prozessen aus, die so aussehen
> Ich liebe Ein-Prozess-FSM:

Ich auch ... Wobei ich dann auch noch lieber Variablen statt Signale 
verwende - für den State zB :)

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


Lesenswert?

Mampf F. schrieb:
> Wobei ich dann auch noch lieber Variablen statt Signale verwende
Wobei man drauf achten sollte, dass unrefletkierter Einsatz von 
Variablen durchaus interessante Probleme und Effekte nach sich ziehen 
kann, wie z.B. im Beitrag "Variable vs Signal" 
beschrieben.

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Lothar M. schrieb:
> Mampf F. schrieb:
>> Wobei ich dann auch noch lieber Variablen statt Signale verwende
> Wobei man drauf achten sollte, dass unrefletkierter Einsatz von
> Variablen durchaus interessante Probleme und Effekte nach sich ziehen
> kann, wie z.B. im Beitrag "Variable vs Signal"
> beschrieben.

Ahja, sehr geil ... Der Thread ist von mir damals xD

Und die damalige Frage zielte darauf ab, weshalb jeder Variablen so 
verteufelt ... Ich hatte nie Probleme damit - damals nicht und jetzt 
auch nicht xD

Aber ja, man sollte den Unterschied schon kennen, sonst kann es zu 
Problemen kommen :)

: Bearbeitet durch User
von Vancouver (Gast)


Lesenswert?

@Johannes:

Bei Deiner FSM fällt auf, dass es keine Eingänge gibt, die den Zustand 
beinflussen. D.h. der Folgezustand und der Ausgangsvektor hängen 
ausschließlich vom aktuellen Zustand ab. Wenn Du nun in die Situation 
kommst, dass sich der Folgezustand einmal nicht ändert, dann wird er 
sich nie wieder ändern und die FSM bleibt im aktuellen Zustand 
(=Endzustand) bis zum nächsten Reset. Ist das so gewollt?

> Ich habe das Problem, dass ich in der Ausgangslogik je
> nach Zustand entweder rauf oder runter zähle und in der Simulation macht
> er den Schritt nur einmal und das wars.

Und das aus dem oben genannten Grund. Aber ich glaube, da hast Du noch 
einen anderen Denkfehler drin. Die Ausgangsfunktion kann nicht hoch- 
oder runterzählen. Die Ausgangsfunktion hat nur die Aufgabe, den 
FSM-Zustand rein kombinatorisch in einen anderen Bitvektor zu 
transformieren.
Wenn Du in Abhängigkeit des FSM-Zustandes auf- oder abwärts zählen 
willst, brauchst Du eine weitere FSM in Form eines Zählers. Deren 
Übergangsfunktion ist ein umschaltbarer Incrementer/Decrementer, der von 
der ersten FSM gesteuert wird.

(Ohoh, ich bekomme sicher gleich wieder irgendwoher eins auf den Deckel, 
aber trotzdem: Ich habe den Eindruck, dass Du VHDL programmierst aber 
kein RTL-Design modellierst. Bitte denk daran, dass im Hintergrund 
irgendwann Register und Gatter verschaltet werden und dann tun müssen, 
was Du ihnen mit Deinem VHDL-Code sagst. Daher brauchst Du für 
Funktionen, die einen inneren Zustand haben (FSMs, Zähler, Flags,...) 
immer ein Register und damit einen getakteten Prozess, i.e. ein Prozess 
mit einem clk in der Sens-Liste oder einem geeigneten WAIT-Statement. 
Deswegen kann die Ausgangsfunktion einer FSM nicht zählen.)

von J. S. (engineer) Benutzerseite


Lesenswert?

Mampf F. schrieb:
> Und die damalige Frage zielte darauf ab, weshalb jeder Variablen so
> verteufelt ... Ich hatte nie Probleme damit - damals nicht und jetzt
> auch nicht xD

Ich sehe nicht, dass die Nutzung von Variablen generell verteufelt wird, 
es ist nur so, dass Vielen ganz offensichtlich nicht klar ist, wozu man 
die benutzen sollte und kann.

Nebst der Abgrenzung von Zuweisungen in lokalen Codebereichen (was 
manche tun) und der Formulierung von Zwischenergebnissen, die nicht ins 
Enddesign fließen (was Ich empfehle) benötigt man Variablen vor allem in 
den Testbenches, um Dinge zu formulieren, die ungeachtet der 
Quantisierung und des Timings des FPGAs laufen, also mit der 
Implementierung nichts zu tun haben müssen oder dürfen.

Leider verwenden viele Anfänger die Variablen aber so, wie sie es vom C 
her gewohnt sind und verkennen dabei, dass sie hinsichtlich der 
Implementierung damit nicht "mehr", sondern "weniger" zur Verfügung 
haben, als mit den Signalen.

Für die allermeisten designs - besonders die Strukturorientierten - 
benötigt man keine Variablen und für viele designs, in denen man sie 
findet, wären sie zumindestens mit Signalen zu ersetzen, was im Sinne 
der Testbarkeit und der Gewinnung eines synthesefähigen Codes für ein 
Testsystem sogar zu bevorzugen wäre.

Ich kann nur immer wieder darauf hinweisen, dass man sich 
vergegenwärtigen muss, dass mit VHDL nicht der FPGA gesteuert (also 
"programmiert") wird, sondern die Synthesesoftware! Diese benutzt die 
Variablen und Signale, führt Loops aus und nutzt die Bedingungen - und 
nicht der FPGA. VHDL ist damit eine Bauanleitung für eine Schaltung, 
deren Ablaufvorschriften von einem virtuellen Layouter ausgeführt 
werden.

Ich vergleiche das immer mit dem Entwurf einer Maschine:

Ein C-Programm ist der Ablauf für eine Maschine, die etwas bauen oder 
ausrechnen soll. Das Programm wird vom Compiler übersetzt, damit die 
Maschine es in ihrer Sprache versteht und richtig arbeitet.

Ein VHDL-Programm ist hingegen die Bauanleitung für die Maschine! Da 
steckt natürlich irgendwo drin, was sie mal  tun wird, also etwas bauen 
oder auch ausrechnen, aber es ist eine Abstraktionsebene höher.

Da VHDL und System-C in FPGA-Synthesetools von einer Software ausgeführt 
werden, die aus einer festgelegten Gatter-Architektur eine virtuelle 
Architektur (Schaltung) konstruiert, haben wir noch eine weitere 
Abstraktionsebene unterhalb der Definition dazwischen.

Faktisch ist also VHDL (und alle Beschreibungen in LAVIEW  SOPC  
MATLAB , die darüber liegen, um am Ende VHDL zu gewinnen) eine Art 
Bauanleitung für eine Maschine, die real aber nicht gebaut wird, sondern 
durch Konfiguration eines Werkzeugroboters erzeugt wird.

Schleifen und Berechnungen laufen dabei aber nicht in dem 
Werkzeugroboter ab, sondern in der "Maschine", der die virtuellen 
Maschine zusammenbaut. Diese Abläufe finden sich dann logischerweise in 
der finalen Maschine nicht dirket wieder!

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.