Hallo allerseits, ich bin gerade dabei, ein paar Sachen fuer die Pruefung morgen nochmal anzusehen. Dabei fiel mir auf, dass in meinem Skript sinngemaess folgendes steht: Neuen Datentyp anlegen: type dtyp is (aa, ab, ac); signal a : dtyp; spaeter in einem Prozess: case a is when aa .... , when ab .... , when ac .... , when others => ... ; end case Hinter when others wird per Kommentar noch angegeben, dass diese Zeile unbedingt noetig sei, wenn die Anzahl der Zustaende von 2^n abweiche. Simulation mit Modelsim und testweises Synthetisieren brachten beim Fehlen dieser Zeile keinen Fehler und ich kann mir eigentlich auch nicht vorstellen, dass der Kommentar im Skript richtig sein soll. Welchen Zustand sollte a denn noch annehmen... Waer fuer einen kurzen Kommentar dankbar :) Gruessle, André
Moegliche Zustaende in der Simulation sind noch z.B. "undefined" wenn kein Wert zugewiesen wird. Das hat mit 2^n aber nichts zu tun.
Der Sinn dieser Maßnahme ist, nicht explizit definierte, aber in der Hardware vorhandene Zustände abzufangen, z.B. der 4. Zustand wenn 2 Bits zur Codierung von 3 Zuständen verwendet werden. Diese Zustände können (ordentlicher synchroner Aufbau vorausgesetzt) nicht im normalen Betrieb, sondern nur durch elektrische Fehler auftreten. Allerdings habe ich starke Zweifel dass dein Code zum gewünschten Ergebnis führen wird, da das "others" wahrscheinlich schon herausgeworfen wird, bevor sich der Compiler Gedanken um die Zustandscodierung macht. Wenn Robustheit gegen falsche Zustände gewünscht ist, dann kann man in der Synthesesoftware die Funktion zur sicheren Zustandscodierung aktivieren ("safe FSM" bei Xilinx). Man muss sich allerdings im Klaren darüber sein was das bedeutet: man rechnet damit, dass jedes Bit zu jedem beliebigen Zeitpunkt kippen kann.
Nunja. Hinter when others stand eigentlich => null, es dient also nur der Vermeidung vermeintlicher Fehler beim Synthetisieren. Nur besteht der Prof hier anscheinend auf etwas, das nicht unbedingt noetig ist und auch keinen Nutzen bringt. Danke auf jeden Fall fuer die bisherigen Antworten. Gruessle, André
André wrote: > Nunja. Hinter when others stand eigentlich => null ... Unnötig, denn a ist vom Typ dtyp und hat damit nur drei Zustände. Weil die alle verwendet sind, kann es keine others, also anderen Zustände mehr geben. Die binäre Codierung ist nur 1 Art der Codierung für die drei Zustände, und zudem bei FPGAs idR. die ineffizienteste.
>Unnötig, denn a ist vom Typ dtyp und hat damit nur drei Zustände. >Weil die alle verwendet sind, kann es keine others, also anderen >Zustände mehr geben. Da aber die drei Zustände in der Synthese mit mindestens zwei Bits codiert werden, kann es theoretisch ungewollte Zustände geben. Ich würde deshalb
1 | when others => |
2 | zustand <= aa; |
schreiben. Also sozusagen eine bevorzugten Zustand einnehmen. Gruß Gast
> Da aber die drei Zustände in der Synthese mit > mindestens zwei Bits codiert werden, kann > es theoretisch ungewollte Zustände geben. Richtig, es kann in der Hardware undefinierte Zustände geben. Bei drei definierten Zuständen wird aber, wenn (wie im Beispiel oben) alle auscodiert sind, für den others-Zweig gar nichts erzeugt. D.h. auch wenn durch einen ESD-Impuls ein undefinierter Zustand erreicht würde, kommt man nicht beim others -Zweig heraus (weil es den in der Hardware gar nicht gibt!). Wenn ich einen default-State haben will, dann muß ich das so schreiben:
1 | type dtyp is (aa, ab, ac); |
2 | signal a : dtyp := aa; |
3 | :
|
4 | :
|
5 | case a is |
6 | when ab .... , |
7 | when ac .... , |
8 | when others => ... ; -- hierher der Code für den Defaultstate aa |
9 | end case |
Dann wird alles, was nicht ab oder ac ist, automatisch aa. Allerdings ist z.B. beim One-Hot-Encoding niemals definiert, was passiert, wenn zwei FFs gleichzeitig aktiv sind. Man kann nur auf Kosten zusätzlicher Ressourcen in den Syntheseeinstellungen eine sichere Implementierung erzwingen. Dadurch gibt es dann keine undefinierten Zustände. Stichwort: FSM Safe Implementation
@gast Das kann ein fataler Irrtum sein! Für den Simulator gibt es keine extra Zustände, da ist das when others überflüssig. Bei der Synthese gibt es : 1) verschiedene Kodierungen des Types, wie Lothar schon erwähnt hat. 2) Der Compiler berücksichtigt bei der Logik generierung nur die 3 Zustände, dass es noch weitere Bit-Kombinationen für den Zustandsvektor gibt ist ihm schnurzpiepegal. Der einzige richtige Weg sind Compiler-Optionen oder Attribute, die wirklich den Compiler anweisen für alle ungültigen Zustände zu einem sicheren Zustand zu springen (SAFE_FSM oder ähnlich). Das wurde auch schon gesagt.
Um mich selber zu zitieren: > Allerdings ist z.B. beim One-Hot-Encoding niemals definiert, was > passiert, wenn zwei FFs gleichzeitig aktiv sind. Ich hatte mal eine SM, die ich One-Hot synthetisieren ließ, und bei der alle Zustände mit when behandelt wurden. Und ab und an machte das Ding Zicken. Also habe ich zusätzlich noch die when others mit eingebaut, und setzte dort einen Pin auf high. Das Ding machte weiter Zicken, aber der Pin wurde nie gesetzt. Daraufhin legte ich jedes einzenle State-FF auf einen eigenen Pin. Und siehe da: Im Fehlerfall waren mehrere States aktiv, aber der others Zweig wurde nicht erreicht (der entsprechende Pin niemals gesetzt). BTW: Der Fehler im obigen Beispiel war ein asynchroner Reset. So konnte sich ein kurzer Spike am Reset-Pin direkt auf die FFs auswirken und die FFs durcheinander bringen.
> Nunja. Hinter when others stand eigentlich => null, es dient also nur > der Vermeidung vermeintlicher Fehler beim Synthetisieren. > Nur besteht der Prof hier anscheinend auf etwas, das nicht unbedingt > noetig ist und auch keinen Nutzen bringt. Wie Lothar sehr schön belegt hat, dient es zu überhaupt nichts, sondern wird einfach von den Tools ignoriert (auch Synthese). Gut möglich, dass der Prof schon zu lange in der Welt der Theorie schwebt. Wenn er ein guter Lehrer ist, dann weise ihn doch mal darauf hin, dass der "others" Zweig nichts bringt. Ansonsten mach das was jeder macht: Rede ihm nach dem Mund und behalte für dich, dass du es besser weißt. Wenn er zufällig genau die Frage stellt, wozu der "others" Zweig gut ist, dann musst du halt abschätzen, ob er die Wahrheit verkraftet.
Ich habe das nochmal nach dem obigen Beispiel durchgemacht und an das Beispiel ein wenig Fleisch gebracht:
1 | library IEEE; |
2 | use IEEE.STD_LOGIC_1164.ALL; |
3 | use IEEE.NUMERIC_STD.ALL; |
4 | |
5 | entity SM_ueberdefiniert is |
6 | Port ( clk : in STD_LOGIC; |
7 | leds : out STD_LOGIC_VECTOR (1 downto 0); |
8 | error : out STD_LOGIC); |
9 | end SM_ueberdefiniert; |
10 | |
11 | architecture Behavioral of SM_ueberdefiniert is |
12 | type dtyp is (aa, ab, ac); |
13 | signal a : dtyp; |
14 | |
15 | begin
|
16 | |
17 | process begin |
18 | wait until rising_edge(clk); |
19 | error <= '0'; -- default |
20 | case a is |
21 | when aa => a<=ab; leds<="00"; |
22 | when ab => a<=ac; leds<="01"; |
23 | when ac => a<=aa; leds<="10"; |
24 | when others => a<=aa; error <= '1'; |
25 | end case; |
26 | end process; |
27 | |
28 | end Behavioral; |
Bei der Synthese erhalte ich den Hinweis
1 | WARNING:Xst:1710 - FF/Latch <error> has a constant value of 0 in block <SM_ueberdefiniert>. |
Im Schaltplan sieht man schön, wie das error Flag fest auf GND verdrahtet ist. Und wenn die Synthese schon nichts generiert, können die nachfolgenden Arbeitsschritte (Translate, P&R) auch nichts mehr herzaubern ;-)
Sehr schoenes Beispiel, danke :). Damit ists nun wirklich sicher. Ich danke allen fuer ihre ausfuehrlichen Antworten :) Viele Gruesse, André
hi, ein beispiel ist leider kein nachweis, dass der von lkmiller beschriebene effekt nicht auftreten kann. im vorliegenden testcase kann der vhdl compiler/synthese die optimierung so ansetzen, dass der "case" und die logic eindeutig ist. der von lkmiller beschriebene fall wuerde zb. eintreten, falls der enum in der port-map als io port aufgefuehrt wird. damit waere an der modul grenze nach der synthese ein 2bit port sichtbar. dieser koennte den undefinierten zustand '11' haben und damit u.U. die state-machine in einen zustand bringen, der NICHT im RTL kodiert ist. das verhalten der schaltung ist dann nur in der gate level simulation sichtbar. das ganze laeuft unter design bug und sollte schon von anfang an ausgeschlossen werden. wenn man noch mehr pech hat, fuehren diese verborgenen states auf eine loop ohne rueckkehr in den RTL state space. das macht spass das zu suchen (jedenfalls bekommt man aufmerksamkeit vom mgmt ...) also: - enums auf 2**n literals auffuellen - integer types (ranges) sollten 2**n values haben - eine case alternative sollte "others" sein - damit ist das case voll auskodiert (auch fuer sachen, an die man nicht gedacht hat ) - am besten einen legal case zu others erweitern: case a is when aa .... , when ab .... , when others => ... ; -- ac end case - damit sollte die synthese dann auch nichts mehr machen was nicht im rtl definiert ist. mfg /uwe
>- enums auf 2**n literals auffuellen Das nutzt nichts - keiner sagt dir, dass die Synthese das dann mit n Signalen codiert. Häufig wird eine one-hot-codierung genommen, die dann 2**n Signale hat. Da hilft kein VHDL-Konstrukt etwas, nur eine Anweisung an die Synthese, eine sichere Implementierung zu wählen.
> - enums auf 2**n literals auffuellen Wie Jan M. schon gesagt hat, erzwingt man damit keineswegs, dass die Zustände auch in n Bits kodiert werden. Davon abgesehen: Was genau hat man von den zusätzlichen Zuständen? Diese müssen dann ja auch Übergänge und Werte für die Ausgangssignale haben. In welchen "gültigen" Zustand soll verzweigt werden? Und so weiter. Da man nicht weiß, warum ein ungültiger Zustand überhaupt erreicht wurde, ist jeder Wechsel in einen "gültigen" Zustand falsch, abgesehen von einem Reset des kompletten Subsystems - und selbst das ist meistens falsch. Egal welchen "Ausweg" man sich ausdenkt, das System macht in 99% aller Fälle etwas, was es eigentlich nicht machen soll. > - integer types (ranges) sollten 2**n values haben Gleiche Argumentation. > - eine case alternative sollte "others" sein Wenn alle definierten Zustände durch case-Zweige abgedeckt sind, wird "others" wie oben beschrieben ignoriert, kann man also auch weglassen. > - damit ist das case voll auskodiert (auch fuer sachen, an die man nicht gedacht hat ) Ich denke, durch das oben geschriebene sollte klar werden, dass sich beim Bau digitaler Logik ein wenig Nachdenken mehr lohnt als der Versuch, Fehler nachträglich durch Rumfrickeln auszubessern. > - damit sollte die synthese dann auch nichts mehr machen was nicht im > rtl definiert ist. Genau das hat sich der Prof des OP sicher auch gedacht: "sollte". Aber die Realität sah anders aus.
> - enums auf 2**n literals auffuellen
Das hilft nichts:
wenn ich 8 Zustände (2**3) habe, und die SM OneHot codiere,
dann gibt es 248 undefinierte Zustände (256-8).
Und es gibt noch viele andere Methoden, eine SM zu codieren.
Die "Safe Implementation" hilft auch nur, dass in keinen undefinierten
Zustand eingetreten wird. Gegen undefinierte Übergänge hilft diese
Syntheseoption auch nichts.
>Wie Jan M. schon gesagt hat, erzwingt man damit keineswegs, dass die >Zustände auch in n Bits kodiert werden. ok, auch lkmiller'ss onehot beispiel zeigt, doch gerade dass es fehlermoeglichkeiten gibt, die auftreten, wenn im enum nicht alle moeglichen binary values des types definiert sind (um im one hot zu bleiben: 8 states=8bit=256 moeglichkeitn-8gueltige=248ungueltige. da dass natuerlich nicht als vollstaendiger enum gefasst wird, wuerde ich besondere vorsicht walten lassen, um nicht in die beliebten one-hot issues zu laufen. >Davon abgesehen: Was genau hat man von den zusätzlichen Zuständen? Diese >müssen dann ja auch Übergänge und Werte für die Ausgangssignale haben. Nö, die dienen nur dazu, zu verhindern, dass es unterschiede zwischen synth. netzliste und dem rtl gibt (sonst kann der fall eintreten dass die synth. state machine ein superset! der im rtl beschriebenen ist - die auf gate level macht also mehr als beschrieben+gewollt. dieses delta an funktionlitaet ist tools/optimierungsabhaenig/etc. wenn man(n) pech hat haengt sich daran das system auf. btw frag doch mal ein formales tool ob gate und rtl gleich sind. >In welchen "gültigen" Zustand soll verzweigt werden? Und so weiter. Da man nicht weiß, warum ein ungültiger Zustand überhaupt erreicht wurde, ist jeder Wechsel in einen "gültigen" Zustand falsch, abgesehen von einem Reset des kompletten Subsystems - und selbst das ist meistens falsch. Egal welchen "Ausweg" man sich ausdenkt, das System macht in 99% aller Fälle etwas, was es eigentlich nicht machen soll. klar, 1. ziel: komplette equivalenz im verhalten rtl vs gate level (ausschliessen von hidden states und transitions welche durch die synthese autreten koennen 2. ziel: wenns schon mal schiefgeht in der hardware (und das passiert :-)) geht es darum das sich das system faengt und in einen definierten zustand zurueckkehrt (und das ohne subsystem/system reset) /mfg
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.