Forum: FPGA, VHDL & Co. Register Contraints setzen, damit Synthese klappt


von Michael W. (Gast)


Lesenswert?

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?

von daniel__m (Gast)


Lesenswert?

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

von Michael W. (Gast)


Lesenswert?

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.

von daniel__m (Gast)


Lesenswert?

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

von Ich (Gast)


Lesenswert?

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.

von Klakx (Gast)


Lesenswert?

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.

von Klakx (Gast)


Lesenswert?

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

von daniel__m (Gast)


Lesenswert?

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

von Michael W. (Gast)


Lesenswert?

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.

von daniel__m (Gast)


Lesenswert?

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).

von Fpgakuechle K. (Gast)


Lesenswert?

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,

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.