Kyle
Kyle

Reputation: 25

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;

Upvotes: 2

Views: 2441

Answers (2)

po.pe
po.pe

Reputation: 1162

You're assigning Q <= temp_q whenever the process is called, means one of the signals in the sensitivity list changes. This means your assigning temp_q <= not(temp_q) or temp_q <= temp_q respectively on the rising edge of the clock and then assign that value to Q on the falling edge as this is when the process is run the next time. The thing would look even stranger when synthesized as it's asynchronous.

I'm not a hundred percent sure what you want to achieve. If you want a complete synchronous design then your if rising_edge(CLK) should be the top IF statement. Further the T signal is not required in the sensitivity list as a change of this signal does not affect any output signal directly.

Upvotes: 0

Staszek
Staszek

Reputation: 951

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;

Upvotes: 2

Related Questions