www.mikrocontroller.net

Forum: FPGA, VHDL & Co. 1 clk impuls erzeugen


Autor: Michi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
Ich rätsel schon ne ganze Zeit lang an einer Lösung für ein Problem...
Ich taste ein einzelnes Signal mit diesen Werten bei 200MHz hab:
00010110111111111111001101000000000

Also ein Rechtecksignal wo nach der Einschalt- und Ausschaltflanke 
einige Spikes entstehen.
Ich möchte daraus ein Signal erzeugen das bei jeder Flanke ein 1 clk 
langen Impuls erzeugt. Wie stell ich das am besten an?

Autor: Albert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie wäre es mit aufsummieren. Eine 0 <> -1 eine 1 <> +1 bei 
überschreiten einer Tresholdgrenze den Impuls auslösen.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So mach ich das:

z.B. 10er Schieberegister,
Eingang wird mit clk (hier 200MHz) z.B. von rechts eingetaktet,
wenn die 10 Bit = "0000011111" sind => flanke ='1'; (steigend)
wenn die 10 Bit = "1111100000" sind => flanke ='1'; (fallend)

Kurz in VDHL:
:
signal sr     : std_logic_vector(9 downto 0);
signal flanke : std_logic;
signal pegel  : std_logic;
:
process (clk)
begin
   if rising_edge(clk) then
      -- Schieberegister
      sr <= sr(8 downto 0) & eingang;
      -- Flankenerkennung
      flanke <= '0';
      if (sr="1111100000") then flanke <= '1' end if; -- fallend
      if (sr="0000011111") then flanke <= '1' end if; -- steigend
      -- Entprellen
      if (sr="1111111111") then pegel <= '1' end if; -- high
      if (sr="0000000000") then pegel <= '0' end if; -- low
   end if;
end process;
:

Autor: Jan M. (mueschel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Michi:
Du kannst aufeinanderfolgende Einsen und Nuller zu zählen und diese 
Zähler jeweils zurückzusetzen, wenn eine 0 resp. eine 1 erkannt wird.
Nun weißt du, wenn z.B. der Einser-Zähler über eine festgelegte Schwelle 
kommt, dass eine Flanke da war.



Lothar Miller wrote:
> if (sr="1111100000") then flanke <= '1' end if; -- fallend
> if (sr="0000011111") then flanke <= '1' end if; -- steigend

Damit gehen dir aber einige Flanken verloren, z.B. 11111101000000 wird 
damit nicht erkannt.

Autor: Michi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eigentlich beginnt die Flanke bei ersten wechsel von 0 nach 1 oder von 1 
nach 0. Zu diesem Zeitpunkt muss ich auslösen, dabei dürfen aber die 
darauffolgenden Wechsel für eine gewisse dauer nicht erkannt werden.

Autor: Eman (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na ganz einfach:

if (edge_switch = '0') then
  if (sr = '1' AND sr_old = '0') then 
    flanke <= '1';
    edge_switch <= '1';
  else
    flanke <= '0';
  end if;
else
  edge_counter <= edge_counter +1;
  if (edge_counter = "1111") then
    edge_switch <= '0';
  end if;
end if;

Ggf. könntest du im else-Zweig, wo der edge_counter hochzählt, auch noch 
die einsen zählen und nach einer bestimmten Anzahl Einsen die Erkennung 
wieder scharfmachen.

Autor: Eman (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Flanke von 1 nach 0 habe ich vergessen, aber ist ja im Prinzip das 
Gleiche. ;) Ohne Haftung, da nur schnell hingeschmiert.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Eigentlich beginnt die Flanke bei ersten wechsel von 0 nach 1 oder von 1
>nach 0. Zu diesem Zeitpunkt muss ich auslösen, dabei dürfen aber die
>darauffolgenden Wechsel für eine gewisse dauer nicht erkannt werden.
Das macht dich aber recht empfindlich auf irgendwelche Spikes oder 
Störungen...

Also, dass ich das richtig sehe:
ideales Signal: ooo11111111111111111ooooooooooooooo
reales Signal:  ooo1o11o111111111111oo11o1ooooooooo
Flanke:         ooo1oooooooooooooooo1oooooooooooooo

Eine Frage, die sich mir stellt, ist dann: wieviele Takte zwischen zwei 
Flankenwechseln ist das Signal dann auch mindestens definiert 0 oder 1?
Mit deinem exemplarischen Signal sind das
ooo1o11o111111111111oo11o1ooooooooo
123111211234567890ab121211123456789
9 Takte o bzw.
11 Takte 1
>  if (edge_counter = "1111") then
sind 16 Takte und würde dann schon mal schiefgehen.

Also, nehmen wir mal 8 Takte, und schalten sofort beim 1. 
Flankenwechsel.
(Nur 1 FF lasse ich noch drin, zur Synchronisation ;-), besser is das)
:
signal sr     : std_logic_vector(7 downto 0);
signal flanke : std_logic;
signal pegel  : std_logic;
:
process (clk)
begin
   if rising_edge(clk) then
      -- Schieberegister
      sr <= sr(6 downto 0) & eingang;
      -- Flankenerkennung
      flanke <= '0';
      if (sr="11111110") then flanke <= '1' end if; -- fallend
      if (sr="00000001") then flanke <= '1' end if; -- steigend
      -- Entprellen
      if (sr="11111111") then pegel <= '1' end if; -- high
      if (sr="00000000") then pegel <= '0' end if; -- low
   end if;
end process;
:


Und für Extremisten, die unvorhergesehene Ergebnisee lieben (oder 
bereits synchronisierte Signale haben), dieser Code:
:
signal sr     : std_logic_vector(7 downto 0);
signal flanke : std_logic;
signal pegel  : std_logic;
:
process (clk)
begin
   if rising_edge(clk) then
      -- Schieberegister
      sr <= sr(6 downto 0) & eingang;
      -- Flankenerkennung
      flanke <= '0';
      if (sr="11111111" and eingang='0') then flanke <= '1' end if; -- fallend
      if (sr="00000000" and eingang='1') then flanke <= '1' end if; -- steigend
      -- Entprellen
      if (sr="11111111") then pegel <= '1' end if; -- high
      if (sr="00000000") then pegel <= '0' end if; -- low
   end if;
end process;
:

Man sieht: fast derselbe Code wie beim ersten Posting, nur die 
Auswertung ist ein wenig anders. Und ja: ich liebe Schieberegister :-)

Autor: Michi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, so funktioniert es super ;-)

Autor: Stefan Zimmermann (wooschder)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

Welchen Baustein verwendest du?

Gruß
Stefan

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Zimmermann wrote:
> Welchen Baustein verwendest du?
Das Verfahren ist unabhängig vom FPGA/CPLD. Wobei der 
Ressourcenverbrauch (Anzahl der verwendeten FF) für ein CPLD unangenehm 
hoch ist.

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.