www.mikrocontroller.net

Forum: FPGA, VHDL & Co. CPLD: Signale von einem Zähler ableiten


Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Um ein Display anzusteuern benötige ich mehrere Signale die alle 
ausgehend vom Zeilenbeginn um bestimmte Pixelanzahlen verschoben sind 
und eine entsprechende Dauer habe.
Daher habe ich einen Zähler verwendet, der mit dem Pixeltakt getaktet 
wird, und synchron mit HSync zurückgesetzt wird.

Jetzt meine Frage:
Wie macht man es richtig in VHDL, wenn man ausgehend von diesem Zähler 
Signale generieren möchte.
Als Beispiel möchte ich jetzt ein Signal haben, das während dem 
Wertebereich des Zählers von 25-625 auf high ist.

Eine Möglichkeit wäre reine kombinatorische Logik, die eben während 
diesen Zählerzuständen ein High liefert. Allerdings befürchte ich, dass 
es dabei Glitches geben könnte. Man müsste also an den Ausgang nochmal 
ein vom Pixeltakt getaktetes Latch dranhängen, damit es wirklich sauber 
ist.

Die nächste Möglichkeit wären zwei Teile mit kombinatorischer Logik, die 
jeweils beim Einschaltzeitpunkt und beim Ausschaltzeitpunkt ein High 
erzeugen, und damit ein RS-FF setzen bzw. zurücksetzen. Aber auch hier 
könnten wieder Glitches auftreten die das FF falsch setzen.

Wie macht man es also richtig in VHDL ?
Oder ist meine Angst um die Glitches übertrieben, und die Lösungen sind 
wirklich praxistauglich ?
Ich habe momentan eine Lösung die meiner Meinung nach nicht ganz 
praxistauglich ist, da gemischt synchron/asynchron, so dass es halt 
irgendwie funktioniert.

Autor: HildeK (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sehe mehrere Möglichkeiten:
- Zustandsautomat nach Moore
- geeignete Codierung des Zählers verwenden z.B. Gray, dann kann auch 
glitchfrei verknüpft werden
- überlegen, inwieweit die Glitche stören in der realen Anwendung. Gehen 
die Signal auf flankensensitive Schaltungsteile (= Takteingäne), dann 
dürfen keine Glitche drin sein. Werden die verknüpten Signale jedoch von 
der nachfolgenden Schaltung auch wieder synchron übernommen, dann ist 
das kein Problem.
- nochmals abtasten (mit FF nicht Latch) ist auch gut, liefert das 
Signal aber um einen Takt verzögert an. Könnte in deinem Fall durch die 
anderen Anfangswerte berücksichtigt werden (24 bis 624).

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde das, wie HildeK am Schluß vorschlägt machen.
Dadurch, dass die Abfrage im Prozess stattfindet, entsteht am Ausgang 
ein FF.

Also so etwa:

vhdl
process(pixel_clk)

begin
  if rising_edge(pixel_clk) then

    pixel_counter <= pixel_counter+1;

    if (pixel_counter > 23 and pixel_counter < 623) then

--mein_signal wird mit der 25.Taktflanke 1 und mit der 625. Flanke 
wieder 0
   mein_signal  <= '1';
     else
         mein_signal  <= '0';
     end if;
   end if;

end process;
/vhdl


Tom

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, war noch ein Fehler drin, hoffentlich passt nun auch die 
Formatierung

process(pixel_clk)

begin
  if rising_edge(pixel_clk) then

    pixel_counter <= pixel_counter+1;

    if (pixel_counter > 23 and pixel_counter < 624) then

--mein_signal wird mit der 25.Taktflanke 1 und mit der 625. Flanke wieder 0
         mein_signal  <= '1';
     else
         mein_signal  <= '0';
     end if;
   end if;

end process;

Autor: Mike (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde das so lösen:

if rising_edge(clock) then
  if counter=x"018" then  -- 24
    flag <= '1';
  elseif counter=x"270" then -- 624
    flag <= '0';
  end if;
end if;

Den Zähler hochzählen und die Resetlogik (falls benötigt) müsste noch 
ergänzt werden.

Aus "flag" wird dabei ein Latch. Das wird immer um einen Takt verzögert 
gesetzt und wieder zurückgesetzt. Die Kombinatiorik hat in diesem Takt 
Zeit sich zu beruhigen.

Autor: Mike (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meine Lösung ist etwas kleiner (9 vs. 10 Slices - bei gleicher Anzahl FF 
und LUTs...) und läuft mit höherem Takt (265 vs. 218 MHz).

Hier noch eine Version ohne Tipfehler (man muss die Werte auch nicht 
unbedingt nach HEX umrechnen):

if rising_edge(clock) then
  if counter=24 then
    flag <= '1';
  elsif counter=624 then 
    flag <= '0';
  end if;
end if;

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke ! Das ist wirklich eine einfache und kompakte Lösung. Darauf muss 
man erstmal kommen. Ich hatte schon alles mögliche ausprobiert, was zwar 
prinzipiell auch ging, aber dann doch die Gefahr von Glitches o.ä. 
hatte.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.