--------------------------------------------------------------------------- -- This VHDL file was developed by Daniel Llamocca (2013). It may be -- freely copied and/or distributed at no cost. Any persons using this -- file for any purpose do so at their own risk, and are responsible for -- the results of such use. Daniel Llamocca does not guarantee that -- this file is complete, correct, or fit for any particular purpose. -- NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. This notice must -- accompany any copy of this file. -------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.math_real.log2; use ieee.math_real.ceil; entity lights_pattern is port (resetn, clock, stop: in std_logic; x, sel: in std_logic_vector (1 downto 0); segs: out std_logic_vector (6 downto 0); EN: out std_logic_vector (3 downto 0)); end lights_pattern; architecture Behavioral of lights_pattern is component my_genpulse generic (COUNT: INTEGER:= (10**8)/2); -- (10**8)/2 cycles of T = 10 ns --> 0.5 s port (clock, resetn, E: in std_logic; Q: out std_logic_vector ( integer(ceil(log2(real(COUNT)))) - 1 downto 0); z: out std_logic); end component; component my_rege generic (N: INTEGER:= 4); port ( clock, resetn: in std_logic; E, sclr: in std_logic; -- sclr: Synchronous clear D: in std_logic_vector (N-1 downto 0); Q: out std_logic_vector (N-1 downto 0)); end component; type state is (S1, S2a, S3a, S4a, S5a, S6a, S7a, S8a, S2b, S3b, S4b, S2c, S3c, S4c, S2d, S3d, S4d, S5d, S6d); signal y: state; type stateo is (S1, S2); signal yo: stateo; signal E_fsm, E, Esg, za, zb, zc, zd, z, s: std_logic; signal dseg, seg: std_logic_vector (7 downto 0); signal psegs: std_logic_vector (6 downto 0); begin -- Counter: 1.5 s ga: my_genpulse generic map (COUNT => 3*((10**8)/2)) port map (clock => clock, resetn => resetn, E => '1', z => za); -- Counter: 1.0 s gb: my_genpulse generic map (COUNT => 10**8) port map (clock => clock, resetn => resetn, E => '1', z => zb); -- Counter: 0.5 s gc: my_genpulse generic map (COUNT => (10**8)/2) port map (clock => clock, resetn => resetn, E => '1', z => zc); -- Counter: 0.25 s gd: my_genpulse generic map (COUNT => (10**8)/4) port map (clock => clock, resetn => resetn, E => '1', z => zd); -- Multiplexor for the counter outputs: with x select z <= za when "00", zb when "01", zc when "10", zd when others; E <= z and not(stop); -- 8-bit register rP: my_rege generic map (N => 8) port map (clock => clock, resetn => resetn, E => Esg, sclr => '0', D => dseg, Q => seg); -- Multiplexor for the 7-segment displays: with s select psegs <= seg(6 downto 3)&"000" when '0', seg(7)&"00"&seg(2 downto 0)&'0' when others; -- segs: |a|b|c|d|e|f|g| segs <= not(psegs); -- Active-low outputs -- Counter: 0.001 s gfsm: my_genpulse generic map (COUNT => 10**5) port map (clock => clock, resetn => resetn, E => '1', z => E_fsm); -- 1-to-2 decoder with s select EN <= "1011" when '0', "0111" when others; -- Main FSM: Transitions: process (resetn, clock, E, sel) begin if resetn = '0' then -- asynchronous signal y <= S1; -- if resetn asserted, go to initial state: S1 elsif (clock'event and clock = '1') then case y is when S1 => if E = '1' then case sel is when "00" => y <= S2a; when "01" => y <= S2b; when "10" => y <= S2c; when others => y <= S2d; end case; else y <= S1; end if; when S2a => if E = '1' then y <= S3a; else y <= S2a; end if; when S3a => if E = '1' then y <= S4a; else y <= S3a; end if; when S4a => if E = '1' then y <= S5a; else y <= S4a; end if; when S5a => if E = '1' then y <= S6a; else y <= S5a; end if; when S6a => if E = '1' then y <= S7a; else y <= S6a; end if; when S7a => if E = '1' then y <= S8a; else y <= S7a; end if; when S8a => if E = '1' then y <= S1; else y <= S8a; end if; when S2b => if E = '1' then y <= S3b; else y <= S2b; end if; when S3b => if E = '1' then y <= S4b; else y <= S3b; end if; when S4b => if E = '1' then y <= S1; else y <= S4b; end if; when S2c => if E = '1' then y <= S3c; else y <= S2c; end if; when S3c => if E = '1' then y <= S4c; else y <= S3c; end if; when S4c => if E = '1' then y <= S1; else y <= S4c; end if; when S2d => if E = '1' then y <= S3d; else y <= S2d; end if; when S3d => if E = '1' then y <= S4d; else y <= S3d; end if; when S4d => if E = '1' then y <= S5d; else y <= S4d; end if; when S5d => if E = '1' then y <= S6d; else y <= S5d; end if; when S6d => if E = '1' then y <= S1; else y <= S6d; end if; end case; end if; end process; Outputs: process (y, E, sel) begin -- Initialization of FSM outputs: dseg <= (others => '0'); Esg <= '0'; case y is when S1 => if E = '1' then case sel is when "00" => dseg <= "00000111"; Esg <= '1'; when "01" => dseg <= "00000101"; Esg <= '1'; when "10" => dseg <= "00010001"; Esg <= '1'; when others => dseg <= "00110011"; Esg <= '1'; end case; end if; when S2a => if E = '1' then dseg <= "00001110"; Esg <= '1'; end if; when S3a => if E = '1' then dseg <= "00011100"; Esg <= '1'; end if; when S4a => if E = '1' then dseg <= "00111000"; Esg <= '1'; end if; when S5a => if E = '1' then dseg <= "01110000"; Esg <= '1'; end if; when S6a => if E = '1' then dseg <= "11100000"; Esg <= '1'; end if; when S7a => if E = '1' then dseg <= "11000001"; Esg <= '1'; end if; when S8a => if E = '1' then dseg <= "10000011"; Esg <= '1'; end if; when S2b => if E = '1' then dseg <= "00010100"; Esg <= '1'; end if; when S3b => if E = '1' then dseg <= "01010000"; Esg <= '1'; end if; when S4b => if E = '1' then dseg <= "01000001"; Esg <= '1'; end if; when S2c => if E = '1' then dseg <= "00100010"; Esg <= '1'; end if; when S3c => if E = '1' then dseg <= "01000100"; Esg <= '1'; end if; when S4c => if E = '1' then dseg <= "10001000"; Esg <= '1'; end if; when S2d => if E = '1' then dseg <= "11100111"; Esg <= '1'; end if; when S3d => if E = '1' then dseg <= "11001100"; Esg <= '1'; end if; when S4d => if E = '1' then dseg <= "11111001"; Esg <= '1'; end if; when S5d => if E = '1' then dseg <= "10000111"; Esg <= '1'; end if; when S6d => if E = '1' then dseg <= "01111000"; Esg <= '1'; end if; end case; end process; -- FSM: serializer for the 7-segment display Trans: process (resetn, clock, E_fsm) begin if resetn = '0' then -- asynchronous signal yo <= S1; -- if resetn asserted, go to initial state: S1 elsif (clock'event and clock = '1') then if E_fsm = '1' then case yo is when S1 => yo <= S2; when S2 => yo <= S1; end case; end if; end if; end process; Outps: process (yo) begin case yo is when S1 => s <= '0'; when S2 => s <= '1'; end case; end process; end Behavioral;