VHDL JK Flip-Flop with logic gates

flipflopvhdl

I am trying to make a JK flip-flop in ActiveHDL environment.
I want to make it with logic gates.

It should look like this:

enter image description here

This is my code:

--nand3.vhd
library ieee;
use ieee.std_logic_1164.all;

entity nand3 is 
    port(
    A,B,C: in std_logic;
    D: out std_logic
    );
end entity;

architecture nand3 of nand3 is 
begin
    D <= not(A and B and C);
end architecture;

--nand2.vhd
library ieee;
use ieee.std_logic_1164.all;

entity nand2 is 
    port(
    A,B: in std_logic;
    C: out std_logic
    );
end entity;

architecture nand2 of nand2 is 
begin
    C <= not (A and B);
end architecture;

--JK.vhd
library ieee;
use ieee.std_logic_1164.all;

entity JK is 
    port(
    J,K: in std_logic;
    Q, NQ: out std_logic;
    CLK: in std_logic
    );
end entity;

architecture JK of JK is
component nand3 
    port(
    A,B,C: in std_logic;
    D: out std_logic
    );
end component;

component nand2
    port(
    A,B: in std_logic;
    C: out std_logic
    );
end component;  

signal s1, s2: std_logic;

begin
    C11: nand3 port map(NQ,J,CLK,S1);
    C12: nand3 port map(Q,K,CLK,S2);
    C21: nand2 port map(S1,NQ,Q);
    C22: nand2 port map(S2,Q,NQ);
end architecture;

The problem is that i am getting this error when I compile JK.vhd file:

# Error: COMP96_0411: JK.vhd : (31, 22): Actual of mode "out" can not be assigned to formal "A" of mode "in"
# Error: COMP96_0411: JK.vhd : (32, 22): Actual of mode "out" can not be assigned to formal "A" of mode "in"
# Error: COMP96_0411: JK.vhd : (33, 25): Actual of mode "out" can not be assigned to formal "B" of mode "in"
# Error: COMP96_0411: JK.vhd : (34, 25): Actual of mode "out" can not be assigned to formal "B" of mode "in"

I think the problem is the backward signals.

Edit1
Improved JK.vhd file. It compiles, but it still does not work:

--JK.vhd
library ieee;
use ieee.std_logic_1164.all;

entity JK is 
    port(
    J,K: in std_logic;
    Q, NQ: out std_logic;
    CLK: in std_logic
    );
end entity;

architecture JK of JK is

    component nand3 port(
        A,B,C: in std_logic;
        D: out std_logic
    );
    end component;

    component nand2 port(
        A,B: in std_logic;
        C: out std_logic
    );
    end component;

signal s1, s2: std_logic;

-- internal copies of output signals
-- initialize
signal Q_int: std_logic := '1';
signal NQ_int: std_logic := '0';

begin
    C11: nand3 port map(NQ_int,J,CLK,S1);
    C12: nand3 port map(Q_int,K,CLK,S2);
    C21: nand2 port map(S1,NQ_int,Q_int);
    C22: nand2 port map(S2,Q_int,NQ_int);

    -- Assign values to output ports
    Q <= Q_int;
    NQ <= NQ_int;
end architecture;

Best Answer

Let's look at one example:

  1. In your entity JK, we have an output signal named Q.
  2. In older versions of VHDL, you are not allowed to read from output signals.
  3. You tie Q to one of the inputs of C12.
  4. You can't do that, because we can't read the value of Q because it is an output signal.

Here's an example of how to fix it:

library ieee;
use ieee.std_logic_1164.all;

entity JK is port(
    J,K: in std_logic;
    Q, NQ: out std_logic;
    CLK: in std_logic
    );
end entity;

architecture JK of JK is
    component nand3 port(
        A,B,C: in std_logic;
        D: out std_logic
    );
    end component;

    component nand2 port(
        A,B: in std_logic;
        C: out std_logic
    );
    end component;  

    signal s1, s2, s3, s4: std_logic;

begin
    C11: nand3 port map(S3,J,CLK,S1);
    C12: nand3 port map(S4,K,CLK,S2);
    C21: nand2 port map(S1,S3,S4);
    C22: nand2 port map(S2,S4,S3);

    NQ <= S3;
    Q  <= S4;
end architecture;

I'm sure we could create better names for these S[1234] variables though.

Related Topic