Latch in einer State Machine verhindern

OP #1673903
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
#1673909
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
Gast #1673969
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
OP #1673978
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
#1673998
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;
Moderator (Firma: Titel) Persönliche Seite #1674099
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren