Das hier ist eine Flankenerkennung mit einer vorgeschalteten Synchronisationsstufe.
Diese Beschreibung lässt sich sehr effizient in ein FPGA implementieren und wird ohne große Anstrengungen bis zu 400MHz schnell ausgeführt. Durch die Verwendung eines lokalen Schieberegisters (Variable sr) bleiben alle relevanten Signale lokal.
library ieee; use ieee.std_logic_1164.all; entity edge_detect is port (async_sig : in std_logic; clk : in std_logic; rise : out std_logic; fall : out std_logic); end; architecture RTL of edge_detect is begin process variable sr : std_logic_vector (3 downto 0) := "0000"; begin wait until rising_edge(clk); -- Flanken erkennen rise <= not sr(3) and sr(2); fall <= not sr(2) and sr(3); -- Eingang in Schieberegister einlesen sr := sr(2 downto 0) & async_sig; end process; end architecture;
Daraus wird dann:...
Hier eine Testbench:
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; use ieee.math_real.all; ENTITY tb_edgedetect_vhd IS END tb_edgedetect_vhd; ARCHITECTURE behavior OF tb_edgedetect_vhd IS COMPONENT edge_detect PORT( async_sig : IN std_logic; clk : IN std_logic; rise : OUT std_logic; fall : OUT std_logic ); END COMPONENT; --Inputs SIGNAL async_sig : std_logic := '0'; SIGNAL clk : std_logic := '0'; --Outputs SIGNAL rise : std_logic; SIGNAL fall : std_logic; BEGIN -- Instantiate the Unit Under Test (UUT) uut: edge_detect PORT MAP( async_sig => async_sig, clk => clk, rise => rise, fall => fall ); clk <= not clk after 5 ns; -- Ein zufälliges asynchrones Signal erzeugen stim : process variable seed1, seed2 : POSITIVE; variable Rand : REAL; variable IRand : INTEGER; begin -- Zufallszahl ziwschen 0 und 1 uniform(seed1, seed2, rand); -- daraus ein Integer zwischen 50 und 150 irand := integer((rand*100.0 - 0.5) + 50.0 ); -- und dann diese Zeit abwarten wait for irand* 1 ns; async_sig <= not async_sig; end process; END;
Und das ist die resultierende Waveform:
Als kleiner Gimmick
Wenn statt
rise <= not sr(3) and sr(2); fall <= not sr(2) and sr(3);
die folgende (genau funktionsgleiche) Beschreibung
rise <= not sr(3) and sr(2); fall <= sr(3) and not sr(2);
verwendet wird, kommt das dabei raus:
Zwei unnötige Inverter. Die Xilinx-Toolchain ist immer für Überraschungen gut.