Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
17 years ago

Capture the falling edge of signals in VHDL

Hi,

Please bear me with a newbie's question:

I want to capture a PWM signal's falling edge. But, I can not use "falling_edge" as the PWM signal is not a clock signal.

Can any expert here give me some idea of what to do it?

Thanks a bunch!!

8 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    
    process(reset_n,clk)
          variable detect : std_ulogic_vector (1 downto 0);
       begin
          if reset_n ='0' then
             detect := "00";
          elsif rising_edge(clk) then
             detect(1) := detect(0); -- record last value of sync in detect(1)
             detect(0) := sync ; --record current sync in detect(0)
             
             if detect = "01" then -- rising_edge
             elsif detect = "10" then --falling_edge
             end if;
          end if;
    end process;
    

    Voilà :-)

    je l'ai déniché je ne sais où : désolé de ne pas pouvoir citer l'auteur

    sorry, i forget original author's name

    EDIT : translations
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    hi,

    maybe you should sample your pwm signal with a clk. every clk's rising edge check the pwm signal state (in the process you need a last state variable, to know the pwm's last state). if there is a change - there was a edge in the pwm signal.

    some thing like that...

    process(clk)

    variable last_state: std_logic := '0';

    begin

    if clk='1' and clk'event then

    --if last_state = '0' and pwm_signal = '1' then --rising edge

    if last_state = '1' and pwm_signal = '0' then --falling edge

    -- pwm edge

    end if;

    last_state := pwm_signal;

    end if;

    end process;

    your clk must be fast enough to detect edges ;)

    hope it helps!

    have a nice day

    joerg
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    If you're strictly looking for the falling edge of the signal, you can use a clock to buffer the previous sample of the signal, and then look for a binary "10".

    Something like this should work. I'd be curious if anyone has a better way to do it :)

    if nreset = '0' then

    sig_buf <= '0';

    elsif rising_edge(clk) then

    sig_buf <= sig_in; -- buffer the input signal on each clock

    if ((sig_buf = '1') and (sig_in = '0')) then --see if falling edge exists

    <this is your condition>

    else

    <keep waiting>

    end if;

    end if;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Looks like a few other people jumped on this one, as well. I think one of these should work :)

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Random comment, but i think it is cool that 3 people both replied with something that will synthesize to close to the same code but look pretty different.

    Pertinent comment: If the PWM signal is asynchronous to the clock you are sampling it with, you may want to clock the PWM signal through a few ff's first so you don't have any metastability issues. If it is on the same clock domain as the sample clock then you don't need to worry about it obviously.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Register your PWM signal whose falling edge you want to detect and then AND the registered signal with the NOT of non-registered one.

    eg.

    pwm

    pwm_reg

    pwm_reg <= pwm; (always at clock)

    falling_edge <= ~pwm & pwm_reg; (assign statement)

    sorry i don't know vhdl that's why i have written like this. Hope you understand what i am trying to say.

    -AmitGarg