Forum: FPGA, VHDL & Co. Automatenzustände schalten willkürlich um, ich bitte um Unterstützung


von Daniel L. (dannynrw)


Lesenswert?

Hallo zusammen,

ich habe folgend dargestellten Automat in VHDL beschrieben, welcher 
soweit auch funktioniert. Allerdings ist es so, dass z.B. bei 
Signalwechsel von "btnci" die Schritte zwischen 0 und 2 hin- und 
hertoggeln. Ich hatte dies vorher mit einer SPS simuliert, wo dies 
logischerweise genauso ist. Meine Idee nun: "btnci", "split" und "csz" 
(allesamt Signale, die über Taster eingebunden werden) zu entprellen und 
anschließend nur einen kurzen Impuls an die Bausteine der Halteglieder 
zu übergeben. Ich habe schon mehrere Versuche unternommen, dies zu 
realisieren, jedoch ohne Erfolg bisher (meinen letzten Versuch habe ich 
mal auskommentiert stehen lassen). Vielleicht kann mir diesbezüglich 
jemand helfen. Anbei der VHDL-Code des Automaten:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
4
entity Automat is
5
 Port ( clock :      in STD_LOGIC; --CPU-Clock
6
          csz :      in STD_LOGIC; --Taster csz
7
          btnci :      in STD_LOGIC; --Taster btnci
8
          split :      in STD_LOGIC; --Taster Split
9
          st0_out: out std_logic; --Test-LED Zustand 0
10
          st1_out: out std_logic; --Test-LED Zustand 1
11
          st2_out: out std_logic; --Test-LED Zustand 2
12
          st3_out: out std_logic; --Test-LED Zustand 3
13
          st4_out: out std_logic); --Test-LED Zustand 4
14
end Automat;
15
16
architecture Behavioral of Automat is
17
18
signal hold1: std_logic := '0'; --Halteglied H1
19
signal hold2: std_logic := '0'; --Halteglied H2
20
signal hold3: std_logic := '0'; --Halteglied H3
21
signal hold4: std_logic := '0'; --Halteglied H4
22
signal st0: std_logic := '0'; --Zustand 0
23
signal st1: std_logic := '0'; --Zustand 1
24
signal st2: std_logic := '0'; --Zustand 2
25
signal st3: std_logic := '0'; --Zustand 3
26
signal st4: std_logic := '0'; --Zustand 4
27
signal btnci_var: std_logic := '0'; --Variable btnci an Halteglieder
28
signal timebuffer: integer range 0 to 1000000000 := 0; --Zählvariable
29
30
31
BEGIN 
32
automat: process (hold1, hold2, hold3, hold4, st0, st1, st2, st3, st4, clock, btnci_var, timebuffer)
33
begin
34
35
--if(rising_edge(clock)) then --Steigende Flanke CPU
36
--if (btnci='1') then --Taster btnci gedrückt
37
--if (timebuffer < 10000) then --Zählvariable kleiner 100ms
38
--timebuffer <= timebuffer+1; --Zählvariable inkrementieren
39
--if (timebuffer = 9000) then
40
--btnci_var <= '1';
41
--if (timebuffer = 9999) then
42
--btnci_var <= '0';
43
--timebuffer <= 0;
44
--end if;
45
--end if;
46
--end if;
47
--end if;
48
--end if;
49
50
-- Generierung der Zustandscodierung
51
52
if (hold1='0' and hold2='0' and hold3='0' and hold4='0') then --Zustand 0
53
st0 <= '1';
54
st0_out <= '1';
55
else 
56
st0 <= '0';
57
st0_out <= '0';
58
end if;
59
60
if (hold1='0' and hold2='1' and hold3='0' and hold4='0') then --Zustand 1
61
st1 <= '1';
62
st1_out <= '1';
63
else 
64
st1 <= '0';
65
st1_out <= '0';
66
end if;
67
68
if (hold1='1' and hold2='0' and hold3='0' and hold4='0') then --Zustand 2
69
st2 <= '1';
70
st2_out <= '1';
71
else 
72
st2 <= '0';
73
st2_out <= '0';
74
end if;
75
76
if (hold1='1' and hold2='0' and hold3='0' and hold4='1') then --Zustand 3
77
st3 <= '1';
78
st3_out <= '1';
79
else 
80
st3 <= '0';
81
st3_out <= '0';
82
end if;
83
84
if (hold1='0' and hold2='0' and hold3='1' and hold4='0') then --Zustand 4
85
st4 <= '1';
86
st4_out <= '1';
87
else 
88
st4 <= '0';
89
st4_out <= '0';
90
end if;
91
92
-- Ansteuerung der Halteglieder
93
94
if (st1='1') then --H1
95
hold1 <= '1';
96
elsif (st3='1' and csz='1') or (st2='1' and btnci_var='1' and split='0' and csz='0') or (st2='1' and csz='1') then
97
hold1 <= '0';
98
end if;
99
    
100
if (st0='1' and btnci_var='1') then --H2
101
hold2 <= '1';
102
elsif (st1='1') then
103
hold2 <= '0';
104
end if;
105
106
if (st3='1' and csz='1') or (st2='1' and csz='1') then --H3
107
hold3 <= '1';
108
elsif (st4='1' and btnci_var='1') then
109
hold3 <= '0';
110
end if;
111
112
if (st2='1' and btnci_var='0' and split='1') then --H4
113
hold4 <= '1';
114
elsif (st3='1' and csz='1') or (st3='1' and split='1') then
115
hold4 <= '0';
116
end if;
117
118
end process automat;
119
120
-- nebenlaeufige Anweisung
121
122
123
end Behavioral;

: Bearbeitet durch Moderator
von Daniel L. (dannynrw)


Lesenswert?

Also, wie ich das sehe, muss an die Sache gezielter herangegangen 
werden. Ich habe das ganze eben nochmal mit Hilfe einer SPS simuliert 
und an den Stellen, an denen "btnci" und "split" auf ein High-Signal 
abgefragt werden, eine Abfrage für die steigende Flanke vorangeschaltet. 
Ich denke, so müsste das auch auf das FPGA mit Hilfe von vhdl übertragen 
werden. Die Tasten müssen wohl trotzdem entprellt werden.
Für Tipps und kurze Codebeispiele wäre ich sehr dankbar.
Gruß
Daniel

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


Lesenswert?

Daniel L. schrieb:
> allesamt Signale, die über Taster eingebunden werden
Diese Taster sind aber schon einsynchronisiert?
Denn sonst passiert schlicht alles Mögliche. Ursache  siehe dort:
http://www.lothar-miller.de/s9y/categories/35-Einsynchronisieren

von Korrektur (Gast)


Lesenswert?

Daniel L. schrieb:
> Also, wie ich das sehe, muss an die Sache gezielter herangegangen
> werden.

vor allem sollte mal die Funktion getakteter Schaltungen verstanden 
werden. So hat man einen Würfelautomaten.

von Theor (Gast)


Lesenswert?

@ Daniel

Die Frage ist für mich in mehrerlei Hinsicht sehr widersprüchlich.

Ich würde mir den Kontext zu wissen wünschen, ehe ich überhaupt anfange 
zu überlegen Hilfe zu leisten. Dazu eine Darstellung der grundlegenden 
Überlegungen zur Übertragung von SPS Programmen in VHDL und zu 
synchronen und asynchronen Automaten.


P.S. Und vernünftig Einrücken wäre auch nett.
P.P.S. Wie viele Warnungen gibt eigentlich dieser Code?
P.P.P.S. Guck mal das STL-Schema an.

von Daniel L. (dannynrw)


Lesenswert?

Danke erst einmal für die Antworten. Grund ist folgender: Ich möchte 
eine Stoppuhr realisieren, die auf Grundlage des vorhandenen Automaten 
ihre Funktionalität erhält. Jeder Zustand soll später mit Leben gefüllt 
werden.

@Lothar: Deine Seite mit einigen Programmbeispielen habe ich schon 
gefunden, aber anscheinend fehlt mir noch ein wenig das Verständnis für 
die Abläufe in der Digitaltechnik. Unter einsynchronisieren sollte ich 
doch an dieser Stelle verstehen, dass die Eingänge zeitgleich mit jedem 
CPU-Takt ihren Zustand übergeben, richtig?

Fakt ist, dass ich in folgenden Situationen das genannte toggeln habe, 
wenn die Weiterschaltbedingungen erfüllt sind:
Zustand 0 -> Zustand 2 und umgekehrt sowie Zustand 2 -> Zustand 3 und 
umgekehrt.

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


Lesenswert?

Daniel L. schrieb:
> Fakt ist, dass ich in folgenden Situationen das genannte toggeln habe,
> wenn die Weiterschaltbedingungen erfüllt sind:
> Zustand 0 -> Zustand 2 und umgekehrt sowie Zustand 2 -> Zustand 3 und
> umgekehrt.
Diesen "Automaten" ohne Takt, den du da gepostet hast, ist letztlich nur 
eine kombinatorische Schleife. Die "Halteglieder" sind irgendwelche 
Latches.

Sieh dir nochmal an, wie z.B. Ich solche Automaten schreibe. Du wirst 
sehen: da muss ein Takt dabei sein, denn sonst macht der Synthesizer 
kein Flipflop draus.

BTW mit den [vhdl] Tags um den Code gibt's Syntaxhighlighting gratis.

: Bearbeitet durch Moderator
von Daniel L. (dannynrw)


Lesenswert?

Das heißt, ich muss meinem Automaten folgende Zeile voranstellen, sodass 
alles ausschließlich mit dem CPU-Takt ausgeführt wird?

wait until rising_edge(clock);

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


Lesenswert?

Im Prinzip ja.
Dann brauchst du auch keine Sensitivliste mehr, bzw. du darfst keine 
mehr verwenden, weil so ein wait until ja nichts anderes als eine 
explizit ausformulierte "Sensitivliste" ist.

Es heißt aber noch viel mehr. Denn es heißt, dass dir noch nicht ganz 
klar ist, wie und warum so ein Automat funktioniert und dass du allem 
voran erstmal daran arbeiten solltest.
Denn man kann einen Automaten auf zig verschiedene Arten beschreiben, 
wenn man weiß, wie er aufgebaut ist und was er zu tun hat.

: Bearbeitet durch Moderator
von Daniel L. (dannynrw)


Lesenswert?

Ich werde mal weiterlesen bezüglich Sensitivliste usw.. Habe hier auch 
schon den einen oder anderen passenden Beitrag zu gefunden.
Allerdings ist es interessant, wirklich mal hinter die Kulissen zu 
blicken. Denn in der SPS funktioniert der Automat mit wenigen Änderungen 
im Funktionsplan einwandfrei. Um die Taktzuordnung und weitere Dinge, 
die hintergründig ablaufen, muss man sich bei einer Sps ja kaum Gedanken 
machen.

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


Lesenswert?

Daniel L. schrieb:
> Denn in der SPS funktioniert der Automat mit wenigen Änderungen im
> Funktionsplan einwandfrei
In der SPS sorgt auch das Drumrum (die 
Eingangsabbild-Verarbeitung-Ausgangsabbild-Geschichte) dafür, dass 
dieser Automat getaktet ist.

Du machst mit VHDL aber eben keine SPS und solltest daher ein Bild 
eine Skizze oder eine Vorstellung deiner Schaltung haben, die du mit der 
HardwareBESCHREIBUNGssprache VHDL beschreiben willst.

Insofern ist die SPS Denkweise für FPGAs eben nicht 100% passend...

> Denn in der SPS funktioniert der Automat mit wenigen Änderungen im
> Funktionsplan einwandfrei
Zum Debuggen einer VHDL-Beschreibung nimmt man üblicherweise einen 
entsprechenden Simulator. Und gibt darin Signale mit einer Testbench 
vor.

: Bearbeitet durch Moderator
von Daniel L. (dannynrw)


Lesenswert?

Den Automatengraph, das Signal-Zeit-Diagramm sowie eine 
Zustandsübergangstabelle bilden die Grundlage für den geposteten Code. 
Diese kann ich gerne nachher mal einstellen, wenn es hilft. Werde mich 
auf jeden Fall weiter schlau machen.

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


Lesenswert?

Daniel L. schrieb:
> Den Automatengraph, das Signal-Zeit-Diagramm sowie eine
> Zustandsübergangstabelle bilden die Grundlage für den geposteten Code.
Trotzdem musst du wissen, wie der Synthesizer gerne einen Automaten 
beschrieben hätte, damit er das daraus macht, was du willst...

> Den Automatengraph, das Signal-Zeit-Diagramm sowie eine
> Zustandsübergangstabelle bilden die Grundlage für den geposteten Code.
Korrekt wäre dieser Ansatz: diese Unterlagen bilden die Anforderungen an 
die Schaltung, die du mit VHDL beschreiben musst, um das gewünschte 
Verhalten zu erreichen.
Sachen wie das Einsynchronisieren oder Entprellen von Eingängen gehören 
letztlich dann "einfach dazu". D.h. sie müssen für eine zuverlässige 
Funktion in die Beschreibung rein, auch wenn sie nicht explizit 
gefordert sind. So  wie eine zuverlässige Spannungsversorgung nötig ist, 
auch wenn das nirgendwo steht.

von Daniel L. (dannynrw)


Lesenswert?

Du hast Recht Lothar, der Synthesizer macht laut Elaborated Design 
Latches daraus.

Edit: Nach Einfügen des Taktes sind D-FFs aus den Latches geworden. 
Allerdings bleibt das Problem, dass ich eben die Tasten entprellen und 
das Signal so an die Halteglieder weiterleiten muss, dass bei einem 
Tastendruck lediglich EIN Zustandswechsel erfolgt. Diese Toggelei nervt 
ganz schön...

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


Lesenswert?

Daniel L. schrieb:
> Allerdings bleibt das Problem, dass ich eben die Tasten entprellen und
> das Signal so an die Halteglieder weiterleiten muss, dass bei einem
> Tastendruck lediglich EIN Zustandswechsel erfolgt.
Naja, ein "Problem" ist das ja nun nicht. Eigentlich eher ein kleiner 
Dreizeiler pro Taster... ?

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.