-- jkff_cntr.vhdl full JK flip flop coded as nand gates, tested as counter -- also can be a master slave flip flop -- also can be an edge triggered flip flop -- also can be an AC flip flop library IEEE; use IEEE.std_logic_1164.all; entity nand3 is -- basic three input nand gate (old technology) port(in1 : in std_logic; -- input 1 in2 : in std_logic; -- input 2 (provide '1' for in3 : in std_logic; -- input 3 unused inputs) outp : out std_logic); -- output end entity nand3; architecture behavior of nand3 is begin -- behavior outp <= not (in1 and in2 and in3) after 10 ps; end behavior; -- of nand3 library IEEE; use IEEE.std_logic_1164.all; entity jkff is -- built from nand gates (old technology) port(j : in std_logic; -- j input on falling clk k : in std_logic; -- k input on falling clk clk : in std_logic; -- trigger on falling clock r : in std_logic; -- unclocked reset, low to reset s : in std_logic; -- unclocked set, low to set q : out std_logic; -- output q_bar : out std_logic); -- complement output end entity jkff; use IEEE.std_logic_textio.all; use STD.textio.all; architecture circuit of jkff is -- internal signals signal jc, kc, m0, m0_bar, m1, m1_bar, clk_bar, qin, qin_bar : std_logic; signal debug : boolean := false; -- for debug print component nand3 is port(in1 : in std_logic; in2 : in std_logic; in3 : in std_logic; outp : out std_logic); end component nand3; begin -- circuit n1: nand3 port map(j, clk, '1', jc); n2: nand3 port map(k, clk, '1', kc); n3: nand3 port map(m0_bar, jc, s, m0); n4: nand3 port map(m0, kc, r, m0_bar); n5: nand3 port map(clk, '1', '1', clk_bar); n6: nand3 port map(m0, clk_bar, '1', m1); n7: nand3 port map(m0_bar, clk_bar, '1', m1_bar); n8: nand3 port map(qin_bar, m1, s, qin); n9: nand3 port map(qin, m1_bar, r, qin_bar); q <= qin after 10 ps; q_bar <= qin_bar after 10 ps; print: process (j, k, jc, kc, m0, m0_bar, m1, m1_bar, qin, qin_bar, clk, clk_bar) variable my_line : line; begin if debug then write(my_line, string'("j=")); write(my_line, j); write(my_line, string'(" k=")); write(my_line, k); write(my_line, string'(" jc=")); write(my_line, jc); write(my_line, string'(" kc=")); write(my_line, kc); write(my_line, string'(" m0=")); write(my_line, m0); write(my_line, string'(" m0_=")); write(my_line, m0_bar); write(my_line, string'(" m1=")); write(my_line, m1); write(my_line, string'(" m1_=")); write(my_line, m1_bar); write(my_line, string'(" q=")); write(my_line, qin); write(my_line, string'(" q_=")); write(my_line, qin_bar); write(my_line, string'(" clk=")); write(my_line, clk); write(my_line, string'(" clk_=")); write(my_line, clk_bar); write(my_line, string'(" at ")); write(my_line, now); writeline(output, my_line); end if; end process print; end architecture circuit; -- of jkff -- test circuit that makes a four bit counter out of JK flip flops entity jkff_cntr is -- test bench end jkff_cntr; library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_textio.all; use STD.textio.all; architecture circuit of jkff_cntr is signal clk : std_logic := '0'; signal reset : std_logic := '0'; -- reset signal to all JK flip flops signal set : std_logic := '1'; -- set signal to all JK flip flops -- J flip flop inputs (also used in cntr as K inputs) are '1', other outputs signal q0, q1, q2, q3 : std_logic := '0'; -- JK flip flop outputs signal q0_bar, q1_bar, q2_bar, q3_bar : std_logic := '1'; -- JK flip flop complement outputs type trace6 is array (1 to 6) of std_logic_vector(0 to 65); signal trace : trace6; type label6 is array (1 to 6) of string(1 to 6); signal labels : label6 := ("reset ", "clk ", "q0 ", "q1 ", "q2 ", "q3 "); procedure print_trace is variable my_line : LINE; begin for j in 1 to 6 loop write(my_line, string'(" ")); for i in 1 to 64 loop if trace(j)(i)='1' and trace(j)(i-1)='1' then write(my_line, '_'); else write(my_line, ' '); end if; end loop; -- i writeline(output, my_line); write(my_line, labels(j)); for i in 1 to 64 loop if trace(j)(i)='U' then write(my_line, character' ('U')); elsif trace(j)(i)='X' then write(my_line, character' ('X')); elsif (trace(j)(i)='1' and trace(j)(i-1)='0') or (trace(j)(i)='0' and trace(j)(i-1)='1') then write(my_line, '|'); elsif trace(j)(i)='0' then write(my_line, '_'); else write(my_line, ' '); end if; end loop; -- i writeline(output, my_line); end loop; -- j writeline(output, my_line); -- blank line end print_trace; begin -- circuit of jkff_cntr clk <= not clk after 10 ns; -- control circuitry, can have long ripple reset <= '1' after 1 ns; -- one time reset -- circuitry that makes a four bit counter out of JK flip flops -- NOTE! wiring the q output to the next clock input triggers the flip -- wired by the twisted q and q_bar outputs into the j-k inputs jkff0: entity WORK.jkff port map(q0_bar, q0, clk, reset, set, q0, q0_bar); jkff1: entity WORK.jkff port map(q1_bar, q1, q0, reset, set, q1, q1_bar); jkff2: entity WORK.jkff port map(q2_bar, q2, q1, reset, set, q2, q2_bar); jkff3: entity WORK.jkff port map(q3_bar, q3, q2, reset, set, q3, q3_bar); print: process variable my_line : line; begin -- process print if reset='0' then write(my_line, string'("q3, q2, q1, q0 q3_ q2_ q1_ q0_ clk")); writeline(output, my_line); wait for 10 ns; end if; write(my_line, q3); write(my_line, string'(" ")); write(my_line, q2); write(my_line, string'(" ")); write(my_line, q1); write(my_line, string'(" ")); write(my_line, q0); write(my_line, string'(" ")); write(my_line, q3_bar); write(my_line, string'(" ")); write(my_line, q2_bar); write(my_line, string'(" ")); write(my_line, q1_bar); write(my_line, string'(" ")); write(my_line, q0_bar); write(my_line, string'(" ")); write(my_line, clk); write(my_line, string'(" at ")); write(my_line, now); writeline(output, my_line); wait for 20 ns; end process print; tracer: process -- serial code begin -- process tracer for i in 0 to 65 loop wait for 5 ns; -- propagating signals -- record values for print_trace trace(1)(i) <= reset; trace(2)(i) <= clk; trace(3)(i) <= q0; trace(4)(i) <= q1; trace(5)(i) <= q2; trace(6)(i) <= q3; end loop; -- i print_trace; -- print saved values wait for 100 ns; end process tracer; end architecture circuit; -- of jkff_cntr