meldet der Synthesizer:
range expression could not be resolved to a constant
Was ist denn hier genau das Problem? Simulieren kann ich das.
Dachte das es vielleicht an dem dynamischen pos signal liegt.
Aber folgende Zeile geht auch:
Ich brauche aber unbedingt diese Lösung.
Soweit ich das sehe kann es ja nicht sein das ich über die vektor
grenzen komme.
Könnt ihr mir sagen wie ich das sonst lösen kann?
Danke
Gruß
Max
Hi,
danke für die Antwort.
Ich benutze Vivado 2019.1
So richtig klar ist es für mich leider nicht warum die untere Zeile
supported wird und die obere nicht :(
Gruß
Max
Max schrieb:> So richtig klar ist es für mich leider nicht warum die untere Zeile> supported wird und die obere nicht :(
In der zweiten Zuweisung scheint das Tool zu erkennen, dass linke und
rechte Anweisung einen gleich breiten Vektor haben. In der ersten
Zuweisung kriegt das Tool das nicht mit.
Außerdem:
Max schrieb:> pos(2)-1
Was macht das Tool, wenn pos(2) hier 0 ist?
So wie ich das verstehe, willst du einen variabel langen Teil eines
Vektors auswählen und zuweisen. In Hardware heißt eine Bitauswahl meist,
dass es mit einem Multiplexer beschrieben werden kann. Ein Multiplexer
kann mit switch/case oder if/else beschrieben werden (oder mit der
anscheinend nicht unterstützten dynamic expression wie du es versucht
hast). switch/case ist bei einer variablen DATA_WIDTH nicht gut machbar.
Eine Möglichkeit wäre eine ausnahmsweise mal erlaubte for loop mit einem
if
1
-- folgendes ist nur ein Beispiel, welches NICHT deiner Logik oben entspricht
2
foriin8toDATA_WIDTHloop
3
if(i<pos(2))then
4
data_array(3)(i+7)<=data_array(2)(i-1);
5
endif;
6
endloop;
7
data_array(3)(7downto0)<="10101010";
Allerdings wird das schon ein ziemliches Mux-Monster, egal mit welcher
Beschreibung. Möglicherweise gibt es eine effizienteren Ansatz das
Gesamtproblem zu lösen, das kann man aber aus deinem Codeschnipsel nicht
erkennen.
>> So richtig klar ist es für mich leider nicht warum die untere Zeile>> supported wird und die obere nicht :(>> In der zweiten Zuweisung scheint das Tool zu erkennen, dass linke und> rechte Anweisung einen gleich breiten Vektor haben. In der ersten> Zuweisung kriegt das Tool das nicht mit.
Wenn die zweite Anweisung vom Tool verstanden wird, kannst du es
natürlich auch mal mit einem Aufsplitten deiner ersten Anweisung
versuchen.
VHDL hotline schrieb im Beitrag #6397105:
>>> So richtig klar ist es für mich leider nicht warum die untere> Zeile>>> supported wird und die obere nicht :(>>>> In der zweiten Zuweisung scheint das Tool zu erkennen, dass linke und>> rechte Anweisung einen gleich breiten Vektor haben. In der ersten>> Zuweisung kriegt das Tool das nicht mit.>> Wenn die zweite Anweisung vom Tool verstanden wird, kannst du es> natürlich auch mal mit einem Aufsplitten deiner ersten Anweisung> versuchen.> data_array(3)(pos(2)+7 downto 8) <= data_array(2)(pos(2)-1 downto 0);> data_array(3)(7 downto 0) <= "10101010";>> Allerdings bleibt hier immer noch das Problem, dass pos(2) für "0" nicht> geht ( (7 downto 8) <= (-1 downto 0) ).
Danke für die Hilfe.
Dieser Ansatz scheint zu funktionieren.
Ich habe aber den Code jetzt ein wenig umgeschrieben:
Und das wird tatsächlich synthetisiert obwohl das Problem mit dem pos(2)
= 0 noch besteht.
Kann es dann zu einem Laufzeitfehler kommen?
Ich habe das ganze jetzt mit einer if abgesichert:
Max schrieb:> Und das wird tatsächlich synthetisiert obwohl das Problem mit dem pos(2)> = 0 noch besteht. Kann es dann zu einem Laufzeitfehler kommen?
Nein, es kommt halt je nachdem, wie der MUX implementiert wurde,
irgendein Blödsinn raus.
> Ich habe das ganze jetzt mit einer if abgesichert
Wenn das jetzt in einem kombinatorischen Prozess steht, hast du ein
Latch an der Backe.
> Ich habe das ganze jetzt mit einer if abgesichert
Kurios. Wenn du in diesem Fall einfach nichts machst, dann ist doch
irgendwie der ganze Multiplexer nicht so wichtig.
BTW: irgendwie erinnert mich das Ganze an die Sache, die Peter da im
Beitrag "Re: Timing Optimierung bei einem Schieberegister"
bearbeitet. Ist das das selbe Problem?
Lothar M. schrieb:> Max schrieb:>> Und das wird tatsächlich synthetisiert obwohl das Problem mit dem pos(2)>> = 0 noch besteht. Kann es dann zu einem Laufzeitfehler kommen?> Nein, es kommt halt je nachdem, wie der MUX implementiert wurde,> irgendein Blödsinn raus.
Wenn ich es simuliere und ich sehe das gewünschte Verhalten. Dann
erwarte ich auch, dass nach der erfolgreichen Synthese dasselbe
Verhalten auf dem Chip passiert. Oder etwa nicht?
>> Ich habe das ganze jetzt mit einer if abgesichert> Wenn das jetzt in einem kombinatorischen Prozess steht, hast du ein> Latch an der Backe.
Das war nur ein ausschnitt vom Prozess. Hier der ganze Prozess:
> BTW: irgendwie erinnert mich das Ganze an die Sache, die Peter da im> Beitrag "Re: Timing Optimierung bei einem Schieberegister"> bearbeitet. Ist das das selbe Problem?
Das gibts doch nicht? Wie bist du darauf gekommen? Ich bin der "Peter"
;)
Ich sehe da überhaupt keine Ähnlichkeit zu dem Schiebergister vom
anderen Post oO....Das ist jetzt echt unheimlich.
Das ist jetzt ein neuer Ansatz das Problem zu lösen :D
Statt das Ganze in einer Periode mit einer Loop zu shiften versuche ich
jetzt ich es jetzt sequentiell von Periode zu Periode zu shiften. Mit
Piplining. Schauen wir mal was dabei rauskommt^^
Gruß
Max (Peter)
Max schrieb:> Wenn ich es simuliere und ich sehe das gewünschte Verhalten. Dann> erwarte ich auch, dass nach der erfolgreichen Synthese dasselbe> Verhalten auf dem Chip passiert. Oder etwa nicht?
Ich kann dir eine Schaltung beschreiben, die läuft in der Simulation
tagelang tadellos. In der Realität versagt sie spätestens nach ein paar
Sekunden... ;-)
Aber wie ich den Code ansehe dürfte das hier nicht passieren.
> Ich sehe da überhaupt keine Ähnlichkeit zu dem Schiebergister vom> anderen Post oO....
Ja doch. Weil eben das damalige "Schieberegister" auch schon keines war,
sondern ein Monstermultiplexer ;-)
> Das gibts doch nicht? Wie bist du darauf gekommen?
Soooo arg viel Traffic ist hier im FPGA-Forum nun doch nicht. Und oft
kommen dann ganze Semesterschwärme an, die das selbe Problem zu lösen
haben.
> Mit Piplining. Schauen wir mal was dabei rauskommt^^
So wie ich das sehe, "rückst" du die Daten jetzt Schritt für Schritt
nach. Durch den variablen Index hast du aber wieder recht komplexe
Multiplexer. Bin gespannt, ob das Timing hinkommt. Auf jeden Fall würde
ich da dann eine STA machen und den kritischen Pfad ansehen.
Lothar M. schrieb:> Max schrieb:>> Wenn ich es simuliere und ich sehe das gewünschte Verhalten. Dann>> erwarte ich auch, dass nach der erfolgreichen Synthese dasselbe>> Verhalten auf dem Chip passiert. Oder etwa nicht?> Ich kann dir eine Schaltung beschreiben, die läuft in der Simulation> tagelang tadellos. In der Realität versagt sie spätestens nach ein paar> Sekunden... ;-)> Aber wie ich den Code ansehe dürfte das hier nicht passieren.
Soviel Erfahrung habe ich dafür noch nicht :)
Da fällt mir spontan höchstens ein Metastabilitätsproblem ein
>> Ich sehe da überhaupt keine Ähnlichkeit zu dem Schiebergister vom>> anderen Post oO....> Ja doch. Weil eben das damalige "Schieberegister" auch schon keines war,> sondern ein Monstermultiplexer ;-)
Ja diese "In-Hardware" Denkweise geht mir leider noch etwas ab :-/
>> Mit Piplining. Schauen wir mal was dabei rauskommt^^> So wie ich das sehe, "rückst" du die Daten jetzt Schritt für Schritt> nach. Durch den variablen Index hast du aber wieder recht komplexe> Multiplexer. Bin gespannt, ob das Timing hinkommt. Auf jeden Fall würde> ich da dann eine STA machen und den kritischen Pfad ansehen.
Mir ist leider kein anderer Ansatz eingefallen.
Ich lass es euch wissen ob es klapt ;)
Gruß
Max
Ist eigentlich schon jemandem aufgefallen, dass dieser Konstrukt:
>data_array(3)(pos(2)+7 downto 0) <= data_array(2)(pos(2)-1
...gar nicht eindeutig darstellbar ist?
Der Synthesizer müsste ALLE möglichen Kombinationen von pos und den
jeweiligen Bits abwärts realisieren und dann mit einem ena einen davon
auswählen.
Ich habe so eine Ahnung was das werden soll und bin sehr sicher, dass
man das mit einem dynamischen shift zur Laufzeit ohne diesen MUX-Wald
lösen kann. Hier wurde einmal mehr probiert, einen klassischen
Softwarekonstrukt, den man so in C bauen würde, ins VHDL reinzuhacken,
ohne aber zu kapieren, dass hier eine HW rauskommt, die parallel
aufgebaut wird und dann folglich nur einer von N Pfaden aktiv ist. Kein
Mensch baut sowas.
Das ist ein klassischer Fall, es sequentiell zu belassen, um Platz zu
sparen. Der MUX-Wald wird nämlich schneckenlangsam, wenn er für ein
großes Array aufbaut werden muss und geht dann sehr schnell über mehr,
als nur 2 Takte, die es im anderen Fall kosten würde. Diese Array laufen
nämlich über BRAMS und es ist in allen solchen Fällen immer
zweckmässiger die RAM-Adressen, die letztlich rauskommen explizit
berechnen zu lassen, damit dann interne MUX im BRAM arbeiten. So kommt
hier eine MUX-Struktur raus, die viel fabric logic verbrät, teuer,
langsam und aufwändig ist.
Weltbester FPGA-Pongo schrieb im Beitrag #6397832:
> Ist eigentlich schon jemandem aufgefallen, dass dieser Konstrukt:>>data_array(3)(pos(2)+7 downto 0) <= data_array(2)(pos(2)-1>> ...gar nicht eindeutig darstellbar ist?>> Der Synthesizer müsste ALLE möglichen Kombinationen von pos und den> jeweiligen Bits abwärts realisieren und dann mit einem ena einen davon> auswählen.>> Ich habe so eine Ahnung was das werden soll und bin sehr sicher, dass> man das mit einem dynamischen shift zur Laufzeit ohne diesen MUX-Wald> lösen kann. Hier wurde einmal mehr probiert, einen klassischen> Softwarekonstrukt, den man so in C bauen würde, ins VHDL reinzuhacken,> ohne aber zu kapieren, dass hier eine HW rauskommt, die parallel> aufgebaut wird und dann folglich nur einer von N Pfaden aktiv ist. Kein> Mensch baut sowas.>> Das ist ein klassischer Fall, es sequentiell zu belassen, um Platz zu> sparen. Der MUX-Wald wird nämlich schneckenlangsam, wenn er für ein> großes Array aufbaut werden muss und geht dann sehr schnell über mehr,> als nur 2 Takte, die es im anderen Fall kosten würde. Diese Array laufen> nämlich über BRAMS und es ist in allen solchen Fällen immer> zweckmässiger die RAM-Adressen, die letztlich rauskommen explizit> berechnen zu lassen, damit dann interne MUX im BRAM arbeiten. So kommt> hier eine MUX-Struktur raus, die viel fabric logic verbrät, teuer,> langsam und aufwändig ist.
Hi,
das befürchte ich auch, dass das ganze viele Recoursen verbrauchen wird.
Nur leider fällt mir momentan keine andere Lösung ein.
Und ja es wird viel mehr als nur 2 takte kosten.
Ich wäre dankbar für Tipps wie man das besser lösen kann.
Hast du vielleicht ein Beispiel wie man sowas mit einem dynamischen
shift lösen kann?
Danke