Hallo,
Ich bin grade dabei das erste mal bei einem größeren Design die Timing
Constraints einzugeben. Dabei hänge ich am Problem, dass ich nicht
finden kann wie ich den Ausgang des DCMs als Takt definiere.
Genauer: Ich gebe 50 MHz rein. Aus denen macht der DCM 60MHz und gibt
sie an einen SDRAM. Die weiteren Signale die an den SDRAM gehen sollten
natürlich die erforderlichen Timinganforderungen bezüglich des SDRAM
Taktes erfüllen.
Aber wie gebe ich das als Constraint an?
Kann ich sinnvoller den Taktausgang als Takt definieren zu dem die
Timingconstrains relativ sind?
Oder wäre es sinnvoller einen zweiten externen Oszillator mit 60MHz zu
verwenden und keinen DCM?
Kann ich irgendwie als Constraint angeben, dass eine Gruppe von Signalen
innerhalb einer anzugebenden Zeitspanne gleichzeitig sein soll? Z.B. die
Adresssignale haben Clock to Pad Zeiten die sich um mehr als eine ns
unterscheiden. Wo kommt das her? Routingdelay kann ich mir nicht so
vorstellen, da die Ausmaße eines FPGAs ja auch nicht so groß sind.
Viele Grüße,
Christian
edit:
P.S. bei googlen habe ich gefunden dass man angeblich mit "Create
elements associated by Nets" anschließend Timingconstraints zum DCM Takt
eingeben kann. Das kann ich aber nirgendwo finden.
Constraints für Takte, die über eine DCM manipuliert werden, werden von
der Toolchain automatisch umgerechnet. Wenn ich z.B. einen Takt mit 30
MHz habe und das als einzigen Constraint angebe, wird für einen von der
DCM z.B. vervierfachten Takt automatisch 120 MHz angesetzt.
> Oder wäre es sinnvoller einen zweiten externen Oszillator mit 60MHz zu> verwenden und keinen DCM?
Du solltest dir eher die Frage stellen, ob du 2 verschiedene Takte
brauchst. Mit dem ganzen Synchronisieren über Clockdomains hinweg...
Lass doch das RAM mit 50MHz laufen, oder den Rest der Schaltung mit 60.
Das macht dir das Leben wirklich einfach.
> Kann ich irgendwie als Constraint angeben, dass eine Gruppe von Signalen> innerhalb einer anzugebenden Zeitspanne gleichzeitig sein soll?
Nein:
Du kannst nicht angeben z.B. die Adressleitungen müssen
zwischen_5_und_8_ns nach dem Takt stabil sein.
Ja:
Du kannst nur bezogen auf die Taktflanke angeben, um wieviel spätestens
danach das letzte FF/der letzte Pin darauf reagiert haben muß.
Frühestens ist hier immer 0ns.
> Clock to Pad Zeiten die sich um mehr als eine ns> unterscheiden. Wo kommt das her? Routingdelay...
Wenn das Design richtig beschrieben ist, werden für alle getakteten
Ausgänge die FFs im IOB verwendet. Das ergibt den geringsten Skew
zwischen den Ausgängen. Wenn aber z.B. für 1 Leitung Kombinatorik am
Ausgnag beschrieben wird, darf das IOB-FF nicht verwendet werden, dann
kommt Routing mit dazu. Und 1 ns ist da durchaus drin...
Lothar Miller wrote:
> Constraints für Takte, die über eine DCM manipuliert werden, werden von> der Toolchain automatisch umgerechnet. Wenn ich z.B. einen Takt mit 30> MHz habe und das als einzigen Constraint angebe, wird für einen von der> DCM z.B. vervierfachten Takt automatisch 120 MHz angesetzt.>
OK, aber wie kann ich angeben, dass der Ausgang Spätestens 5 ns nach der
60MHz Flanke anliegt? Mit anderen Worten: Wie gebe ich an dass die Clock
To Pad Zeit sich auf die 60MHz bezieht und nicht auf die 50MHz? Oder
geht das auch automatisch? Oder meinst du das sogar?
>> Oder wäre es sinnvoller einen zweiten externen Oszillator mit 60MHz zu>> verwenden und keinen DCM?> Du solltest dir eher die Frage stellen, ob du 2 verschiedene Takte> brauchst. Mit dem ganzen Synchronisieren über Clockdomains hinweg...> Lass doch das RAM mit 50MHz laufen, oder den Rest der Schaltung mit 60.> Das macht dir das Leben wirklich einfach.
Ja brauche leider 2 Takte. Die es gibt ADC Eingänge die mit 50MHz
abgetastet werden. Die Daten sollen alle ohne Unterbrechung in den RAM
geschrieben werden. Und dann muss der nunmal schneller als mit 50MHz
laufen. Andere Möglichkeit wären überall 100MHz und die Eingänge werden
nur jedes 2. Mal abgefragt. Ich weiß aber nicht ob das die Sache für
mich wirklich einfacher macht. Ich meine 100MHz sind schwieriger zu
handhaben als 60.
Momentan habe ich auch das Problem, dass das Design nicht mal mit 60MHz
läuft. Ich habe den Fehler gemacht mich auf die Werte bei Synthesize zu
verlassen. Die waren nie unter 150MHz. Möglich sind nach Place and Route
nur noch etwas mehr als 20. Naja wenigstens was dazu gelernt.
Ich habe keine Ahnung wo der Flaschenhals im Design steckt. Gibt es da
ein Verfahren wie man das raus finden kann?
>>> Kann ich irgendwie als Constraint angeben, dass eine Gruppe von Signalen>> innerhalb einer anzugebenden Zeitspanne gleichzeitig sein soll?> Nein:> Du kannst nicht angeben z.B. die Adressleitungen müssen> zwischen_5_und_8_ns nach dem Takt stabil sein.> Ja:> Du kannst nur bezogen auf die Taktflanke angeben, um wieviel spätestens> danach das letzte FF/der letzte Pin darauf reagiert haben muß.> Frühestens ist hier immer 0ns.
Hm. Schade. Und was Zählt alles als Taktflanke? Nur Signale auf
Taktleitungen? Oder auch davon nur ein paar? Wenn es automatisch immer
um den Takt geht, der am entsprechenden FF anliegt, dann verstehe ich
nicht warum man das beim Constraint noch explizit angeben muss um
welchen Takt es geht.
>>> Clock to Pad Zeiten die sich um mehr als eine ns>> unterscheiden. Wo kommt das her? Routingdelay...> Wenn das Design richtig beschrieben ist, werden für alle getakteten> Ausgänge die FFs im IOB verwendet.
Da habe ich besonders drauf geachtet. Ich werde aber noch mal prüfen ob
sich irgendwo ein Fehler eingeschlichen hat.
Tristate Ausgänge sind hoffentlich kein Problem? Kommt es da durch den
Tristatebuffer zu einer zusätzlichen Verzögerung? Oder ist der immer
drin und bei Output einfach nie auf "Z" geschaltet?
> Das ergibt den geringsten Skew> zwischen den Ausgängen. Wenn aber z.B. für 1 Leitung Kombinatorik am> Ausgnag beschrieben wird, darf das IOB-FF nicht verwendet werden, dann> kommt Routing mit dazu. Und 1 ns ist da durchaus drin...
Ok, aber die Verzögerung kommt dann sicher doch nicht vom Routing
sondern von den Durchlaufzeiten durch die verschiedenen Gatter der
Kombinatorik?
> Möglich sind nach Place and Route nur noch etwas mehr als 20.
Das ist jetzt aber wirklich langsam. Knapp 50 ns zwischen 2 FFs, das
will gelernt sein. Da hast du Logik offenbar ungünstig beschrieben.
In der Statischen Timing-Analyse wird dir der kritische Pfad angezeigt,
und wieviele Logikebenen und Routing da drinhängt, dann kannst du
kontrollieren, ob du da etwas ungünstig beschrieben hast.
Evtl. sind das gar keine Timing-relevanten Pfade, die dir so eine
niedrige Taktfrequenz einbringen. Dann solltest du Multi-Cycle-Pfade
oder Pseudo-Pfade in den Constraints angeben.
Wenn du dir noch 1 Takt Latency erlauben kannst, dann klemme ganz hinten
noch ein Register an, und erlaube Register-Banalncing. Das kann dir die
Taktfrequenz gleich mal verdoppeln.
> Und was Zählt alles als Taktflanke?
Alles, was ein FF im FPGA taktet.
> Wenn es automatisch immer um den Takt geht, der am entsprechenden FF> anliegt, dann verstehe ich nicht warum man das beim Constraint noch> explizit angeben muss um welchen Takt es geht.
Richtig, die Tools sind da scheinbar noch etwas einfältig. Aber die
Regel ist die, dass ein Takt constrained wird, und damit alle Signale
die an diesem Takt hängen. Ein Constraint kann also nicht eigentlich auf
einem Signal sein. Höchstens über den Umweg, dass eine Gruppe nur mit
diesem Signal gebildet wird, und der Takt nur für diese (Einzel-)Gruppe
constrained wird.
> aber die Verzögerung kommt dann sicher doch nicht vom Routing> sondern von den Durchlaufzeiten durch die verschiedenen Gatter> der Kombinatorik?
Sieh dir die Statische Timing-Analyse an, da siehst du, dass das
Verhältnis der Laufzeit von Kombinatorik zu Verdrahtung etwa 50/50 ist.
Eine (1) Kombinatorikebene (1 Element = 1 LUT) ist immer gleich schnell,
dann kommt noch die Verdrahtung dazu. Wenn du aufwendigere Logik
beschreibst, dann können schon mal etliche Logikebenen
hintereinanderkommen und eine entsrechend aufwendige Verdrahtung
benötigen.
Lothar Miller wrote:
> In der Statischen Timing-Analyse wird dir der kritische Pfad angezeigt,> und wieviele Logikebenen und Routing da drinhängt, dann kannst du> kontrollieren, ob du da etwas ungünstig beschrieben hast.
Das ist ein guter Tipp, Danke.
Im Anhang befindet sich ein Stück aus dem Report. Ist das die richtige
Stelle an der angegeben ist was zu lange braucht?
> Evtl. sind das gar keine Timing-relevanten Pfade, die dir so eine> niedrige Taktfrequenz einbringen. Dann solltest du Multi-Cycle-Pfade> oder Pseudo-Pfade in den Constraints angeben.> Wenn du dir noch 1 Takt Latency erlauben kannst, dann klemme ganz hinten> noch ein Register an, und erlaube Register-Banalncing. Das kann dir die> Taktfrequenz gleich mal verdoppeln.
OK. Ich habe ein paar Vergleicher drin. Die brauchen ja enorm viel Logik
Zuerst dachte ich die muss ich auf jeden Fall pipelinen, aber es sah so
aus als ob das in einer FPGA irgendwie effizienter realisiert werden
kann. Was ist richtig?
>>> Und was Zählt alles als Taktflanke?> Alles, was ein FF im FPGA taktet.
OK, ich meinte ehr, was man als Taktquelle angeben kann. Schon ein wenig
irritierend, wenn automatisch der zutreffende Takt verwendet wird.
> Sieh dir die Statische Timing-Analyse an, da siehst du, dass das> Verhältnis der Laufzeit von Kombinatorik zu Verdrahtung etwa 50/50 ist.> Eine (1) Kombinatorikebene (1 Element = 1 LUT) ist immer gleich schnell,> dann kommt noch die Verdrahtung dazu. Wenn du aufwendigere Logik> beschreibst, dann können schon mal etliche Logikebenen> hintereinanderkommen und eine entsrechend aufwendige Verdrahtung> benötigen.
OK.
Was mich momentan am meisten irritiert ist, dass die einzelnen Module
die ich instantiiere mit ca 100MHz laut Place and Route laufen. Wenn ich
aber in einem großen Projekt alle Module instantiiere erhalte ich
Meldungen dass schon innerhalb einer Instanz die Verzögerungen zu groß
sind. Woran liegt das? Besonders voll ist die FPGA auch nicht. FFs: 9%
Slices 18%
Christian H. wrote:
> OK. Ich habe ein paar Vergleicher drin. Die brauchen ja enorm viel Logik> Zuerst dachte ich die muss ich auf jeden Fall pipelinen, aber es sah so> aus als ob das in einer FPGA irgendwie effizienter realisiert werden> kann. Was ist richtig?
Naja, ich hab hier einige 16-Bit Vergleicher laufen, die mit 80MHz gehn.
Laut P&R sogar bis knapp 100MHz in einem Spartan 3e. Hab sie allerdings
über den CoreGen erzeugt, da sind sie schneller. Außerdem alles in
pipelining, so wenig wie möglich Kombinatorik zwischen 2 Registern. Dann
klappts.
16 Bit ist eine Menge. Wie viele Stufen hat die Pipeline denn?
Der Vergleicher ist im RTL Schematic ein Symbol dessen Inhalt sich nicht
anzeigen lässt. Ich vermute daher, dass es auch eine Instanz einer Art
Core ist. Mir fällt grade auf, dass ich mich nicht geschickt ausgedrückt
habe, ich meine einen Vergleicher "<=" und nicht "=".
Allerdings glaube ich auch nicht, dass der Vergleicher die Ursache ist.
Die einzelnen Teile laufen ja schneller als sie müssten.
So weit ich es erkennen kann entstehen die Probleme an Stellen, an denen
die Signale von einer Taktfrequenz zur anderen gehen.
Es sind "langsame" Signale die eigentlich einige 100 ns Zeit haben sich
zu stabilisieren bevor sie verwendet werden. Daher habe ich auch auf der
Empfängerseite kein weiteres FF vorgesehen, dass das asynchrone Signal
eintaktet. Es ist auch so, dass sich die Werte im Betrieb nicht ändern.
Wenn es aber sinnvoll ist werde ich das noch ändern. Was meint ihr?
Ich habe versucht ein Constraint anzulegen, das festlegt, dass diese
Konfiguration-FFs nicht kritisch sind, aber ich habe wohl etwas falsch
gemacht. Es werden immer noch die gleichen Pfade bemängelt.
Meine Constraints sehen so aus:
1
...
2
NET "T_source<2>" TNM_NET = "Config_Regs"; #Register in denen Konfiguration gespeichert ist
3
NET "T_source<3>" TNM_NET = "Config_Regs"; #Register in denen Konfiguration gespeichert ist
4
NET "Autotrigger_Enable" TNM_NET = "Config_Regs"; #Register in denen Konfiguration gespeichert ist
5
TIMESPEC "TS_neu" = FROM "Config_Regs" TO "FFS" 200 ns;
Wie müsste es richtig aussehen?
Oder ist hier auch der Fehler, dass nicht direkt auf das 60MHz FF ein
50MHz FF folgt?
Christian H. wrote:
> 16 Bit ist eine Menge. Wie viele Stufen hat die Pipeline denn?
Meine ganze Pipeline hat 6 Stufen, aber da ist noch mehr drin:
Gleichrichtung (also ein Volladdierer), Umschaltung zwischen 1/2
Wege-Gleichrichtung, eben der Vergleicher, noch ein Umschalter zwischen
gespeichertem und aktuellem Wert usw. Der Vergleicher ist halt aus dem
Coregen, direkt für den Spartan 3e erzeugt. Bei sonst gleicher Schaltung
sagt ISE 100MHz statt 80Mhz beim COMP16 aus dem Schaltplan-Editor für
diese Pfade. Der 16er Komparator aus dem Schematic hat einige
Logikstufen, kein Wunder. Kann man mit Push into Symbol sogar anschauen.
Ein Übergang zwischen zwei Takten kann nicht constrained werden. Ich
kann zwar für den einen Takt eine Zykluszeit angeben und auch für den
anderen. Aber die Grenze zwischen den Taktdomänen muss händisch
abgehandelt und synchronisiert werden.
Angenommen wir hätten 10 ns und 8ns Zykluszeit. Zum Zeitpunkt A kämen
beide Takte gleichzeitig. Das nächste Mal kommt der 8ns ein wenig
früher, usf. Bis zum Zeitpunkt B (nach 4 bzw. 5 Takten) wieder einer
gleichzeitig kommt.
1
Zeitp. A B
2
100MHz | | | | | | |
3
125MHz | | | | | | | | |
Es macht daher keinen Sinn (und ist auch nicht möglich) Signale einer
Taktdomäne auf den Takt der anderen zu beziehen.
> Es ist auch so, dass sich die Werte im Betrieb nicht ändern.> Wenn es aber sinnvoll ist werde ich das noch ändern. Was meint ihr?
Nicht nötig, das sind klassische False Paths. Du schreibst z.B.
Konfigurationsdaten. Und erst nachdem die geschrieben sind, wird ein
Start-Flag gesetzt, anhand dessen z.B. eine SM auf diese
Konfigurationsdaten zugreift. Pseudo-Pfade (False Paths) werden mit TIG
(Timing IGnore) von den Timing constraints ausgenommen.
1
TIMESPEC "TS_pseudopfade" = FROM "Config_Regs" TO "FFS" TIG;
Warum lässt du nicht den RAM mit 100MHz synchron zum 50MHz-ADC Takt
laufen und erzeugst bei jedem Daten abholen vom ADC einen Schreibimpuls?
Ist doch synchroner RAM, da musst du doch nur einen Impuls mit 1
RAM-Takt Länge erzeugen um was zu schreiben. Das würde die Sache
wesentlich vereinfachen.
Lothar Miller wrote:
> Es macht daher keinen Sinn (und ist auch nicht möglich) Signale einer> Taktdomäne auf den Takt der anderen zu beziehen.
Eigentlich anschaulich klar. Ich verstehe aber nicht warum die Analyse
einen Fehler liefert (bzw nur einen sehr kleinen möglichen Takt), wenn
ich nicht einstelle, dass die Timings zu ignorieren sind.
>> Es ist auch so, dass sich die Werte im Betrieb nicht ändern.>> Wenn es aber sinnvoll ist werde ich das noch ändern. Was meint ihr?> Nicht nötig, das sind klassische False Paths. Du schreibst z.B.> Konfigurationsdaten. Und erst nachdem die geschrieben sind, wird ein> Start-Flag gesetzt, anhand dessen z.B. eine SM auf diese> Konfigurationsdaten zugreift.
Ganz genau so habe ich es auch umgesetzt. Vielleicht sollte ich noch
nach dem setzen der werte ein paar Taktzyklen Pause einbauen um sicher
zu gehen, dass sich auch alles stabilisiert hat, wenn einmal drauf
zugegriffen wird. Andererseits hat man durch das Start-Flag ja
mindestens einen Zyklus Pause.
> Pseudo-Pfade (False Paths) werden mit TIG> (Timing IGnore) von den Timing constraints ausgenommen.>
1
> TIMESPEC "TS_pseudopfade" = FROM "Config_Regs" TO "FFS" TIG;
2
>
OK, ich hatte jetzt selbst ein wenig rumprobiert und statt TIG 200ns
eingegeben. Damit komme ich auf 114 MHz. Das reicht ja.
An einer anderen Stelle habe ich das Problem, dass sich das Signal doch
ändert. Es ist kein Config Wert sondern eine Art Ready-Signal. Ich meine
aber, dass ich das Design so konzipiert habe, dass das Signal erst viele
Takte später Valide sein muss. Also sollte das eigentlich auch kein
Problem sein (hier habe ich auch ein FF zum eintakten verwendet.) Aber
da muss ich mich nochmal rein denken.
@Christian R.:
Es handelt sich ja um SDRAM und da muss ich irgendwo die refreshes
unterbringen. Mit 100MHz könnte ich es trotzdem laufen lassen, was das
Design vereinfachen würde. In einem anderem Thread im Forum hat man mir
aber dazu geraten ehr kleinere Frequenzen zu verwenden, da das auf dem
PCB einfacher ist. Daher nehme ich 60 und nicht 100.
Andere Frage:
Was muss ich eigentlich beim vergeben der Pins beachten? Ich wollte die
Pins so vergeben, dass ich möglichst wenige Überkreuzungen zwischen den
Chips habe.
Ist das richtig: Die Zuordnung zu einer Bank im FPGA sagt nur dass alle
die gleiche I/O-Spannung verwenden? Muss ich bei Taktnetzen etwas
beachten? Ich meine die Clock-Regions und Local Clocks.
Christian H. wrote:
> @Christian R.:> Es handelt sich ja um SDRAM und da muss ich irgendwo die refreshes> unterbringen. Mit 100MHz könnte ich es trotzdem laufen lassen, was das> Design vereinfachen würde. In einem anderem Thread im Forum hat man mir> aber dazu geraten ehr kleinere Frequenzen zu verwenden, da das auf dem> PCB einfacher ist. Daher nehme ich 60 und nicht 100.
Das macht doch der SDRAM Controller IP-Core ;)
Christian R. wrote:
> Das macht doch der SDRAM Controller IP-Core ;)
Nagut, wäre eine Möglichkeit gewesen. Ich habe jetzt einen eigenen
Controller beschrieben.
Welchen Controller hättest du genommen? Von Open Cores? Xilinx bietet
für SDRAM ja nichts mehr an...