-- test various D flip flops -- dff.vhdl this could be three or more files library IEEE; use IEEE.std_logic_1164.all; entity nand2 is -- simple two input nand gate with delay port(a : in std_logic; b : in std_logic; c : out std_logic); end entity nand2; architecture circuits of nand2 is begin -- circuits of nand2 c <= a nand b after 1 ns; end architecture circuits; -- of nand2 library IEEE; use IEEE.std_logic_1164.all; entity nand3 is -- simple three input nand gate with delay port(a : in std_logic; b : in std_logic; c : in std_logic; d : out std_logic); end entity nand3; architecture circuits of nand3 is begin -- circuits of nand3 d <= not(a and b and c) after 1 ns; end architecture circuits; -- of nand3 library IEEE; use IEEE.std_logic_1164.all; entity dff1 is -- simple DFF four nand gates port(d : in std_logic; -- q follows d when c=1 c : in std_logic; q : out std_logic; q_bar : out std_logic); end entity dff1; architecture circuits of dff1 is signal d_bar, s_bar, r_bar, qt, qf : std_logic; begin -- circuits of dff1 i1: d_bar <= not d after 500 ps; n1: entity work.nand2 port map(d, c , s_bar); n2: entity work.nand2 port map(d_bar, c , r_bar); n3: entity work.nand2 port map(s_bar, qf , qt ); n4: entity work.nand2 port map(r_bar, qt , qf ); d1: q <= qt; d2: q_bar <= qf; end architecture circuits; -- of dff1 library IEEE; use IEEE.std_logic_1164.all; entity dff2 is -- edge triggered DFF six nand gates port(d : in std_logic; -- q follows d when c goes 0 to 1 c : in std_logic; reset : in std_logic; q : out std_logic; q_bar : out std_logic); end entity dff2; architecture circuits of dff2 is signal s, r, s_bar, r_bar, qt, qf : std_logic; begin -- circuits of dff2 n1: entity work.nand3 port map(reset, d, r , r_bar); n2: entity work.nand3 port map(r_bar, c , s, r); n3: entity work.nand3 port map(reset, s_bar, c , s); n4: entity work.nand2 port map(r_bar, s , s_bar); n5: entity work.nand2 port map(s , qf , qt ); n6: entity work.nand3 port map(reset, r , qt , qf ); d1: q <= qt; d2: q_bar <= qf; end architecture circuits; -- of dff2 library STD; use STD.textio.all; library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_textio.all; use IEEE.std_logic_arith.all; entity dff is end dff; architecture circuits of dff is signal c: std_logic := '0'; signal d: std_logic := '0'; signal q: std_logic_vector(1 to 2); signal q_bar: std_logic_vector(1 to 2); signal reset : std_logic := '0'; type trace6 is array (1 to 6) of std_logic_vector(0 to 64); signal trace : trace6; type label6 is array (1 to 6) of string(1 to 6); signal labels : label6 := ("d ", "c ", "q1 ", "q1_bar", "q2 ", "q2_bar"); procedure print_values is -- format output variable my_line : LINE; begin write(my_line, string'("d=")); write(my_line, d); write(my_line, string'(", c=")); write(my_line, c); write(my_line, string'(", q=")); write(my_line, q); write(my_line, string'(" q_bar=")); write(my_line, q_bar); write(my_line, string'(" at ")); write(my_line, now); writeline(output, my_line); end print_values; 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 63 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 63 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 -- circuits of dff d1: entity WORK.dff1 port map(d, c, q(1), q_bar(1)); -- parallel code d2: entity WORK.dff2 port map(d, c, reset, q(2), q_bar(2)); -- parallel code reset <= '1' after 5 ns; driver: process -- serial code variable my_line : LINE; begin -- process driver write(my_line, string'("dff.vhdl clock and d change at same time")); writeline(output, my_line); write(my_line, string'("q1 and q1_bar are level sensitive DFF")); writeline(output, my_line); write(my_line, string'("q2 and q2_bar are rising edge sensitive DFF")); writeline(output, my_line); for i in 0 to 64 loop if i/16 mod 2 = 0 then c <= '0'; else c <= '1'; end if; if i/8 mod 2 = 0 then d <= '0'; else d <= '1'; end if; wait for 500 ps; -- propagating signals -- print_values; -- write output trace(1)(i) <= d; trace(2)(i) <= c; trace(3)(i) <= q(1); trace(4)(i) <= q_bar(1); trace(5)(i) <= q(2); trace(6)(i) <= q_bar(2); end loop; -- i print_trace; -- print saved values wait for 100 ns; end process driver; end architecture circuits; -- of dff