Hallo Zusammen,
ich bin Anfänger im Bereich FPGA/VHDL und habe eine Frage zu
Multiplikationen von z.B. Integern.
Wenn ich z.B. folgendes habe:
1
process(i_clk)
2
begin
3
4
ifrising_edge(i_clk)then
5
6
ifi_rst='0'then
7
8
r_counter_internal<=i_section*327+i_counts;
9
10
else
11
r_counter_internal<=0;
12
endif;
13
endif;
14
15
o_counter<=r_counter_internal;
16
17
endprocess;
Wobei alle Signale als Integer definiert sind.
Kann ich hier davon ausgehen, wenn mir der Compiler keine Timing-Errors
gibt, dass er die Multiplikation und Addition bei z.B. 200MHz schafft.
Die 200MHz kommen über eine PLL und sind der Systemtakt.
Wenn die Antwort "nein" lautet, wie kann ich rausfinden wieviele Takte
ich brauche?
Andere Additionen und Rechenoperationen laufen stabil und gut, nur das
Ergebnis in o_qdec_counter macht mich stutzig, da es bei jeder
Neu-Berechnung sehr stark schwankt, auch wenn die Eingabewerte
(i_section und i_counts) relativ stabil anliegen.
Vielen Dank und beste Grüße!
Kommt auf dein FPGA und Synthesewerkzeug an.
Mal 327 wird wohl über (wenn verfügbar) interne Multiplizierer laufen,
weil es sonst 5 Additionen wären.
200 Mhz wiederum als Multiplikation + Addition dürfte knapp werden auf
Low-Cost FPGA.
Auf aktuellen Virtex/Kintex/Ultrascale/Stratix eher kein Problem.
100 Mhz(also 2 Takte mit Multicycle Constraint) sollte auch auf
Spartan/Cyclone problemlos klappen.
Hatte ich vergessen, sorry!
Als IDE verwende ich Quartus 19 lite und als Prototypboard habe ich ein
altera de0nano. Später soll es auf einem Max10 laufen.
Wie müsste in dem Fall ein multicycle constraint aussehen?
Oder löst man sowas durch eine pipeline, indem ich die Ausgabe auf
o_counter manuell um einen Takt verzögere?
VHDL Newbie schrieb im Beitrag #6147400:
> Andere Additionen und Rechenoperationen laufen stabil und gut, nur> das Ergebnis in o_qdec_counter macht mich stutzig, da es bei jeder> Neu-Berechnung sehr stark schwankt, auch wenn die Eingabewerte> (i_section und i_counts) relativ stabil anliegen.
Wie lange ist i_rst aktiv? Und was bedeutet "relativ konstant"?
> Kann ich hier davon ausgehen, wenn mir der Compiler keine Timing-Errors> gibt, dass er die Multiplikation und Addition bei z.B. 200MHz schafft.
Wenn du ihm das korrekte Timing mitteilst und selber einhältst, dann
normalerweise schon.
i_rst ist zu Beginn einige Taktzyklen high, die genaue Dauer ist nicht
definiert, da sie u.a. von der Einregelzeit eines eigenen NCOs abhängt.
Relativ konstant bedeutet plausibel zu den Messwerten in i_counts und
uns i_section. Das Signal o_counter schwankt um ein vielfaches. Daher
kam die Vermutung auf, ob da irgendwelche Register aus der
Multiplikation gelesen werden bevor das Ergebnis fertig ist.
Bisher habe ich keine constraints angegeben, also keine eigenen. Möglich
dass die IDE automatisch irgendwelche grundsätzlichen constraints beim
Erstellen des Projekts angelegt hat, aber von mir stammen keine.
Ich dachte wenn ich alles ohne constraints bei den 200MHz zum laufen
bekomme is es ja besser/einfacher, die constraints dienen doch nur zum
lockern der timing-vorgaben, oder habe ich das falsch verstanden.
VHDL Newbie schrieb im Beitrag #6147641:
> Bisher habe ich keine constraints angegeben,
Wenn Du bei Quartus gar keine Constraints angibst (also nicht mal die
Clock und ihre Frequenz), rechnet der Timing-Analyzer mit 1000 MHz - da
wird praktisch immer ein knallrotes Timing-Ergebnis rauskommen.
Habe mich gerade nochmal durch die Dateien gesucht und festgestellt dass
ich da tatsächlich constraints habe. Konnte mich dann auch erinnern dass
ich da zu Beginn (vor nem Jahr oder so) auch mal Versuche hatte etwas
zum laufen zu bekommen.
Hier mal der Inhalt der *.sdc Datei. Hoffe es gibt nicht noch mehr
Dateien, die ich jetzt nicht gefunden habe...
Offensichtlich gibts für die 50MHz Grundtakt vom Board einen constraint
und ich hatte mal testweise für die 200MHz aus der PLL (IP-Core aus dem
Wizard) ein Pendant erzeugt. Aber wohl wieder auskommentiert da es mir
bei dem damaligen Problem vmtl. nichts geholfen hat.
Bedeutet das nun, dass der Compiler versucht alles nur auf 50MHz zu
optimieren und es mir deswegen ab und an was zerhauen kann (wie z.B.
meine Multiplikation?)?
Oft reicht es sen Takt des Oszillators über ein Constraint mitzuteilen.
Bei Xilinx gibt es Multiplizierer die Pipelining können. Das sollte es
bei Intel auch geben.
das hier:
VHDL Newbie schrieb im Beitrag #6147680:
> derive_pll_clocks -create_base_clocks
sorgt dafür, dass der Timing-Analyzer clocks, die von PLLs erzeugt
werden, selbstständig aus der Netzliste "einsammelt" (schliesslich kann
er alle benötigten Informationen aus der PLL-Definition auslesen).
Mehr brauchst Du also zunächst nicht, deine 200 MHz Clock ist bekannt
(die 200 MHz Clock-Definition wäre tatsächlich eher kontraproduktiv).
Und wenn Du wissen willst, wann genau deine Multiplier was ausspucken,
machst Du das, was man in solchen Fällen immer macht:
Simulieren.
Alternativ könntest Du natürlich auch dein Handbuch lesen ;) -
("LPM_MULT" ist, was Du suchst)
VHDL Newbie schrieb im Beitrag #6147400:
> Wobei alle Signale als Integer definiert sind.
Sind die unbeschränkt oder mit einem Range definiert? Falls ersteres
bedeutet dass 32 Bit und kann nicht mit einem einzelnen Multiplizierer
implementiert werden und dann könnte es wirklich knapp werden. Und
brauchst du die vollen 32 Bit wirklich?
Andere haben schon darauf hingewiesen aber ich habe noch keine Antwort
gesehen: Was steht im Timing-Report? Wird alles eingehalten für den 200
MHz Takt?
Da hier wild herum geraten wird, welche Elemente der Synthesizer nun
benutzt hat und entsprechend welche Doku nun zu lesen ist: Lass dir mal
das Schaltungsschema generieren nach dem "Map" schritt. Darin siehst du,
welche Elemente im FPGA wie genutzt werden.
Üblicherweise implementiert man die madd-Operation zunächst so, wie du
es gemacht hast. Dann schaut man, ob die Implementierung bei einem
gegebenen Clock-Constraint das Timing einhalten kann. Falls ja, fertig.
Falls nicht, hängt man ein oder zwei (oder drei ...) Register hinter die
Operation und überlässt des den Tools, diese als Pipeline-Register in
die Arithmetik "hinein zu ziehen" (nennt sich Automatic Pipeline
Balancing oder Register Retiming). Früher war das ein Glücksspiel, aber
mittlerweile beherrschen das die aktuellen Tools erfreulich gut.
Vancouver schrieb:> Falls nicht, hängt man ein oder zwei (oder drei ...) Register hinter die> Operation und überlässt des den Tools, diese als Pipeline-Register in> die Arithmetik "hinein zu ziehen" (nennt sich Automatic Pipeline> Balancing oder Register Retiming). Früher war das ein Glücksspiel, aber> mittlerweile beherrschen das die aktuellen Tools erfreulich gut.
Wobei zu bemerken bleibt, daß Register Retiming in Quartus nur dann
stattfindet, wenn man's auch ein- (bzw. in neueren Quartus-Releases
nicht aus) schaltet.
Hallo zusammen,
vielen Dank für die Antworten. Inzwischen habe ich auch den Fehler
gefunden, und er könnte peinlicher/dümmer nicht sein. Das äußere Signal
i_section war falsch verdrahtet und somit waren die Werte natürlich
falsch. Dennoch habe ich was dazugelernt, vielen Dank für eure Mühe.
Die funktionsfähige Version läuft jetzt sogar ohne Register-Retiming und
mit den 200MHz. Die Integer-Signale waren schon auf den benötigten
Bereich (i_section: 0-40 und i_counts: 0-16383) eingegrenzt.
Wenn ich mir das Ergebnis der Synthese anschaue sehe ich auch den
lpm_mult eingebaut.
Das Vorgehen, dass man erstmal alles mit den constraints für 200MHz
angeht und nur im Notfall einem Signal länger zeit Gibt, ist so in
Ordnung oder eher unüblich?
@Markus F.
kann es sein, dass man in Quartus 16 Lite die Option zum
Register-Retiming nicht aktivieren/deaktivieren kann? Ich habe eine
Anleitung für die normale Version 13 gefunden, aber den dort
beschriebenen Ort nicht gefunden. Das Obermenü gibt es bei mir schon gar
nicht.
VHDL Newbie schrieb im Beitrag #6149283:
> @Markus F.> kann es sein, dass man in Quartus 16 Lite die Option zum> Register-Retiming nicht aktivieren/deaktivieren kann? Ich habe eine> Anleitung für die normale Version 13 gefunden, aber den dort> beschriebenen Ort nicht gefunden. Das Obermenü gibt es bei mir schon gar> nicht.
Quartus 16 weiß ich nicht. Ich kenne nur 13.0, 13.1 (weil das für
Cyclone II bzw. III die letzten unterstützten Versionen sind) und 18.1
(weil ich die für den MAX10 einsetze und mir die neue 19er LITE Version
nicht ganz geheuer ist).
Das Register Timing kann man bei den 13er Versionen in "Settings ->
Compilation Process Settings -> Physical Synthesis Optimizations" und
bei der 18er in "Settings -> Compiler Settings" aus- und einschalten.
Ich kann mir allerdings nicht viele (vernünftige) Gründe vorstellen, das
jemals ausschalten zu wollen...
VHDL Newbie schrieb im Beitrag #6149283:
> Das Vorgehen, dass man erstmal alles mit den constraints für 200MHz> angeht und nur im Notfall einem Signal länger zeit Gibt, ist so in> Ordnung oder eher unüblich?
Bei so etwas simplen ist das völlig normal und auch ok so.
Wenn du etwas Umfangereicheres baust, dann musst du dir vorher überlegen
welche Geschwidigkeit das wohl erreichen kann und wie du diese
erreichst.
Ansonsten hast du am Ende ein Design was das Timing nicht schafft, aber
durch die Architektur eventuell keinen einfachen Umbau erlaubt.
VHDL Newbie schrieb im Beitrag #6149283:
> Die Integer-Signale waren schon auf den benötigten> Bereich (i_section: 0-40 und i_counts: 0-16383) eingegrenzt.
Das ist auch eine wichtige Information, wenn du eine Einschätzung
erwartest was funktionieren kann und was nicht.
Eine Multiplikation von 6 Bit mal 327 ist halt VIEL schneller als 32 Bit
mal 327, also Integer ohne Beschränkung.