1

I'm trying to implement JK flip-flop in VHDL, and here is my code:

library ieee;
use ieee.std_logic_1164.all;

entity jk_flip_flop is
port(
    J, K     : in std_logic;
    clk      : in std_logic;
    Q, Q_bar : out std_logic
);
end jk_flip_flop;

architecture behavioral of jk_flip_flop is
begin
   process(J, K, clk)
        variable temp: std_logic;
   begin
        if (clk'event and clk='1') then
             temp:='1' when(J='1' AND K='0') else
                    '0' when(J='0' AND K='1') else
                    NOT temp when(J='1' AND K='1') else
                    temp when(J='0' AND K='0');
              Q <= temp;
              Q_bar <= NOT temp;
         end if;
    end process;
end behavioral;

The error I'm getting from it is:

Error (10500): VHDL syntax error at jk_flip_flop.vhd(18) near text "when";  expecting ";"
Error (10500): VHDL syntax error at jk_flip_flop.vhd(18) near text "else";  expecting ":=", or "<="
Error (10500): VHDL syntax error at jk_flip_flop.vhd(19) near text "else";  expecting ":=", or "<="
Error (10500): VHDL syntax error at jk_flip_flop.vhd(20) near text "else";  expecting ":=", or "<="
Error (10500): VHDL syntax error at jk_flip_flop.vhd(21) near text ";";  expecting ":=", or "<="

What exactly is wrong here? Am I not allowed to use when-else inside a process or is the syntax of when-else statement wrong here?

Also I'm confused whether I need to pass J and K into the process above, or is it enough if I pass only clk, since it should be enough if the new output gets produced at rising edge of the clock pulse.

theCursedPirate
  • 165
  • 1
  • 1
  • 7

1 Answers1

2

So your temp := value when ... else ... statement only works outside of a process statement. So you've got three options.

Option 1

Upgrade to VHDL 2008, where you can also use this kind of statement in a process.

Option 2

Use a global variable to store the next value... something like:

architecture behavioral of jk_flip_flop is
   signal Q_val: std_logic;
   signal Q_next: std_logic;
begin
   Q_next <= '1' when(J='1' AND K='0') else
             '0' when(J='0' AND K='1') else
             NOT Q_val when(J='1' AND K='1') else
             Q_val;
   Q <= Q_next;
   Q_bar <= not Q_val;

   process(clk)
   begin
        if (clk'event and clk='1') then
             Q_val := Q_next;
         end if;
    end process;
end behavioral;

Option 3

Use ifs instead of when.

architecture behavioral of jk_flip_flop is
begin
   process(J, K, clk)
        variable temp: std_logic;
   begin
        if (clk'event and clk='1') then
             if (J='1' and K='0') then
               temp := '1';
             elsif (J='0' AND K='1') then
               temp := '0';
             elsif (J='1' AND K='1') then
               temp := NOT temp;
             end if;
             Q <= temp;
             Q_bar <= NOT temp;
         end if;
    end process;
end behavioral;

I'm not sure if this will work though... I thought temp would need to be defined at the architecture level for it to have a memory... But I could be wrong about that.

And on the sensitivity list...

Also I'm confused whether I need to pass J and K into the process above, or is it enough if I pass only clk, since it should be enough if the new output gets produced at rising edge of the clock pulse.

You only need to pass clk in.

Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
  • 1
    Vhdl has no "global variables". In your answer you used a `signal` which in your answer is neither global nor a variable. – Tricky Mar 02 '22 at 06:44
  • A variable can have "memory". The inference will depend upon the behaviour in the code. The inference will have nothing to do with where the variable is declared. In your example though, the register is inferred from the signal `Q` while the variable `temp` simply infers combinatorial logic. To infer a register with a variable, the value must be read before it is assigned. – Tricky Mar 02 '22 at 06:45
  • @Tricky: Thanks. "Global variable" was really just a way to note a signal outside of the process. I'd encourage you to do a edit if you think there's a better way to word it. For the second point, the code (at least in option 3) does read `temp`, when `J=1 and K=1`. – Bill Lynch Mar 02 '22 at 16:34
  • Would it make a difference if Q_val and Q_next were declared as a variable instead of signal? – theCursedPirate Mar 03 '22 at 10:09
  • @theCursedPirate Can't you only have variables inside a process? In which case... I don't think I understand your question. – Bill Lynch Mar 03 '22 at 15:24
  • I only realized that today. Sorry for the silly question. – theCursedPirate Mar 06 '22 at 15:45