user24883
user24883

Reputation: 75

VHDL edge detection

I want to detect the edges on the serial data signal (din). I have written the following code in VHDL which is running successfully but the edges are detected with one clock period delay i.e change output is generated with one clk_50mhz period delay at each edge. Could anyone please help me to detect edges without delay. Thank you.

 process (clk_50mhz)
 begin
        if clk_50mhz'event and clk_50mhz = '1' then
            if (rst = '0') then
                shift_reg <= (others => '0');
            else
                shift_reg(1) <= shift_reg(0);
                shift_reg(0) <= din;    
                        end if;      
        end if;
 end process;

    process (clk_50mhz)
    begin
        if clk_50mhz'event and clk_50mhz = '1' then
            if rst = '0' then
                change <= '0' ;
            elsif(clk_enable_2mhz = '1') then
                change <= shift_reg(0) xor shift_reg(1);                    
            end if ;
        end if ;
    end process ;

When I changed my code to following I am able to detect the edges

 process (clk_50mhz)
begin
    if clk_50mhz'event and clk_50mhz = '1' then
        if (RST = '0') then
            shift_reg <= (others=>'0');
        else
            shift_reg(1) <= shift_reg(0);
            shift_reg(0) <= din;    
  end if;     
    end if;
end process;

change <= shift_reg(1) xor din; 

Upvotes: 4

Views: 19004

Answers (2)

Passepartout
Passepartout

Reputation: 442

Here you go

library ieee;
use ieee.std_logic_1164.all;

entity double_edge_detector is
    port ( 
        clk_50mhz   : in std_logic;
        rst         : in std_logic;
        din         : in std_logic;
        change      : out std_logic
    );
end double_edge_detector;

architecture bhv of double_edge_detector is

signal din_delayed1 :std_logic;

begin
    process(clk_50mhz)
    begin
        if rising_edge(clk_50mhz) then
            if rst = '1' then
                din_delayed1 <= '0';
            else
                din_delayed1 <= din;
            end if;
        end if;

    end process;

    change <= (din_delayed1 xor din); --rising or falling edge (0 -> 1 xor 1 -> 0)


end bhv;

Upvotes: 4

Tomi Junnila
Tomi Junnila

Reputation: 7543

You have to use a combinatorial process to detect the difference without incurring extra clock cycle delays. (You will still need one register to delay the input as well.)

DELAY: process(clk_50mhz)
begin
    if clk_50mhz'event and clk_50mhz = '1' then
        din_reg <= din;
    end if;
end process;

change <= din xor din_reg;

Upvotes: 1

Related Questions