mikrocontroller.net

Forum: FPGA, VHDL & Co. VHDL: Aufzählungstyp (state) als Signal ausgeben


Autor: Martin Kohler (mkohler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
ich möchte den aktuellen Zustand einer FSM als Signal ausgeben, so dass 
ich diesen über ein Register auslesen kann.

Meist werden die Zustände ja in der Art definiert
type ZUSTAENDE is (RESET, IDLE, RUNNING, STOP)
signal ZUSTAND : ZUSTAENDE := RESET;

...
case ZUSTAND is
  when RESET => ... ;
  ...
  when STOP => ... ;
...
Nun möchte ich den aktuellen Zustand als Signal haben, dabei aber genau 
wissen, welcher Wert welchem Zustand zugeordnet ist, z.b.
RESET   : "00"
IDLE    : "01"
RUNNING : "02"
STOP    : "03"

Die Zuordnung muss unabhängig von der Implementierung der FSM (one hot, 
...) sein.

Als Workaround kann ich explizit in jedem State einem separaten Signal 
den passenden Wert zuordnen, würde dies aber gerne vermeiden.

Wie kann ich das in VHDL beschreiben?

Autor: Jan M. (mueschel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das wirst du von Hand machen muessen, also in jeden Zustand noch eine 
Zuweisung an ein signal, z.B.

when IDLE =>
  state_bits <= "01";
when RUNNING =>
  state_bits <= "10";

etc.

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin Kohler schrieb:
> Hallo zusammen,
> ich möchte den aktuellen Zustand einer FSM als Signal ausgeben, so dass
.
.
> Die Zuordnung muss unabhängig von der Implementierung der FSM (one hot,
> ...) sein.
.
.
> Wie kann ich das in VHDL beschreiben?
Ich kenns nur so:
 type ZUSTAENDE is (RESET, IDLE, RUNNING, STOP)
 signal ZUSTAND : ZUSTAENDE := RESET;
 signal reg : std_logic_vector(1 downto 0);
 
 ...
 case ZUSTAND is
   when RESET => reg <= "00";
      
   when STOP =>  reg <= "01";
 ...
 

Autor: Martin Kohler (mkohler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Läubi .. schrieb:
> Ich kenns nur so:

Also auch die Variante "von Hand" von Jan M.
Schade, das hatte ich befürchtet.

Dann spendier ich halt jedem Zustand die Registerzuweisung.

Danke für die Antworten.

Autor: cfgardiner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Folgendes geht auch (meistens):

Library IEEE;
Use IEEE.numeric_std.all;

type ZUSTAENDE is (RESET, IDLE, RUNNING, STOP)
signal ZUSTAND : ZUSTAENDE := RESET;
signal zustand_as_num : std_logic_vector(1 downto 0);
  ....

zustand_as_num <= std_logic_vector(to_unsigned(ZUSTAENDE'pos(ZUSTAND),
                                   zustand_as_num'length));


Mit meistens, meine ich, dass die Voraussetzung eine sequentielle 
Kodierung der FSM ist (keine one-hot). Synplify hat jedenfalls sonst 
Schwierigkeiten.
Mit Synplify muss man dann zusätzlich ein attribute setzen wie (im 
Deklarationsteil, am Besten unmittelbar nach der type Definition)
   attribute syn_enum_encoding   : string;
   attribute syn_enum_encoding of ZUSTAENDE  : type is "sequential";

Autor: Sadik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Frage ist zwar schon sehr alt, aber dennoch:
Folgendes geht auch und ist noch einfacher, wie ich finde:

package types is
    type ZUSTAENDE is (RESET, IDLE, RUNNING, STOP);
    attribute enum_encoding : string;
    attribute enum_encoding of ZUSTAENDE : type is "00 01 10 11";
end types;

Dann steht Reset für 00, Idle für 01 usw.

Autor: Klaus Könner (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Das attribute enum_encoding ist IMHO kein VHDL-standard und es liegt an 
dem Synthesetool, ob es sich daran hält oder nicht.

Synthesetools richten sich auch gern nach Optionen wie 
FSM_encoding_style = (oneHot|gray|binary) und werfen festdefinierte 
Zustandscodsierungen über den haufen. Bei Medwedew-FSM kann man dagegen 
gleich den Outputvector als debug-ausgabe der states verwenden.

Auch verändert dein Vorschlag den internen Aufbau des FSM, es oll aber 
nur ein debug output erzeugt werden der den rest (fsm-timing) nicht 
beeinflusst.

IMHO führt kein Weg an einer extra Codierung bspw mit 'when' vorbei.

MfG

Autor: user (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
es geht auch sowas

type ZUSTAENDE is (RESET, IDLE, RUNNING, STOP)
signal ZUSTAND : ZUSTAENDE := RESET;
signal X : std_logic_vector(2 downto 0);
...

X <= conv_std_logic_vector(ZUSTAENDE'POS(ZUSTAND),3);

Autor: Karl (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Klaus Könner schrieb:
> Das attribute enum_encoding ist IMHO kein VHDL-standard und es liegt an
> dem Synthesetool, ob es sich daran hält oder nicht.

Denke aber das attribut hat sich etabliert, die meisten Synthesetools 
die ich kenne verstehen das "korrekt" ...

Autor: Fpga Kuechle (fpgakuechle) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
user schrieb:
> es geht auch sowas
>
> type ZUSTAENDE is (RESET, IDLE, RUNNING, STOP)
> signal ZUSTAND : ZUSTAENDE := RESET;
> signal X : std_logic_vector(2 downto 0);
> ...
>
> X <= conv_std_logic_vector(ZUSTAENDE'POS(ZUSTAND),3);

Interessant, wobei eventuell die Umwandlung von integer nach slv u.U. 
problematisch ist, also unsigned dazwischen.

MfG,

Autor: Fpga Kuechle (fpgakuechle) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl schrieb:
> Klaus Könner schrieb:
>> Das attribute enum_encoding ist IMHO kein VHDL-standard und es liegt an
>> dem Synthesetool, ob es sich daran hält oder nicht.
>
> Denke aber das attribut hat sich etabliert, die meisten Synthesetools
> die ich kenne verstehen das "korrekt" ...

Also schon synplify hat da so seine Probleme damit wenn es um FSM geht
(siehe post von  cfgardiner und 
http://www.cse.sc.edu/~jimdavis/Tools/Synplicity/s... 
seite 7-28.

Ebenso XST: http://www.doulos.com/knowhow/fpga/fsm_optimization/


Also um enum_encoding nutzen zu können, muß die automatische 
FSM-codierung und damit -optimierung abgeschaltet werden...

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

Bewertung
0 lesenswert
nicht lesenswert
Mit XST funktioniert 'pos unabhängig von der FSM Implementierung:
 http://www.lothar-miller.de/s9y/categories/37-FSM

Autor: dired (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so gehts auch

subtype tStateOneHot is std_logic_vector(2 downto 0);

constant cST_S0 : tStateOneHot  := "000";
constant cST_S1 : tStateOneHot  := "001";
constant cST_S2 : tStateOneHot  := "010";
constant cST_S3 : tStateOneHot  := "100";

signal state, reg : tStateOneHot;

..
...

 ...
 case state is
   when cST_S0 => 
      
   when cST_S1 => 
 ...



reg <= state;


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.