Hi everyone
Consider the JK flip flop schematic below:
I write the following VHDL code for it:
Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity jkff is
Port ( j : in STD_LOGIC;
k : in STD_LOGIC;
clk : in STD_LOGIC;
q : out STD_LOGIC;
qb : out STD_LOGIC);
end jkff;
architecture Behavioral of jkff is
signal a, b, c, d : std_logic;
begin
q <= d;
qb <= c;
a <= not (j and clk and c);
b <= not (k and clk and d);
d <= not (c and a);
c <= not (d and b);
end Behavioral;
When I synthesize it using Xilinx ISE 14.5, a combinatorial feedback loop is detected and the outputs q and qb remain uninitialized. However, when I implement the D Flip Flop in a similar manner, according the following schematic:
Code:
entity dff is
Port ( d : in STD_LOGIC;
c : in STD_LOGIC;
q : out STD_LOGIC;
qb : out STD_LOGIC);
end dff;
architecture Behavioral of dff is
signal e, f, g, h, i, j, k, l, qs, qbs : std_logic;
begin
qs <= k nand qbs;
qbs <= l nand qs;
e <= not c;
h <= not e;
f <= not(d and e);
g <= not(e and f);
i <= not(f and j);
j <= not(g and i);
k <= not(i and h);
l <= not(h and k);
q <= qs;
qb <= qbs;
end Behavioral;
The D Flip Flop synthesizes and simulates just fine.
My question is, why does the JK Flip Flop not compile while the D Flip Flop does even though the code and schematic is so much similar?
Both designs are legal VHDL, both implement combinational loops. Combinational generate a warning but don't prevent compilation or simulation of a circuit. If there are actual error messages, please report it exactly.
Uninitialized std_logic signals can be a problem in simulation, they aren't in hardware synthesis. Explicit initialization may be required for consistent simulation.
I presume that designing memory primitives in VHDL isn't but an exercise problem, it makes no sense in terms of FPGA synthesis. It's impossible to achieve reasonable timing with these components.
Hi FvM
Thanks for the reply. First off, this is an academic exercise and I am trying to understand the objective behind this. I can simulate a JK FF using behavioural syntax (if-else) but not using logic gates.
I was a bit inaccurate in my statement. I am simulating it. By "synthesize", I meant the design compiles.
I tried initializing d to 0 and c to 1 but the q and qb outputs still remain uninitialized. I tried initializing d to 1 and c to 0, but the same result.
Now, I have gotten rid of the c and d signals, resulting in the following code:
Code:
architecture Behavioral of jkff is
signal a, b : std_logic;
begin
a <= not (j and clk and qb);
b <= not (k and clk and q);
q <= not (qb and a);
qb <= not (q and b);
end Behavioral;
But, the simulation result in still the same:
Any clues as to why the q and qb outputs are always un-initialized?
Both designs are legal VHDL, both implement combinational loops. Combinational generate a warning but don't prevent compilation or simulation of a circuit. If there are actual error messages, please report it exactly.
Uninitialized std_logic signals can be a problem in simulation, they aren't in hardware synthesis. Explicit initialization may be required for consistent simulation.
I presume that designing memory primitives in VHDL isn't but an exercise problem, it makes no sense in terms of FPGA synthesis. It's impossible to achieve reasonable timing with these components.
Because Q and Qb rely on each other, and neither has an initial value, then in simulation, they will always be U.
The best way around this would be to have an internal version of Q and Qb and give them an initial value:
Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
architecture Behavioral of jkff issignal a, b :std_logic;signal q_i, qb_i =std_logic:= '0';begin
a <=not(j and clk and qb_i);
b <=not(k and clk and q_i);
q_i <=not(qb_i and a);
qb_i <=not(q_i and b);
q <= q_i;
qb <= qb_i;end Behavioral;
Hi
That's similar to my original code. Nonetheless, I pasted your code, fixed a minor typo and simulated it. The result is:
ERROR: at 0 ps: Iteration limit 10000 is reached. Possible zero delay oscillation detected where simulation can not advance in time because signals can not resolve to a stable value in File "E:/Users/Arnold/Documents/VHDL/jkff/jkff.vhd" Line 51. Please correct this code in order to advance past the current simulation time.
Because Q and Qb rely on each other, and neither has an initial value, then in simulation, they will always be U.
The best way around this would be to have an internal version of Q and Qb and give them an initial value:
Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
architecture Behavioral of jkff issignal a, b :std_logic;signal q_i, qb_i =std_logic:= '0';begin
a <=not(j and clk and qb_i);
b <=not(k and clk and q_i);
q_i <=not(qb_i and a);
qb_i <=not(q_i and b);
q <= q_i;
qb <= qb_i;end Behavioral;
I believe the JK flip flop model involves some more problems. If you get rid of the uninitialized signals, e.g. by adding reset logic, the real problems come. The circuit involves a kind of ring oscillator (combinational feedback with odd number of inversions), active if J and K or both '1'. It gives errors in functional simulation unless you add transport delay to the circuit. I don't oversee if it will give useful results then. In hardware simulation, the results seem to depend on arbitrary gate delays and are not as expected for JK FF.
This is essentially a problem of the level triggered JK flip-flop topology. Real JK flip-flops are edge sensitive by using a master-slave topology like your DFF model does. You should proceed to a reasonable JK model.
I will read up on the ring oscillator to better understand your comment. Do you recommend any specific source for that?
Meanwhile, I wired up the master-slave JK FF as follows. My JKFF looks like:
Code:
architecture Behavioral of jkff is
signal a, b : std_logic;
signal q_i, qb_i : std_logic := '0';
begin
a <= not (j and clk and qb_i);
b <= not (k and clk and q_i);
q_i <= not (qb_i and a);
qb_i <= not (q_i and b);
q <= q_i;
qb <= qb_i;
end Behavioral;
The master slave JK FF is:
Code:
architecture Behavioral of msjk is
component jkff is
Port ( j : in STD_LOGIC;
k : in STD_LOGIC;
clk : in STD_LOGIC;
q : buffer STD_LOGIC;
qb : buffer STD_LOGIC);
end component;
signal q1, qb1 : std_logic;
begin
master : jkff port map(j, k, clk, q1, qb1);
slave : jkff port map(q1, qb1, not clk, q, qb);
end Behavioral;
However, when simulating, I get the following error:
ERROR: at 0 ps: Iteration limit 10000 is reached. Possible zero delay oscillation detected where simulation can not advance in time because signals can not resolve to a stable value in File "E:/Users/Saqib Ilyas/Documents/namal/DDH/VHDL/jkff/jkff.vhd" Line 51. Please correct this code in order to advance past the current simulation time.
I believe the JK flip flop model involves some more problems. If you get rid of the uninitialized signals, e.g. by adding reset logic, the real problems come. The circuit involves a kind of ring oscillator (combinational feedback with odd number of inversions), active if J and K or both '1'. It gives errors in functional simulation unless you add transport delay to the circuit. I don't oversee if it will give useful results then. In hardware simulation, the results seem to depend on arbitrary gate delays and are not as expected for JK FF.
This is essentially a problem of the level triggered JK flip-flop topology. Real JK flip-flops are edge sensitive by using a master-slave topology like your DFF model does. You should proceed to a reasonable JK model.
The ring oscillator point was meaned as an intuitive explanation for the unstable logic behavior. "zero delay oscillations" is exactly what you get when simulating this kind of circuit without transport delay. Instead of an oscillator, you want to design a bistable circuit which is falling into either "0" or "1" state like the DFF circuit does. It's not reasonable to enlarge about oscillators, instead study topologies of working memory circuits.
In case of the master slave JK FF, it doesn't help to cascade two of the unstable level triggered JKs, instead use JK logic in front of the working MS DFF, as suggested in literature.