Hallo! ich beschäftige mich seit kurzem mit FPGA's allerdings komme ich mit den Timings noch nicht so ganz zurecht. Ich besitze ein Xilinx Spartan 3 AN Starter Kit und experimentiere mit dem 50MHz Oszilator (E12). Ich habe inzwischen ein Blinklicht (ich weiß, nicht besonders herausfordernd) mit Verilog und der ISE 10.1 Sp3 gemacht, das ganze indem ich jeweils bei der steigenden Flanke der Ckl einen Zähler hinaufgezählt hab, und somit den Takt geteilt hab, was auch wunderbar funktioniert hat. Was mir allerdings auch durch diverse Dokumentationen nicht ganz klar wird, ist der "PERIOD" Parameter in der UCF Datei. Ist es möglich mit diesem den Takt schon im vorhinein zu Teilen (z.B. indem man die benötigte Frequenz eingibt) oder ist dieser nur zur internen Optimierung vorgesehen? Denn jegliche Änderungen des Wertes ergaben keine sichtbaren Veränderungen, deshalb bin ich etwas verunsichert was genau dieser Parameter verursacht. Oder gibt es noch eine andere Möglichkeit den Takt zu verändern, ohne manuell einen Prescaler mittels Zähler zu erstellen? Mit einem DCM- Objekt müsste dies doch relativ "einfach" machbar sein, wenn ich das richtig gesehen habe. Ich hatte ausserdem ein kleines Problem bei dem ISE 10 Tutorial (stopwatch). Soweit ich das beurteilen konnte, fehlt da die LOC der Clock. Ich habe es noch nicht nachgeprüft, bin mir allerdings ziemlich sicher. Vielen Dank für die Hilfe! Charlie
>... ist der "PERIOD" Parameter in der UCF Datei.
Stichwort: Timing Constraints.
Constraints sind Einschränkungen, die du den Design-Tools zur Arbeit
übergibst. Wenn du keine Constraints angibst, haben die Tools alle
Freiheiten: sie können die Pins irgendwohin legen, sie können beliebig
umständliche (und damit langsame) Routing- und Logikpfade wählen.
Mit dem LOC Constraint gibst du Platzierungs-Vorgaben z.B. Pins.
Mit PERIOD gibst du die einfachste Zeitvorgabe, indem du sagst:
Ich möchte, dass mein Design mit dieser Frequenz läuft.
Wenn du nichts sagst, dann kann es sein, dass alles klappt. Es kann aber
genausogut sein, dass die Tools sich nicht genügend "anstrengen" und das
Design nicht ausreichend schnell ist.
Also sollte in der UCF-Datei mindestens
1) die Pinzuordnung und
2) die Taktfrequenz angegeben sein.
Hallo! danke für die Antwort! also das mit den Pinzuordnungen habe ich verstanden, also dass die ucf die verwendeten I/O's aus dem VHDL/Verilog Design auf die Pins des FPGA's abbildet. Aber nochmal zu den Timing-Constraints der Clock. Wie gesagt: ich habe einen 50Mhz Oszillator auf dem Board, ich schreib also in die UCF (laut Datenblatt): NET "clk" LOC = "E12"; NET "clk" PERIOD = 20.0ns HIGH 40%; bzw. laut Mikrocontroller.net und diverse andere Quellen: NET "clk" LOC = "E12"; NET "clk" TNM_NET = clk_div; TIMESPEC "TS_CLK" = PERIOD "clk_div" 20ns HIGH 40%; Die beiden Varianten sind ja prinzipiell gleich, funktionieren auch. Diese Quelle ist also nur zur Information für das Placing und Routing- Tool und kann hier nicht weiter verändert werden, verstehe ich das ungefähr richtig? Ich hatte die Vorstellung, dass ich die Period eventuell auf 40.0 hätte setzen können, um den vom Oszillator kommenden Takt schon automatisch im FPGA halbieren zu können. Das geht so wohl nicht?
der letzt construct ist nur ein alias konstruct, er hilft, wenn viele signale zu bussen geschaltet werden können und gemeinsam constrained werden
die angaben der Timing Constrains im UCF File haben keinen direkten einfluss auf die funktionalität, also man kann dort nich den takt schonmal vorteilen oder ihn sonst irgendwie manipulieren. hier gibt man nur an, mit welcher geschwindigkeit das design hinterher auch sicher laufen soll. sprich, man gibt dem systhese tool eine mindestgeschwindigkeit, die das design hinterher auch erfüllen muss und das sythesetool versucht dann alles so zu optimieren, dass es auch so schnell ist hinterher.
> Ich hatte die Vorstellung, dass ich die Period eventuell auf 40.0 hätte > setzen können, um den vom Oszillator kommenden Takt schon automatisch im > FPGA halbieren zu können. Das geht so wohl nicht? Nein. Würdest du PERIOD auf 40.0 setzen, dann würde der place-and-route-Schritt mit diesen (falschen) Angaben rechnen und evtl. das Design so langsam umsetzen, dass es nur mit 25 MHz noch läuft, unter der Annahme dass der Takt ja nur 25 MHz beträgt, und dann lieber z.B. die Größe optimiert wird. Für deine Theorie mit dem Halbieren müssten die Synthesetools ja auch überhaupt erst einmal wissen, dass der Takt 50 MHz beträgt. Das wissen sie aber nicht. Im Gegenteil, mit PERIOD machst du genau diese Angabe, also sollte sie auch richtig sein. Wenn du den Takt halbieren, verdoppeln oder sonstwas willst, dann musst du einen DCM (clock manager) verwenden. Beispiel halbieren: Stelle den DCM auf halbieren, 50 MHz Takt rein, 25 MHz Takt raus, gib PERIOD 20.0 für den ersten Takt, und PERIOD 40.0 für den erzeugten Takt. Genaugenommen könntest du PERIOD 20.0 für den Eingangstakt weglassen, solange keine Logik dran hängt, denn PERIOD ist ja wie gesagt nur eine Zielvorgabe für die Logikminimierung und place-and-route.
> Genaugenommen könntest du PERIOD 20.0 für den Eingangstakt weglassen...
Noch genauergenommen könntest du nur den Eingangstakt spezifizieren, und
der Takt nach dem/den DCM wird automatisch von der Toolchain
constrained. Das ist schön wenn z.B. mehrere DCM verwendet werden und
verschiedene Teiler- bzw. Multiplikator-Verhältnisse eingestellt werden.
Vielen Dank für die Erklärungen. Ich denke ich habe die Problematik, zumindest im thoeretischen Sinne, verstanden. Bei Gelegenheit werde ich das mal praktisch anwenden.
@Lothar: hab deine Antwort leider zu spät bemerkt. Das heißt im Klartext, ich gebe nur den Eingangstakt, also meine 20ns vom 50Mhz Oszillator an, und alle aus den DCM resultierenden Taktfrequenzen werden dann automatisch constrained? Es sind also keine weiteren Einträge in der UCF notwendig? Ich hatte mir schon gedacht, dass das automatisch (von der ISE) gemacht werden könnte, da alle Spezifikationen angegeben werden. Zumindest wenn es sich um Frequenzänderungen mit DCM' s handelt. Wie sieht das dann aber aus, wenn ich die Frequenz "von Hand" erzeuge, also ein Binärzähler implementiere und dann so eine Art PWM erzeuge? also in Verilog wär das dann sowas z.B. (nur die Instanz): wire clk_x // hier sei dann das resultierende "PWM" // Instanz erzeugt "PWM" div_clk clk_1 ( .CLK_IN(CLK_25), // Seien die 50/2 = 25MHz von einem DCM .CLK_OUT(clk_x) // Taktfrequenz resultiert von Binärzähler ); Wenn ich clk_x in die UCF aufnehmen möchte (brauch ich das überhaupt) wie würde so ein Eintrag dann Beispielsweise aussehen? Sorry für die Fragerei, aber ich mach es mir gerade bei den Timing-Constraints vielleicht schwerer als ich müsste. Den Sinn und Zweck hab ich verstanden, nur an der Umsetzung haperts leider noch.
Im Prinzip musst du nur den Eingangstakt angeben, alle anderen Abhängigkeiten kennt das Design-Tool ja und bastelt die Contraints (wenn nötig) daraus. Ob allerdings eine Taktteilung mittels Binärzähler sinnvoll ist, lassen wir mal dahingestellt....
> Wie sieht das dann aber aus, wenn ich die Frequenz "von Hand" erzeuge, > also ein Binärzähler implementiere und dann so eine Art PWM erzeuge? Dann wirst du u.U. schon mal Probleme haben das Ganze wieder auf ein Globales Taktnetz zu bekommen. Am Anfang (oder für Anfänger) gilt einfach: nur 1 Takt im ganzen Design. Weil im ganzen FPGA jetzt nur 1 Takt da ist, werden die restlichen Timings werden über Clock-Enable-Signale gesteuert. Du wirst nicht glauben, was du dir für seltsame Effekt einhandelst, wenn du mehrere/verschiedene Takte auf dem FPGA hast. Gerade am Anfang, wenn du noch soviel anderes zu lernen hast, wirst du damit einige schlaflose Nächte mit der Fehlersuche zubringen.
Achso, ok. Also den Takt beibehalten, alle Prozeduren mit diesem Takt steuern, also sowas wie always @ (posedge clk) begin if( enable )begin .... und nur das enable wird dann auf einem anderen weg erzeugt. Also wenn man jetzt beispielsweise sowas wie ein Blinklicht machen würde, müsste man noch eine Logik, die den Takt irgendwie weiter Teilt (DCM o.Ä.), entwerfen und damit enable ansteuert.. (Blinklicht ist jetzt nicht unbedingt so Zeitkritisch, aber ich denke ihr versteht was ich damit meine). Das Löst einige Warnungen und noch mehr Probleme.. Vielen Dank nochmal
> also sowas wie > always @ (posedge clk) begin > if( enable )begin > .... > und nur das enable wird dann auf einem anderen weg erzeugt. Ich beschreibe selber zwar in VHDL, aber das sieht richtig aus. > die den Takt irgendwie weiter Teilt (DCM o.Ä.) Nein, dazu würde ich einen ordinären Binärzahler nehmen, und den Enable lokal dort erzeugen, wo er gebraucht wird. Solche DCM-Geschichten sind Hardware-Ressourcen, - die 1. Zielsystemabhängig sind (DCM gibts nur bei Xilinx) [jajaja, klar gibts sowas ähnliches in allen anderen FPGAs] - die 2. nur in begrenzter Anzahl auf dem FPGA vorhanden sind - die 3. nicht FPGA-weit implementierbar sind (die sind lokalisiert)
Kann ich hier noch mal einhaken? Das bedeutet also für einen schnelleren und einen langsameren Takt z.B. fum entprellen oder für 7-Seg Anzeige, daß für den langsamen Takt in den Modulen die den brauchen, der schnelle Systemtakt mit einem entsprechend langsamen "slow_clock_enable" geundet werden sollte? Ich habe derzeit ein Takt Modul das spuckt wirklich einen langsamen takt aus, der entsprechend mit rising_edge erkannt wird. So also nicht, sondern if( rising_edge(fast_clock) and slow_clock_enable ). Was genau schiefgeht (früher oder später) wenn man es nicht macht lässt sich vermutlich für mich verständlich nicht in 3 Sätzen erklären? ;-) ich hätte nämlich vermutet, daß Probleme bei der Taktverteilung nur für 'schnelle' relevant wäre und bei so was wie 200 Hz zum entprellen keine Rolle spielt.
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.