Guten Morgen,
hat jemand ein Beispiel - bei Google finde ich keins :'( - mit dem man
einen Multicycle-Path für einen kompletten std_logic_vector $A nach
std_logic_vector $B definiert?
Der Vector hat 1458Bit, weshalb jedes Bit einzeln definieren etwas sehr
unschön wäre.
Bei sowas befindet man sich aber gleich in Regionen, wo man kaum noch
Informationen findet.
Man könnte die schlechten Pfade nach der Timing-Analyze einzeln explizit
definieren, das ist aber ein seltsam aufwändiger Brute-Force-Ansatz und
nach dem Routen sind es ja eh wieder andere Pfade, die nicht passen.
Ich würde daher gerne den gesamten Vektor als Multicycle-Path
definieren.
Hat jemand eine Ahnung, wie das funktioniert?
Vielen Dank!
Mampf
Hmm, ob das Kommando, das Vivado generiert hat auch in Quartus
funktioniert? Vivado bietet da immerhin eine hübsche Gui dafür ...
set_multicycle_path -from [get_pins -hierarchical *state*] -to [get_pins
-hierarchical *mid*] 2
Martin O. schrieb:> Bei mir hat das geklappt:>> set_multicycle_path -from regB[*] -to sumAB[*] -setup 2> set_multicycle_path -from regB[*] -to sumAB[*] -hold 1
Vielen Dank! Das probier ich aus :)
Martin O. schrieb:> Ich find es immer total schwierig herauszubekommen wie man die> Signale> richtig spezifiziert.
Die Signal sucht man sich m.E. am besten im Timing-Report von TimeQuest
raus, kopiert sie von dort und "schmückt" sie anschließend im .sdc-File
mit den passenden tcl-Wildcards.
Also ich hab herausgefunden - falls ich keinen Fehler gemacht habe -
dass ich eigentlich multicycle-path gar nicht wollte ... Scheinbar hat
der Router dann versucht, alles andere auch zu verzögern, sodass es
wieder zusammen passt oder so ... Ganz seltsam.
Ich probier gerade set_max_delay aus, weil ich denke, dass das
eigentlich ist, was ich benötige.
Diese "mid"-register sind ziemlich statisch, weshalb er da das Timing
(fast) gar nicht berücksichtigen soll.
Auch beim setzen der Register hab ich einige Taktzyklen Zeit, weshalb
sich der Router mit dem Timing da nicht abmühen soll.
Bin mal gespannt, ob das timing-technisch was bringt.
Für state -> mid hab ich jetzt mal 15ns angegeben, für mid -> state 20
... Das sollte doch ausreichend sein :)
Ohne constraints hat der Timing-Report einen Setup-Slack von -5,3ns bei
5ns Clock gemeldet für state -> mid. Ich hätte das quasi ignorieren
können, da es eh funktioniert, aber ich denke, wenn der Router nicht
quasi durch sinnloses optimieren abgelenkt wird, könnte der Rest besser
werden.
Mampf F. schrieb:> Diese "mid"-register sind ziemlich statisch, weshalb er da das Timing> (fast) gar nicht berücksichtigen soll.>> Auch beim setzen der Register hab ich einige Taktzyklen Zeit, weshalb> sich der Router mit dem Timing da nicht abmühen soll.
Ich habe den leisen Verdacht, daß Du möglicherweise doch einen
Multicycle-Pfad haben wolltest und jetzt mit set_max_delay und
set_min_delay irgendwas asynchrones "hinzwirbeln" willst. Einfach
deswegen, weil set_min_delay und set_max_delay meist stumpf falsch ist.
Ohne Multicycles geht TimeQuest davon aus, daß die nächstgelegene
Taktflanke am Zielregister die ist, zu der die (kombinatorisch
ermittelten) Daten stabil abgreifbar sein müssen.
set_multicycle_path sagt "du brauchst dich nicht abmühen, mir reicht's,
wenn das Ergebnis da ist, wenn ich beim nächsten (oder übernächsten) Mal
vorbeikomme".
Das ist ein Versprechen.
Du mußt dann in deinem Design sicherstellen, daß das auch wahr ist (Du
am Zielregister tatsächlich auch erst frühestens zur "versprochenen"
Taktflanke mit den Daten etwas anstellst). Das wird wahrscheinlich nicht
ohne Designänderung funktionieren, wenn nicht z.B. sowieso schon
irgendwie ein "valid" Signal oder ein "Flankenzähler" vorhanden ist.
Wenn Du das aber gemacht hast, wird das Timing auf diesem
kombinatorischen Pfad unkritisch und der Fitter kann sich anderen
Engpässen widmen.
set_min_delay und set_max_delay ist eine Ebene drunter. Damit legst Du
das Fenster für die gewünschte "Signalankunft" praktisch willkürlich
(unabhängig von irgendwelchen Signalflanken rein über die Delays) fest.
Das kann richtig sein (wenn Du das Zeitfenster triffst, das
set_multicycle_path auch ausgewählt hätte, dann kannst Du aber auch
gleich - ohne potentielle Fehlerquelle - eben das nehmen), meist dürfte
es aber schlicht danebenliegen: die Timing-Analyse paßt (weil
"angelogen"), aber dein Design funktioniert trotzdem nicht.
Markus F. schrieb:> Ich habe den leisen Verdacht, daß Du möglicherweise doch einen> Multicycle-Pfad haben wolltest und jetzt mit set_max_delay und> set_min_delay irgendwas asynchrones "hinzwirbeln" willst. Einfach> deswegen, weil set_min_delay und set_max_delay meist stumpf falsch ist.
Ja ich glaub du hast recht ... Bei meinem ersten Versuch hatte ich
vergessen, den -hold Parameter zu setzen, weswegen er dann wohl Register
dupliziert hat.
Mit korrekt gesetztem Multipath halbiert sich der negative Setup-Slack
gleich auf die Hälfte und es funktioniert immer noch.
Vielen vielen Dank für deine anderen Erklärungen!
Mampf F. schrieb:> Mit korrekt gesetztem Multipath halbiert sich der negative Setup-Slack> gleich auf die Hälfte und es funktioniert immer noch.
Schön.
Ein negativer Setup-Slack ist allerdings immer falsch. Das bedeutet, daß
Du (zumindest aus Timing-Analyzer-Sicht) die Daten verwendest, bevor sie
da sind.
Weil das wohl eher unwahrscheinlich ist, wenn's trotzdem funktioniert,
stimmt mit deinen Constraints wahrscheinlich noch immer etwas nicht -
sie passen nicht zum Design.
Markus F. schrieb:> Weil das wohl eher unwahrscheinlich ist, wenn's trotzdem funktioniert,> stimmt mit deinen Constraints wahrscheinlich noch immer etwas nicht -> sie passen nicht zum Design.
Nein nein, der Clock ist einfach zu hoch xD
Aus Performance-Gründen overclocke ich das Design ganz erheblich, kurz
bevor es nicht mehr funktioniert :)
Irgendwann fängt es dann an Fehler (manchmal) zu produzieren, aber der
Geschwindigkeits-Gewinn trotz Fehlerkorrektur (d.h. nochmal rechnen
lassen) ist deutlich höher.
Da D. schrieb:> Bitte sag uns, dass es ein reines privates Hobbyprojekt ist! ;-)
Haha ja, natürlich xD
Sowas würde ich in dieser Form niemals verkaufen xD
Nur für den "internen Betrieb" gedacht :)
Mampf F. schrieb:> Irgendwann fängt es dann an Fehler (manchmal) zu produzieren, aber der> Geschwindigkeits-Gewinn trotz Fehlerkorrektur (d.h. nochmal rechnen> lassen) ist deutlich höher.
Wie stellst Du falsche Ergebnisse fest? Oder anders, wenn Du schon
weißt, was rauskommen muß, warum rechnest Du dann überhaupt?
Markus F. schrieb:> Mampf F. schrieb:>> Irgendwann fängt es dann an Fehler (manchmal) zu produzieren, aber der>> Geschwindigkeits-Gewinn trotz Fehlerkorrektur (d.h. nochmal rechnen>> lassen) ist deutlich höher.>> Wie stellst Du falsche Ergebnisse fest? Oder anders, wenn Du schon> weißt, was rauskommen muß, warum rechnest Du dann überhaupt?
Naja, man kann das Ergebnis leicht auf Korrektheit überprüfen - man
sucht quasi den Input, der ein korrektes Ergebnis erzeugt und das muss
man per Brute-Force machen, leider :)
So ähnlich wie Proof-of-Work bei Bitcoin.