www.mikrocontroller.net

Forum: FPGA, VHDL & Co. if => case Statement. Choice XXX is not a static expression.


Autor: christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

ich habe folgendes Problem mit meinem VHDL-Code. Ich habe einen Process 
mit einem riesigen If-Statement. Es sind knapp 65 If-Bedingungen und 
könnten auch noch mehr werden. Synthesetechnisch ist das ja jetzt 
ziemlich ungeschickt, da hierbei ja dann 65 MUX hintereinander 
geschaltet werden und der Logik-Pfad viel zu lang wird. Ich würde das 
jetzt gerne Parallel mit einem Case-Statement aufziehen. Das geht aber 
leider mit folgendem Fehler in die Hose:
Choice XXX is not a static expression.
Das ist auch leider richtig. XXX ist ein std_logic_vector(63 downto 0) 
der einen Adressoffset + die Register Adresse zugewiesen bekommt.
XXX <= addr_offset + addr
Dieser Adressoffset wird mir von einem Linux PC einmal am Anfang 
zugewiesen und der ändert sich dann nicht mehr. Aus sicht des FPGAs ist 
XXX somit aber auf jedenfall nicht static.
Ich hoffe das war jetzt nicht zu verwirrend...

Jetzt zur Frage. Gibt es eine möglichkeit diese riesige If-Anweisung, 
die nicht statische Ausdrücke enthält, umzuschreiben, daß das ganze 
parallel synthetisiert wird? Bin sehr dankbar für jeden Tipp!

Gruß,
Christian

Autor: Jan M. (mueschel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast da eine etwas falsche Vorstellung vom Synthesizer.
Case und If werden prinzipiell erst einmal genau gleich in Hardware 
umgesetzt. Der einzige Unterschied liegt in Prioritäten, die du dir mit 
verschachtelten if ganz schnell einhandelst und die ein case 
prinzipbedingt nicht hat.
Auch bei 65 "elsif" im Code wird da sicher keine Kette von 65 
Multiplexern erzeugt.

Besser ist folgende Vorstellung: Der Synthesizer analysiert für jedes 
einzelne signal in einem Prozess alle Zuweisungen, erstellt daraus eine 
Wahrheitstabelle und setzt diese dann in Logik um.
Wie du das dann genau beschreibst spielt keine Rolle mehr.


In deinem speziellen Fall wuerde ich aber einfach zuerst einfach den 
Offset von deiner Adresse subtrahieren und dann die ganze Logik mit 
einem case erschlagen.

Autor: Georg A. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Es sind knapp 65 If-Bedingungen

Von denen aber doch nur eine treffen kann, also geht elsif.

> Ich würde das jetzt gerne Parallel mit einem Case-Statement aufziehen.

Was keinen Unterschied zur elsif-Implementierung macht...

> XXX <= addr_offset + addr

Wenn du das nicht byteweise veschiebbar brauchst, ist das doch auch 
kein Problem.

Der normale Weg sieht dann so aus:

if addr(63 downto 20)=addr_offset(63 downto 20) then
   case addr(19 downto 0) is
   when x"00000" =>
   when x"00001" =>
   ...

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

Bewertung
0 lesenswert
nicht lesenswert
> Ich habe einen Process mit einem riesigen If-Statement.
Da könnte man fragen: was steht denn in jedem Zweig?

> Gibt es eine möglichkeit diese riesige If-Anweisung,
> die nicht statische Ausdrücke enthält, umzuschreiben
Dazu müsst man etwas mehr sehen...  Sourcecode zum Beispiel.

Autor: christian (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Jan M. schrieb:
> Du hast da eine etwas falsche Vorstellung vom Synthesizer.
> Case und If werden prinzipiell erst einmal genau gleich in Hardware
> umgesetzt. Der einzige Unterschied liegt in Prioritäten, die du dir mit
> verschachtelten if ganz schnell einhandelst und die ein case
> prinzipbedingt nicht hat.
> Auch bei 65 "elsif" im Code wird da sicher keine Kette von 65
> Multiplexern erzeugt.

Oh, dann hab ich scheinbar wirklich eine falsche Vorstellung davon ;-) 
Ich hab gerade angefangen mich mit der Synthetisierbarkeit und 
Optimierung von VHDL zu beschäftigen und mir die Video-Tutorials "Virtex 
5 HDL Coding Techniques" und "Basic HDL Coding Techniques" von Xilinx 
angesehen. Da wurde beschrieben, das If-Elsif-Verschachtelungen durch 
eine Hintereinanderschaltung von Multiplexern realisiert wird. Ich hab 
die Folie von Xilinx mal angehängt. Xilinx empfiehlt deswegen immer die 
verwendung con case-Abfragen.
Wenn Eine IF-Then-Abfrage aber wirklich genauso parallel aufgebaut 
werden, dann kann ich meinen Code ja so lassen wie er ist. Laufen tut 
er.

Georg A. schrieb:
> if addr(63 downto 20)=addr_offset(63 downto 20) then
>    case addr(19 downto 0) is
>    when x"00000" =>
>    when x"00001" =>
>    ...

Auf die Idee bin ich noch nicht gekommen. Werde es mal ausprobieren.

Lothar Miller schrieb:
> Da könnte man fragen: was steht denn in jedem Zweig?
Nur eine Adress abfrage. Das ganze ist ein Prozess um über eine 
PCI-Schnittstelle die Register auszulesen.

Habt Ihr vielleicht einen Tipp für ein Buch o. Literatur die sich damit 
beschäftigt, wie VHDL Code synthetisiert wird? Bin auf dem Gebiet noch 
Unerfahren.

Danke Euch Allen für die Hilfe und Hinweise!

Gruß,
Christian

Autor: iulius (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie synthetisiert wird hängt immer vom jeweiligen Synthesetool ab.

Auch wenn alles nur in LUTs gepackt wird muss das trotzdem nicht gleich 
aussehen.


Zu der Folie :

ja ist klar, wenn du wirklich nur elsifs hintereinander packst, was 
machst du denn dann ?

das bedeutet : Condition 1 darf nicht erfüllt sein, Condition 2 
nicht,.... aber condition n muss erfüllt sein.
Das gibt natürlich viel Logik.


In deinem Fall ist es aber egal wie cond 1 bis n-1 aussieht da alle das 
gleiche signal prüfen.

d.h. es ist garnicht möglich das die adresse z.b. gleichzeitig 17 und 42 
ist. deshalb musst du auch nicht ausschließen das die adresse nicht 17 
ist und brauchst demnach auch kein elsif sein.

Denn elsif sagt ja eben explizit aus : die vorige bedingung darf nicht 
erfüllt.


Ob das synthesetool das von selbst merkt bleibt offen, aber eigentlich 
würde ich denen das zutrauen.

Das ergibt ja die simpelste aller Kürzungsregeln überhaupt : a and nicht 
nicht a.
Na was wird da wohl rauskommen...

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

Bewertung
0 lesenswert
nicht lesenswert
> Habt Ihr vielleicht einen Tipp für ein Buch o. Literatur die sich damit
> beschäftigt, wie VHDL Code synthetisiert wird?
Siehe den Beitrag "Re: VHDL-Buch f. Einsteiger"

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
christian schrieb:
> Choice XXX is not a static expression.

Ist das ein Fehler oder eine Warnung?
Was sagt Modelsim dazu?

Duke

Autor: Klaus Falser (kfalser)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
christian schrieb:
> Habt Ihr vielleicht einen Tipp für ein Buch o. Literatur die sich damit
> beschäftigt, wie VHDL Code synthetisiert wird? Bin auf dem Gebiet noch
> Unerfahren.

Dazu, wie etwas genau synthetisiert wird, gibt es wahrscheinlich wenig 
Literatur, weil dies von FPGA Familie zu FPGA Familie unterschiedlich 
ist.

Das ist ähnlich zu C, dort gibt es auch keine Bücher darüber, welcher 
Assembler Code hinten raus kommt, weil es von Compiler zu Compiler und 
von der Optimierung abhängt.
Es gibt aber die Datenblätter zu den FPGAs mit der Beschreibung zu den 
Grundbausteinen (Slices), die der Synthesizer zur Verfügung hat, also 
aus denen das Design letztendlich aufgebaut wird.
Um bei der Analogie zum C-Compiler zu bleiben: dort gibt es die 
Datenblätter zu dem Prozessor, wo der Sprungbefehl beschrieben wird, den 
der Compiler letztendlich verwenden muss.

Es ist bei FPGAs aber genauso wie mit Microprozessoren: Man kann zwar 
manchmal etwas besser oder schlechter beschreiben, aber letztendlich 
kommt of das selbe heraus, weil der Compiler optimiert.
Und im Grunde interessiert es nicht, bzw. man kann und will gar nicht 
wissen ob das Ergebnis optimal ist, solange alles nur schnell genug ist.

Aus diesem Grund gibt man beim FPGA Timing constraint vor, damit sagt 
man, wie schnell man die Schaltung braucht, und der Compiler bemüht sich 
dies zu erreichen.

Versuch also nicht dem Compiler die Arbeit abzunehmen, sondern 
beschreibe dein Design so wie Du es brauchts.
Das heißt aber nicht, dass man beliebigen VHDL Kode schreiben kann, der 
VHDL Kode muss schon weiterhin in einer Form geschrieben werden, dass er 
synthetisierbar ist.
Der VHDL Compiler versteht nur bestimmt Konstrukte, also z.B. nur die, 
welche letztendlich ein FF ergeben.
Dazu gibt es z.B. das Buch von Schwarz, das ich zwar nicht kenne, aber 
hier öfters empfohlen wurden.

Autor: christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

iulius schrieb:
> Zu der Folie :
>
> ja ist klar, wenn du wirklich nur elsifs hintereinander packst, was
> machst du denn dann ?
>
> das bedeutet : Condition 1 darf nicht erfüllt sein, Condition 2
> nicht,.... aber condition n muss erfüllt sein.
> Das gibt natürlich viel Logik.
>
>
> In deinem Fall ist es aber egal wie cond 1 bis n-1 aussieht da alle das
> gleiche signal prüfen.
>
> d.h. es ist garnicht möglich das die adresse z.b. gleichzeitig 17 und 42
> ist. deshalb musst du auch nicht ausschließen das die adresse nicht 17
> ist und brauchst demnach auch kein elsif sein.
>
> Denn elsif sagt ja eben explizit aus : die vorige bedingung darf nicht
> erfüllt.

So, jetzt ist die Verwirrung perfekt ;-).

Jan M. schrieb:
> Auch bei 65 "elsif" im Code wird da sicher keine Kette von 65
> Multiplexern erzeugt.

Die beiden Aussagen wiedersprechen sich doch jetzt oder?

Wenn ich iulius richtig verstanden habe, dann müsste ich ja, wenn ich 
die if-elsif Anweisung durch eine hintereinander reihung von 
if-Anweisungen ersetzen, die ja dann parallel umgesetzt werden müssten, 
da jedes if das vorherige if nicht ausschließt. Richtig?

Duke Scarring schrieb:
> Ist das ein Fehler oder eine Warnung?
Ein Fehler.

Klaus Falser schrieb:
> Es ist bei FPGAs aber genauso wie mit Microprozessoren: Man kann zwar
> manchmal etwas besser oder schlechter beschreiben, aber letztendlich
> kommt of das selbe heraus, weil der Compiler optimiert.
> Und im Grunde interessiert es nicht, bzw. man kann und will gar nicht
> wissen ob das Ergebnis optimal ist, solange alles nur schnell genug ist.
>
> Aus diesem Grund gibt man beim FPGA Timing constraint vor, damit sagt
> man, wie schnell man die Schaltung braucht, und der Compiler bemüht sich
> dies zu erreichen.
>
> Versuch also nicht dem Compiler die Arbeit abzunehmen, sondern
> beschreibe dein Design so wie Du es brauchts.

Laut Xilinx beeinflußt die Art und Weise wie man seine Schaltung 
beschreibt schon sehr den Compiler. Dies kann unter anderem wohl auch 
zur Folge haben, daß durch eine ungeeignete Beschreibung die gewünschten 
Timing constraints nicht eingehalten werden können, bzw. es dem Compiler 
erschwert wird die timing constraints einzuhalten. In diesem Fall hatte 
ich das so verstanden, wie iulius es auch beschrieben hat, daß durch die 
if-elsif Anweisungen sehr viel Logik erzeugt wird, was dann wiederum 
schlecht fürs Timing wäre.

Grüße,
Christian

Autor: Klaus Falser (kfalser)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
christian schrieb:
> Wenn ich iulius richtig verstanden habe, dann müsste ich ja, wenn ich
> die if-elsif Anweisung durch eine hintereinander reihung von
> if-Anweisungen ersetzen, die ja dann parallel umgesetzt werden müssten,
> da jedes if das vorherige if nicht ausschließt. Richtig?

Wie Julius das gemeint hat, weiss ich nicht, aber ein 
hintereinanderschalten von if's löst das Problem nicht.
Die letze Zuweisung gewinnt:
if (a) then 
   y <= 1; 
end if; 

if (b) then 
   y <= 2; 
end if; 
ist equivalent zu der if-else Kette
if (b) then 
   y <= 2; 
else if (a) then  
   y <= 1; 
end if; 


>
> Klaus Falser schrieb:
>> Es ist bei FPGAs aber genauso wie mit Microprozessoren: Man kann zwar
>> manchmal etwas besser oder schlechter beschreiben, aber letztendlich
>> kommt of das selbe heraus, weil der Compiler optimiert.
>> Und im Grunde interessiert es nicht, bzw. man kann und will gar nicht
>> wissen ob das Ergebnis optimal ist, solange alles nur schnell genug ist.
>>
>> Aus diesem Grund gibt man beim FPGA Timing constraint vor, damit sagt
>> man, wie schnell man die Schaltung braucht, und der Compiler bemüht sich
>> dies zu erreichen.
>>
>> Versuch also nicht dem Compiler die Arbeit abzunehmen, sondern
>> beschreibe dein Design so wie Du es brauchts.
>
> Laut Xilinx beeinflußt die Art und Weise wie man seine Schaltung
> beschreibt schon sehr den Compiler. Dies kann unter anderem wohl auch
> zur Folge haben, daß durch eine ungeeignete Beschreibung die gewünschten
> Timing constraints nicht eingehalten werden können, bzw. es dem Compiler
> erschwert wird die timing constraints einzuhalten. In diesem Fall hatte
> ich das so verstanden, wie iulius es auch beschrieben hat, daß durch die
> if-elsif Anweisungen sehr viel Logik erzeugt wird, was dann wiederum
> schlecht fürs Timing wäre.
>

Ich habe nicht gesagt, dass man keine Unterschied gibt, aber dass man 
erst optimieren soll, wenn es wirklich notwendig ist.
Abgesehen davon, dass case und if-else nicht equivalent sind, gibt es in 
einem FPGA keine Kette von hintereinandergeschalteten AND oder ODER 
Gitter. Die Gleichungen werden auf LUTs reduziert, und das sind immer 
Funktionen mit mit 4 oder 5 Eingängen. Gerade im Beispiel von Xilinx 
weiter oben würde (falls die Bedingungen nur einfache Signale sind) 
alles in eine einzige LUT passen und genauso schnell sein wie wenn die 
Kette nur aus 1 oder 2 else-if bestehen würde.
Letztendlich werden die booleschen Gleichungen für die Signale immer 
minimiert und sich ausschließende Alternativen wegoptimiert.

Autor: christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Falser schrieb:
> Ich habe nicht gesagt, dass man keine Unterschied gibt, aber dass man
> erst optimieren soll, wenn es wirklich notwendig ist.
> Abgesehen davon, dass case und if-else nicht equivalent sind, gibt es in
> einem FPGA keine Kette von hintereinandergeschalteten AND oder ODER
> Gitter. Die Gleichungen werden auf LUTs reduziert, und das sind immer
> Funktionen mit mit 4 oder 5 Eingängen. Gerade im Beispiel von Xilinx
> weiter oben würde (falls die Bedingungen nur einfache Signale sind)
> alles in eine einzige LUT passen und genauso schnell sein wie wenn die
> Kette nur aus 1 oder 2 else-if bestehen würde.
> Letztendlich werden die booleschen Gleichungen für die Signale immer
> minimiert und sich ausschließende Alternativen wegoptimiert.

Boah, das ganze Thema ist ganz schön komplex. Als Fazit kann man also 
sagen, daß ich Alles beim Alten lassen kann, da der Compiler sich bemüht 
den Code zu optimieren, und erst selber Anfangen muss zu optimieren, 
wenn der Compiler es nicht mehr schafft alle Timing Constraints zu 
erfüllen.

Da hat Xilinx mich ganz schön durcheinander gebracht mit den "HDL coding 
techniques"...

Danke nochmal Allen für die Hilfe!

Christian

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

Bewertung
0 lesenswert
nicht lesenswert
Wesentlich ist auch, ob die Bedingungen voneinander unabhängig sind. 
Sowas:
if      (a=23) then 
   y <= 3; 
else if (b=33) then  
   y <= 2; 
else if (c=43) then  
   y <= 1; 
end if; 
wird ganz anders implementiert als sowas:
if      (a=23) then 
   y <= 3; 
else if (a=33) then  
   y <= 2; 
else if (a=43) then  
   y <= 1; 
end if; 
Im zweiten Fall kann der Synthesizer Abhängigkeiten erkennen und 
reduzieren. Dieser Spezialfall ist dann nichts als eine case Abfrage 
über a.

Autor: Jan M. (mueschel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Jan M. schrieb:
>> Auch bei 65 "elsif" im Code wird da sicher keine Kette von 65
>> Multiplexern erzeugt.
>
> Die beiden Aussagen wiedersprechen sich doch jetzt oder?

Lass mich das noch etwas präzisieren:

- elsif-Kette, bei der immer das gleiche Signal abgefragt wird: Gleiches 
Syntheseergebnis wie bei einem case.
- elsif-Kette, bei der immer unterschiedliche Signale abgefragt werden: 
Logisch gesehen muss eine Kette von Multiplexern erzeugt werden. Die 
Synthese ist aber klug genug, Optimierungen anzuwenden und nicht stur 
Multiplexer zu instanziieren. Die Tiefe steigt grob gesagt mit log(n), 
nicht mit n wie es bei einer reinen Kette zu erwarten wäre.

Ein guter Anhaltspunkt ist immer der RTL-View der synthetisierten Logik.

Autor: Klaus Falser (kfalser)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und abschließend : "Don't cares" sind auch nützlich :

z.B.
a <= "110" when b = "10" else 
     "101" when b = "01" else 
     "---"; 
Damit kann der Compiler am meist optimieren. Aber Achtung, gerade in der 
Simulation machen "don't cares" nicht immer was man denkt,
z.B.
 res <= '1' when sel = "1-" else '0';
ergibt '0' bei sel = "10" weil das '-' nicht speziell behandelt wird.
Korrekt ist :
res <= '1' when std_match(sel,"1-") else '0';

Autor: christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jan M. schrieb:
> - elsif-Kette, bei der immer das gleiche Signal abgefragt wird: Gleiches
> Syntheseergebnis wie bei einem case.
> - elsif-Kette, bei der immer unterschiedliche Signale abgefragt werden:
> Logisch gesehen muss eine Kette von Multiplexern erzeugt werden. Die
> Synthese ist aber klug genug, Optimierungen anzuwenden und nicht stur
> Multiplexer zu instanziieren. Die Tiefe steigt grob gesagt mit log(n),
> nicht mit n wie es bei einer reinen Kette zu erwarten wäre.

Super, dann kann ich in dem Fall ja getrost bei meiner If-Anweisung 
bleiben, da immer nur die Adresse abgefragt wird. Der Hinweis ist sehr 
Hilfreich
Ich werde mir dann jetzt noch das Buch von Schwartz bestellen und mich 
mal etwas intensiver mit der Synthese beschäftigen.

Grüße,
Christian

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.