library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; entity controllore is port ( CLK : in std_logic; RESET : in std_logic; ONOFF : in std_logic; FULL : in std_logic; TEMP_REF : in unsigned(6 downto 0); TEMP_CORR : in unsigned(6 downto 0); GIRO : in std_logic; MOTOR_ON : out std_logic; RES_ON : out std_logic; WATER : out unsigned(1 downto 0)); end controllore; architecture ESAME of controllore is type stato1 is (idle,riempimento,lettura,scarica,attesa,riscaldamento); signal cs1,ns1 : stato1; type stato2 is (idle,attesa,attiva,lettura); signal cs2,ns2 : stato2; signal onoff_clk, onoff_clk2, start, stop, read_temperature, read_speed,attiva_motore : std_logic; signal current_count_4s, next_count_4s : unsigned(11 downto 0); signal current_count_1s, next_count_1s : unsigned(9 downto 0); signal current_count_giri, next_count_giri : unsigned(4 downto 0); begin --coppia di registri per campionare i fronti di salita e discesa di onoff process(clk,reset) begin if reset = '1' then onoff_clk <= '0'; else if clk'event and clk='1' then onoff_clk <= onoff; end if; end if; end process; process(clk,reset) begin if reset = '1' then onoff_clk2 <= '0'; else if clk'event and clk='1' then onoff_clk2 <= onoff_clk; end if; end if; end process; start <= '1' when onoff_clk2 = '0' and onoff_clk = '1' else '0'; stop <= '1' when onoff_clk2 = '1' and onoff_clk = '0' else '0'; -- CONTATORE PER 4 SECONDI process(clk) begin if clk'event and clk='1' then if reset = '1' or read_temperature='1' then current_count_4s <= conv_unsigned(0, 12); else current_count_4s <= next_count_4s; end if; end if; end process; next_count_4s <= current_count_4s + conv_unsigned (1,12); read_temperature<= '1' when current_count_4s = conv_unsigned (2,12) else '0'; -- macchina a stati process(clk,reset) begin if reset = '1' then cs1 <= idle; else if clk'event and clk='1' then cs1 <= ns1; end if; end if; end process; process(cs1,start,read_temperature,stop,TEMP_REF,TEMP_CORR,FULL) begin RES_ON <= '0'; WATER <= "00"; case cs1 is when idle => if(start = '1') then ns1 <= riempimento; else ns1 <= cs1; end if; when riempimento => WATER <= "11"; if (FULL = '1') then ns1 <= attesa; else ns1 <= cs1; end if; when attesa => if (stop='1') then ns1 <= scarica; else RES_ON <= '0'; if (read_temperature = '1') then ns1 <= lettura; else ns1 <= cs1; end if; end if; when lettura => if (stop='1') then ns1 <= scarica; else if (TEMP_REF > TEMP_CORR) then ns1 <= riscaldamento; else ns1 <= attesa; end if; end if; when riscaldamento => if (stop='1') then ns1 <= scarica; else RES_ON <= '1'; if (read_temperature = '1') then ns1 <= lettura; else ns1 <= cs1; end if; end if; when scarica => if (FULL = '1') then ns1 <= cs1; WATER <= "01"; else ns1 <= idle; end if; when others => ns1 <= idle; end case; end process; --seconda parte -- macchina a stati process(clk,reset) begin if reset = '1' then cs2 <= idle; else if clk'event and clk='1' then cs2 <= ns2; end if; end if; end process; process(cs2,start,read_speed,stop,attiva_motore) begin MOTOR_ON <= '0'; case cs2 is when idle => if(start = '1') then ns2 <= attesa; else ns2 <= cs2; end if; when attesa => if (stop='1') then ns2 <= idle; else MOTOR_ON <= '0'; if (read_speed = '1') then ns2 <= lettura; else ns2 <= cs2; end if; end if; when lettura => if (stop='1') then ns2 <= idle; else if (attiva_motore='1') then ns2 <= attiva; else ns2 <= attesa; end if; end if; when attiva => if (stop='1') then ns2 <= idle; else MOTOR_ON <= '1'; if (read_speed = '1') then ns2 <= lettura; else ns2 <= cs2; end if; end if; when others => ns2 <= idle; end case; end process; -- CONTATORE PER 1 SECOND0 process(clk) begin if clk'event and clk='1' then if reset = '1' or read_speed='1' then current_count_1s <= conv_unsigned(0, 10); else current_count_1s <= next_count_1s; end if; end if; end process; next_count_1s <= current_count_1s + conv_unsigned (1,10); read_speed <= '1' when current_count_1s = conv_unsigned (2,10) else '0'; --contatore numero di giri process(clk) begin if clk'event and clk='1' then if reset = '1' or read_speed = '1' then current_count_giri <= conv_unsigned(0, 5); else if GIRO='1' then current_count_giri <= next_count_giri; end if; end if; end if; end process; next_count_giri <= current_count_giri + conv_unsigned (1,5); attiva_motore <= '1' when (current_count_giri >= conv_unsigned(25,5)) else '0'; end esame;