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