Forum: FPGA, VHDL & Co. Entscheidungsblock


von Felix B. (Gast)


Lesenswert?

Hallo!

Komme grad irgendwie nicht weiter. Folgendes Problem:

In LabView kann ich zwischen drei Moden wählen (Strom-, Drehzahl- und 
Drehmomentgeregelter Betrieb meiner Reluktanzmaschine). Um nicht immer 
die Bezeichnungen im Quartus ändern zu müssen und die unterschiedlichen 
Moden über LabView sofort ändern zu können, will ich mir einen 
Modus-Regler basteln.

Dieser soll alle für jeden einzelnen Fall benötigte Signale (jeweils 2, 
ergo ins. 6) je nach Modus einfach nur weitergeben. Hört sich nicht 
schwer an, nur steh ich grad mit Quartus und dem Syntax im Konflikt ;)

Habe es mit "Case is" versucht, mekkert er rum:

case Modus is
  when "0000000000000000" => Isoll_H <= I_gereg_Hyst_H;
  when "0000000000000000" => Isoll_L <= I_gereg_Hyst_L;
  when "0000000000000010" => Isoll_H <= M_gereg_Hyst_H;
  when "0000000000000010" => Isoll_L <= M_gereg_Hyst_L;
  when others => null;
end case;

Habe es mit ner Zuweisung versucht, mekkert er rum:

Isoll_H  <=  I_gereg_Hyst_H when Modus = "0000000000000000";
Isoll_L  <=  I_gereg_Hyst_L when Modus = "0000000000000000";
Isoll_H  <=  N_gereg_Hyst_H when Modus = "0000000000000001";
Isoll_L  <=  N_gereg_Hyst_L when Modus = "0000000000000001";
Isoll_H  <=  M_gereg_Hyst_H when Modus = "0000000000000010";
Isoll_L  <=  M_gereg_Hyst_L when Modus = "0000000000000010";

Quartus gefällt die doppelte Modusverwendung jeweils nicht.


Hoffe ihr habt mein Problem verstanden, was ich eigentlich vor habe ;) 
Für Anregungen bin ich jeder Zeit dankbar!

Beste Grüße,
Felix

von ralf (Gast)


Lesenswert?

Zumindest Dein erster Konstrukt ist falsch oder unvollständig. Du musst 
für alle cases alle Zuweisungen beschreiben, hier also 16!

von Nur so (Gast)


Lesenswert?

Probier mal, ob das geht:
1
Isoll_H  <=  I_gereg_Hyst_H when Modus = "0000000000000000" else
2
             N_gereg_Hyst_H when Modus = "0000000000000001" else;
3
             M_gereg_Hyst_H when Modus = "0000000000000010"; -- ggf. when .. weglassen
Und bei Isoll_L analog

von Nur so (Gast)


Lesenswert?

Das Semikolon in der zweiten Zeile ist natürlich zuviel.

von Nur so (Gast)


Lesenswert?

ralf schrieb:
> Zumindest Dein erster Konstrukt ist falsch oder unvollständig. Du musst
> für alle cases alle Zuweisungen beschreiben, hier also 16!

Braucht er nicht, er hat doch ein "when others" drin.

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


Lesenswert?

Nur so schrieb:
> Braucht er nicht, er hat doch ein "when others" drin.
Und damit vermutlich gleich auch ein Latch an der Backe.
Und das ist idR. schlecht... :-/

Nur so schrieb:
> ralf schrieb:
>> Zumindest Dein erster Konstrukt ist falsch oder unvollständig. Du musst
>> für alle cases alle Zuweisungen beschreiben, hier also 16!
Das wären dann mindestens 2**16 Kombinationen, die beachtet werden 
müssten.
Weil aber Modus vermutlich ein std_logic_vector ist, gibt es da sehr, 
sehr viel mehr Kombinationen, nämlich 9**16 (weil std_logic 9-wertig 
ist!). Z.B. die hier:
"XULH-Z01W0LZZ001H" gehört ganz sicher zu when others...

von Achim S. (Gast)


Lesenswert?

ein Grund für das "Meckern" ist, dass du in der case Anweisung 
identische Fälle mehfach aufgeführt hast.

Anstatt

case Modus is
  when "0000000000000000" => Isoll_H <= I_gereg_Hyst_H;
  when "0000000000000000" => Isoll_L <= I_gereg_Hyst_L;
  when "0000000000000010" => Isoll_H <= M_gereg_Hyst_H;
  when "0000000000000010" => Isoll_L <= M_gereg_Hyst_L;
  when others => null;
end case;

sollte es z.B.

case Modus is
  when "0000000000000000" =>
     Isoll_H <= I_gereg_Hyst_H; Isoll_L <= I_gereg_Hyst_L;
  when "0000000000000010" =>
     Isoll_H <= M_gereg_Hyst_H; Isoll_L <= M_gereg_Hyst_L;
  when others => null;
end case;

heißen.

von Felix B. (Gast)


Lesenswert?

Danke für die vielen Antworten.

Hab es mit der Variante von Nur so probiert. Sieht soweit gut aus, nur 
warnt mich Quartus bei der Compilation, dass meine Ausgänge Isoll_H 
und_L "has unsafe behavior" (Latch). Leider kann ich nicht beurteilen, 
in wie fern dies kritisch sein könnte. Jedenfalls gefällt mir das nicht 
;)

Probiere das jetzt weiter aus sowie die Variante von Achim S. und gebe 
dann Rückmeldung!

Beste Grüße,
Felix

von Achim S. (Gast)


Lesenswert?

wenn du meine Variante wirklich implementieren willst, dann mach doch 
gleich ein

case Modus(1 downto 0) is
  when "00" =>
     Isoll_H <= I_gereg_Hyst_H; Isoll_L <= I_gereg_Hyst_L;
  when "10" =>
     Isoll_H <= M_gereg_Hyst_H; Isoll_L <= M_gereg_Hyst_L;
  when others => null;
end case;

daraus. Das schränkt die Anzahl der möglichen Fälle deutlich ein.

Das Latch-Verhalten hast du damit immer noch. Um es loszuwerden kannst 
du evlt. deine Zuweisung in einen getakteten Prozess packen...

schöne Grüße

Achim

von Nur so (Gast)


Lesenswert?

Felix B. schrieb:
> Leider kann ich nicht beurteilen,
> in wie fern dies kritisch sein könnte.

Für die Synthese ist das sehr kritisch. Für die Simulation ist das egal.

Das Latch wird verhindert, wenn du noch einen zusätzlichen else-Zweig 
einbaust mit einem Default-Wert.
ALTERNATIV machst du die letzte when-Abfrage als else (so wie ich das 
oben in dem Kommentar angedeutet habe).
Allerdings ist das nicht ganz äquivalent zu dem geforderten Verhalten. 
Musst du entscheiden, ob das geht.

von Felix B. (Gast)


Lesenswert?

Ja wunderbar, nachdem ich den CLk mit reingezogen habe, kommt keine 
Latchwarnung mehr. Super, dankeschön :)

Nur fürs Protokoll, hier der verwendete Code:

process(clk,Modus)
begin
  if rising_edge(clk) then
    case Modus(1 downto 0) is
      when "00" => Isoll_H <= I_gereg_Hyst_H; Isoll_L <= I_gereg_Hyst_L;
      when "01" => Isoll_H <= N_gereg_Hyst_H; Isoll_L <= N_gereg_Hyst_L;
      when "10" => Isoll_H <= M_gereg_Hyst_H; Isoll_L <= M_gereg_Hyst_L;
      when others => null;
    end case;
  end if;
end process;

von Nur so (Gast)


Lesenswert?

Nach meinem Verständnis sollte da aber ein Latch entstehen, weil Isoll_H 
und Isoll_L keine Default-Werte haben. Wenn Modus(1 downto 0) = "11" 
wird doch der zuvor im Latch gespeicherte Wert weiterverwendet.

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


Lesenswert?

Nur so schrieb:
> Nach meinem Verständnis sollte da aber ein Latch entstehen, weil Isoll_H
> und Isoll_L keine Default-Werte haben.
In einem FPGA gibt es 2 Speicherglieder:
D-FFs (mit Takt) und Latches (mit statischem Pegel)
In einem getakteten Prozess kann daher niemals ein Latch entstehen.

von Achim S. (Gast)


Lesenswert?

Da kein Default-Wert definiert wurde, wird im Fall
Modus(1 downto 0) = "11"
immer noch der letzte Wert gespeichert. Aber wie von Lothar beschrieben 
geschieht das eben nicht mehr in einem Latch sondern in einem 
taktflankengesteuerten Flipflop. Und damit ist Felix B. seine störende 
Warnung los.

Bei dieser Anwendung mit der wahrscheinlich (quasi)statischen Steuerung 
des Modus wäre das Latch meines Erachtens gar nicht mal so schlimm 
gewesen. Aber wenn einen Takt zur Verfügung steht und der eine Zyklus 
Latenz nicht stört, würde ich so was immer getaktet realisieren.

schöne Grüße

Achim

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


Lesenswert?

Achim S. schrieb:
> Bei dieser Anwendung mit der wahrscheinlich (quasi)statischen Steuerung
> des Modus wäre das Latch meines Erachtens gar nicht mal so schlimm
> gewesen.
Blöd nur, dass dieses Latch auf einen kombinatorische Verknüpfung von 16 
Bits regieren soll. Und wehe, da ändert sich eines ein wenig schneller 
oder langsamer. Das würde in der Praxis nie und nimmer stabil laufen...

von Nur so (Gast)


Lesenswert?

Stimmt, ihr habt recht. Latches können nur in asynchronen Prozessen 
auftreten.

von Achim S. (Gast)


Lesenswert?

Hallo Lothar,

generell bin ich ganz deiner Ansicht, dass man Latches vermeiden sollte, 
wenn man sie nicht bewusst einsetzen will, und dass sie ziemlich 
gefährlich sein können. Bei der Beurteilung von Felix Anwendung komme 
ich aber weiter auf eine andere Einschätzung als du. Meine Gründe:

- Felix legt per Modus fest, auf welche Art ein Motor gesteuert wird. 
Ich habe oben vermutet, dass Modus statisch auf einer der drei erlaubten 
Bitkombinationen liegt. Diese Vermutung war vielleicht etwas gewagt, 
aber ich würde immer noch vermuten, dass die Betriebswahl nicht im 
ms-Abstand geändert wird.

- beim Umschalten von Modus ist tatsächlich nicht vorhersagbar, welcher 
Wert im Latch landet. Aber für den hier gezeigten Teil des Codes ist es 
auch ziemlich "egal", welcher Wert gelatcht wird. Er wird (im hier 
gezeigten Code) nicht zurückgekoppelt, er kann keine Statemachine 
durcheinander bringen, ... Wenn Modus glitcht macht der Ausgang etwas 
nicht vorhersagbares, aber sobald Modus(1 downto 0) stabil auf einer der 
drei "erlaubten" Bitkombinationen steht, schaltet das Latch auf 
transparent und der gewünschte 3 zu 1 Mux wird an die Ausgänge 
durchgereicht.

- gefährlich könnte es aus meiner Sicht nur werden, wenn die Ausgänge 
des MUX im FPGA als Eingänge einer Statemachine (Motorregelung) genutzt 
werden, und wenn diese SM nicht getaktet realisiert wird (bzw. Modus 
nicht mit diesem Takt syncrhonisiert läuft). Dann könnte der kleinste 
Glitch auf einem Signal die SM zum Aufhängen bringen. Aber das würde ich 
nicht dem relativ harmlosen kombinatorischen 3:1 MUX zurechnen sondern 
der sehr gewagten Realisierung einer SM ohne Takt und synchronisierte 
Eingänge. Ist die potentiell nachgeschaltete SM vernünftig gebaut (als 
mit Takt und synchronisierten Eingängen), dann ist aus meiner Sicht auch 
das Latch im MUX harmlos.

schöne Grüße

Achim

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


Lesenswert?

Achim S. schrieb:
> Bei der Beurteilung von Felix Anwendung komme
> ich aber weiter auf eine andere Einschätzung als du. Meine Gründe:
Deine Betrachtungen sind korrekt, und der Knackpunkt ist, dass du weißt, 
was ein Latch ist, und ob du eines willst oder gar brauchst und wie du 
zu einem kommst oder es los wirst. Felix macht das Ding "aus Versehen" 
rein. Und das ist das Gefährliche daran...

> Ist die potentiell nachgeschaltete SM vernünftig gebaut (also
> mit Takt und synchronisierten Eingängen), dann ist aus meiner Sicht auch
> das Latch im MUX harmlos.
Nichtsdestoweniger aber unnötig.

Felix B. schrieb:
> Dieser soll alle für jeden einzelnen Fall benötigte Signale (jeweils 2,
> ergo ins. 6) je nach Modus einfach nur weitergeben.
Ganz konkret ist hier also nicht mal ein Latch gefordert. Ein ordinärer 
kombinatorischer Multiplexer würde locker ausreichen...

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.