Forum: FPGA, VHDL & Co. XC9572 erzeugt falschen Takt


von Sebastian (Gast)


Angehängte Dateien:

Lesenswert?

Hi,

ich will mit einem mit dem XC9572 einen Takt für eine CCD-Zeile
erzeugen, nur leider will der CPLD nicht so wie ich es ihm sage. Ich
der Simulator sagt zeigt mir das was ich sehen will, einen Takt
(ccd_clk) mit knapp 20,9kHz. Als ich mir das Signal aber mit einem Oszi
angeschaut habe war ich etwas verwundert. Das Oszi zeigt zwar eine
Frequenz von 20,85kHz an aber die das Taktsignal bleibt nur für ca.
50ns auf dem Low-Pegel. Alle anderen Signal die ich mir angeschaut habe
stimmen zu 100% mit dem Simulator und meinen Überlegungen überein. Bin
leider VHDL-Anfänger und hab keine Ahnung woran es liegen könnte.
Vielleicht sieht ja einer von euch den Fehler.

Dem Simulator habe ich folgendes gesagt:

CLOCK: PROCESS
BEGIN
       CLK <= '1';
       WAIT FOR 25ns;
       CLK <= '0';
       WAIT FOR 25ns;
END PROCESS CLOCK;

Gruß,
Sebastian

von SupaChris (Gast)


Lesenswert?

Das wird wohl daran liegen, dass ein wait-statement nicht
synthetisierbar ist. Sowas geht nur in der Simulation. Wie soll der
echte Chip warten? Der weiß doch nicht, was 25ns sind.
Du musst schon einen Quarzoszillator oder sowas an den echten CPLD
hängen und entsprechend runter teilen.

von Tobias (Gast)


Lesenswert?

Das Oszi zeigt zwar eine Frequenz von 20,85kHz an aber die das
Taktsignal bleibt nur für ca. 50ns auf dem Low-Pegel.

Komisch ich dachte immer wait statements könnte man nicht
synthetisieren.

von Sebastian (Gast)


Lesenswert?

Hallo ihr zwei Schlauberger,
meint ihr ich hänge ich erwarte mir aus aus dem 'CLOCK: ... ' einen
Takt? So dumm bin ich nun auch nicht. Da hängt schon ein Oszillator am
CPLD, oder wie erklärt ihr euch, daß alle anderen Signale vom Timing
(am realen Oszilloskop) her stimmen?

Naja, vielleicht ist es doch keine so gute Idee gewesen hier
nachzufragen.

Danke trotzdem fürs Interesse!

Gruß,
Sebastian

von Michael F. (grisu901)


Lesenswert?

@ Sebastian

Welcher Takt hat der externe Oszillator? Dir ist schon klar, daß der
Takt ein ganzzahliges Vielfaches von dem Takt sein sollte, den Du haben
willst, oder?

Was willst Du uns mit diesem Programmteil sagen?
"
-- Takt-Erzeuger für CCD-Takte (20,88kHz)
CLK_PRESCALER: PROCESS (CLK_CNT)
VARIABLE TEMP : BIT;
BEGIN
TEMP := PIX_CLK;
  IF CLK_CNT = 0 THEN
    PIX_CLK <= NOT TEMP;
  END IF;
END PROCESS CLK_PRESCALER;
"

Ich hab irgendwo mal folgendes gelernt:
1. Keine  Variablen verwenden, da die Hardware nicht für die sofortige
Zuweisung innerhalb eines Prozesses gemacht ist, was ja bei Variablen
passiert. Lieber Signale verwenden. Da weiß man, was die Synthese
daraus macht.

2. Du verwendest in dem Design unterschiedliche Taktdomänen. Manche
Prozesse laufen mit CLK manche mit PIX_CLK, CLK_CNT, usw. Besser wäre
es, wenn Du alle Prozesse mit CLK laufen läßt und über den Zählerstand
von CLK_CNT einzelne Signale erzeugst, die nur 1 Taktzyklus lang aktiv
sind und die entsprechenden Prozesse starten oder direkt den
Zählerstand abfragst. z.B.

process (clk)
begin
  if reset = '1' then
    ...
  elsif clk = '1' and clk'event then
    if clk_cnt = 87 then
      ...
    end if;
  end if;
end process;

Ich hoffe, das hilft Dir erstmal weiter. Falls es noch weitere Fragen
gibt, einfach nochmal melden.

Noch was zu Deiner Meinung über das Forum. Es gibt hier genauso, wie in
anderen Foren Leute, die Ahnung von dem haben, was sie schreiben. Und
natürlich auch welche, bei denen es weniger zutrifft. Meinst Du
wirklich, daß hier immer alle Posts sofort von allen Leuten gelesen
werden? Nur 7 Stunden nach Deinem Post willst Du schon alles hinwerfen,
weil nicht die richtige Antwort dabei ist? Etwas mehr Geduld ist
manchmal erforderlich.

p.s. Wer Rechtschreibfehler findet, darf sie behalten.

Da ich in letzer Zeit (zu) viel in Verilog programmiere, kann bei
meinen Codebeispielen ein Mix von VHDL und Verilog auftreten ;-)

von SupaChris (Gast)


Lesenswert?

Sorry für die schnelle falsche Antwort. Hab das Zip File nicht beachtet
und war vom Text ausgegangen.

von Sebastian (Gast)


Lesenswert?

Entschuldigung, hab vielleicht doch etwas übertrieben reagiert!

@ Michael

Danke schon mal für deine kompetente Antwort!
Ich verwende einen 20MHz Oszillator. Es müssen nicht exakt 20,88kHz...

Den Programmteil den du erwähnt hast habe ich mehr oder wengiger ohne
Verstand so hingebogen. Der Simulator hat mir nach langem Probieren
endlich das ausgespuckt was ich sehen wollte.

Wie stelle ich es am besten an wenn ich aus 20MHz auf ca. 20,88kHz
kommen will. Es ist mir ehrlich gasagt zuviel Arbeit, einen
Johnson-Zähler (Reichardt & Schwarz S.52) für meinen Fall,
einzutippen.

Wieso die Prozesse auf die verschiedenen Takte "hören":
Ich dachte mir wenn zwei Prozesse auf die gleiche Taktflanke warten,
und einer noch zusätzlich ein Signal auswerten soll was der andere
erzeugt, bekommt er dies vielleicht garnicht mehr mit.

Werde in den nächsten Tagen mal versuchen die Hardware nur auf einen
Takt reagieren zu lassen und am Donnerstag (wenn ich wieder ein Oszi
zur Verfügung habe) nochmal schauen ob ich endlich einen anständigen
Takt bekomme.

Gruß,
Sebastian

von Michael F. (grisu901)


Lesenswert?

Hallo Sebastian

Du hast ja im CPLD (oder FPGA) Laufzeiten von eingen ns. Wenn Du nun
einen Prozess auf den Takt lauschen läßt und einen anderen Prozess auf
clk_cnt, so wird zuerst der Teil für den Takt ausgeführt, der den
Counter inkrementiert. Anschließend wird ein paar ns später der zweite
Prozess ausgeführt, da sich ja der Zustand vom Zähler mit einer
Verzögerung geändert hat. Wenn Du nun einen dritten Prozess hast, der
den Takt und den Zähler in der Sensitivity List hat, dann wird dieser
unter Umständen zweimal ausgeführt, da sich ja kurz hintereinander
zweimal die Signale in der Sensitivity List geändert haben. Wenn Du
alles über den normalen Systemtakt steuerst und über Zähler einzelne
Bits erzeugst, die andere Prozesse steuern, bist Du auf der sicheren
Seite, daß alles nur einmal und zum richtigen Zeitpunkt ausgeführt
wird.

z.B.

process (reset, clk)
begin
  if reset = '0' then
    counter <= (others=>'0');
  elsif clk = '1' and clk'event then
    if counter = "1010" then
      bit1 <= '1';
      counter <= (others=>'0');
    else
      counter <= counter +1;
      bit1 <= '0';
    end if;
  end if;
end process;

process (reset, clk)
begin
  if reset = '0' then
    clk_out <= '0';
  elsif clk = '1' and clk'event then
    if bit1 = '1' then
      clk_out <= not clk_out;
    end if;
  end if;
end process;

Der obere Prozess setzt beim Zählerstand "1010" für einen Taktzyklus
das Bit bit1 auf '1'. Im zweiten Prozess wird synchron zum Takt das
Bit angefragt und falls dieses '1' ist, das Signal invertiert. Da
Signale immer am Ende des Prozessen zugewiesen werden, wird bit1 erst
am Ende des 10. Takts gesetzt und kann dann also erst im 11. Takt vom
2. Prozess ausgewertet werden, aber das kann man ja recht einfach über
die Schaltschwelle des Zählers ausgleichen.

'bit1' und 'clk_out' sollten als Signale definiert sein. Man kann
dann auch alles in einen Prozess packen und spart sich somit das
mehrmalige Schreiben der Reset-Logik.

Der Zähler, der im Buch beschrieben ist, ist deshalb so aufwendig, da
ja keine normale Codierung der Zustände verwendet wird, sondern der
Gray-Code (glaub ich). Hat den Vorteil, daß sich immer nur ein Bit
ändert, macht aber mehr Arbeit.

Gruß
Michael

p.s. Wer Rechtschreibfehler findet, darf sie behalten.

Da ich in letzer Zeit (zu) viel in Verilog programmiere, kann bei
meinen Codebeispielen ein Mix von VHDL und Verilog auftreten ;-)

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.