mikrocontroller.net

Forum: FPGA, VHDL & Co. Typedefinition mit 3 Zustaenden


Autor: André (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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é

Autor: Jan M. (mueschel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moegliche Zustaende in der Simulation sind noch z.B. "undefined" wenn 
kein Wert zugewiesen wird. Das hat mit 2^n aber nichts zu tun.

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: André (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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é

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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
when others =>
  zustand <= aa;

schreiben. Also sozusagen eine bevorzugten
Zustand einnehmen.

Gruß

Gast

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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:
type dtyp is (aa, ab, ac);
signal a : dtyp := aa;
:
:
case a is
   when ab .... ,
   when ac .... ,
   when others => ... ; -- hierher der Code für den Defaultstate aa
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

Autor: Klaus Falser (kfalser)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Morin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe das nochmal nach dem obigen Beispiel durchgemacht und an das 
Beispiel ein wenig Fleisch gebracht:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity SM_ueberdefiniert is
    Port ( clk   : in  STD_LOGIC;
           leds  : out  STD_LOGIC_VECTOR (1 downto 0);
           error : out  STD_LOGIC);
end SM_ueberdefiniert;

architecture Behavioral of SM_ueberdefiniert is
type dtyp is (aa, ab, ac);
signal a : dtyp;

begin

   process begin
      wait until rising_edge(clk);
      error <= '0'; -- default
      case a is
         when aa => a<=ab; leds<="00";
         when ab => a<=ac; leds<="01";
         when ac => a<=aa; leds<="10";
         when others => a<=aa; error <= '1';
      end case;
   end process;

end Behavioral;
Bei der Synthese erhalte ich den Hinweis
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   ;-)

Autor: André (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sehr schoenes Beispiel, danke :). Damit ists nun wirklich sicher.

Ich danke allen fuer ihre ausfuehrlichen Antworten :)

Viele Gruesse,
André

Autor: jetztnicht (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Jan M. (mueschel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>- 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.

Autor: Morin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> - 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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> - 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.

Autor: jetztnicht (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.