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


von christian (Gast)


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

von Jan M. (mueschel)


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.

von Georg A. (Gast)


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

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


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.

von christian (Gast)


Angehängte Dateien:

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

von iulius (Gast)


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

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


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"

von Duke Scarring (Gast)


Lesenswert?

christian schrieb:
> Choice XXX is not a static expression.

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

Duke

von Klaus F. (kfalser)


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.

von christian (Gast)


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

von Klaus F. (kfalser)


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:
1
if (a) then 
2
   y <= 1; 
3
end if; 
4
5
if (b) then 
6
   y <= 2; 
7
end if;
ist equivalent zu der if-else Kette
1
if (b) then 
2
   y <= 2; 
3
else if (a) then  
4
   y <= 1; 
5
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.

von christian (Gast)


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

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


Lesenswert?

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

von Jan M. (mueschel)


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.

von Klaus F. (kfalser)


Lesenswert?

Und abschließend : "Don't cares" sind auch nützlich :

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

von christian (Gast)


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

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.