1 clk impuls erzeugen

Gast #946226
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?
Moderator (Firma: Titel) Persönliche Seite #946298
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:
1
:
2
signal sr     : std_logic_vector(9 downto 0);
3
signal flanke : std_logic;
4
signal pegel  : std_logic;
5
:
6
process (clk)
7
begin
8
   if rising_edge(clk) then
9
      -- Schieberegister
10
      sr <= sr(8 downto 0) & eingang;
11
      -- Flankenerkennung
12
      flanke <= '0';
13
      if (sr="1111100000") then flanke <= '1' end if; -- fallend
14
      if (sr="0000011111") then flanke <= '1' end if; -- steigend
15
      -- Entprellen
16
      if (sr="1111111111") then pegel <= '1' end if; -- high
17
      if (sr="0000000000") then pegel <= '0' end if; -- low
18
   end if;
19
end process;
20
:
#946337
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.
Gast #946685
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.
Gast #946689
Lesenswert?

Na ganz einfach:
1
if (edge_switch = '0') then
2
  if (sr = '1' AND sr_old = '0') then 
3
    flanke <= '1';
4
    edge_switch <= '1';
5
  else
6
    flanke <= '0';
7
  end if;
8
else
9
  edge_counter <= edge_counter +1;
10
  if (edge_counter = "1111") then
11
    edge_switch <= '0';
12
  end if;
13
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.
Moderator (Firma: Titel) Persönliche Seite #946739
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)
1
:
2
signal sr     : std_logic_vector(7 downto 0);
3
signal flanke : std_logic;
4
signal pegel  : std_logic;
5
:
6
process (clk)
7
begin
8
   if rising_edge(clk) then
9
      -- Schieberegister
10
      sr <= sr(6 downto 0) & eingang;
11
      -- Flankenerkennung
12
      flanke <= '0';
13
      if (sr="11111110") then flanke <= '1' end if; -- fallend
14
      if (sr="00000001") then flanke <= '1' end if; -- steigend
15
      -- Entprellen
16
      if (sr="11111111") then pegel <= '1' end if; -- high
17
      if (sr="00000000") then pegel <= '0' end if; -- low
18
   end if;
19
end process;
20
:


Und für Extremisten, die unvorhergesehene Ergebnisee lieben (oder 
bereits synchronisierte Signale haben), dieser Code:
1
:
2
signal sr     : std_logic_vector(7 downto 0);
3
signal flanke : std_logic;
4
signal pegel  : std_logic;
5
:
6
process (clk)
7
begin
8
   if rising_edge(clk) then
9
      -- Schieberegister
10
      sr <= sr(6 downto 0) & eingang;
11
      -- Flankenerkennung
12
      flanke <= '0';
13
      if (sr="11111111" and eingang='0') then flanke <= '1' end if; -- fallend
14
      if (sr="00000000" and eingang='1') then flanke <= '1' end if; -- steigend
15
      -- Entprellen
16
      if (sr="11111111") then pegel <= '1' end if; -- high
17
      if (sr="00000000") then pegel <= '0' end if; -- low
18
   end if;
19
end process;
20
:

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren