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


von Martin K. (mkohler)


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
1
type ZUSTAENDE is (RESET, IDLE, RUNNING, STOP)
2
signal ZUSTAND : ZUSTAENDE := RESET;
3
4
...
5
case ZUSTAND is
6
  when RESET => ... ;
7
  ...
8
  when STOP => ... ;
9
...
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?

von Jan M. (mueschel)


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.

von Läubi .. (laeubi) Benutzerseite


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:
1
 type ZUSTAENDE is (RESET, IDLE, RUNNING, STOP)
2
 signal ZUSTAND : ZUSTAENDE := RESET;
3
 signal reg : std_logic_vector(1 downto 0);
4
 
5
 ...
6
 case ZUSTAND is
7
   when RESET => reg <= "00";
8
      
9
   when STOP =>  reg <= "01";
10
 ...

von Martin K. (mkohler)


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.

von cfgardiner (Gast)


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";

von Sadik (Gast)


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.

von Klaus Könner (Gast)


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

von user (Gast)


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);

von Karl (Gast)


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" ...

von Fpgakuechle K. (Gast)


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,

von Fpgakuechle K. (Gast)


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/synplify_ref_1001.pdf 
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...

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


Lesenswert?

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

von dired (Gast)


Lesenswert?

so gehts auch

1
subtype tStateOneHot is std_logic_vector(2 downto 0);
2
3
constant cST_S0 : tStateOneHot  := "000";
4
constant cST_S1 : tStateOneHot  := "001";
5
constant cST_S2 : tStateOneHot  := "010";
6
constant cST_S3 : tStateOneHot  := "100";
7
8
signal state, reg : tStateOneHot;
9
10
..
11
...
12
13
 ...
14
 case state is
15
   when cST_S0 => 
16
      
17
   when cST_S1 => 
18
 ...
19
20
21
22
reg <= state;

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.