Hallo,
ich hab da ein paar evtl. blöde Fragen (liegt wahrscheinlich an
gefährlichem Halbwissen...)
Ich lese immer wieder davon das es wichtig ist default Werte zu setzen
und z.B. bei case das when others nicht zu vergessen z.B.:
1
typetstateis(state_idle,state_count);
2
signalstate:tstate;
3
signalcounter:natural;
4
signalcounter_en:std_logic;
5
signalcounter_count:std_logic;
6
...
7
test_proc:process
8
waituntilrising_edge(clock);
9
casestateis
10
whenstate_idle=>
11
counter<=0;
12
state<=state_idle;
13
if(counter_en='1')then
14
state<=state_count;
15
endif;
16
17
whenstate_count=>
18
state<=state_count;
19
if(counter<10)then
20
if(counter_count='1')then
21
counter<=counter+1;
22
endif;
23
else
24
state<=state_idle;
25
endif;
26
27
whenothers=>
28
counter<=0;
29
state<=state_idle;
30
endcase;
31
if(reset='1')then
32
counter<=0;
33
state<=state_idle;
34
endif;
35
endprocesstest_proc;
Könnte ich das "when others" weglassen wenn ich z.B. schreibe:
1
...
2
test_proc:process
3
waituntil(rising_edge(clock));
4
state<=state_idle;
5
casestateis
6
...
oder lässt man das "when others" dann einfach leer ? (Haben "leere" when
others überhaupt einen Sinn?)
1
...
2
whenothers=>
3
4
endcase;
5
if(reset='1')then
6
...
Wie verhält sich das mit dem counter?
Dessen Zustand wird ja nicht bei jedem Takt gesetzt sondern nur wenn
auch "counter_count den Zustand '1' hat.
Ignoriere ich das einfach weil eh kein Latch erzeugt wird weil es in
einem getaktetem Prozess abläuft? Oder schreibt man dann eher sowas:
1
...
2
whenstate_count=>
3
counter<=counter;
4
state<=state_count;
5
if(counter<10)then
6
...
Kommt mir irgendwie komisch vor genau wie ein "leeres" when others.
Lothar M. schrieb:> Das gilt nur bei kombinatorischen Prozessen. Denn sonst hast du> pfeilschnell ein Latch an der Backe...
Was meinst du mit einem Latch? Ich verstehe darunter - im Gegensatz zu
einem taktflankengesteuerten Speicherelement, also einem Flipflop -
einen taktpegelgesteuerten Speicher:
https://martin-thoma.com/flipflops-und-latches
Wie man so eine Taktpegelsteuerung durch ein "when others" bekäme, wäre
mir nicht klar.
Lothar M. schrieb:> In deiner FSM ist der others Pfad unnötig:
Das gilt aber nur für den Idealfall, der keine unerwarteten Zustände
kennt, die z. B. durch SEUs erzeugt werden können. Die sind, zugegebener
Weise, auf der Erde eher selten, aber ausgeschlossen nicht.
Solange man keine vollen 2^n Zustände oder eine One-hot-Codierung
erhält, sollte es daher auch immer einen gültigen Folgezustand im
fiktiven Fehlerfall geben. Ansonsten wären Folgezustände
nichtdeterministisch, im worst-case bliebe man sogar im Nirwana hängen.
Irgendwie meine ich, dass einige Synthesizer ohne das "when others"
sogar mit einer Fehlermeldung aussteigen.
dfIas schrieb:> Lothar M. schrieb:>> In deiner FSM ist der others Pfad unnötig:> Das gilt aber nur für den Idealfall, der keine unerwarteten Zustände> kennt
Wie ich schrieb: in deiner FSM. Und in jeder anderen FSM, in der alle
Zustände auscodiert sind. Und jetzt kommt der Witz: das gilt auch für
eine FSM, die 6 Zustände hat, aber binär codiert in 3 Bits abgelegt
werden. Und es gilt auch für diese 6-Bit FSM, wenn die als One-Hot
umgesetzt wird, aber dann einen undefinierten Zustand mit 2 gesetzten
Flipflops einnimmt.
Es wird schlicht trotz des "when others" kein Code für diese
"unerwarteten Zustände" erzeugt.
> die z. B. durch SEUs erzeugt werden können.
Man sollte TLA/DBA wenigstens einmal mit dem kompletten Namen erwähnen.
Na, wie auch immer...
Das Problem bei amoklaufenden FSM sind ganz selten EMV/ESD-Probleme und
hier auf der Erde so gut wie nie strahlungsbedingte "Single Event
Upset"-Geschichten, sondern schlicht irgendwelche asynchrone Eingänge,
die unsynchronisiert auf das Design losgelassen werden. Und allen voran
ist der Reset ein solcher asynchroner Eingang, der von vielen einfach
entsprechend den Lehrbüchern von 1999 direkt vom Pin asynchron auf die
FSM losgelassen wird.
> Irgendwie meine ich, dass einige Synthesizer ohne das "when others"> sogar mit einer Fehlermeldung aussteigen.
In deinem Fall (und in dem auf meiner HP) wäre eine solche Fehlermeldung
ein Fehler. Denn du hast mit state_idle und state_count alle Zustände
deines Typs tstate auscodiert, da kann es keinen weiteren mehr geben.
Das "When others" ist also überflüssig. Das wurde hier schon ein paar
mal diskutiert. Z.B. auch im
Beitrag "Re: WHEN others notwendig?"
Ich kenne das im Gegenteil so, dass das "when others" wie in deinem Fall
mit der Info/Warnung "wird nicht berücksichtig" gemeldet wird. So wie
auch im Beitrag "Re: Fragen zu ersten VHDL Beschreibung (UART Transmitter)"
beschrieben.
Und im Oldtimer Beitrag "Re: Typedefinition mit 3 Zustaenden" ist
das ganze mal Schritt für Schritt durchgekaut.
dfIas schrieb:> Wie man so eine Taktpegelsteuerung durch ein "when others" bekäme, wäre> mir nicht klar.
In deinem Fall eines vollständig synchronen Prozesses wirst du ein
solches Latch auch nicht bekommen, denn bereits dadurch, dass alle
berechneten Signale vom clock abhängen, wird es ausschließlich Flipflops
geben.
Aber nehmen wir mal den Code aus dem
Beitrag "Re: VHDL Verbindung nur wenn "enabled""
Der sieht so aus, und da wird nichts gespeichert, das Design ist
vollständig auscodiert, es gibt keine weiteren Zustände:
1
process(digit)begin
2
casedigitis
3
when0=>segments<="1000000";
4
when1=>segments<="1111001";
5
when2=>segments<="0100100";
6
:
7
:
8
when8=>segments<="0000000";
9
when9=>segments<="0010000";
10
whenothers=>segments<="0111111";
11
endcase;
12
endprocess;
Wenn ich das jetzt mal so abändere, dass das hier herauskommt:
1
process(digit)begin
2
casedigitis
3
when1=>segments<="0000111";
4
when8=>segments<="1110000";
5
when9=>segments<="0101010";
6
endcase;
7
endprocess;
Was passiert dann, wenn digit erst mal 9 ist und danach 0 wird?
Richtig: der Wert 0101010 muss (ganz ohne Takt) in segments gespeichert
bleiben. Soweit die Theorie.
Aber der Übergang von digit=9 (=1001) nach digit=0 (=0000) geht z.B. so,
dass für 500ps der Zwischenwert 1000 oder 0001 auftritt (das wäre ein
Glitch), dann könnte eben auch 1110000 oder 0000111 gespeichert werden.
Und noch schlimmer: wenn der Glitch kurz genug ist, dann könnte auch
irgendwas anderes als einer dieser 3 definierten Werte herauskommen,
weil die Energie in diesem Glitch nicht dafür reicht, alle beteiligten
Speicherzellen zum Umschalten zu bewegen.
Und solche Designfehler (asynchrone Eingänge und Latches) erzeugen dann
solche unerklärlichen Effekte, die irgendwelchen radioaktiven oder
elektromagnetischen Strahlungen in die Schuhe geschoben werden.
Wie auch immer: wenn ich ein Design sehe, in dem alle Zustände
auscodiert sind und trotzdem ein "when others" da steht, dann ist das
für mich ein Warnzeichen. Denn dann darf ich in diesem Design noch
andere falsch verstandene und falsch angewendete Designpraktiken
vermuten.
Moin,
ich meine, bei einem der Synthese-Tools, kann mit Synplify Pro oder
Modelsim ME sein, da musste zwingend ein "when others" in den Switch.
Auch möglich, dass ansonsten nur eine Warnung ausgegeben wird. Notfalls
musste bei vollständiger Codierung (2^n) der letzte oder einer der Codes
durch "when others" ersetzt werden. Ein leeres "when others" war
jedenfalls ok, nur weglassen halt nicht.
One-hot kann man übrigens per Settings verhindern. Mit SEUs & Co. habe
ich zwar ständig zu tun, aber bei den RH- oder RT-Versionen der FPGAs
rechnet man die S-Cells durch TMR gesund. C-Zellen sind per se deutlich
unempfindlicher (laut Actel/Microsem & Co., heute Microchip).
Ein anderer wichtiger Punkt, solange man asynchrone Inputs auf eine FSM
gibt, ist, die Replizierung zumindest der Synchronstufe durch Attribute
zu verhindern. Die muss unique sein. Synthese-Tools replizieren gerne
ganze FSMs, um das Fan-out zu kontrollieren. Und wenn S0 auf das eine
Synchron-FF zugreift, S1 hingegen auf ein repliziertes (parallel
geschaltetes) Synchron-FF, kann das schnell in die Hose gehen. S0 sieht
noch eine 0, S1 bereits eine 1 usw. S wird falsch zusammengesetzt. Alle
Bits von S müssen den gleichen Input sehen, egal ob noch 0 oder schon 1.
Replizierung ist der typische FSM-Killer.
Auch mehrstufige FFs helfen hier nicht. Metastabilität ist bei heutiger
HW nur noch ein untergeordnetes Problem - aber die mehrstufige Abtastung
verkleinert eine bereits geringe Wahrscheinlichkeit noch einmal um die
entsprechenden Potenzen.
Da du schreibst, dass "when others" ggf. nicht alle undefinierten
Zustände abdeckt, muss man somit wohl auf eine Binärcodierung mit 2^n
ausweichen - wenn man es dann haben muss. Für Flug-H/W setzen wir
zusätzlich auf übergeordnete Überwachung, z. B. Watchdogs, um mögliche
Hänger von einzelnen FSMs, einem FPGA, dem gesamten System oder der
nicht zu vernachlässigenden Firmware/Software zu erkennen. Allerdings
dauert diese Erkennung und es ruckt gewaltig im System, wenn nur noch
ein Reset hilft.
dfIas schrieb:> da musste zwingend ein "when others" in den Switch.
Das war für die Synthese noch nie "zwingend". Besonders eben nicht, wenn
alle States verwendet und auscodiert sind.
> bei vollständiger Codierung (2^n)
Ein std_logic_vector ist im Gegensatz zu einem binären Bit eben
neunwertig und es gibt damit eben 9^n verschiedene Zustände. Bereits bei
einem std_logic_vector(1 downto 0) mit 2 Elementen gibt es deshalb 81
Möglichkeiten. Und wenn man dann "nur" die binären 00, 01, 10 und 11
auscodiert und die anderen 77 Varianten nicht beachtet, dann kann es
sein, dass die Simulation(!) seltsame Ergebnisse bringt, weil ja solche
Kombinationen wie LH, LL, XU, Z-, WH, LX, usw. nicht berücksichtigt
sind. Und genau in der Simulation wäre es dann auch sinnvoll, solche
Fälle mit einer Meldung abzufangen.
Der Synthesizer wird sich trotzdem keinen Deut um diese "anderen"
Kombinationen scheren. Denn in der Hardware kann kein L oder X oder U
abgebildet und somit eben auch nicht abgefragt werden.
Dort in der Hardware gibt es für Eingänge nur die Werte 0 und 1. Für die
Ausgänge gibt es 0, 1 und als Spezialfall noch Z. Aber auch dieses Z
wird von Eingängen wieder als 0 oder 1 zurückgelesen.
Und deshalb ist in der Hardware eine Abfrage eines std_logic_vector[1
downto 0) mit den 4 Werten 00, 01, 10 und 11 vollständig auscodiert. Da
kann es kein "others" mehr geben. Und deshalb kann der Synthesizer das
auch nicht "brauchen".
> Da du schreibst, dass "when others" ggf. nicht alle undefinierten> Zustände abdeckt, muss man somit wohl auf eine Binärcodierung mit 2^n> ausweichen - wenn man es dann haben muss.
Im Grunde ja. Man kann aber natürlich auch eine FSM mit eignen Werten
definieren und muss die dann auf die nächsten 2^n auffüllen:
Dieser tstate braucht binär codiert 3 Bits. Und weil alle Zustaände
definiert sind, kann ich nach der Abfrage auf idle...cleanup eben auch
ein "when others" hinschreiben. Und dann wird auch Hardware dafür
erzeugt.
Wenn ich aber nur 5 Zustände definiere und schreibe:
1
typetstateis(idle,count,eval,send,cleanup);
Dann kann ich noch so "when others" hinschreiben, aber es wird trotzdem
keine Hardware für diese "anderen" Fälle erzeugt! Denn welche "anderen
Fälle" wären das?
Und jetzt kommt der Witz: wenn ich (weil ich es ja so gelernt habe)
wieder mal die "vollständige" Definition hinschreibe:
... aber dann keine binäre FSM mache, dann kann es sein, dass diese FSM
one-hot umgesetzt wird und so in den dafür verwendeten 8 Flipflops binär
256 Kombinationen abgebildet werden können. weil ich aber mit der
Abfrage
auf idle...cleanup und "when others" aber eben nur die 8 im tstate
definerten Zustände abfrage, gibt es noch 248 undefinerte Zustände, für
die keine Hardware erzeugt wird.
> Für Flug-H/W> ...> Mit SEUs & Co
Und da kommt mir ein ganz anderer Aspekt in den Sinn: mag sein, dass man
eine einzelne FSM auf diese Art händisch "abfangen" und geradebügeln
kann, aber was ist mit den ganz alltäglichen FSM: den Zählern und
Timern? Wer fängt bei einem binär implementierten Zähler 0..9 die
restlichen 6 States ab? Könnte ja durch ein kippendes Bit aus einer 0101
auf einmal eine 1101 werden. Weil aber diese 13 ausserhalb der
definerten 0..9 ist, wurde für einen Übergang von dort irgendwo anders
hin keine definerte Hardware erzeugt.
Es kann also sein, dass der Zähler von der Synthese so ungeschickt
implementiert wurde, dass er fürderhin 13,14,11,13,14,11,13,14... zählt
und sich nie wieder "fängt".
> Mit SEUs & Co
Hier sehe ich das Risiko, dass ein Flipflop einer FSM umkippt,
wesentlich nachrangig dagegen, dass irgend ein Flipflop der
Konfiguration umkippt. Denn immmerhin besteht die LUT vor dem
Zustands-Flipflop aus 16 oder 64 Flipflops (4er oder 6er LUT) und auch
die ganzen Konfigurations-Flipflops zum Umschalten der Multiplexer und
dem Routing in der Makrozelle übersteigen die Anzahl der FSM-Flipflops
bei weitem. Und wenn so ein Konfigurations-Flipflop umgekippt ist, dann
kann es schon sein, dass die FSM dank "Fail Safe Implementation"
ursprünglich mal mit einer Übergangslogik versehen war, die undefinerte
Übergänge abgefangen hat, aber durch ein umgekipptes Bit in der LUT
führt dann genau dieser "umgekippte" Sicherheitsmechanismus zum Chaos.
Lothar M. schrieb:>> Mit SEUs & Co> Hier sehe ich das Risiko, dass ein Flipflop einer FSM umkippt,> wesentlich nachrangig dagegen, dass irgend ein Flipflop der> Konfiguration umkippt.
Dafür wurde 'scrubbing' erfunden. Dabei wird die Konfiguration des FPGA
öfter mal nachgeladen. Eine Suchmaschine der Wahl liefert für "+seu
+scrubbing" diverse wissenschaftliche Veröffentlichungen. Welche davon
durch den Weltraum fliegen oder mal mit harter Strahlung getestet
wurden, muß man selber prüfen.
Duke
dfIas schrieb:> Notfalls musste bei vollständiger Codierung (2^n)
Wie Lothar schon geschrieben hat, die Annahme das "vollständig Codieren"
klappt nicht gut. Genau auch weil der Synthesizer so schlau ist und
deine FSM als FSM erkennt und die extrahiert und dann die Codierung
ändern/anpassen/optimieren kann.
Dafür gibt es dann die Attribute für den Synthesizer um ihm eine
codierung (z. B. one-hot, Gray oder wenn nötig und Geld vorhanden
Hamming) vorzuschreiben und ihm zu sagen, dass man gerne extra Logik hat
um von illegalen/ungenutzten Zuständen eine Transition in den Reset
Zustand zu haben.
Lothar M. schrieb:>> Mit SEUs & Co> Hier sehe ich das Risiko, dass ein Flipflop einer FSM umkippt,> wesentlich nachrangig dagegen, dass irgend ein Flipflop der> Konfiguration umkippt.
Das ist ein ganz anderes Fass. Zum einen genau das, was Duke geschrieben
hat zu Scrubbing oder einen FPGA nehmen, bei dem die Konfiguration nicht
kippt unter den zu erwartenden Umständen (Flash oder Antifuse je nach
Anforderung).
oh scheint ja doch ein paar unterschiedliche Meinungen zu geben...
Lothar M. schrieb:> Das gilt nur bei kombinatorischen Prozessen. Denn sonst hast du> pfeilschnell ein Latch an der Backe...
Ach ja, die hatte ich gar nicht mehr auf dem Schirm, sorry, hatte mich
länger nicht mit diesen Dingen beschäftigt und mache das auch nur
Hobby-mäßig und anscheinend hatte ich einiges falsch behalten und nach
den falschen Dingen gesucht.
> In deiner FSM ist der others Pfad unnötig:> http://www.lothar-miller.de/s9y/categories/25-when-others
die Webseite ist wirklich Gold wert!
dfIas schrieb:> Was meinst du mit einem Latch?
ein asynchrones, pegelgesteuertes Element, aber das bezog sich auf den
counter und das hatte Lothar ja auch erklärt.
Danke!
Lothar M. schrieb:> Es wird schlicht trotz des "when others" kein Code für diese> "unerwarteten Zustände" erzeugt.
Mag sein, aber trotzdem wird es bei der Synthese berücksichtig.
Oder wie ist das zu verstehen:
""default_state" Forces the state machine into the state that is
specified with the default state in RTL, even if that state is
unreachable, using Hamming-2 encoding detection for one bit/flip."
"For VHDL, the "when others" keywords has the same effect."
"With the default_state set for the fsm_safe_state attribute, the value
applied to the state register in the default or "when others" section of
a case statement will be used as the safe state."
aus https://support.xilinx.com/s/article/60799?language=en_US (September
2021)
Man kann es auch anders machen, aber so wie ich das verstehe, ist "when
others" auch bei einer komplett definierten state machine nicht immer
sinnlos oder wird ignoriert.
Ich habe es nochmal ausprobiert.
In Vivado 2019.1 macht bei einer über ihre Zustände definierten state
machine das Vorhandensein eines "when others" einen Unterschied im
Synthese und Implementierungsergebnis, auch wenn alle Zustände ihr
eigenes 'when' haben.
Wahrscheinlich habe ich die Diskussion falsch verstanden. Nur stimmt
halt nicht, wie ich die Aussage verstanden habe, dass ein "when others"
bei einer volldefinierten State Machine wirkungslos ist.
Die entsprechenden Bilder kann ich leider gerade nicht anhängen, weil
die auf einem anderen Computer sind.
Dussel schrieb:> Ich habe es nochmal ausprobiert
Ja, schon, aber lass doch mal die Zeilen mit dem fsm_safe_state Klimbim
weg. Das führt dazu, dass damit der Synthesizer angewiesen wird, den
einen fehlenden Zustand bei einer Binärcodierung oder die fehlenden 5
Zustände der One-Hot-Codierung abzufangen. Oder gar zur Fehlererkennung
und -behebung die FSM-Bits mehrfach anzulegen.
Hier gibt's erste Hinweise: https://support.xilinx.com/s/article/60799
Nachteilig ist dabei natürlich, dass dieses Attribut und dessen Resultat
auf Verhaltensebene nicht simuliert werden kann und natürlich auch nicht
portierbar ist.
Lothar M. schrieb:> Hier gibt's erste Hinweise: https://support.xilinx.com/s/article/60799
Genau das habe ich doch oben schon verlinkt und daraus zitiert. ;-)
Lothar M. schrieb:> Dussel schrieb:>> Ich habe es nochmal ausprobiert> Ja, schon, aber lass doch mal die Zeilen mit dem fsm_safe_state Klimbim> weg.
Das ändert dann natürlich etwas. Dafür sind Attribute ja da.
Mir ging es hauptsächlich darum, dass ich vor einiger Zeit 'when others'
in einer voll definierten State Machine in Verbindung mit fsm_safe_state
nach bestem Wissen und Gewissen benutzt habe (in einer Anwendung, in der
Strahlung tatsächlich ein realistisches Problem ist).
Dann von jemandem wie dir zu lesen, dass das ('überdefinierte' State
Machine) Quatsch/falsches Verständnis ist, hat mich dann doch erstmal
ein bisschen verunsichert. Deshalb wollte ich es nochmal für mich
nachprüfen.
Dussel schrieb:> Genau das habe ich doch oben schon verlinkt und daraus zitiert. ;-)
Drum kam mir das so bekannt vor... 😉
> zu lesen, dass das ('überdefinierte' State Machine) Quatsch/falsches> Verständnis ist
Offenbar haben die Toolchain-Programmierer da nachgeholt. Allerdings
eben herstellerabhängig unterschiedlich. Und eben auch nicht für eine
0815-FSM ohne spezielle Behandlung.
Duke Scarring schrieb:>> Hier sehe ich das Risiko, dass ein Flipflop einer FSM umkippt,>> wesentlich nachrangig dagegen, dass irgend ein Flipflop der>> Konfiguration umkippt.> Dafür wurde 'scrubbing' erfunden. Dabei wird die Konfiguration des FPGA> öfter mal nachgeladen. Eine Suchmaschine der Wahl liefert für "+seu> +scrubbing" diverse wissenschaftliche Veröffentlichungen. Welche davon> durch den Weltraum fliegen oder mal mit harter Strahlung getestet> wurden, muß man selber prüfen.
Nein, so einfach ist das nicht. Mit Scrubbing kannst du aus EDAC-Memory
akkumulierte, aber noch korrigierbare Fehler bereinigen. Beispiel wären
hier Hamming- oder RS-geschützte Arbeits- und Massenspeicher.
FPGAs werden noch überwiegend mit fester Programmierung (fusible-link)
eingesetzt. Bei den RH- und RT-Typen werden alle FFs verdreifacht und
mit Voter ausgestattet (TMR). Natürlich kann eine Ionisierungsspur auch
mal zwei oder mehr FFs auf einmal umwerfen, aber das ist einige
Zehnerpotenzen seltener als die üblichen SEUs.
Was du meinst, wäre kein Scrubbing, sondern ein Refresh der
Konfiguration. Dazu muss man wissen, dass z. B. bei Xilinx sowohl die
Konfiguration als auch der Dateninhalt geladen wird. Die Daten kann man
aber maskieren, so dass man hinterrücks nur die Konfiguration
(Verbindungsnetze) überschreibt bei Beibehaltung des Datenmusters. Bei
aktuellen Projekten werden (noch relativ selten) auch rekonfigurierbare
FPGA eingesetzt und relativ neu gibt es dort die ersten RT-Typen.
Solange ist ein RTAX-2000 immer noch die erste Wahl.
dfIas schrieb:> Nein, so einfach ist das nicht.
Danke für die Aufklärung. Bei mir hat bisher immer Abstand und
Schwerbeton gereicht, um die Strahlung und deren Wirkung zu
reduzieren...