Hallo zusammen, ich habe für einen Altera Cyclone V folgendes Constraint vorgegeben: set_max_delay -from [get_ports {PORTNAMEN}] -to [get_registers *] 5.000 Die Ports sind asynchron zum internen Takt. Mit diesem Constraint sollte doch vorgegeben sein, dass das Signal vom Port bis zum ersten Register maximal 5ns dauern darf. Quartus könnte die Register der IO-Cell verwenden und damit dieses Constraint einhalten. Stattdessen platziert es die Register mitten in den Chip und reportet, dass das Constraint nicht gehalten wird. Wie kann ich den Fitter dazu bewegen, die Register der IO-Cell zu verwenden? (außer manuelles Platzieren)
Ich mache es jeweils so, dass ich entsprechende Register in separate Entities isoliere und dann mit folgenden Attributes arbeite: In:
1 | attribute altera_attribute : string; |
2 | attribute altera_attribute of InxD : signal is "-name FAST_INPUT_REGISTER ON"; |
Out:
1 | attribute altera_attribute : string; |
2 | attribute altera_attribute of OutxD : signal is "-name FAST_OUTPUT_REGISTER ON"; |
Natürlich darf zwischen dem Pad und dem Register keine Logik sein...
Das ging doch mit dem Constraint Editor selber per "Fast Output", bzw "Fast Output Enable" Register, wenn es ein Buffer war.
Thomas U. schrieb: > Das ging doch mit dem Constraint Editor selber per "Fast Output", bzw > "Fast Output Enable" Register, wenn es ein Buffer war. Natürlich kannst Du das auch mit dem Constraint Editor machen. Ich finde es einfach bequemer, wenn ich das entsprechende Register einfach per Entity im Design drin habe, ohne mich dann noch kümmern zu müssen wie der Pfad nun im Detail heisst und wo ich wieder was im GUI-Klicki-Bunti setzen muss.
Hallo! Vielen Dank! Der Hinweis hat mich auf die richtige Fährte gebracht. Habe im QSF-File FAST_INPUT_REGISTER auf ON gestellt und nun sind die Register da, wo sie sein sollten. Aber mal ehrlich: Der Fitter ist ja schon ein bisschen doof, oder? Wenn ich ihm eine maximale Zeit vorgebe, dann würde ich erwarten, dass er weiss, dass der Chip IO-Register hat und dann von selbst auf die Idee kommt, diese zu verwenden.
Mäxle Delay schrieb: > Aber mal ehrlich: Der Fitter ist ja schon ein bisschen doof, oder? > Wenn ich ihm eine maximale Zeit vorgebe, dann würde ich erwarten, dass > er weiss, dass der Chip IO-Register hat und dann von selbst auf die Idee > kommt, diese zu verwenden. Doof ja, er arbeitet ja nur "mechanisch". Aber IO-Zellen kennt er schon und nutzt sie auch. Es muss also an Deiner HDL-Beschreibung liegen. Stell sie doch mal hier rein, evtl. auf's notwendige gekürzt. Dann kann man Dir erkären, woran es lag. Meine Vermutung: eine oder mehrere Register werden noch durch Logik angesteuert. Ob er dann aber den Versuch komplett abbricht, keine Ahnung?
Es sind wirklich nur ganz einfache Sample-Register ohne jegliche Logik drumrum. Selbst der Reset ist asynchron, da hier bei einer Setup-Violation nichts passieren kann. Primitiver geht es eigentlich gar nicht. Hier mal der vereinfachte Code: addr_x ist das Register, addr ist der Eingang
1 | process(clk50, reset) |
2 | begin
|
3 | if reset = '0' then |
4 | addr_x <= (others => '0'); |
5 | ....
|
6 | elsif rising_edge(clk50) then |
7 | addr_x <= addr; |
8 | ...
|
9 | end if; |
10 | end process; |
Ich habe leider schon öfter die Erfahrung gemacht, dass der Fitter von Altera nicht gerade mit Intelligenz gesegnet ist. Er hat mir schon einmal nen Pfad von einem Pin zu einem Register kreuz und quer über den gesamten Chip geroutet.
Mäxle Delay schrieb: > Selbst der Reset ist asynchron,.. Also direkt vom Pin getrieben? Aber in Deinem Code wird Reset mit '0' verglichen, d.h. da hast Du erstens schon mal Logik. Und dann musst Du verstehen, dass dieses Reset-Signal ja für alle addr_x-Register verwendet wird. Das ganze ist also nur innerhalb des FPGA synthbar.
Sigi schrieb: > Also direkt vom Pin getrieben? More or less.. Ne Kombinatorik aus LOCK der PLL und externem Pin. Sigi schrieb: > Aber in Deinem Code wird Reset mit '0' > verglichen, d.h. da hast Du erstens schon > mal Logik. Im Code ja, aber letztendlich wird einfach nur der asynchrone Reset des Registers mit dem Reset-Signal verdrahtet. Also keine Logik Sigi schrieb: > Und dann musst Du verstehen, > dass dieses Reset-Signal ja für alle > addr_x-Register verwendet wird. Genau so ist es ja auch gewünscht. Für jede Adressleitung ein Register, dessen ASYNC-Eingang mit dem Reset-Signal beaufschlagt wird. Sigi schrieb: > Das ganze > ist also nur innerhalb des FPGA synthbar. Da soll es ja auch hin ;-) Zusammegefasst kann ich sagen: Durch Aktivieren von FAST_INPUT_REGISTER macht der Fitter genau das, was ich von ihm erwartet habe. Er baut in der FPGA-Fabric einen kombinatorischen, asynchronen Reset und führt diesen an den RST-Eingang der Register in den IO-Cells. An die D-Eingänge der Register wird dann das jweilige Pad angeschlossen. Der Chip "kann" also, was ich will. Nur der Fitter ist zu doof, trotz knappem Constraining des Pfades zwischen Pad und Register von selbst auf die Idee zu kommen, das IO-Register zu benutzen.
Ich glaube, der Altera Fitter ist wirklich doof, oder was mache ich falsch? Folgender concurrend Code (Teil eines asnychronen Bus-Interface):
1 | -- Tristate the Output-Pin
|
2 | data <= rd_data_q when (OEn = '0' and CSn = '0') else |
3 | (OTHERS => 'Z'); |
Der virtuelle Takt für die externen Signale beträgt 200 Mhz und für den Pfad ist ein Multicycle von 3 constrained. SDC: create_clock -name virtual_clk -period 5 set_multicycle_path -from [get_ports {OEn CSn}] -to [get_ports {data*}] 3 Der Pfad dürfte also maximal 15ns lang sein (3 * 5ns) Die Logik kann in einer LUT abgevespert werden und die Pins liegen räumlich nahe beieinander. Sollte also locker zu schaffen sein. Das Ergebnis ist allerdings haarsträubend: Fast 30ns werden für diesen lächerlichen Pfad benötigt. Die Betrachtung im Chip-Planner ergibt, dass in der Tat auch nur eine LUT herangezogen wird und der Rest für´s Routing drauf geht. Mit der Option "Show Routing" im Chip Planner wird dann das Drama sichtbar. Das Signal wird kreuz und quer über den gesamten Chip hin und her geroutet. Die Zeitvorgabe von 15ns ist eigentlich relativ relaxed und sollte gut zu schaffen sein. Aber der Fitter/Router zieht es vor, das Signal wild über den ganzen Chip zu Routen und dann eine Setup-Violation zu melden. Hat jemand von euch sowas auch schon mal beobachtet?
Das liegt daran, dass du kein Multicycle für die Hold-Beziehung angegeben hast. Dadurch hat der Fitter absichtlich lange Routing delays eingefügt, um das Hold-Timing zu schaffen. Bei set_multi_cycle kann man mit -hold und -setup angeben, ob man den Wert für die Setup oder Hold-Beziehung angeben möchte. Wenn man nichts angibt ist es automatisch Setup. Versuch mal folgendes:
1 | set_multicycle_path -setup -from [get_ports {OEn CSn}] -to [get_ports {data*}] 3 |
2 | set_multicycle_path -hold -from [get_ports {OEn CSn}] -to [get_ports {data*}] 2 |
Danke, Da Dieter. Ich habe das gerade geändert und lasse alles nochmal durchlaufen. Das dauert jetzt leider ne Weile. Letztendlich macht mir hier generell Probleme, dass ich nicht weiss, wie ich einen asynchronen Pfad constraine. Das betrifft rein kombinatorische Pfade, als auch Pfade von Pads zu den Sampleregistern. So wie es sich für mich darstellt, kann Timequest einfach nichts asynchrones berechnen, sondern es wird immer ein Quell- und ein Zieltakt benötigt. Das macht dann solche Pfade wie den o.g. nur constrainbar, indem man mit einem Takt arbeitet, den es eigentlich gar nicht gibt. Es würde reichen, wenn man angeben könnte, dass der maximale Delay von X nach Y eben soundso lang ist. Genauso ist es mit den Pfaden zu den Sampleregistern. Ein Asynchroner Eingang, der im Sampleregister synchronisiert wird, führt an diesem zu Setup- und Hold-Violations, das liegt einfach in der Natur der Dinge. Man könnte diese Pfade jetzt als FALSE_PATH constrainen, aber dann gibt man jegliche Kontrolle ab. Der Pfad könnte dann auch beliebig lange werden. Sobald ich aber den Pfad in seiner Länge begrenzen will, geht das nur über SET_MAX_DELAY oder SET_INPUT_DELAY. Und beide stellen dann aber einen Phasenbezug vom Pad zum Register her, den es in Wirklichkeit nicht gibt. Lässt sich dieses Thema irgendwie elegant lösen?
Mäxle Delay schrieb: > Lässt sich dieses Thema irgendwie elegant lösen? Such mal nach "Quartus II TimeQuest Timing Analyzer Cookbook", das ist eine schöne kompakte Einführung in das Thema Constraints. Dazu noch das Kapitel zu TimeQuest im Quartus-Manual und Du müsstest wunschlos glücklich werden(?). (Im Cookbook werden grundlegende Techniken plus Prakmatiken vorgestellt, die etwa 99% der allgem. Probleme abdecken.)
Och Sigi, genau das machen die von Dir vorgeschlagenen Pamphlete eben nicht. Suche doch bitte einmal nach dem User RSYC. Hier findest Du nutzbare Tutorials. Generell bleiben Dir falsepath und multicycle.
Ich schrieb: > genau das machen die von Dir vorgeschlagenen Pamphlete eben nicht. Stimmt nur zum Teil. Ich habe noch "TimeQuest Terminology and Concepts" vergessen, ist glaube ich im Quartus Manual enthalten. Trotzdem ist das Cookbook in diesem Fall sehr hilfreich!
Vielen Dank schonmal für die Infos. Ich werde mir das mal zu Gemüte führen. Allerdings komme ich heute nicht mehr dazu.
So, ich habe mir das mal angeschaut. Informativ, aber die Frage, die ich habe, konnte ich damit auch nicht beantworten. Mir geht es letztendlich um das Handling von asynchronen Eingängen. Annahme: An einem Pad kommt ein asynchrones Signal. Dieses geht auf ein Register und wird dort synchronisiert. Dann "Verarbeitung" in n Takten Dann Ausgabe auf ein Pad. Die Zeit, die das Signal vom Anlegen am Pin, bis zur Ausgabe des Ergebnis benötigt, soll nun auf einen Maximalwert begrenzt werden. Die maximal-Zeit setzt sich dann folgendermaßen zusammen: 1.) Signallaufzeit vom Pad bis zum Eingang des ersten Registers 2.) "Unschärfe" durch Abtastung (maximal 1 Systemtakt) 3.) n Takte Verabreitungsdauer 4.) Laufzeit vom Ausgabereigster bis zum Pad. Die Phasenlage des Taktes zum Signal bzw. der Clock-Skew innerhalb des FPGA spielen bei dieser Betrachtung keine Rolle. Es ist unrelevant, wie des Skew des Taktes am 1. Register zur Taktquelle ist. Und hier liegt mein Problem. Mit den "klassischen" Methoden wie SET_INPUT_DELAY oder SET_MAX_DELAY wird immer der Skew des Taktes im FPGA mit berücksichtigt. Und das verfälscht das Ergebnis. Wenn ich z.B. die maximale Laufzeit von Punkt 1.) auf 3ns begrenzen möchte und das mit SET_MAX_DELAY mache, dann wird das immer in Relation zum Takt gesehen. Ist der Clock-Skew am Sampleregister z.B. 5ns, und die Signallaufzeit statt der constrainten 3ns z.B. 4ns, dann führt das nicht zu einer Timing-Violation, da tsu noch gehalten wird. Sprich: Weder der Fitter/Router ist bemüht, es in den 3ns "hin zu bekommen", noch Timequest reported eine Violation, da es keine gibt. Aber dennoch wurde mein "Wunsch", die Signallaufzeit auf 3ns zu begrenzen, nicht erfüllt. Bei Xilinx wird sowas über DATAPATHONLY gelöst. Bei Lattice heißt das Zauberwort DATAPATH_ONLY.. Bei Altera......?
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.