Forum: FPGA, VHDL & Co. Spartan 3AN und UCF File


von Christian M. (charlie)


Lesenswert?

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

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


Lesenswert?

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

von Christian M. (charlie)


Lesenswert?

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?

von Henk ten Bakker (Gast)


Lesenswert?

der letzt construct ist nur ein alias konstruct, er hilft, wenn viele 
signale zu bussen geschaltet werden können und gemeinsam constrained 
werden

von Nephilim (Gast)


Lesenswert?

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.

von Morin (Gast)


Lesenswert?

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

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


Lesenswert?

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

von Christian M. (charlie)


Lesenswert?

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.

von Christian M. (charlie)


Lesenswert?

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

von Christian R. (supachris)


Lesenswert?

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

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


Lesenswert?

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

von Christian M. (charlie)


Lesenswert?

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

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


Lesenswert?

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

von J.H. (Gast)


Lesenswert?

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