Search code examples
vhdl

VHDL rising_edge function instead uses falling edge?


I've been trying to write an simulate a toggle flip-flop for a while now. I can't find anything wrong with my code here, but for some reason when I simulate it, the output toggles on the falling edge of the clock instead of the rising edge. Is there a mistake that I've missed?

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity TFF is
  Port (EN, T, CLK : in std_logic; 
        Q : out std_logic);
end TFF;

architecture Behavioral of TFF is

signal temp_q : std_logic := '0';

begin
    proc1 : process (EN, T, CLK)
    begin
        if EN = '1' then
            if rising_edge(CLK) then
                if T = '1' then temp_q <= (not temp_q);
                else temp_q <= temp_q; end if;
            end if;
        else Q <= temp_q; end if;
        Q <= temp_q;
    end process proc1;
end Behavioral;

Solution

  • It toggles on falling edge, because in rising_edge it uses old value of temp_q (remember, that assigning to signals is NOT done at once, it is scheduled, and done at the end of the process), and because you have assignment outside of rising_edge() if, it is done on falling edge.

    You shouldn't have anything outside rising_edge() if. This process launches every time clock edge changes, so also on falling edge. You also don't need anything apart from CLK on the sensitivity list. Assigning to Q also does not has to be done in process - it can be done concurrently. You can also move temp_q <= temp_q; to the beginning of the process body, so it will be always scheduled, and in case of T = '0' it will be inverted. Lastly, you should first check for rising_edge, and then for clock enable.

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    
    entity TFF is
      Port (EN, T, CLK : in std_logic; 
            Q : out std_logic);
    end TFF;
    
    architecture Behavioral of TFF is
    
    signal temp_q : std_logic := '0';
    
    begin
    
    Q <= temp_q;
    
        proc1 : process (CLK)
        begin
            if rising_edge(CLK) then
                if EN = '1' then
    
                    temp_q <= temp_q;
    
                    if T = '1' then 
                        temp_q <= not temp_q;
                    end if;
    
                end if;
            end if;
        end process proc1;
    end Behavioral;