-- Risultati di sintesi, su MAX7000 (EPM7064LC44-7) -- fmax = 37MHz -- 51 LC, 23 FF -- Essendo la fmax >> 5MHz, -- si privilegia l'ottimizzazione dell'occupazione -- di area nel processo di sintesi, non risultando necessario -- perseguire ulteriori ottimizzazioni di prestazione library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; entity unitacontrollo is port ( CLOCK : in std_logic; RESET : in std_logic; START : in std_logic; SENSORDATA : in unsigned(11 downto 0); BUSY : out std_logic; PHI1 : out std_logic; SIG1 : out std_logic; SIG2 : out std_logic; PHI2 : out std_logic; AVERAGE : out unsigned(11 downto 0) ); end unitacontrollo; architecture A of unitacontrollo is type control_state is (idle, s1, s2, s3, s4); signal present_state, next_state : control_state; signal accumulate : std_logic; signal last_count : std_logic; signal current_cycle, next_cycle : unsigned(3 downto 0); -- con 4 bit conto da 0 a 15 -- per sommare 16 numeri a 12 bit mi servono 16 bit signal accumulator_reg, sum : unsigned(15 downto 0); begin -- commutazione dello stato della FSM process(clock) begin if clock'event and clock = '1' then if reset = '1' then present_state <= idle; else present_state <= next_state; end if; end if; end process; -- processo combinatorio, calcolo uscite e stato successivo process(present_state, START, last_count) begin case present_state is when idle => PHI1 <= '0'; PHI2 <= '0'; SIG1 <= '0'; SIG2 <= '0'; accumulate <= '0'; BUSY <= '0'; if START = '1' then next_state <= s1; else next_state <= idle; end if; when s1 => PHI1 <= '1'; PHI2 <= '0'; SIG1 <= '1'; SIG2 <= '0'; accumulate <= '0'; BUSY <= '1'; next_state <= s2; when s2 => PHI1 <= '1'; PHI2 <= '0'; SIG1 <= '0'; SIG2 <= '1'; BUSY <= '1'; accumulate <= '0'; next_state <= s3; when s3 => PHI1 <= '0'; PHI2 <= '1'; SIG1 <= '0'; SIG2 <= '0'; BUSY <= '1'; accumulate <= '0'; next_state <= s4; when s4 => PHI1 <= '0'; PHI2 <= '0'; SIG1 <= '0'; SIG2 <= '0'; BUSY <= '1'; accumulate <= '1'; if last_count = '1' then next_state <= idle; else next_state <= s1; end if; when others => PHI1 <= '0'; PHI2 <= '0'; SIG1 <= '0'; SIG2 <= '0'; BUSY <= '0'; accumulate <= '0'; next_state <= idle; end case; end process; -- contatore delle 16 letture, che viene resettato -- ad ogni inizio di operazione process(clock) begin if clock'event and clock = '1' then if reset = '1' or START = '1' then current_cycle <= conv_unsigned(15,4); elsif accumulate = '1' then current_cycle <= next_cycle; end if; end if; end process; -- valore successivo di conteggio next_cycle <= current_cycle - conv_unsigned(1,4); -- ultimo ciclo di lettura last_count <= '1' when current_cycle = conv_unsigned(0,4) else '0'; -- registro in cui accumulo la somma dei campioni -- Viene azzerato quando comincia un nuova -- richiesta di elaborazione -- OVVIAMENTE, come è ragionevole supporre, START deve andare basso prima che accumulate si attivi -- (specifica sulle temporizzazioni degli ingressi della nostra entity) process(clock) begin if clock'event and clock = '1' then if reset = '1' or START = '1' then accumulator_reg <= conv_unsigned(0,16); elsif accumulate = '1' then accumulator_reg <= sum; end if; end if; end process; -- calcolo della somma sum <= accumulator_reg + conv_unsigned(SENSORDATA,16); -- finalmente la media AVERAGE(11 downto 0) <= accumulator_reg(15 downto 4); end A;