hallo Leute...
Hab jetzt die Aufgabe, einen Frequenzteiler in VHDL zu Programmieren.
Mein Eingangssignal kommt vom Altium Live Design Evaluation Board
(Spartan 3) und nennt sich CLK_BRD.
Kann mir jemand helfen?
Bräuchte einen 50MHz Takt, den kann ich ja direkt vom Board übernehmen,
da dieser ja nen Quarz mit 50MHz hat.
Dann brauch ich noch einen takt mit 500kHz und einen mit 50Hz.
Wäre für Lösungen sehr sehr dankbar, da ich selber leider noch keinen
wirklichen Plan hab, wie ich das ganze angehen soll.
Danke!!!
Jonas
Das ist eine Standardaufgabe. Du brauchst einen Zähler bzw. Timer; der
zählt bei jedem 50MHz-Takt um eins rauf, und immer, wenn er bei 50
angekommen ist, schaltest du den 500kHz-Ausgang auf high, und wenn er
bei 100 ankommt schaltest du ihn wieder auf low, und resettest den
Zähler auf 0. Für 50 Hz machst du das gleiche, nur mit 500 und 1000.
>achja, ich brauch die takte dann als Ausgangsports, da wir ne>gruppenarbeit haben, und andere damit weiterarbeiten....
was wollen andere denn dranhängen?
üblicherweise würde man einen Puls ('1' mit Dauer 20 ns @50MHz)
erzeugen, egal ob man 1ms oder 1sec irgendwo braucht.
Das das geht wundert mich ein wenig.
Hier wird bei erreichen von 100000000 ein impliziter Reset auf 0
angenommen, der aber weder von der Simulation noch von der Hardware
unterstützt wird (mal davon abgesehen, dass der Zähler um 1 zu weit
zählen würde: von 0 bis 100000000 sind es 100000001 Takte).
Die Simulation bringt eine Bereichsverletzung:
1
# ** Fatal: (vsim-3421) Value 100000001 for cnt is out of range 0 to 100000000.
Die Synthese macht einen 27Bit-Zähler, und der geht bis 134217727, erst
dann läuft er über (siehe Screenshot) :-o
Ich beschreibe das dann eher so:
... denn die Auswertung des Vergleichs cnt=100e6 braucht doch einiges
an Logik (Screenshot), und wehe, da kommt mal ein kleiner Glitch
zusammen.
Dann wird der Zähler einfach vor Erreichen des Endwerts zurückgesetzt.
Fazit: Finger weg von solchen asynchronen Beschreibungen.
Kommt jetzt einer auf die Idee, den Vergleich auch noch zu takten:
1
cnt<=0whencnt=100e3-1andrising_edge(clk)else
2
cnt+1whenrising_edge(clk);
Dann klopft ihm der Synthesizer auf die Finger und bemängelt eine
bad asynchronous descritpion.
Ich habe leider nicht nachgeschaut was aus meiner Kurzform nach
der Synthese wird. Dafür mache ich noch zu wenig mit den FPGA's
:)
Auf den Fehler in der Simulation bin ich aber auch irgendwann mal
gekommen. Das war glaube ich sogar bei der längeren Form wie
ich sie oben geschrieben habe.
Eigentlich müsste die Übergangslogik für cnt_next sauber heissen
1
cnt_next<=0whencnt=100e6else
2
cnt+1;
3
sec_pulse<='1'whencnt=100e6else'0';
Dann sollte auch cnt_next nie 100e6+1 werden.
Ich schaue mir deine RTL jpgs genauer etwas später an.
Bin jetzt etwas beschäftigt dafür.
Diese getrennte Schreibweise (cnt und cnt_next, das ist fast schon der
Zwei-Prozess-SM Stil) ist überflüssig und führt nur zu unüberschaubaren
Zähl- und Rücksetzbedingungen.
Mach den gesamten Zähler in einem (1) getakteten Prozess, dann sind
alle Zählbedingungen sofort einsichtig und Querverbindungen
ausgeschlossen.
Um dein eigenes Beispiel zu nehmen:
hallo lothar, danke für deinen Tip,
hat alles so geklappt, wie ich das brauchte....
das mit dem (CLK'event and CLK = '1') kam bei uns so in der
Digitaltechnik vorlesung dran, deswegen hab ich das so verwendet.
wir bauen gerade eine Smart Cockpitsteuerung zusammen, deswegen muss ich
die Frequenz als Port nehmen und an andere weiterleiten, die die
Frequenz brauchen....
Jonas