Hallo!
Im Beispiel unten wird ein Zeitstempel fuer die Zeit, die zwischen vier
low/high Wechseln von (i_signal_sync) vergeht, ermittelt, durch vier
geteilt (untere zwei Bits von r_timersum verworfen), und letztlich an
ein FIFO weitergegeben (o_timerout, o_newdata). Nachdem ich den 10-Bit
timer in einen 4-bit und einen 6-bit Timer aufgeteilt habe (warum macht
Xilinx ISE dies eigentlich nicht selber im Fall der Faelle?!), lief das
Design das erste Mal ohne violation der (von der DCM Routine automatisch
erstellten) timing constraints durch (worst slack +0.1ns).
Als ich nun jedoch noch die Overflow-Kondition (r_overflow) mit
eingebaut habe, findet selbst SmartXplorer keine Strategie mehr, um das
Ganze bei 250 MHz noch ohne Violation unterzubringen (worst slack -0.2ns
fuer timersum2 oder timerout). Wenn ich das richtig verstehe, bedeutet
das aber doch lediglich, dass timerout nicht direkt zum naechsten
clk_250 Zyklus korrekte Daten enthaelt, oder?
Tatsaechlich uebernehme ich den Timerstand ja schon direkt nach dem
vierten low/high Wechsel von i_signal, aber das newdata Signal, was
letztlich zum Export ins FIFO fuehrt, wird ja erst beim darauffolgenden
low/high Wechsel gesetzt (zu dem Zeitpunkt liegen dann sowohl Timerstand
und newdata Signal fuer die gesamte Zeit bis zum wiederum naechsten
low/high Wechsel an). Das FIFO ist mit 50 MHz getaktet, und sowohl
newdata als auch timerout werden noch ueber ein FF von der 250MHz in die
50MHz Domaene ueberfuehrt, obwohl das wegen DCM vielleicht noch nicht
einmal noetig gewesen waere.
i_signal ist ein externes Signal und kann sich vielleicht maximal alle
40ns einen low/high Wechsel aufweisen, bin ich damit auf der sicheren
Seite, auch wenn das Design diese Timing-Violation zeigt?
Danke, Lothar, für den Begriff der Multi Cycle Constraints. Kannte ich
so gar nicht, dass diese FROM TO Felder für diesen Zweck sind! Das
scheint ja exakt zu beschreiben, was ich meinte damit, dass diese zwei
Signale ja gar nicht im nächsen Cycle, sondern erst deutlich später
gültig sein müssen. Viele Infos habe ich dazu jetzt nicht auf die
Schnelle gefunden, ausser einem ellenlangen Guide über Constraints
generell, und beispielsweise diese Xilinx Answer
https://www.xilinx.com/support/answers/9416.html
Also die Paths muss ich alle einzeln identifizieren, und dann selber
überlegen, nach wie vielen Clock Cycles das Signal frühestens gültig
ist? Die Xilinx Tools können nicht erkennen, dass wie im oben genannten
Beispiel ja aufgrund der
aufeinanderfolgenden Zuweisung von timerout und newdata,
der alleinigen Verwendung beider Signale gemeinsam,
und dem ausschließlichen Auftauchen der Signale in den entsprechend
getakteten Prozessen,
sowieso bereits mindestens X cycles 'ins Land gehen' bevor die Signale
verwendet werden? Oder hätte das erkannt werden sollen, und ich hab in
meinem Code möglicherweise noch irgendwo irgendeine "Leiche", die ohne
dass ich das direkt sehe doch bereits ein gültiges Signal im nächsten
Clock cycle erwartet?
Besten Dank schonmal!
Weltbester FPGA-Pongo schrieb im Beitrag #5557309:
> Was soll das denn bitte bewirken?
Die Idee ist, wenn irgendwann zwischen dem 1. Und 4. Signalwechsel
low/high der Timer überlauft, diesen overflow festzuhalten und statt
einer falschen Zeit eben diesen Überlauf (0) auszugeben. Der zeitstempel
0 ist real nicht möglich, eine doppelbelegung dieses Ausgabewertes ist
deshalb hier unkritisch.
Die Schreibweise, r_name für alles, was ein register bewirken wird,
w_name für direkte Verbindungen, und i_name und o_name lediglich für
echte inputs und outputs zu benutzen, habe ich vermutlich zu Beginn in
einem vhdl Lehrbuch so gesehen und seitdem so verwendet. Ich fand, es
kann helfen, z. B. Bei allen r_ daran zu denken, in jedem möglichen
case einen entsprechenden Wert zuzuweisen und ungewollte latches zu
verhindern.
Würde ich die von dir zitierte Zeile einfach weglassen, wäre doch
overflow nur direkt nach jedem timer2 Überlauf für 15 Timer cycles
gesetzt, und danach nicht mehr? Sicher gibt es da andere Möglichkeiten,
das umzusetzen. Aber dies schien seinen Zweck perfekt zu erfüllen.
Viele Grüße!
ppuls schrieb:> Also die Paths muss ich alle einzeln identifizieren, und dann selber> überlegen, nach wie vielen Clock Cycles das Signal frühestens gültig> ist?
Ja. Habe bisher kein Tool angetroffen, dass so etwas selbständig
erkennt.
Immerhin darfst du bei den meisten Tools in den From/To Feldern Wildcard
Symbole (*/?) nutzen um gleich ganze Busse oder mehrere Instanzen
abzudecken.
ppuls schrieb:> Also die Paths muss ich alle einzeln identifizieren, und dann selber> überlegen, nach wie vielen Clock Cycles das Signal frühestens gültig> ist? Die Xilinx Tools können nicht erkennen, dass wie im oben genannten> Beispiel ja aufgrund der>> aufeinanderfolgenden Zuweisung von timerout und newdata,> der alleinigen Verwendung beider Signale gemeinsam,> und dem ausschließlichen Auftauchen der Signale in den entsprechend> getakteten Prozessen,
Naja, du hast doch die Zeilen geschrieben, also musste auch wissen was
du damit erreichen willst.
Und eigentlich analysiert man nicht den code nachher, sondern überlegt
sich vorher, in welchem Takt die signale gültig sein sollten und
schreibt den code entsprechend.Also erst ein timing
Diagramm,Ablaufdiagramm zeichnen und dann coden. Die entscheidung, was
du überhaupt haben willst, können dir die tools nicht abnehmen.
Das ist eben einen Unterschied zur C-Programmierung, wo man die
zeitlichen Abläufe komplett dem Compiler/runtime-environment überlässt
und drauf hofft das compiler schon selber optimiert.
Du musst halt ein Gefühl für "chiplevel" entwickeln: wieviel Logik/LUT's
werden zwischen 2 FF's geklemmt und felche maximale taktfrequenz
resultiert daraus. Wenns zu langsam ist, kann man immer noch Pipeline-FF
einbauen und manchmal schubsen die tools die FF auch so das die optimale
Taktfrequenz realisiert wird ("register balancing")
Zeigefinger schrieb:>> Also die Paths muss ich alle einzeln identifizieren, und dann selber>> überlegen, nach wie vielen Clock Cycles das Signal frühestens gültig>> ist?
Natürlich.
Und dein Code sollte natürlich dazu passen - wenn Du einen
Multicycle-Pfad im Design definierst und nachher trotzdem zu früh
ungültige Daten abholst, ist das dein Fehler - nicht der der Tools.
Der Multicycle-Pfad macht nur für die Timing-Analyse das Timing-Fenster
breiter. Ob dein Design das hergibt, musst Du selber wissen ...
Vielen Dank fuer eure Antworten! Damit habe ich jetzt auf jeden Fall
verstanden, was an dieser Stelle von mir gefordert ist. Vielleicht muss
ich da nachher noch einmal laenger drueber gruebeln, aber ganz klar ist
mir noch nicht, wieso ich das fuer interne Signale ...
> Natürlich
... selbst ueberlegen muss. Ich meine, klar, wenn ich so ein schnelles
Signal einfach hart auf irgendeinen Ausgangspin lege, und die IDE dann
natuerlich keine Ahnung hat, was fuer Timing Anforderungen die externe
Peripherie hat, logisch dass ich das selbst formulieren muss. Aber
intern, wenn ich doch keine andere Zeile VHDL geschrieben habe, die
irgendetwas beschreibt, was sich dieses Signal jemals frueher als "drei
Takte spaeter" ansehen kann, wieso sollte sich das nicht automatisch
herausfinden lassen?
Nur als Beispiel, fuer welchen Fall ich vor kurzem an anderere Stelle
als Laie eine "Entspannung der Timings" erwartet haette (die wegen des
nicht definierten Multi Path dann wohl nicht eingetreteten ist): Anstatt
in einem State alle Counter zu aktualiseren, und das entsprechende
"valid" Signal im selben State zu setzen (das nun letztlich anderen
Prozessen sagt, diese Counter zu "lesen"), habe ich das Setzen des valid
Signals erst im Folgetakt erledigt, zusammen mit den "festgehaltenen"
Counterwerten des vorigen Taktes. Das war fuer mich an dieser Stelle
logisch, dass das direkt beruecksichtigt wird: Keins der Zeahlerstaende
ist nach extern geroutet, und keins der internen Beschreibungen "liest"
sie bis zum naechsten State.
Wie auch immer, ich glaube ich werde mir ein genaues Timingdiagramm, so
wie ich es geplant habe, entwerfen, dann ueberpruefen, ob es mit meiner
Beschreibung zusammen passt, und als letztes an all den Stellen, wo
solche gewollten Multi Clk Pathes "entstanden" sind, die Constraints
entsprechend aendern. Wahrscheinlich fuehrt das letztlich noch zu einer
viel hoehreren maximal errechneten Taktfrequenz (wobei ich nun nach
einigen kleinen Aenderungen an anderer Stelle auch gerade eben knapp
"positiv" durch die Timing Ueberpruefung schramme, ohne irgendwelche
Multi Path Definitionen).
Besten Dank nochmal!