2

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;
Kyle
  • 25
  • 5
  • I think you would benefit from a more consistent code indentation style. – scary_jeff May 22 '18 at 08:17
  • Can you please add your test bench? – JHBonarius May 22 '18 at 08:28
  • by the way, apart from all the better solutions proposed, you could also fix this by adding `temp_q` to the process sensitivity list. – JHBonarius May 22 '18 at 08:29
  • 1
    Possible duplicate of [Flip flop implementation with process. \[VHDL\]](https://stackoverflow.com/questions/17659138/flip-flop-implementation-with-process-vhdl) –  May 22 '18 at 09:11
  • 1
    Besides either needing q_temp in the sensitivity list as JHBonarius suggests or moving the the assignment to Q to it's own process/concurrent statement, you don't need T in the sensitivity list. It's inside the if statement with the rising edge condition. –  May 22 '18 at 09:19

2 Answers2

2

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;
Staszek
  • 849
  • 11
  • 28
0

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.

po.pe
  • 1,047
  • 1
  • 12
  • 27