Forum: FPGA, VHDL & Co. bleibe in Zustand hängen, warum?


von Ole (Gast)


Lesenswert?

Hi!

Habe einen Zustandsautomaten programmiert und bleibe nun in einem 
Zustand hängen. Ist folgende Abfrage gültig?
1
when Z_3S =>     if QINT > 30 then 
2
                    FOLGE_Z <= Z0;
3
                  else FOLGE_Z <= Z_3S;
4
                  end if;

Hier wird im Zustand Z_3S abgefragt, ob der Zähler QINT (integer) größer 
als 30 ist. Ist dem so, dann wird auf den Grundzustand Z0 gewechselt, 
ansonsten im Zustand Z_3S geblieben. Eine Simulation mit Modelsim zeigt 
nun aber, dass der Zustand Z_3S nie verlassen wird, obwohl der Zähler 
bereits weit über 30 hinausläuft.
Woran kann das liegen?

Vielen Dank für Tipps,

bg, Ole





Zur weiteren Information hier noch der gesamte Code:
1
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer: 
4
-- 
5
-- Create Date:    19:14:23 10/09/2012 
6
-- Design Name: 
7
-- Module Name:    Versuch1VBb - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description:   wenn sw7 komplett geschlossen -> taster auslesen und entsprechenden 
12
--           code auf LEDs ausgeben
13
--
14
-- Dependencies: 
15
--
16
-- Revision: 
17
-- Revision 0.01 - File Created
18
-- Additional Comments: 
19
--
20
----------------------------------------------------------------------------------
21
library IEEE;
22
use IEEE.STD_LOGIC_1164.ALL;
23
use IEEE.STD_LOGIC_ARITH.ALL;
24
use IEEE.STD_LOGIC_UNSIGNED.ALL;
25
26
---- Uncomment the following library declaration if instantiating
27
---- any Xilinx primitives in this code.
28
--library UNISIM;
29
--use UNISIM.VComponents.all;
30
31
entity Versuch1VBb is
32
    Port ( SW7 : in  BIT_VECTOR (3 downto 0);  -- Switch SW7
33
           CLK,RESET : in BIT;        
34
        TASTER: in BIT_VECTOR (4 downto 0);  -- Taster up, enter, down, left, right
35
           LED : out  BIT_VECTOR (3 downto 0);  -- 4 LEDs
36
        TEST_QINT: out integer;    -- für testbench
37
        TEST_ZUSTAND: out integer;                -- für testbench
38
        TEST_RESET: out bit);                    -- für testbench
39
end Versuch1VBb;
40
41
architecture Verhalten of Versuch1VBb is
42
type ZUSTAENDE is (Z0, Z_UP, Z_ENTER, Z_DOWN, Z_LEFT, Z_RIGHT, Z_3S);
43
-- Z0 = Grundzustand
44
-- Z_UP..Z_RIGHT = Taster drücken
45
-- Z_3S = 3 sekunden warten
46
signal ZUSTAND, FOLGE_Z: ZUSTAENDE;
47
signal QINT: integer;
48
signal ZAEHLERRESET : bit;
49
50
begin
51
----SPEICHER----
52
Z_SPEICHER: process(CLK, RESET)
53
  begin
54
    if RESET='1' then ZUSTAND <= Z0; --bei reset in Z0 gehen
55
    elsif CLK='1' and CLK'event then
56
      if SW7 = "1111" then ZUSTAND <= FOLGE_Z;
57
      end if;
58
    end if;
59
  end process Z_Speicher;
60
61
----UEBERGANGSSCHALTNETZ----
62
UE_SN: process (TASTER, ZUSTAND)
63
  begin
64
    case ZUSTAND is
65
      when Z0 =>     case TASTER is
66
                  when "11110" => FOLGE_Z <= Z_UP;
67
                  when "11101" => FOLGE_Z <= Z_ENTER;
68
                  when "11011" => FOLGE_Z <= Z_DOWN;
69
                  when "10111" => FOLGE_Z <= Z_LEFT;
70
                  when "01111" => FOLGE_Z <= Z_RIGHT;
71
                  when others  => FOLGE_Z <= Z0;
72
                end case;
73
      when Z_UP =>     FOLGE_Z <= Z_3S;
74
      when Z_ENTER =>   FOLGE_Z <= Z_3S;
75
      when Z_DOWN =>   FOLGE_Z <= Z_3S;
76
      when Z_LEFT =>   FOLGE_Z <= Z_3S;
77
      when Z_RIGHT =>   FOLGE_Z <= Z_3S;
78
      when Z_3S =>     if QINT > 30 then 
79
                    FOLGE_Z <= Z0;
80
                  else FOLGE_Z <= Z_3S;
81
                  end if;
82
    end case;
83
  end process UE_SN;
84
85
----AUSGANGSSCHALTNETZ----
86
A_SN: process (ZUSTAND)
87
  begin
88
    case ZUSTAND is
89
      when Z0 =>       LED <= "1111";
90
                  TEST_ZUSTAND <= 0;
91
      when Z_UP =>     LED <= "1001";
92
                  ZAEHLERRESET <= '1';
93
                  TEST_ZUSTAND <= 1;
94
      when Z_ENTER =>   LED <= "0000";
95
                  ZAEHLERRESET <= '1';
96
      when Z_DOWN =>   LED <= "0110";
97
                  ZAEHLERRESET <= '1';
98
      when Z_LEFT =>   LED <= "0101";
99
                  ZAEHLERRESET <= '1';
100
      when Z_RIGHT =>   LED <= "1010";
101
                  ZAEHLERRESET <= '1';
102
      when Z_3S =>    ZAEHLERRESET <= '0';
103
                  TEST_ZUSTAND <= 6;
104
    end case;
105
  end process A_SN;
106
107
----TIMER----                
108
ZAEHLER: process (CLK)
109
  begin
110
    if CLK='1' and CLK'event then
111
    TEST_RESET <= ZAEHLERRESET;  
112
      if ZAEHLERRESET = '1' then
113
        QINT <= 0;
114
      else
115
        QINT <= QINT + 1;
116
      end if;
117
    TEST_QINT <= QINT;
118
    end if;
119
  end process ZAEHLER;
120
121
end Verhalten;

von Maik F. (sabuty) Benutzerseite


Lesenswert?

Für die Simulation fehlt QINT in der Sensitivity List deines Prozesses:

UE_SN: process (TASTER, ZUSTAND, QINT)

von user (Gast)


Lesenswert?

du hast in der Sensivity-Liste den Zähler vergessen

UE_SN: process (TASTER, ZUSTAND, QINT)


Tipp: du kannst auch Modelsim zur Ausgabe eines solchen Fehlers 
veranlassen
Trage in der modelsim.ini folgendes ein:

CheckSynthesis = 1

von Ole (Gast)


Lesenswert?

Danke euch, das wars!

Nun scheint alles bestens zu funktionieren :)

Werde dann auch mal CheckSynthesis = 1 probieren.

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


Lesenswert?

Ole schrieb:
> Nun scheint alles bestens zu funktionieren :)
In der Simulation: Ja.
Ind der Praxis: Nie und nimmer.
Warum bin ich mir da so sicher?
Weil du hier asynchrone Eingänge einfach ohne Einsynchronisieren auf 
eine FSM loslässt:
1
   TASTER: in BIT_VECTOR (4 downto 0);  -- Taster up, enter, down, left, right
2
3
   when Z0 =>     case TASTER is
http://www.lothar-miller.de/s9y/archives/64-State-Machine-mit-asynchronem-Eingang.html



Und ob du da Probleme mit prellenden Tasten haben kannst, da blicke ich 
noch nicht so recht durch mit den verwurstelten Zählerreset. Ich würde 
da auf jeden Fall erst mal die Taster entprellen und dann eine 
Flankenerkennung dahinter hängen: 
http://www.lothar-miller.de/s9y/categories/5-Entprellung
Aber irgendwie habe ich den Eindruck, dass du was einfaches kompliziert 
machst...  :-/
Was willst du denn erreichen?

von Ole (Gast)


Lesenswert?

Hallo Lothar!

Vielen Dank für deine Kritik.
Erreicht werden soll folgendes: Wenn der Vierfachswitch SW7 komplett 
geschlossen ist, sollen die fünf Taster Up, Enter, Down, Left und Right 
ausgelesen werden. Jedem Taster ist ein LED-Code zugeordnet, welcher 
nach dem Drücken 3 Sekunden lang anliegen soll.
Bspw. sollen bei der Taste Up die LEDs 0110 anzeigen, also die mittleren 
beiden sollen 3 Sekunden leuchten.

Du hast im Übrigen Recht, ich habe diesen Code noch nicht auf einem 
Board ausprobiert. Ob es zu Laufzeitproblemen kommt, kann ich demnach 
nicht sagen.

Die prellenden Taster halte ich für vernachlässigbar, da ja ganze drei 
Sekunden gewartet werden soll. Ich glaube nicht, dass dem menschlichen 
Nutzer dann auffällt, ob der so eben losgelassene Taster noch ein paar 
mal in den nächsten µs den Zähler resettet. Für zeitlich kritische 
Anwendungen hast du natürlich Recht.

OT: Mein Lob an deine sehr gut verständliche Homepage! Habe darin eben 
gelesen und bin über den synchronen Reset gestolpert. Ich habe gelernt, 
dass der Reset aus Sicherheitgründen assynchron auszuführen ist. Falls 
mal der Takt ausfällt, ist es dann immer noch möglich, die zu steuernde 
Maschine (oder andere Dinge) auf einen Grundzustand zurück zu bringen.

Vielen Dank noch mal für deine Hilfe,
bg, Ole

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


Lesenswert?

Ole schrieb:
> Ich habe gelernt, dass der Reset aus Sicherheitgründen assynchron
> auszuführen ist. Falls mal der Takt ausfällt, ist es dann immer noch
> möglich, die zu steuernde  Maschine (oder andere Dinge) auf einen
> Grundzustand zurück zu bringen.
Das eine hat mit dem Anderen nichts zu tun. Es gibt in der 
Sicherheitstechnik andere Methoden, Ausgänge sicher zu schalten. Denn 
um die geht es da ja ausschließlich. Du müsstest also nur den 
Ausgangstreiber mit dem Reset in einen sicheren Zustand bringen. 
Sicherheitstechnisch reicht es nämlich gar nicht aus, ein so tief 
vergrabenes Bauteil wie das FPGA "sicher" zu machen, und sich dann drauf 
zu verlassen, dass die nachfolgenden Bauteile sicher abschalten.

> Falls mal der Takt ausfällt
Dann ist der Reset sicher eines der kleineren Probleme!
Ich hatte im Feld noch nie einen ausgefallenen Quarzoszillator.

Dass ein asynchroner Reset im FPGA Ressourcen frisst, das zeigt der 
Beitrag "Xilinx und die Resets"
Für andere Hersteller lont es sich, das Handbuch zu lesen. Und wenn 
schon, dann sollte der Reset zwar asynchron kommen (können), aber nur 
synchron weggehen dürfen! Denn sonst läuft dir dein Sytem mal an und mal 
nicht. Ich konnte das seinerzeit auch nicht glauben, ist aber so...  ;-)

> Die prellenden Taster halte ich für vernachlässigbar
Wenn du es nur nicht vergisst, dass die Dinger potentiell unsauber sind, 
dann kannst du das schon machen.

> OT: Mein Lob an deine sehr gut verständliche Homepage!
Danke.

von Ole (Gast)


Angehängte Dateien:

Lesenswert?

Hallo!

Lothar hatte Recht, auf einem Board ging mit dem Code schon mal gar 
nichts. Lag wahrscheinlich an Latches.
Demnach wurde nun noch mal ein neuer Code entwickelt, indem vor allem 
die Signale "LAUFEN" und "FERTIG" eingeführt wurden. Wenn "LAUFEN" 1 
ist, zählt der Zähler hoch und stellt nach 3 Sekunden "FERTIG" auf 1. 
Solange "FERTIG" nicht 1 ist, kann nicht in einen anderen Zustand 
gewechselt werden.
Daraus ergibt sich die Logik, dass FERTIG und LAUFEN nicht gleichzeitig 
1 bzw. 0 sein können.
Genau das tritt jedoch leider ein, wie bei der angehängten 
Timing-Simulation ersichtlich.

Was genau funktioniert da nicht?
1
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer: 
4
-- 
5
-- Create Date:    19:14:23 10/09/2012 
6
-- Design Name: 
7
-- Module Name:    Versuch1VBb - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description:   wenn sw7 komplett geschlossen -> taster auslesen und entsprechenden 
12
--           code auf LEDs ausgeben
13
--
14
-- Dependencies: 
15
--
16
-- Revision: 
17
-- Revision 0.01 - File Created
18
-- Additional Comments: 
19
--
20
----------------------------------------------------------------------------------
21
library IEEE;
22
use IEEE.STD_LOGIC_1164.ALL;
23
--use IEEE.STD_LOGIC_ARITH.ALL;
24
use IEEE.STD_LOGIC_UNSIGNED.ALL;
25
26
---- Uncomment the following library declaration if instantiating
27
---- any Xilinx primitives in this code.
28
--library UNISIM;
29
--use UNISIM.VComponents.all;
30
31
entity Versuch1VBb is
32
    Port ( DIPSW : in  BIT_VECTOR (3 downto 0);  -- Switch SW7
33
           CLK,RESET : in BIT;        
34
        TASTER: in BIT_VECTOR (4 downto 0);  -- Taster up, enter, down, left, right
35
           LED : out  BIT_VECTOR (3 downto 0));  -- 4 LEDs
36
end Versuch1VBb;
37
38
architecture Verhalten of Versuch1VBb is
39
type ZUSTAENDE is (Z0, Z_UP, Z_ENTER, Z_DOWN, Z_LEFT, Z_RIGHT);
40
------ Z0 = Grundzustand
41
------ Z_UP..Z_RIGHT = Taster drücken
42
43
signal ZUSTAND, FOLGE_Z: ZUSTAENDE;
44
signal LAUFEN: bit :='0';
45
signal FERTIG: bit :='1';
46
signal QINT: integer :=0;
47
48
begin
49
50
----SPEICHER----
51
Z_SPEICHER: process(CLK, RESET)
52
  begin
53
    if RESET='0' then ZUSTAND <= Z0;   --bei reset in Z0 gehen
54
    elsif CLK='1' and CLK'event then
55
      if DIPSW = "1111" then         -- nur reagieren, wenn alle schalter geschlossen sind (LVTTL)
56
         ZUSTAND <= FOLGE_Z;         -- berechneten folgezustand zu aktuellem zustand machen
57
      end if;
58
    end if;
59
  end process Z_Speicher;
60
61
----UEBERGANGSSCHALTNETZ----
62
UE_SN: process (TASTER, ZUSTAND, FERTIG)
63
  begin
64
    if FERTIG='1' then        -- Zustandswechsel nur, wenn der zähler fertig ist
65
      case ZUSTAND is
66
        when Z0 =>     case TASTER is    -- Z0 = grundzustand, es wird auf eingabe gewartet
67
                    when "11110" => FOLGE_Z <= Z_ENTER;        
68
                    when "11101" => FOLGE_Z <= Z_UP;
69
                    when "11011" => FOLGE_Z <= Z_DOWN;
70
                    when "10111" => FOLGE_Z <= Z_LEFT;
71
                    when "01111" => FOLGE_Z <= Z_RIGHT;
72
                    when others  => FOLGE_Z <= Z0;
73
                  end case;
74
        when Z_UP =>     FOLGE_Z <= Z0;
75
        when Z_ENTER =>   FOLGE_Z <= Z0;
76
        when Z_DOWN =>   FOLGE_Z <= Z0;
77
        when Z_LEFT =>   FOLGE_Z <= Z0;
78
        when Z_RIGHT =>   FOLGE_Z <= Z0;
79
      end case;
80
    else
81
      FOLGE_Z<=ZUSTAND;    -- aktuellen zustand beibehalten, wenn zähler zählt
82
    end if;
83
  end process UE_SN;
84
85
----AUSGANGSSCHALTNETZ----
86
A_SN: process (ZUSTAND)
87
  begin
88
    case ZUSTAND is
89
      when Z0 =>       LED <= "1111";     --LEDs aus
90
                  LAUFEN <= '0';    --zähler darf nicht zählen
91
      when Z_UP =>     LED <= "1001";    --LEDcode bei tasterdruck ausgeben
92
                  LAUFEN <= '1';    --zähler darf zählen
93
      when Z_ENTER =>   LED <= "0000";
94
                  LAUFEN <= '1';
95
      when Z_DOWN =>   LED <= "0110";
96
                  LAUFEN <= '1';
97
      when Z_LEFT =>   LED <= "0101";
98
                  LAUFEN <= '1';
99
      when Z_RIGHT =>   LED <= "1010";
100
                  LAUFEN <= '1';
101
    end case;
102
  end process A_SN;
103
104
----TIMER----                
105
ZAEHLER: process (CLK, LAUFEN)
106
  
107
  begin
108
    
109
    if CLK='1' and CLK'event then  
110
      if LAUFEN = '1' then        -- nur zählen, wenn LAUFEN 1
111
        if QINT > 300000000 then    -- 3 sekunden zählen
112
          FERTIG <= '1';
113
        else 
114
          FERTIG <= '0';
115
        end if;
116
        QINT <= QINT + 1;
117
      else
118
        QINT <= 0;            -- wenn LAUFEN 0, zähler null setzen
119
      end if;
120
      
121
    end if;
122
  end process ZAEHLER;
123
124
end Verhalten;

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


Lesenswert?

Ich verrate dir nicht, wo der Fehler liegt, aber ich kann dir sagen, 
dass es von der Mischung synchroner und asychroner Prozesse kommt und 
sich "Latency" nennt.
Nur so viel: du kommst beim Zurücksetzten von LAUFEN 1 Takt "zu spät"
(= to late) , weil du den Umweg über ein weiteres Signal machst. Dieser 
Umweg kostet dich 1 Takt.


BTW:
1
ZAEHLER: process (CLK, LAUFEN)
2
begin
3
    if CLK='1' and CLK'event then 
4
    ...
Dieser Prozess ist nur auf clk sensitiv...

von Ole (Gast)


Lesenswert?

Hi!

Danke für deine Hilfe! Dieses doppelte Signal war tatsächlich ein Dorn 
im Auge, jedoch fand ich es einfach schön, vom Timer ein Signal 
zurückgeben zu können.
Nun wird im Übergangsschaltnetz einfach wieder auf den Zählerstatus 
abgefragt. Herausgekommen ist Folgendes:
1
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer: 
4
-- 
5
-- Create Date:    19:14:23 10/09/2012 
6
-- Design Name: 
7
-- Module Name:    Versuch1VBb - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description:   wenn sw7 komplett geschlossen -> taster auslesen und entsprechenden 
12
--           code auf LEDs ausgeben
13
--
14
-- Dependencies: 
15
--
16
-- Revision: 
17
-- Revision 0.01 - File Created
18
-- Additional Comments: 
19
--
20
----------------------------------------------------------------------------------
21
library IEEE;
22
use IEEE.STD_LOGIC_1164.ALL;
23
--use IEEE.STD_LOGIC_ARITH.ALL;
24
use IEEE.STD_LOGIC_UNSIGNED.ALL;
25
26
---- Uncomment the following library declaration if instantiating
27
---- any Xilinx primitives in this code.
28
--library UNISIM;
29
--use UNISIM.VComponents.all;
30
31
entity Versuch1VBb is
32
    Port ( DIPSW : in  BIT_VECTOR (3 downto 0);  -- Switch SW7
33
           CLK,RESET : in BIT;        
34
        TASTER: in BIT_VECTOR (4 downto 0);  -- Taster up, enter, down, left, right
35
           LED : out  BIT_VECTOR (3 downto 0));  -- 4 LEDs
36
end Versuch1VBb;
37
38
architecture Verhalten of Versuch1VBb is
39
type ZUSTAENDE is (Z0, Z_UP, Z_ENTER, Z_DOWN, Z_LEFT, Z_RIGHT);
40
------ Z0 = Grundzustand
41
------ Z_UP..Z_RIGHT = Taster drücken
42
signal ZUSTAND, FOLGE_Z: ZUSTAENDE;
43
signal LAUFEN: bit :='0';
44
signal QINT: integer := 31;
45
46
begin
47
48
----SPEICHER----
49
Z_SPEICHER: process(CLK, RESET)
50
  begin
51
    if RESET='0' then ZUSTAND <= Z0; --bei reset in Z0 gehen
52
    elsif CLK='1' and CLK'event then
53
      if DIPSW = "1111" then 
54
         ZUSTAND <= FOLGE_Z;
55
      end if;
56
    end if;
57
  end process Z_Speicher;
58
59
----UEBERGANGSSCHALTNETZ----
60
UE_SN: process (TASTER, ZUSTAND, QINT)
61
  begin
62
      if ZUSTAND = Z0 then
63
        case TASTER is
64
          when "11110" => FOLGE_Z <= Z_ENTER;        
65
          when "11101" => FOLGE_Z <= Z_UP;
66
          when "11011" => FOLGE_Z <= Z_DOWN;
67
          when "10111" => FOLGE_Z <= Z_LEFT;
68
          when "01111" => FOLGE_Z <= Z_RIGHT;
69
          when others  => FOLGE_Z <= Z0;
70
        end case;
71
      else
72
        if QINT >300000000 then
73
          FOLGE_Z <= Z0;
74
        else
75
          FOLGE_Z <= ZUSTAND;
76
        end if;
77
      end if;
78
  end process UE_SN;
79
80
----AUSGANGSSCHALTNETZ----
81
A_SN: process (ZUSTAND)
82
  begin
83
    case ZUSTAND is
84
      when Z0 =>       LED <= "1111";
85
                  LAUFEN <= '0';
86
      when Z_UP =>     LED <= "1001";
87
                  LAUFEN <= '1';
88
      when Z_ENTER =>   LED <= "0000";
89
                  LAUFEN <= '1';
90
      when Z_DOWN =>   LED <= "0110";
91
                  LAUFEN <= '1';
92
      when Z_LEFT =>   LED <= "0101";
93
                  LAUFEN <= '1';
94
      when Z_RIGHT =>   LED <= "1010";
95
                  LAUFEN <= '1';
96
    end case;
97
  end process A_SN;
98
99
----TIMER----                
100
ZAEHLER: process (CLK)  
101
  begin    
102
    if CLK='1' and CLK'event then  
103
      if LAUFEN = '1' then
104
        QINT <= QINT + 1;
105
      else
106
        QINT <= 0;
107
      end if;
108
    end if;
109
  end process ZAEHLER;
110
111
end Verhalten;

Blöderweise kann das leider wieder noch nicht auf einem Board 
ausprobiert werden, in der Simulation läuft es aber zu mindest schon 
mal.

Ich frage mich, was du gegen die asynchronen Prozesse hast. Im 
Übergangsschaltnetz wird der Folgezustand berechnet und später dann der 
Zustand in SPEICHER aktualisiert. Letzteres passiert Taktsynchron. Das 
Ausgangsschaltnetz habe ich bis jetzt noch nicht synchron gesehen.
Zusätzlich vertraue ich auf den jetzigen Code, da laut Synthetisierer 
keine Latches erzeugt werden.

Danke nochmals, lg,
Ole

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


Lesenswert?

Ole schrieb:
> Ich frage mich, was du gegen die asynchronen Prozesse hast. Im
> Übergangsschaltnetz wird der Folgezustand berechnet und später dann der
> Zustand in SPEICHER aktualisiert. Letzteres passiert Taktsynchron.
Und wie hast du dir die Latency eingefangen? Weil du die verschlungenen 
Wege vom einen zum anderen Signal nicht mehr nachvollziehen konntest. 
Und noch immer machst du einen unnötigen Umweg über den State, um deinen 
Zähler zurückzusetzen. Dein Zähler wird einen Takt zu spät 
zurückgesetzt. Auch das ist ein Takt Latency.

Lies einfach mal das durch:
http://www.lothar-miller.de/s9y/archives/43-Ein-oder-Zwei-Prozess-Schreibweise-fuer-FSM.html

> Das Ausgangsschaltnetz habe ich bis jetzt noch nicht synchron gesehen.
Gegenfrage: Wofür braucht man ein Ausgangsschaltnetz, wenn man jeden 
Ausgang registrieren kann, weil im IO-Pin vom FPGA sowieso ein Flipflop 
ist?

> Zusätzlich vertraue ich auf den jetzigen Code,
> da laut Synthetisierer keine Latches erzeugt werden.
Gut, wenn du deinen Beschreibungsstil gefunden hast und damit glücklich 
bist...

> Danke nochmals
Keine Ursache.

von Bronco (Gast)


Lesenswert?

Ole schrieb:
> Ich frage mich, was du gegen die asynchronen Prozesse hast.

Als ich mit VHDL angefangen hab, hab ich mal einen einfachen 
Zustandsautomat geschrieben, der ohne Takt auskommen sollte.
Auf einem CPLD ausprobiert: geht!
Auf einem FPGA ausprobiert: geht nicht!
Tatsächlich nahm der Automat im FPGA Zustände ein, die es in meinem Code 
überhaupt nicht gab.
Wie kann das sein?

Der Zustand (in Deinem Fall "ZUSTAENDE") wird als Bitwort kodiert, d.h. 
der tatsächliche Zustand des Automaten ergibt sich aus der Kombination 
der einzelnen Bits im Wort.
Im FPGA werden nun die Bits unterschiedliche Laufzeiten haben, d.h. beim 
Übergang von einem Zustand in einen anderen, wird es vorkommen, daß es 
zwischenzeitlich auch ein ganz anderer Zustand im Bitwort steht.
Mit Takt ist das kein Problem, weil das Bitwort zu einem ganz bestimmten 
Zeitpunkt "geschrieben" und "gelesen" wird und dazwischen der Zustand 
egal ist.
Ohne Takt reagiert der Automat sofort auf jede Änderung, dann verrennt 
er sich und Du kommst in Teufels Küche.

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.