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


von David M. (david107)


Lesenswert?

Hallo zusammen,

ich bekomme durch das folgende (unvollständige) Codestück einen Latch 
und habe leider keine Ahnung wie ich es beheben kann:
1
entity xzy is
2
port(
3
  ...
4
  round : out std_logic_vector(3 downto 0));
5
end;
6
7
architecture rtl of xzy is
8
9
signal current_round : std_logic_vector(3 downto 0) := "0000";
10
11
begin
12
  process(state)
13
  begin
14
    round <= "0000";
15
    case state is
16
      ...
17
      when wait_sb => current_round <= current_round +1;
18
                      round <= current_round;
19
      when mix => 
20
      when other =>
21
    end case;
22
  end process;
23
  ...
24
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

von Falk B. (falk)


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

von David M. (david107)


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.

von David M. (david107)


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.

von Falk B. (falk)


Lesenswert?

@  David Meister (david107)

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

Tja, dann hast du wohl Pech.

von Andreas (Gast)


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

von David M. (david107)


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:
1
process(clk, reset)
2
begin
3
  if reset = '1' then
4
    state <= IDLE;
5
  elseif clk'event and clk = '1' then
6
    state <= next_state;
7
  end if;
8
end;
also die States ändern sich mit jedem Takt.

Gruß David

von Klaus F. (kfalser)


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.

von Klaus F. (kfalser)


Lesenswert?

Schiebe das Zählen in den Synchronen Prozess
1
process(clk, reset)
2
begin
3
   if reset = '1' then
4
     state <= IDLE;
5
   elseif clk'event and clk = '1' then
6
     state <= next_state;
7
     case next_state is
8
      ...
9
      when wait_sb => current_round <= current_round +1;
10
       when mix => 
11
      when other =>
12
    end case;
13
14
   end if;
15
end;
16
17
round <= current_round;

von David M. (david107)


Lesenswert?

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

Super!
Das war es, vielen Dank!

von Falk B. (falk)


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

von David M. (david107)


Lesenswert?

Falk Brunner schrieb:

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

sorry, da hatte ich dich wohl missverstanden

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


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-oder-Zwei-Prozess-Schreibweise-fuer-FSM.html
1
      when wait_sb => current_round <= current_round +1;
2
                      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-Kombinatorische-Schleife

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.