Forum: FPGA, VHDL & Co. Eingang digital filtern - wie am einfachsten?


von Martin K. (mkohler)


Lesenswert?

Hallo,
Das Problem im weiter unten stehenden Thread "Pegelproblem am Spartan3 
XC3S250-4VQG100CCS1" hat sich als Optokoppler-Problem herausgestellt.

Ein Workaround besteht darin, die Eingangssignale zu filtern. Als Filter 
stelle ich mir vor, dass das Eingangssignal nur dann übernommen wird, 
wenn es während mind. 5 Taktzyklen/Samples konstant gewesen ist.

Wie lässt sich das am einfachsten umsetzen?
- 5 FFs hintereinander
- Sample = Input, falls alle FF gleich, sonst alter Wert behalten

Die Verzögerung um 5 Takte ist durchaus verschmerzbar.

Hat jemand eine andere Idee?

Gruss, M.Kohler

von heiko (Gast)


Lesenswert?

Summe der 5 Eingänge > 4 dürfte genügen.
Das Ergebniss kann man ja trotzdem prozessieren und dann als gültig 
annehmen, wenn diese Randkriterium stimmt.

von Francesco N. (franceso-)


Lesenswert?

Ein Filter, der 3 Werte mittelt.
------------------------------------------------------------------------ 
----------
-- filter.vhd
--
-- Copyright (C) 2006 Michael Poppitz
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or (at
-- your option) any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- General Public License for more details.
--
-- You should have received a copy of the GNU General Public License 
along
-- with this program; if not, write to the Free Software Foundation, 
Inc.,
-- 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
--
------------------------------------------------------------------------ 
----------
--
-- Details: http://sump.org/projects/analyzer/
--
-- Fast 32 channel digital noise filter using a single LUT function for 
each
-- individual channel. It will filter out all pulses that only appear 
for half
-- a clock cycle. This way a pulse has to be at least 5-10ns long to be 
accepted
-- as valid. This is sufficient for sample rates up to 100MHz.
--
-- Noise cancelation is important when connecting to 5V signals with 
high
-- slew rate, because cross talk will occur.
-- It may or may not be necessary with low voltage signals.
--
------------------------------------------------------------------------ 
----------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity filter is
    Port ( input : in  STD_LOGIC_VECTOR (31 downto 0);
        clock : in std_logic;
        clock180 : in std_logic;
           output : out  STD_LOGIC_VECTOR (31 downto 0));
end filter;

architecture Behavioral of filter is

signal input0, input180, input360, input180Delay, nresult, result : 
STD_LOGIC_VECTOR (31 downto 0);

begin
  process(clock)
  begin
    if rising_edge(clock) then
      input0 <= input;
      input180 <= input180Delay;
      input360 <= input0;
      result <= nresult;
    end if;
  end process;
  output <= result;

  process(clock180)
  begin
    if rising_edge(clock180) then
      input180Delay <= input;
    end if;
  end process;

  -- determine next result
  process(input0, input180, input360, result)
  begin
    for i in 31 downto 0 loop
      if
        (result(i) = '0' and input360(i) = '0' and input180(i) = '0' and 
input0(i) = '0')
        or (result(i) = '0' and input360(i) = '0' and input180(i) = '0' 
and input0(i) = '1')
        or (result(i) = '0' and input360(i) = '0' and input180(i) = '1' 
and input0(i) = '0')
        or (result(i) = '0' and input360(i) = '1' and input180(i) = '0' 
and input0(i) = '0')
        or (result(i) = '0' and input360(i) = '1' and input180(i) = '0' 
and input0(i) = '1')
        or (result(i) = '1' and input360(i) = '0' and input180(i) = '0' 
and input0(i) = '0')
        or (result(i) = '1' and input360(i) = '0' and input180(i) = '0' 
and input0(i) = '1')
        or (result(i) = '1' and input360(i) = '1' and input180(i) = '0' 
and input0(i) = '0')
      then
        nresult(i) <= '0';
      else
        nresult(i) <= '1';
      end if;
    end loop;
  end process;

end Behavioral;

von Martin K. (mkohler)


Lesenswert?

Ich danke euch für die Antworten.

Die Implementation ähnlich dem vorgeschlagenen Code scheint mir 
plausibel zu sein. Ich werde es mal so versuchen.

Gruss, M.Kohler

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.