Hallo zusammen, ich habe folgendes Problem: Ich habe in meinem Projekt ein recht timingkritisches Staduim erreicht. Die aktuelle Version läuft stabil und so wie es soll. Nun habe ich das Problem, dass ich beim einfügen einer simplen weiteren if oder case Abfrage Probleme bekomme und der FPGA nicht mehr so reagiert wie erwartet. Ich vermute es liegt am unterschiedlichen Placement der einzelnen Komponenten. Ich würde nun gerne das funktionierende Placement verwenden und als contraints einfügen. ISE soll im Place&Route Verfahren nur noch die Komponenten und Gatter neu routen, die dazu gekommen sind. Kann ich das bestehende Projekt vielleicht mit Hilfe einer Datei verwenden und die neu implementierten Sachen nur neu hinzufügen lassen, in der Hoffnung, dass die Timings weiterhin stimmen? Vielen Dank! Andi
incremental Place & Route - dazu finde ich im ISE 11.3 leider keinen Hinweis, was ist denn das? Ist das die Geschichte mit den Partitions, wie in XAPP918? Da kann ich ja nur komplette vhdl Dateien fest definieren, aber nicht einzelne Codepassage des Topfiles, oder? Danke! andi
Incremental P&R hat nichts mit partitionierung zu tun. Beim inc. P&R nimmt das P&R entweder das letzte oder ein anderes referenz design, analysiert die unterschiede und placed und routet nur noch die unterschiede. Also genau was du suchst. Xilinx nennt das guided P&R. Aber vorsicht! Ein design sollte auch ohne incr. P&R implementierbar sein. Da auch incr. P&R rgendwann versagt (zu große änderungen) und dann ist man sowieso gezwungen wieder ein P&R von scratch zu machen. Incr. P&R ist eher für die schnelle änderung gedacht.
>> Nun habe ich das Problem, dass ich beim einfügen einer simplen weiteren >> if oder case Abfrage Probleme bekomme das was du da vor dir hast ist kein µC. Ein scheinbar "simples" if kann große Folgen haben. Bsp : vergleiche mal einen 32bit Vektor auf (31 downto 0 => '0'). Bei 4er Luts macht das mal eben 4 (ggf. zusätzliche !) Logikebenen. Je nach Design und Taktanforderung kann das bereits zu viel sein. Wenn du dann vielleicht noch 2 Vektoren vergleichst die aus unterschiedlichen Teilen kommen... Kuck dir lieber mal den Teil mit der längster Verzögerung an und versuch dort zu optimieren. Davon würde ich mir mehr versprechen.
> Ich vermute .... Hmmm...., meinst du, das ist die richtige Vorgehensweise? > Ich habe in meinem Projekt ein recht timingkritisches Staduim erreicht. Welches FPGA? Wie hoch ist die Taktfrequenz? > Kuck dir lieber mal den Teil mit der längster Verzögerung an Und zwar einfach mit der statischen Timinganalyse. Evtl. kannst du im langsamsten Pfad über einen Takt Latency mit Register Aligning etwas erreichen.
Hast du überhaupt schon irgendwelche Placement-Constraints im UCF? Wenn
nicht, versuch doch mal, die Teile des kritischen Moduls zwangweise
zusammenzubringen. Ansonsten hat map zuviel Spielraum und verteilt dem
Kram zu sehr. Das Trauerspiel kann man im fpga_editor auch recht gut
sehen.
Also zB. im UCF mit
INST "modul1/modul2/*" LOC="SLICE_X10Y10:SLICE_X20Y20"
mal alles etwas zusammenquetschen. Das gibt dann auch eine Art
Kristallisationspunkt für den Rest. Mit ein ein paar von solchen groben
Hints kann man das Mapping/Routen auch beschleunigen.
Bei noch in Entwicklung befindlichem Code lohnt es sich IMO nicht, da
noch detailierter zu werden. Blockrams, DCMs, BUFGs und Multiplier/DSP
kann man machen, notfalls auch grössere Blöcke aus distributed RAM (das
aber eher per RLOC), aber das explizite Festlegen von einzelne FFs
schadet meistens mehr als dass es nutzt. Falls man mehrere Blöcke so
festlegt, sollte man übrigens etwas Überlappung einrechnen.
BTW: Es lohnt sich durchaus auch, an anderen Stellschrauben zu drehen.
Wenn du xst nutzt, bewirkt das Umstellen der Optimierung von Speed auf
Area (geht ja im xcf auch modulweise) manchmal erstaunliche Effekte.
BTW2: Nutzt du auch Timing-Constraints? Wenn du nicht gerade
irgendwelchen asynchronen Schweinerein gemacht hast, sollte dir die
statische Analyse eindeutig sagen, ob dein gewünschtes Timing erreicht
wird. Falls ja und es geht trotzdem nicht mehr -> asynchrone Schweinerei
;) Und so nebenbei sorgt die Angabe eines solchen Ziels auch dafür, dass
sich Mapper/Router überhaupt anstrengen. Der Unterschied kann da schon
>40% sein.
Hallo, genau für so etwas wurde das "Guided Design" entwickelt. Tom
Andreas B. schrieb: > Hallo zusammen, > > ich habe folgendes Problem: > Ich habe in meinem Projekt ein recht timingkritisches Staduim erreicht. > Die aktuelle Version läuft stabil und so wie es soll. > > Nun habe ich das Problem, dass ich beim einfügen einer simplen weiteren > if oder case Abfrage Probleme bekomme und der FPGA nicht mehr so > reagiert wie erwartet. > > Ich vermute es liegt am unterschiedlichen Placement der einzelnen > Komponenten. Wahrscheinlich nicht, IF kann mehrere Logikebenen (logic level:LUT's hintereinander) hinzufügen, dann wird das timing meist deutlich (einige nanosecs) schlechter. Ein ungünstiges Placement äußert sich eher in zusätzlichen verzögerungen kleiner eine Nanosec. wenn du xilinx benutzt: -Statische Timinganalyse (timingan.exe) und Analyse des implementierten Designs (fpga_editor.exe). -Sortieren der IF's nach Bedingungen die auf '0' '1' oder D setzten kann deutlich helfen: http://www.xilinx.com/support/documentation/white_papers/wp275.pdf Wenn klar ist, das durch das IF keine neue Logikebene eimgebaut wurde, kann man an den Optimierungsschaltern für Synthese, map und place+route drehen. Wenn das nicht hilft, gibt es ein Dutzend andere Optimierungsmöglichkeiten (z.B. FSM codierung unstellen). Manuelles Placement sollte einer der letzten Schritte sein. MfG,
Die Aussage am Anfang wundert mich halt:
> und der FPGA nicht mehr so reagiert wie erwartet.
Klingt so, als wüsste Andreas gar nicht, was und warum da sowas
passiert.
Entweder es gibt Timing-Constraints im ucf, dann würden die aber wohl
deutlich verletzt, das steht dann aber da und Andreas würde uns das
sagen und nicht obigen schwammigen Satz. Oder es gibt keine, dann ist
das ganze Gefummel mit Guided Design von vornherein die falsche Lösung.
Guided Design ist so ziemlich der letzte Notnagel und eigentlich nur zur
Verringerung der Routingzeiten gedacht. Wenn die synthetisierte Struktur
anders ist, hilft die Vorlage auch nicht mehr oder machts nur schlimmer.
Meine Erfahrungen bei Xilinx damit sind jedenfalls nicht sehr positiv.
Hallo, vielen Dank für die vielen hilfreichen Hinweise und Kritiken. Ich versuche mal alle Fragen zu beantworten: Verwendet wird ein Spartan 3A DSP (XC3SD1800A-4CSG484C). Die Taktfrequenz für den Dateneingang (lesen) liegt bei 160Mhz DDR und am Datenausgang (schreibend) bei 83Mhz SDR. Durch die hohe Taktfrequenz am Eingang habe ich selbstverständlich Timing constraints gesetzt und diese werden auch eingehalten. Dabei mußte ich meine Datenquelle mit einem konstanten Delay zwischen Takt und Daten beaufschlagen, was bisher wunderbar und stabil funktioniert hat. (siehe auch meinen Thread dazu: Beitrag "Data Path Delay zum IOB FF 5,8ns") Grob umschrieben mache ich folgendes: Ich habe serielle LVDS Daten von einem ADC auf 4 Kanälen. Diese Daten parallelisiere ich, sortiere sie zurecht und schiebe sie anschließend in ein Fifo (Schreib- und Lesetakt sind asynchron), von wo sie ausgelesen werden. Das hat bisher funktioniert. An einer weiteren Abfrage, welche Bits auf den Ausgangsbus gelegt werden, scheitert es nun. Abschließend möchte ich noch sagen, dass ich mir keinesfalls anmaße, keine Fehler zu machen und alles beachtet zu haben. Das ist 100%ig nicht der Fall... Ich wurde mehr oder weniger ins kalte Wasser geworfen und habe nun dieses Projekt vor mir, was für einen Anfänger sicher nicht der einfachste Einstieg ist. VHDL wurde im bisher absolvierten Studium eher stiefmütterlich behandelt. Ich freue mich deshalb über jede Kritik und jeden Hinweis zu meinen Gedanken und meinem Design. Die statische Timinganalyse werde ich mir mal anschauen, vielleicht kann ich daraus schon weitere Erkenntnisse gewinnen. Vielen Dank!
Andreas B. schrieb: > XC3SD1800A > 160Mhz DDR Das ist m.E. schon ganz schön sportlich. > An einer weiteren Abfrage, welche Bits auf den Ausgangsbus gelegt > werden, scheitert es nun. Soll das so'ne Art Vorverstärker werden? Welche Bits musst Du wie schnell selektieren? Wie oft verändert sich das (Selektions-)Bitmuster? An welcher Stelle im Datenpfad wählst Du aus, vorne bei 320MSamples oder hinten bei 83MSamples? Rick
Hallo, ich habe 4 Eingangskanäle mit LVDS. Daraus ergeben sich dann in der Parallelisierung 2x 16 bit mit ca. 40MHz. Ich habe pro Kanal je ein Fifo, was mit dem kompletten 16bit Wert gefüllt wird. Nach dem Fifo entscheide ich dann, welche Bits auf den Ausgang gelegt werden. Da ich einen 16bit breiten Ausgang habe, lege ich je 8bit von jedem Kanal/Fifo auf. Abhängig von einem Registerwert kann ich quasi aus den 16bit im Fifo 8bit auswählen. Das ist die einzige Entscheidung, die ich am Ausgang zu treffen habe. Es wird also mit den 83MHz getaktet. MfG Andi
Das mit den Kanälen, Bitbreiten und FIFOs ist immer noch etwas unklar. Hier mal eine kleine Skizze (nur ein Kanal), hab ich das so richtig verstanden?:
1 | +--------------+ +-------+ |
2 | | |--> 8 Bit -->| | |
3 | | 16bit FIFO | | DEMUX |--> 8 Bit --> Ausgang |
4 | | |--> 8 Bit -->| | |
5 | +--------------+ +-------+ |
Falls der Demultiplexer nur 2-1 ist, und damit das Timing zerschmeißt solltest Du noch ein Register dazwischenhängen. Falles es ein größerer Demultiplexer ist, würde ich ihn in kleinere 2-1 Demuxer teilen und ggf. mit Registerstufen pipelinen. Rick
Hier die Skizze: +--------------+ +-------+ | | | | | 16bit FIFO |--> 16 Bit -->| DEMUX |--> 8 Bit --> | | | | | | +--------------+ +-------+ | |--> 16 bit Ausgang +--------------+ +-------+ | | | | | | | 16bit FIFO |--> 16 Bit -->| DEMUX |--> 8 Bit --> | | | | | +--------------+ +-------+ So sollte es stimmen. Es werden also die kompletten 16bit aus dem Fifo gelesen, aber nur 8bit davon werden auf den Bus gelegt, die anderen bits werden verworfen. Die beiden ausgewählten 8bit ergeben dann zusammen den 16bit Ausgang. Ich hoffe es ist jetzt etwas besser erklärt? MfG Andi
Hast du denn für die Lese-Seite des FIFOs, also bei den 83MHz auch zumindest für den CLK ein Constraint gesetzt? Wird das eingehalten? Wenn ja, und es kommt Unsinn raus, wird es vielleicht eher eine Schweinerei am externen Bus sein.
Wenn die Schaltung zerfällt, obwohl die statischen Constrainst eingehalten werden, ist da was asynchrones drin, was du mit den jetzigen Constraints entweder nicht abdeckst oder es auch nur schwer abzudecken ist, weil externer Einfluss. Eine andere Möglichkeit (von Routingbugs mal abgesehen) gibt es eigentlich nicht. Ich hatte bei der Entwicklung von einem DDR-Controller (3S1600E mit 132MHz) auch so Effekte, dass laut Analyse alles OK war, es aber mit den Routing-Blindgängern immer schlimmer wurde. Im Endeffekt waren es dann mehrere Punkte, und seit deren Beseitung ist jedes Routing auch im realen FPGA ein Erfolg: 1) Trotz Constraints/Attributen im Code hat xst die DDR-FFs nicht immer(!) in die IOBs gepackt. Das traf nur die am Eingang. Der Skew vom IOB zum FF im Array hat halt dann je nach Routing das Datenauge total verzogen. Dringender Rat: Schau im fpga_editor nach, wie das verlegt ist und ob es das ist, was du dir vorgestellt hast. 2) Das Zusammenführen der um 180° versetzten IOB-DDR-FFs muss ja auf einen gemeinsamen Takt gehen, irgendwann muss man das DDR ja mal loswerden. Also müssen je zwei identisch getaktete FFs dahinter. Die sind per Constraint direkt in die Reihe neben den IOBs gezwungen, damit ist das Routing dann immer erfolgreich. Vorher war das Glückssache, map hat die sonstwohin plaziert und par konnte die halben Taktperioden für die N-FFs nicht einhalten. 3) Der Offset zum Einlesen wird über eine DCM mit variabler Phasenverschiebung und einer Trainingssequenz gemacht. Vermutlich bräuchte es die aber nicht, das Ergebnis fürs grösste Datenauge ist über diverse PCBs und Umweltbedingungen recht ähnlich. D.h. es würde vermutlich reichen, den Wert einmal zu bestimmen und dann hart zu kodieren. Alles andere (externe Verzögerung, interne mit geschalteten Buffern, etc.) sind IMO die Lizenz zum Selbstschuss ins Knie.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.