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; POWER : in unsigned(7 downto 0); THETA : out unsigned(7 downto 0); E_STIM : out unsigned(17 downto 0)); end controllore; architecture ESAME of controllore is type stato is (idle,sample,compare,decrease,wait20min,startcount); signal cs,ns : stato; signal count10sec, next_count10sec : unsigned(13 downto 0); signal count20min, next_count20min : unsigned(20 downto 0); signal angle, next_angle : unsigned(7 downto 0); signal start_count10sec, start_count20min, angle_enable, sample_enable, energy_enable : std_logic; signal diecisecondi, ventiminuti, compare_power,forward : std_logic; signal current_power, old_power : unsigned(7 downto 0); signal energy, next_energy : unsigned(7 downto 0); begin process(clk) begin if clk'event and clk='1' then if reset='1' then cs<=idle; else cs<=ns; end if; end if; end process; process(diecisecondi,ventiminuti,cs,compare_power) begin start_count10sec <= '0'; start_count20min <= '0'; angle_enable <= '0'; forward <= '0'; sample_enable <= '0'; energy_enable <= '0'; case cs is when idle => ns <= compare; when sample => sample_enable <= '1'; angle_enable <= '1'; forward <= '1'; start_count10sec <= '1'; ns <= compare; when compare => if diecisecondi = '1' then if compare_power = '1' then ns <= decrease; else ns <= sample; end if; else ns<= cs; end if; when decrease => ns <= wait20min; angle_enable <= '1'; energy_enable <= '1'; forward <= '0'; start_count20min <= '1'; when wait20min => if ventiminuti = '1' then ns <= startcount; else ns <= cs; end if; when startcount => start_count20min <= '1'; ns <= sample; when others => ns <= idle; end case; end process; --contatore che pilota l'inclinazione del pannello solare process(clk) begin if clk'event and clk='1' then if reset='1' then angle <= conv_unsigned(30,8); else angle <= next_angle; end if; end if; end process; process(angle, angle_enable, forward) begin if (angle_enable = '0') then next_angle <= angle; else if (forward = '1') then next_angle <= angle + conv_unsigned(1,8); else next_angle <= angle - conv_unsigned(1,8); end if; end if; end process; --contatore per 20 minuti: N. di bit = 1000 (1KHz) * 60 * 20 = 1200000, 2^21 = 2097152 process(clk) begin if clk'event and clk='1' then if reset='1' or start_count20min='1' then count20min <= conv_unsigned(0,21); else count20min <= next_count20min; end if; end if; end process; next_count20min <= count20min + conv_unsigned(1,21); ventiminuti <= '1' when count20min = conv_unsigned(25,21) else '0'; --contatore per 10 secondi: N. di bit = 1000 (1KHz) * 10 = 10000, 2^14 = 16384 process(clk) begin if clk'event and clk='1' then if reset='1' or start_count10sec='1' then count10sec <= conv_unsigned(0,14); else count10sec <= next_count10sec; end if; end if; end process; next_count10sec <= count10sec + conv_unsigned(1,14); diecisecondi <= '1' when count10sec = conv_unsigned(1,14) else '0'; --shifter register campionamento dati di ingresso process(clk) begin if clk'event and clk='1' then if reset='1' or start_count20min='1'then current_power <= (others => '0'); elsif clk'event and clk='1' then if sample_enable='1' then current_power <= POWER; end if; end if; end if; end process; --shifter register campionamento dati di ingresso process(clk) begin if clk'event and clk='1' then if (reset='1' or start_count20min='1') then old_power <= (others => '0'); elsif clk'event and clk='1' then if sample_enable = '1' then old_power <= current_power; end if; end if; end if; end process; compare_power <= '1' when old_power > current_power else '0'; theta <= angle; --registro per accumulare energia process(clk) begin if clk'event and clk='1' then if reset='1' then energy <= (others => '0'); elsif clk'event and clk='1' then if energy_enable = '1' then energy <= next_energy; end if; end if; end if; end process; next_energy <= energy + current_power; e_stim <= energy&conv_unsigned(0,10); end ESAME;