library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; entity SQUAREWAVE is port( BUTTON : in std_logic; CLOCK : in std_logic; RESET : in std_logic; WAVE440 : out std_logic ); end SQUAREWAVE; architecture A of SQUAREWAVE is signal SELECT_WAVE : std_logic; signal wave : std_logic; type stato is (on1, on0, off1, off0); signal current_state, next_state : stato; signal current_count, next_count : unsigned(4 downto 0); begin ----- -- Multiplexer, se la selezione è attiva porto in uscita la forma d'onda -- altrimenti porto in uscita un valore basso ----- WAVE440 <= wave when SELECT_WAVE = '1' else '0'; ----- -- Macchina a stati per la gestione del pulsante e del segnale di selezione ----- -- registro di stato process(CLOCK) begin if CLOCK'event and CLOCK='1' then if RESET = '1' then current_state <= off0; else current_state <= next_state; end if; end if; end process; -- processo combinatorio per uscite e calcolo stato futuro process(current_state, BUTTON) begin case current_state is when off0 => SELECT_WAVE <= '0'; if BUTTON = '1' then next_state <= on1; else next_state <= off0; end if; when on1 => SELECT_WAVE <= '1'; if BUTTON = '1' then next_state <= on1; else next_state <= on0; end if; when on0 => SELECT_WAVE <= '1'; if BUTTON = '1' then next_state <= off1; else next_state <= on0; end if; when off1 => SELECT_WAVE <= '0'; if BUTTON = '1' then next_state <= off1; else next_state <= off0; end if; when others => SELECT_WAVE <= '0'; next_state <= off0; end case; end process; ---- -- Ora definisco un contatore, che conta un numero di cicli corrispondenti a T = 1/440 -- Questo contatore, ogni volta che arriva al valore corrispondente deve azzerarsi e -- ricominciare da 0 -- -- se f = 440Hz ==> T = 2.27ms ==> Ncicli = T/Tck = 2.27ms/0.1ms = 22.7 -- (arrotondiamo Ncicli = 22, e ci vorranno 5 bit) ---- -- registro del contatore process(CLOCK) begin if CLOCK'event and CLOCK='1' then if RESET = '1' then current_count <= conv_unsigned(0,5); else current_count <= next_count; end if; end if; end process; -- logica combinatoria per calcolo stato futuro next_count <= conv_unsigned(0,5) when current_count=conv_unsigned(21,5) else current_count+conv_unsigned(1,5); ---- -- logica combinatoria per calcolo forma d'onda ---- wave <= '1' when current_count < conv_unsigned(11,5) else '0'; end A;