mikrocontroller.net

Forum: FPGA, VHDL & Co. Latch in einer State Machine verhindern


Autor: David Meister (david107)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich bekomme durch das folgende (unvollständige) Codestück einen Latch 
und habe leider keine Ahnung wie ich es beheben kann:
entity xzy is
port(
  ...
  round : out std_logic_vector(3 downto 0));
end;

architecture rtl of xzy is

signal current_round : std_logic_vector(3 downto 0) := "0000";

begin
  process(state)
  begin
    round <= "0000";
    case state is
      ...
      when wait_sb => current_round <= current_round +1;
                      round <= current_round;
      when mix => 
      when other =>
    end case;
  end process;
  ...
end;
(in einem anderen Case-Statement wird current_round bei "1001" 
zurückgesetzt)

Die Sache ist, dass ich round inkrementieren muss, aber da es ein 
out-Port ist, nehme ich dazu das Hilfsignal current_round, welches den 
latch durch den "mix"-case bildet.
ich habe schon versucht current_round als Variable zu deklarieren und 
auch im "mix"-case das Statement current_round <= current_round or 
"0000" und Ähnliches getestet...
Ich hoffe man versteht was ich hier meine und vielleicht hat jemand 
einen Tipp dazu?

Gruß David

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ganz einfach. In JEDEM Zustand muss JEDE Variable einen direkten Wert 
zugewiesen bekommen. Und zwar einen, welcher VERSCHIEDEN von sich selbst 
ist, denn das ist das Latch.

Oder noch besser, vergiss solche rein kombinatorischen Dinger und mach 
es gleich in einem getakteten Prozess. Dort werden automatisch FlipFlops 
erzeugt und fertig.

MFG
Falk

Autor: David Meister (david107)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Falk,
das ist mir schon klar :)

Aber das Problem an der Sache ist, im Case mix darf das Signal "nicht" 
verändert werden, sondern nur im anderen Case.
Daher ist meine Frage, wie kann ich ein Latch verhindern, aber dabei den 
Wert beibehalten.

Autor: David Meister (david107)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falk Brunner schrieb:
> Oder noch besser, vergiss solche rein kombinatorischen Dinger und mach
> es gleich in einem getakteten Prozess. Dort werden automatisch FlipFlops
> erzeugt und fertig.

Das kann und ich will ich nicht abändern, das ganze ist ein größeres 
Projekt was sich auf diese State Machine stützt. Dies war nur ein kurzer 
Ausschnitt.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  David Meister (david107)

>Das kann und ich will ich nicht abändern,

Tja, dann hast du wohl Pech.

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo David Meister,

eine der besten Methoden ein Latch zu vermeiden ist keines zu 
beschreiben...

Du hast also eine CASE Anweisung.
In einem State beschreibst Du das dein Wert etwas (anderes) werden soll.

Das weglassen einer Zuweisung in den anderen CASEs heist aber nichts 
anderes als das das Signal seinen Zustand behalten soll.

Waers nun ein getakteter Prozess haettest Du da jetzt Register.Da dein 
Prozess aber kombinatorisch ist, gibts einen Satz Latches gratis.

Ausserdem testest Du wohl im Moment eher die Leistungsfaehigkeit deines 
FPGAs:

In deiner Zeile
wait_sb => current_round <= current_round +1;
wird dein Counter entweder vor sich hinrasen oder wahlweise aus dem 
Tritt kommen... Kann mir jetzt nicht vorstellen, dass das so gewollt 
war...

Gruss

Andreas

Autor: David Meister (david107)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas schrieb:
> Ausserdem testest Du wohl im Moment eher die Leistungsfaehigkeit deines
> FPGAs:
>
> In deiner Zeile
> wait_sb => current_round <= current_round +1;
> wird dein Counter entweder vor sich hinrasen oder wahlweise aus dem
> Tritt kommen... Kann mir jetzt nicht vorstellen, dass das so gewollt
> war...

wie bereits erwähnt:
in einem anderen Case-Statement wird current_round bei "1001"
zurückgesetzt :)

aber ich sollte besser noch einen weiteren Stück Code aufzeigen, den ich 
hätte dazuschreibem müssen, sorry an der Stelle
Dies gehört noch dazu:
process(clk, reset)
begin
  if reset = '1' then
    state <= IDLE;
  elseif clk'event and clk = '1' then
    state <= next_state;
  end if;
end;
also die States ändern sich mit jedem Takt.

Gruß David

Autor: Klaus Falser (kfalser)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
David Meister schrieb:
> Daher ist meine Frage, wie kann ich ein Latch verhindern, aber dabei den
> Wert beibehalten.

Das beißt sich sich.
Webb Du den Wert behalten willst, dann braucht es ein Speicherelement ( 
= Latch oder FF).
Falk hat jedenfalls recht: Mach es ordentlich und verwende einen 
getakteten Prozess. Auf die State-Variable zu takten ist der reinste 
Mist.

Autor: Klaus Falser (kfalser)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Schiebe das Zählen in den Synchronen Prozess
process(clk, reset)
begin
   if reset = '1' then
     state <= IDLE;
   elseif clk'event and clk = '1' then
     state <= next_state;
     case next_state is
      ...
      when wait_sb => current_round <= current_round +1;
       when mix => 
      when other =>
    end case;

   end if;
end;

round <= current_round;


Autor: David Meister (david107)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Falser schrieb:
> Schiebe das Zählen in den Synchronen Prozess

Super!
Das war es, vielen Dank!

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  David Meister (david107)

>Klaus Falser schrieb:
>> Schiebe das Zählen in den Synchronen Prozess

>Super!
>Das war es, vielen Dank!

Weil ich das ja auch gar nicht vorher geschrieben habe . . .

Autor: David Meister (david107)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falk Brunner schrieb:

> Weil ich das ja auch gar nicht vorher geschrieben habe . . .

sorry, da hatte ich dich wohl missverstanden

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

Bewertung
1 lesenswert
nicht lesenswert
>> Schiebe das Zählen in den Synchronen Prozess
> Super!
> Das war es, vielen Dank!
Der Klassiker bei der Zwei-Prozess-Schreibweise...

Und für alle, die jetzt kopfschüttelnd dastehen und sagen "wie konnte er 
nur?" hier der Hintergrund, warum das immer wieder passiert:
http://www.lothar-miller.de/s9y/archives/43-Ein-od...
      when wait_sb => current_round <= current_round +1;
                      round <= current_round;
Das, was hier dem Zähler passiert, heißt im Fachbegriff "Kombinatorische 
Schleife". Mehr dazu dort: 
http://www.lothar-miller.de/s9y/categories/36-Komb...

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.