Ich habe ein Problem, Constrains zu definieren. ISE kapiert nicht, was
ich möchte. Vielleicht könnt ihr mir helfen:
Man hat mich beauftragt, eine alte Spartan 3E Schaltung (1500er) auf
einen neuen Stand zu bringen und das timing anzupassen. Leider kann der
FPGA nicht getauscht werden, weil schon viele Baugruppen in den Racks
der Kunden stecken. Nur die Software kann getauscht werden - update. Der
neue Prozessor greift schneller zu, daher hat man die Frequenz
hochgedreht und nun gibt es ein Lauzzeitproblem zwischen Lesetakt und
Schreibtakt, weil der FPGA intern seine eigene PLL macht und der
Prozessor auch.
Die Sache sieht so aus:
Oszillator -> ARM-PLL -> 80 MHz -> 20 MHz-Auflösung für das Bustiming
und 5 MHz Datenrate wegen 4 states.
Oszillator -> FPGA-PLL-> 40 MHz -> 10 MHz Datenschreiben in 2 states
Das Datenholen und Bereitstellen aus dem SRAM klappt, die 40MHz
funktionieren gut und ich kann alle 10MHz ein Datenwort liefern, aber
der Takt wackelt gegenüber dem Lesetakt des Prozessors. Eigentlich
sollten jeweils 50ns zur Verfügung stehen, doch wegen der gegenseitig
verschobenen Takte sind es zwischen 45 und 55ns wobei die 45 zu kurz
sind!
Deshalb kann ich es nicht mehr sampelten und habe das Registerinterface
mit dem Prozessortakt ans Laufen gebracht und arbeite intern asynchron:
Oszillator -> FPGA-PLL_1-> 80 MHz -> Register-Interface in 4 states
FPGA-PLL_2-> 40 MHz -> 10 MHz Datenschreiben ins FIFO
Das FIFO ist 4 Takte tief - ss wird nun in Phase 1 geschrieben und in
Phase 3 gelesen, also stehen +/-20ns zur Verfügung für
Taktverschiebungen.
Jetzt kommt aber das timing nicht mehr hin, weil die Synthese ständig
versucht, den Takt von intern 1 auf intern 2 zu matchen, womit wieder
ein Problem entsteht. Auch ein Erhöhen des internen Taktes 2 bringt
keine Verbesserung.
Ich muss irgendwie erreichen, dass die Synthese den Pfad von
FIFO-Eingang mit dem FPGA Takt und FIFO-Ausgang mit dem
Prozessorähnlichen Takt komplett ignoriert. Wie macht man das?
Laut UG kann man ein timing ignore auf die Register setzen, aber ich
weiss nicht wie. In der Netzliste heissen sie auch bei jedem Durchlauf
anders. Einmal hatte ich mit dem Contrains-Editor was festgelegt, dass
schon kurze Zeit später nicht mehr funktioninerte, weil die Signale
anders genannt wurden intern.
Wie wäre da die Strategie?? Und wie die richtige Syntax? Auf welche
Signalnamen soll man sich beziehen?
Hi,
irgendwie klingt das Ganze unnötig kompliziert. Wie läuft denn die
Kommunikation? Greift der ARM lediglich auf ein SRAM im FPGA zu? Dann
würde sich ein True Dual Port RAM anbieten. Ein Port arbeitet mit dem
ARM-Takt, der andere Port mit dem FPGA-Takt.
grüße
Nein, es muss auch noch etwas an Funktion passieren, weil der ARM bei
bestimmten Codes, Adressen und Daten besondere Funktionen auslöst.
Betnutzt wird ein manuells 4 WORT-RAM mit zwei Zählern im Abstand von im
Mittel = 2. Ein richtiges Fifo wäre mir auch zu groß. Zudem fehlt BRAM.
Im Prinzip ist es ja auch ein True Dual Port Fifo - brächte also
trotzdem Contraints.
hi,
für mich klingt das dann nach einem "normalen" Clock Domain Crossing. Da
der "duty cycle" der Daten bezogen auf den Takt recht gering ist, könnte
man hier evtl. sogar komplett auf ein FIFO verzichten. Ich habe ein
ähnliches Interface am laufen. Hier könnte man die Daten mittels
ARM-Takt im FPGA einlesen (wr Signal des FIFOs) und lediglich ein Flag
setzten (z.b. ein Toggle-Signal), dass neue Daten anliegen. Dieses Flag
wird mit dem FPGA-Takt gesampled und auf Änderung geprüft, welches dann
die weitere Verarbeitung auslöst.
Die Timing Constraints sind dann relativ einfach: Daten+Flag bekommen
ein MaxSkew = x, Flag bekommt MaxDelay = y, Daten bekommen ein MaxDelay
= y+n*FPGA-Periode-x. (n hängt von der Detaillösung des Flags ab).
grüße
Ich schrieb:> Hallo,> Ich komme zwar aus der Altera Ecke, aber dort macht man es mit set false> path. Mit set false path trennt man zwei unabhängige Clockdomains.
Das ist die richtige Antwort. Man muss die clocks auf Timing ignore
setzen. Dann optimiert die synthese auch nicht mehr dort.
Alle Übergänge brauchen dann aber saubere handshakes.
Und das Kommando für ise
Schau mal im Constraint Guide nach from to von ganzen Timing Gruppen auf
tig setzen
Erst erstellt man beide Timing Gruppen, dann setzt man from to in beide
Richtungen
Ich schrieb:> Mit set false path trennt man zwei unabhängige Clockdomains.
Bei Xilinx lautet es TIG. Jedoch bin ich sehr vorsichtig damit, da es
die Timingbehandlung auf dem Netz komplett abschaltet, was oft zuviel
ist. Vor allem bei CDC von Bussen mit Handshaking (zb. FIFOs) ist TIG
genau genommen falsch, da die Daten zueinander und zu den Handshaking
Flags in einer bestimmten Beziehung stehen müssen. Hier müssen die
Beziehungen manuell angegeben werden (siehe oben).
Im User Guide von Xilinx zu den FIFOs im asynchronen Betrieb (CDC) wird
z.b. auch MAXDELAYs auf bestimmte Netze erwähnt, die manuell in das
Constraint File eingetragen werden müssen. (FIFO Generator v9.2, Seite
153)
grüße
Das war auch meine Befürchtung, dass ein brutales TIG mir wieder andere
Probleme bereiten wird. Ich suche jetzt nochmals mal nach den Registern
im Wizzard. Wie schon angedeutet, habe ich öfters mal was "entspannt",
stieß jedochauf das Problem, dass sich die Namen ändern und die
Anweisungen ins Leere laufen.
M. W. schrieb:> dass sich die Namen ändern
Das passiert eigentlich nur, wenn das Signal ein implizites,
kombinatorisches Signal ist. Wenn das TIG auf ein Signalbeginn an einem
synchronem Element (FF, BRAM, DSP, ...) angewendet wird, sollte dieses
sich nicht ändern, da diese Signale eigentlich immer explizit sind (im
Code via Signal deklariert).
M. W. schrieb:> Jetzt kommt aber das timing nicht mehr hin, weil die Synthese ständig> versucht, den Takt von intern 1 auf intern 2 zu matchen, womit wieder> ein Problem entsteht. Auch ein Erhöhen des internen Taktes 2 bringt> keine Verbesserung.
Erzeuge die FIFO mit dem Core-generator, den fasst die Synthese nicht
mehr an. Core-generator sollte auch die passenden TIGS mit generieren.
Eventuell muss man noch eine Haken setzen bei Primitive nicht
optimieren.
Die passenden Namen kann man mit dem FPGA-editor ermitteln, dort in dem
Fensterrechts oben mit wildcards den Instance-name angeben bis nur das
gewünschte rot markiert wird.
beim Timing-analyzer ging es meines erachtens auch gut mal schnell ein
constraint hinzuschreiben und sich davon betroffenen Pfade anzeigen zu
lassen. Damit sollt man die passenden TIGS auch bei geänderten Namen gut
hinbekommen.
MfG,