Forum: FPGA, VHDL & Co. manuelles und automatisches Placement


von Andreas B. (loopy83)


Lesenswert?

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

von Ottmar (Gast)


Lesenswert?

Suche mal bei deinem P&R tool nach incremental P&R.

von Andreas B. (loopy83)


Lesenswert?

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

von Ottmar (Gast)


Lesenswert?

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.

von Iulius (Gast)


Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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

von Georg A. (Gast)


Lesenswert?

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.

von Thomas R. (Firma: abaxor engineering) (abaxor)


Lesenswert?

Hallo,

genau für so etwas wurde das "Guided Design" entwickelt.


Tom

von Fpgakuechle K. (Gast)


Lesenswert?

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,

von Georg A. (Gast)


Lesenswert?

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.

von Andreas B. (loopy83)


Lesenswert?

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!

von Rick Dangerus (Gast)


Lesenswert?

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

von Andreas B. (loopy83)


Lesenswert?

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

von Rick Dangerus (Gast)


Lesenswert?

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

von Andreas B. (loopy83)


Lesenswert?

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

von Christian R. (supachris)


Lesenswert?

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.

von Georg A. (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.